diff --git a/.clang-format b/.clang-format index 57c1b1d78..949f7e5a6 100644 --- a/.clang-format +++ b/.clang-format @@ -1,99 +1,289 @@ # SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2018-2020 Carles Fernandez-Prades +# SPDX-FileCopyrightText: 2018-2024 Carles Fernandez-Prades --- Language: Cpp # BasedOnStyle: Google # More info: https://clang.llvm.org/docs/ClangFormatStyleOptions.html AccessModifierOffset: -4 AlignAfterOpenBracket: DontAlign -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlinesLeft: true -AlignOperands: true -AlignTrailingComments: true +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseArrows: false + AlignCaseColons: false +AlignConsecutiveTableGenBreakingDAGArgColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenCondOperatorColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenDefinitionColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseExpressionOnASingleLine: true AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLambdasOnASingleLine: All AllowShortLoopsOnASingleLine: true AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: false +AttributeMacros: + - __capability BinPackArguments: true BinPackParameters: true +BitFieldColonSpacing: Both BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterExternBlock: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true + IndentBraces: true + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakAfterReturnType: None +BreakArrays: true BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always BreakBeforeBraces: GNU +BreakBeforeInlineASMColon: OnlyMultiline BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakFunctionDefinitionParameters: false +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +BreakTemplateDeclarations: MultiLine ColumnLimit: 0 CommentPragmas: '^ IWYU pragma:' -ConstructorInitializerAllOnOneLineOrOnePerLine: true +CompactNamespaces: false ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: true DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] -IncludeBlocks: Merge +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Merge IncludeCategories: - Regex: '^.*.h"' Priority: 1 + SortPriority: 0 + CaseSensitive: false - Regex: '^.*(benchmark|boost|gflags|glog|gnsssdr|gnuradio|gnsstk|gsl|gtest|pmt|uhd|volk)/' Priority: 2 + SortPriority: 0 + CaseSensitive: false - Regex: '^.*(armadillo|iio|matio|pugixml)' Priority: 2 + SortPriority: 0 + CaseSensitive: false - Regex: '.*' Priority: 3 + SortPriority: 0 + CaseSensitive: false - Regex: '^<.*\.h>' Priority: 4 + SortPriority: 0 + CaseSensitive: false - Regex: '^<.*' Priority: 5 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true IndentWidth: 4 IndentWrappedFunctionNames: false -KeepEmptyLinesAtTheStartOfBlocks: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLines: + AtEndOfFile: false + AtStartOfBlock: false + AtStartOfFile: true +LambdaBodyIndentation: Signature +LineEnding: DeriveLF MacroBlockBegin: '' MacroBlockEnd: '' +MainIncludeChar: Quote MaxEmptyLinesToKeep: 2 NamespaceIndentation: None +ObjCBinPackProtocolList: Auto ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: false +PackConstructorInitializers: NextLine +PenaltyBreakAssignment: 2 PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer ReflowComments: true -SortIncludes: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false SpacesBeforeTrailingComments: 2 -SpacesInAngles: false +SpacesInAngles: Never SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + ExceptDoubleParentheses: false + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false SpacesInSquareBrackets: false Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TableGenBreakInsideDAGArg: DontBreak TabWidth: 8 UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE ... diff --git a/.clang-tidy b/.clang-tidy index 0ef91e2ec..3ddbd1a51 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -120,7 +120,6 @@ Checks: '-*, readability-uppercase-literal-suffix' WarningsAsErrors: '' HeaderFilterRegex: '' -AnalyzeTemporaryDtors: false FormatStyle: 'file' CheckOptions: - key: performance-unnecessary-copy-initialization.ExcludedContainerTypes diff --git a/.github/workflows/gnss-sdr_archs.yml b/.github/workflows/gnss-sdr_archs.yml index ca9595187..f3e86bb1f 100644 --- a/.github/workflows/gnss-sdr_archs.yml +++ b/.github/workflows/gnss-sdr_archs.yml @@ -58,8 +58,8 @@ jobs: CXX: ${{ matrix.compiler.cxx }} shell: /bin/sh install: | - apt-get update -q -y - apt-get install -q -y ${{ matrix.compiler.name }} git ninja-build cmake \ + apt update + apt install -y ${{ matrix.compiler.name }} git ninja-build cmake \ libboost-dev libboost-date-time-dev libboost-system-dev libboost-filesystem-dev \ libboost-thread-dev libboost-chrono-dev libboost-serialization-dev \ liblog4cpp5-dev gnuradio-dev gr-osmosdr libpugixml-dev libpcap-dev libblas-dev \ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index eeecbaf38..0dd3b46c8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2020-2022 Carles Fernandez-Prades +# SPDX-FileCopyrightText: 2020-2024 Carles Fernandez-Prades name: Simple CI on: @@ -18,9 +18,9 @@ jobs: - uses: actions/checkout@v4 - name: install dependencies run: | - sudo apt-get update -y + sudo apt update sudo apt install -y libunwind-dev - sudo apt-get install -y --no-install-recommends ninja-build cmake \ + sudo apt install -y --no-install-recommends ninja-build cmake \ libboost-dev libboost-date-time-dev libboost-system-dev libboost-filesystem-dev \ libboost-thread-dev libboost-chrono-dev libboost-serialization-dev \ liblog4cpp5-dev gnuradio-dev gr-osmosdr libpugixml-dev libpcap-dev libblas-dev \ @@ -28,18 +28,23 @@ jobs: libgnutls-openssl-dev libmatio-dev googletest protobuf-compiler libprotobuf-dev \ python3-mako liborc-0.4-dev - name: configure - run: cd build && cmake -GNinja .. + run: cmake -S . -B build -GNinja - name: build - run: cd build && ninja + run: cmake --build build - name: check - run: cd build && ninja check && ../install/volk_gnsssdr_profile && ../install/run_tests + run: cmake --build build --target check && ./install/volk_gnsssdr_profile && ./install/run_tests - name: default position_test - run: cd build && cmake -DENABLE_SYSTEM_TESTING_EXTRA=ON .. && ninja && ../install/position_test + run: | + cmake -S . -B build -DENABLE_SYSTEM_TESTING_EXTRA=ON -DENABLE_UNIT_TESTING_EXTRA=OFF && \ + cmake --build build && ./install/position_test && ./install/run_tests --gtest_filter=Osnma* build-macos: runs-on: macos-latest steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' - name: install dependencies run: | brew update @@ -53,21 +58,27 @@ jobs: rm /usr/local/bin/pydoc3.1* || true rm /usr/local/bin/python3.1* || true export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 - brew install ninja hdf5 automake armadillo lapack libmatio \ - gflags glog gnuradio log4cpp openssl pugixml protobuf python-mako + brew link --overwrite python@3.12 + brew install ninja hdf5 automake armadillo lapack libmatio gnuradio openssl pugixml protobuf boost + pip3 install mako - name: configure - run: cd build && cmake -GNinja .. + run: cmake -S . -B build -GNinja - name: build - run: cd build && ninja + run: cmake --build build - name: check - run: cd build && ninja check && ../install/volk_gnsssdr_profile && ../install/run_tests + run: cmake --build build --target check && ./install/volk_gnsssdr_profile && ./install/run_tests - name: default position_test - run: cd build && cmake -DENABLE_SYSTEM_TESTING_EXTRA=ON .. && ninja && ../install/position_test + run: | + cmake -S . -B build -DENABLE_SYSTEM_TESTING_EXTRA=ON -DENABLE_UNIT_TESTING_EXTRA=OFF && \ + cmake --build build && ./install/position_test && ./install/run_tests --gtest_filter=Osnma* build-macos-xcode: runs-on: macos-latest steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' - name: install dependencies run: | brew update @@ -81,40 +92,49 @@ jobs: rm /usr/local/bin/pydoc3.1* || true rm /usr/local/bin/python3.1* || true export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 - brew install ninja pkg-config hdf5 automake armadillo lapack libmatio \ - gflags glog gnuradio log4cpp openssl pugixml protobuf python-mako + brew link --overwrite python@3.12 + brew install ninja pkg-config hdf5 automake armadillo lapack libmatio gnuradio openssl pugixml protobuf boost + pip3 install mako - name: configure - run: cd build && cmake -GXcode .. + run: cmake -S . -B build -GXcode - name: build - run: cd build && xcodebuild -configuration Release + run: cmake --build build --config Release - name: check run: | - cd build - xcodebuild -configuration Release -target check - ../install/volk_gnsssdr_profile - ../install/run_tests + cmake --build build --config Release --target check + ./install/volk_gnsssdr_profile + ./install/run_tests - name: default position_test run: | - cd build - cmake -DENABLE_SYSTEM_TESTING_EXTRA=ON .. - xcodebuild -configuration Release -target position_test - ../install/position_test + cmake -S . -B build -DENABLE_SYSTEM_TESTING_EXTRA=ON -DENABLE_UNIT_TESTING_EXTRA=OFF + cmake --build build --config Release --target position_test + ./install/position_test + ./install/run_tests --gtest_filter=Osnma* clang-format: runs-on: ubuntu-latest + strategy: + matrix: + path: + - 'src' + - 'tests' + - 'utils' steps: - uses: actions/checkout@v4 - name: run clang-format - uses: jidicula/clang-format-action@v4.11.0 + uses: jidicula/clang-format-action@v4.14.0 with: - clang-format-version: "15" - check-path: "src" - exclude-regex: '(libs\/gsl\/)|^.*\.(cu|proto)$' + clang-format-version: "19" + check-path: ${{ matrix.path }} + exclude-regex: '(libs\/gsl\/)|(tmpl)|(cpu_features)|^.*\.(cu|proto)$' clang-tidy: runs-on: macos-latest steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' - name: install dependencies run: | brew update @@ -128,15 +148,16 @@ jobs: rm /usr/local/bin/pydoc3.1* || true rm /usr/local/bin/python3.1* || true export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 - brew install llvm pkg-config hdf5 armadillo lapack gflags glog gnuradio libmatio \ - log4cpp openssl pugixml protobuf python-mako + brew link --overwrite python@3.12 + brew install ninja pkg-config hdf5 automake armadillo lapack libmatio gnuradio openssl pugixml protobuf llvm boost + pip3 install mako ln -s $(brew --prefix llvm)/bin/clang-tidy /usr/local/bin ln -s $(brew --prefix llvm)/bin/clang-apply-replacements /usr/local/bin - ln -s $(brew --prefix llvm)/bin/run-clang-tidy /usr/local/bin + ln -s $(brew --prefix llvm)/bin/run-clang-tidy.py /usr/local/bin - name: Prepare run - run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.13.0 core_monitor core_libs pvt_libs + run: cmake -S . -B build && cmake --build build --target volk_gnsssdr_module gtest-1.16.0 core_monitor core_libs pvt_libs - name: run clang-tidy - run: cd build && run-clang-tidy -fix + run: cd build && /opt/homebrew/opt/llvm/bin/run-clang-tidy -fix - name: check run: | git diff > clang_tidy.patch @@ -149,11 +170,11 @@ jobs: steps: - uses: actions/checkout@v4 - name: install dependencies - run: sudo apt-get install python3-pip && sudo pip3 install cpplint + run: sudo apt install python3-pip && sudo pip3 install cpplint - name: run checks - run: "find ./src/ -iname *.h -o -iname *.cc | xargs cpplint - --filter=-,+build/class,+build/c++14,+build/deprecated,+build/explicit_make_pair,\ - +build/include_what_you_use,+build/printf_format,+build/storage_class,\ + run: "find ./src/ ./utils ./tests -iname *.h -o -iname *.cc | xargs cpplint + --filter=-,+build/class,+build/deprecated,+build/explicit_make_pair,\ + +build/forward_decl,+build/printf_format,+build/storage_class,\ +readability/constructors,+readability/namespace,+readability/newline,\ +readability/utf8,+runtime/casting,+runtime/explicit,\ +runtime/indentation_namespace,+runtime/init,+runtime/invalid_increment,\ @@ -163,7 +184,7 @@ jobs: +whitespace/end-of-line,+whitespace/ending-newline,+whitespace/semicolon,\ +whitespace/tab --exclude=./src/core/interfaces/gnss_block_interface.h --exclude=./src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/hwcaps_for_testing.* - --exclude=./src/utils/nav-listener/build/nav_message.pb.h" + --exclude=./utils/nav-listener/build/nav_message.pb.h" prettier-markdown: runs-on: ubuntu-latest @@ -180,7 +201,6 @@ jobs: - uses: actions/checkout@v4 - name: install dependencies run: | - sudo python -m pip install --upgrade pip sudo pip install cmakelint - name: check CMake scripts run: find . -iname "CMakeLists.txt" -o -iname "*.cmake" | xargs cmakelint --filter=-linelength,-readability/wonkycase @@ -189,21 +209,21 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install dependencies run: | python -m pip install --upgrade pip pip install mako - name: configure shell: powershell - run: cd build; cmake -G "Visual Studio 17 2022" ..\src\algorithms\libs\volk_gnsssdr_module\volk_gnsssdr + run: cmake -S src\algorithms\libs\volk_gnsssdr_module\volk_gnsssdr -B build -G "Visual Studio 17 2022" - name: build run: cmake --build build --config Release - name: test shell: powershell - run: cd build; ctest -C Release + run: ctest -C Release --test-dir build - name: install run: cmake --install build - name: run profile @@ -216,11 +236,11 @@ jobs: - name: install dependencies run: sudo apt install python3-mako liborc-dev - name: configure - run: cd build && cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr + run: cmake -S src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr -B build - name: build - run: cd build && make -j2 + run: cmake --build build - name: install - run: cd build && sudo make install && sudo ldconfig + run: sudo cmake --install build && sudo ldconfig - name: test run: volk_gnsssdr_profile @@ -228,29 +248,39 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 - - name: install dependencies - run: pip3 install mako + - uses: actions/setup-python@v5 + with: + python-version: '3.13' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mako - name: configure - run: cd build && cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr + run: cmake -S src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr -B build - name: build - run: cd build && make -j2 && sudo make install + run: cmake --build build && sudo cmake --install build - name: test - run: cd build && ctest -C Release --exclude-regex volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc + run: ctest -C Release --test-dir build --exclude-regex volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc volk-gnsssdr-macos-xcode: runs-on: macos-latest steps: - uses: actions/checkout@v4 - - name: install dependencies - run: pip3 install mako + - uses: actions/setup-python@v5 + with: + python-version: '3.13' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mako - name: configure - run: cd build && cmake -GXcode ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr + run: cmake -S src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr -B build -GXcode - name: build - run: cd build && xcodebuild -configuration Release + run: cmake --build build --config Release - name: install - run: cd build && sudo xcodebuild -configuration Release -target install + run: sudo cmake --install build - name: test - run: cd build && ctest -C Release --exclude-regex volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc + run: ctest -C Release --test-dir build --exclude-regex --exclude-regex volk_gnsssdr_32fc_32f_rotator_dotprodxnpuppet_32fc shellcheck: runs-on: ubuntu-latest @@ -259,7 +289,7 @@ jobs: - name: install dependencies run: sudo apt install shellcheck - name: check scripts - run: shellcheck src/utils/scripts/* + run: shellcheck utils/scripts/* REUSE-compliance: runs-on: ubuntu-latest @@ -268,4 +298,4 @@ jobs: - name: Check REUSE compliance uses: docker://fsfe/reuse with: - args: lint + args: lint \ No newline at end of file diff --git a/.github/workflows/volk_gnsssdr_android.yml b/.github/workflows/volk_gnsssdr_android.yml index 04a33c3d4..2d5da7473 100644 --- a/.github/workflows/volk_gnsssdr_android.yml +++ b/.github/workflows/volk_gnsssdr_android.yml @@ -32,29 +32,32 @@ jobs: - name: Update repositories run: sudo apt update - name: Install dependencies - run: sudo apt install -y cmake openjdk-11-jre-headless wget unzip make python3-mako + run: sudo apt install -y cmake python3-mako + + # Setup Java + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + # Setup Android SDK, and auto-accept licenses - name: Install Android SDK run: | - wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip - mkdir android-sdk-linux - unzip -qq android-sdk.zip -d android-sdk-linux - export ANDROID_HOME=./android-sdk-linux - echo y | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=android-sdk-linux --update + wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip && \ + mkdir android-sdk-linux && unzip -qq android-sdk.zip -d android-sdk-linux && export ANDROID_HOME=./android-sdk-linux && echo y | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=android-sdk-linux --update && \ (echo y; echo y; echo y; echo y; echo y; echo y; echo y; echo y) | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=android-sdk-linux --licenses + # Call SDKManager to install the Android NDK - name: Install Android NDK - run: $GITHUB_WORKSPACE/android-sdk-linux/cmdline-tools/bin/sdkmanager --sdk_root=$GITHUB_WORKSPACE/android-sdk-linux --install "ndk;24.0.8215888" --channel=3 + run: $GITHUB_WORKSPACE/android-sdk-linux/cmdline-tools/bin/sdkmanager --sdk_root=$GITHUB_WORKSPACE/android-sdk-linux --install "ndk;27.2.12479018" --channel=3 + # Setup build directory - name: Setup ${{ matrix.arch.name }} shell: bash run: | - cd $GITHUB_WORKSPACE/ - cd build - cmake -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/android-sdk-linux/ndk/24.0.8215888/build/cmake/android.toolchain.cmake \ - -DANDROID_ABI=${{ matrix.arch.name }} \ - -DANDROID_PLATFORM=android-24 \ - ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr + cd $GITHUB_WORKSPACE/ && mkdir -p build && cd build && \ + cmake -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/android-sdk-linux/ndk/27.2.12479018/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ matrix.arch.name }} -DANDROID_PLATFORM=android-34 ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr + # Build - name: Build ${{ matrix.arch.name }} shell: bash diff --git a/.github/workflows/volk_gnsssdr_archs.yml b/.github/workflows/volk_gnsssdr_archs.yml index 6f4e31454..b265c1f6e 100644 --- a/.github/workflows/volk_gnsssdr_archs.yml +++ b/.github/workflows/volk_gnsssdr_archs.yml @@ -1,21 +1,17 @@ # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: 2023 Carles Fernandez-Prades -name: Run volk_gnsssdr tests +name: Run gnss-sdr in non-x86 archs on: push: - paths: - - "src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/**" - - "CMakeLists.txt" - pull_request: - paths: - - "src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/**" - - "CMakeLists.txt" + branches: + - "**-archs" + - main workflow_dispatch: jobs: - build-ubuntu-non-x86: + gnss-sdr-non-x86: runs-on: ubuntu-latest name: ${{ matrix.distro }} ${{ matrix.arch }} ${{ matrix.compiler.name }} @@ -33,22 +29,22 @@ jobs: - arch: armv7 distro: ubuntu22.04 compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 } - - arch: ppc64le - distro: ubuntu22.04 - compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 } - - arch: s390x - distro: ubuntu22.04 - compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 } - arch: riscv64 distro: ubuntu22.04 compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 } + # - arch: ppc64le + # distro: ubuntu22.04 + # compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 } + # - arch: s390x + # distro: ubuntu22.04 + # compiler: { name: g++-12, cc: gcc-12, cxx: g++-12 } steps: - uses: actions/checkout@v4 - uses: uraimo/run-on-arch-action@v2.7.1 - name: Build in non-x86 container - # continue-on-error: ${{ contains(fromJson('["ppc64le", "s390x"]'), matrix.arch) }} - id: build + name: Test in non-x86 container + continue-on-error: ${{ contains(fromJson('["ppc64le", "s390x"]'), matrix.arch) }} + id: test with: arch: ${{ matrix.arch }} distro: ${{ matrix.distro }} @@ -56,24 +52,28 @@ jobs: setup: | mkdir -p "${PWD}/testing" dockerRunArgs: | - --volume "${PWD}:/volk_gnsssdr" + --volume "${PWD}:/gnss-sdr" env: | CC: ${{ matrix.compiler.cc }} CXX: ${{ matrix.compiler.cxx }} shell: /bin/sh install: | - apt-get update -q -y - apt-get install -q -y git cmake python3-mako liborc-dev ${{ matrix.compiler.name }} + apt update + apt install -y ${{ matrix.compiler.name }} git ninja-build cmake \ + libboost-dev libboost-date-time-dev libboost-system-dev libboost-filesystem-dev \ + libboost-thread-dev libboost-chrono-dev libboost-serialization-dev \ + liblog4cpp5-dev gnuradio-dev gr-osmosdr libpugixml-dev libpcap-dev libblas-dev \ + liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \ + libgnutls-openssl-dev libmatio-dev googletest protobuf-compiler libprotobuf-dev \ + python3-mako liborc-0.4-dev run: | - git config --global --add safe.directory /volk_gnsssdr - cd /volk_gnsssdr + git config --global --add safe.directory /gnss-sdr + cd /gnss-sdr cd testing - cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/ + mkdir install + cmake -DENABLE_SYSTEM_TESTING_EXTRA=ON -DCMAKE_INSTALL_PREFIX=/gnss-sdr/testing/install -DENABLE_INSTALL_TESTS=ON .. echo "Build with $(nproc) thread(s)" make -j$(nproc) - ./apps/volk_gnsssdr-config-info --alignment - ./apps/volk_gnsssdr-config-info --avail-machines - ./apps/volk_gnsssdr-config-info --all-machines - ./apps/volk_gnsssdr-config-info --malloc - ./apps/volk_gnsssdr-config-info --cc - ctest -V + make install + cd install/bin + ./position_test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 007b9ab0c..2155a88bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,30 @@ # SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2011 Carles Fernandez-Prades +# SPDX-FileCopyrightText: 2011-2024 Carles Fernandez-Prades *~ .*.swp -docs/doxygen/Doxyfile -docs/html -docs/latex -docs/GNSS-SDR_manual.pdf -src/tests/data/output.dat -thirdparty/ -src/utils/nav-listener/build -.settings -.project -.cproject -.idea -cmake-build-debug/ +/build/ +/build*/ +/cmake-build-debug/ +/data/ +/docs/doxygen/Doxyfile +/docs/html/ +/docs/latex/ +/docs/GNSS-SDR_manual.pdf +/gnss_sdr_pvt.nmea +/GSDR* +/HAS_* +/PVT_* +/Testing/ +/tests/data/output.dat +/thirdparty/ +/utils/nav-listener/build/ +/utils/nav-listener/build*/ /install +.cproject .DS_Store +.idea +.project .pydevproject -.vscode/ +.settings .vs/ -Testing/ +.vscode/ diff --git a/AUTHORS b/AUTHORS index ad0660662..00d9a4e75 100644 --- a/AUTHORS +++ b/AUTHORS @@ -33,39 +33,44 @@ Contact Information List of authors -------------------------------------------------------------------------------- -Carles Fernández-Prades carles.fernandez@cttc.cat Project manager -Javier Arribas javier.arribas@cttc.es Developer -Luis Esteve Elfau luis@epsilon-formacion.com Developer -Marc Majoral marc.majoral@cttc.cat Developer -Jordi Vilà-Valls jordi.vila-valls@isae-supaero.fr Consultant -Pau Closas pau.closas@northeastern.edu Consultant -Álvaro Cebrián Juan acebrianjuan@gmail.com Contributor -Andres Cecilia Luque a.cecilia.luque@gmail.com Contributor -Anthony Arnold anthony.arnold@uqconnect.edu.au Contributor -Antonio Ramos antonio.ramosdet@gmail.com Contributor -Carlos Avilés carlos.avilesr@googlemail.com Contributor -Cillian O'Driscoll cillian.odriscoll@gmail.com Contributor -Damian Miralles dmiralles2009@gmail.com Contributor -Daniel Fehr daniel.co@bluewin.ch Contributor -David Pubill david.pubill@cttc.cat Contributor -En Shin seanstone5923@gmail.com Contributor -Fran Fabra fabra@ice.csic.es Contributor -Gabriel Araujo gabriel.araujo.5000@gmail.com Contributor -Gerald LaMountain gerald@gece.neu.edu Contributor -Into Pääkkönen into.paakkonen@aalto.fi Contributor -Irene Pérez Riega iperrie@inta.es Contributor -Jim Melton jim.melton@sncorp.com Contributor -Josh Schindehette jschindehette@geontech.com Contributor -Leonardo Tonetto tonetto.dev@gmail.com Contributor -Malte Lenhart malte.lenhart@mailbox.org Contributor -Mara Branzanti mara.branzanti@gmail.com Contributor -Marc Molina marc.molina.pena@gmail.com Contributor -Marc Sales marcsales92@gmail.com Contributor -Piyush Gupta piyush04111999@gmail.com Contributor -Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor -Stefan van der Linden spvdlinden@gmail.com Contributor -Will Silberman wsilberm@google.com Contributor -Carlos Paniego carpanie@hotmail.com Artwork + +Carles Fernández-Prades carles.fernandez@cttc.cat Project manager +Javier Arribas javier.arribas@cttc.es Developer +Luis Esteve Elfau luis@epsilon-formacion.com Developer +Marc Majoral marc.majoral@cttc.cat Developer +Xavier Guerrero xavier.guerrero@cttc.es Developer +Jordi Vilà-Valls jordi.vila-valls@isae-supaero.fr Consultant +Pau Closas pau.closas@northeastern.edu Consultant +Álvaro Cebrián Juan acebrianjuan@gmail.com Contributor +Andres Cecilia Luque a.cecilia.luque@gmail.com Contributor +Anthony Arnold anthony.arnold@uqconnect.edu.au Contributor +Antonio Ramos antonio.ramosdet@gmail.com Contributor +Carlos Avilés carlos.avilesr@googlemail.com Contributor +Cesare Ghionoiu Martinez c.ghionoiu-martinez@tu-braunschweig.de Contributor +Cillian O'Driscoll cillian.odriscoll@gmail.com Contributor +Damian Miralles dmiralles2009@gmail.com Contributor +Daniel Fehr daniel.co@bluewin.ch Contributor +David Pubill david.pubill@cttc.cat Contributor +En Shin seanstone5923@gmail.com Contributor +Fran Fabra fabra@ice.csic.es Contributor +Gabriel Araujo gabriel.araujo.5000@gmail.com Contributor +Gerald LaMountain gerald@gece.neu.edu Contributor +Into Pääkkönen into.paakkonen@aalto.fi Contributor +Irene Pérez Riega iperrie@inta.es Contributor +Jim Melton jim.melton@sncorp.com Contributor +Josh Schindehette jschindehette@geontech.com Contributor +Leonardo Tonetto tonetto.dev@gmail.com Contributor +Malte Lenhart malte.lenhart@mailbox.org Contributor +Mara Branzanti mara.branzanti@gmail.com Contributor +Marc Molina marc.molina.pena@gmail.com Contributor +Marc Sales marcsales92@gmail.com Contributor +Piyush Gupta piyush04111999@gmail.com Contributor +Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor +Stefan van der Linden spvdlinden@gmail.com Contributor +Víctor Castillo-Agüero victorcastilloaguero@gmail.com Contributor +Will Silberman wsilberm@google.com Contributor +Carlos Paniego carpanie@hotmail.com Artwork + # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: 2011-2024 Carles Fernandez-Prades diff --git a/CITATION.cff b/CITATION.cff index 0f11b55f1..5aebc8b3c 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2024 C. Fernandez-Prades carles.fernandez(at)cttc.es +# SPDX-FileCopyrightText: 2024-2025 C. Fernandez-Prades carles.fernandez(at)cttc.es --- authors: - affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)" @@ -20,6 +20,11 @@ authors: family-names: Majoral given-names: Marc orcid: "https://orcid.org/0000-0001-6161-6747" + - affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)" + alias: xguerreropau + email: xavier.guerrero@cttc.es + family-names: Guerrero + given-names: Xavier - alias: Gastd email: gabriel.araujo.5000@gmail.com family-names: Araujo @@ -34,6 +39,11 @@ authors: email: mara.branzanti@gmail.com family-names: Branzanti given-names: Mara + - alias: castle055 + affiliation: "Instituto Nacional de Técnica Aeroespacial" + email: victorcastilloaguero@gmail.com + family-names: "Castillo-Agüero" + given-names: Víctor - alias: acebrianjuan email: acebrianjuan@gmail.com family-names: "Cebrián-Juan" @@ -51,6 +61,11 @@ authors: - email: daniel.co@bluewin.ch family-names: Fehr given-names: Daniel + - alias: cesaaargm + affiliation: "Technische Universität Braunschweig" + email: c.ghionoiu-martinez@tu-braunschweig.de + family-names: "Ghionoiu Martinez" + given-names: Cesare - alias: piyush0411 email: piyush04111999@gmail.com family-names: Gupta @@ -119,7 +134,7 @@ authors: family-names: "van der Linden" given-names: Stefan cff-version: "1.2.0" -date-released: "2024-01-23" +date-released: "2025-04-01" identifiers: - description: "The concept DOI of the work. This is a DOI always pointing to the latest stable release." type: doi @@ -327,4 +342,4 @@ repository-code: "https://github.com/gnss-sdr/gnss-sdr" title: GNSS-SDR type: software url: "https://gnss-sdr.org" -version: "0.0.19" +version: "0.0.20" diff --git a/CMakeLists.txt b/CMakeLists.txt index 99e567462..f5db2d939 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2010-2024 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2010-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause ################################################################################ @@ -16,7 +16,7 @@ endif() # Build type can still be overridden by setting -DCMAKE_BUILD_TYPE= set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") -cmake_minimum_required(VERSION 2.8.12...3.28) +cmake_minimum_required(VERSION 2.8.12...4.0) project(gnss-sdr CXX C) set(GNSSSDR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) # Allows to be a sub-project @@ -44,6 +44,10 @@ option(ENABLE_AD936X_SDR "Enable the use of AD936X front-ends using libiio, requ option(ENABLE_AD9361 "Enable the use of AD9361 direct to FPGA hardware, requires libiio" OFF) +option(ENABLE_MAX2771 "Enable the use of MAX2771 direct to FPGA hardware, requires the spidev driver" OFF) + +option(ENABLE_DMA_PROXY "Enable the use of the DMA direct to FPGA hardware, requires the DMA Proxy driver" OFF) + option(ENABLE_RAW_UDP "Enable the use of high-optimized custom UDP packet sample source, requires libpcap" OFF) option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNU Radio driver" OFF) @@ -52,6 +56,8 @@ option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal option(ENABLE_ZMQ "Enable GNU Radio ZeroMQ Messaging, requires gr-zeromq" ON) +option(ENABLE_ION "Enable ION GNSS-SDR Metadata Standard signal source" OFF) + # Performance analysis tools option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF) @@ -74,9 +80,20 @@ option(ENABLE_PACKAGING "Enable software packaging" OFF) option(ENABLE_OWN_GLOG "Download glog and link it to gflags" OFF) +option(ENABLE_GLOG_AND_GFLAGS "Force using Google glog and Gflags instead of Abseil" OFF) + +option(ENABLE_OWN_ABSEIL "Forces downloading and building of Abseil" OFF) +if(CMAKE_VERSION VERSION_LESS 3.24) + set(ENABLE_OWN_ABSEIL OFF) +endif() +if(ENABLE_OWN_ABSEIL) + set(ENABLE_OWN_GLOG OFF) + set(ENABLE_GLOG_AND_GFLAGS OFF) +endif() + option(ENABLE_OWN_ARMADILLO "Download and build Armadillo locally" OFF) -option(ENABLE_LOG "Enable logging" ON) +option(ENABLE_LOG "Enable internal logging" ON) option(ENABLE_ARMA_NO_DEBUG OFF) @@ -84,6 +101,8 @@ option(ENABLE_STRIP "Create stripped binaries without debugging symbols (in Rele option(Boost_USE_STATIC_LIBS "Use Boost static libs" OFF) +option(ENABLE_GNUTLS "Forces linking against GnuTLS" OFF) + if(ENABLE_PACKAGING) set(ENABLE_ARMA_NO_DEBUG ON) set(CMAKE_VERBOSE_MAKEFILE ON) @@ -178,9 +197,9 @@ endif() set(VERSION_INFO_MAJOR_VERSION 0) set(VERSION_INFO_API_COMPAT 0) if(${THIS_IS_A_RELEASE}) - set(VERSION_INFO_MINOR_VERSION 19) + set(VERSION_INFO_MINOR_VERSION 20) else() - set(VERSION_INFO_MINOR_VERSION 19.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) + set(VERSION_INFO_MINOR_VERSION 20.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) endif() set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION}) @@ -211,7 +230,7 @@ endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") include(DetectLinuxDistro) if(CMAKE_CROSSCOMPILING) - message(STATUS "Configuring GNSS-SDR v${VERSION} to be cross-compiled on ${LINUX_DISTRIBUTION} ${LINUX_VER} (${CMAKE_HOST_SYSTEM_PROCESSOR}) for ${CMAKE_SYSTEM_PROCESSOR} ${ARCHITECTURE_STRING}") + message(STATUS "Configuring GNSS-SDR v${VERSION} to be cross-compiled on ${LINUX_DISTRIBUTION} ${LINUX_VER} (${CMAKE_HOST_SYSTEM_PROCESSOR}) for ${CMAKE_SYSTEM_PROCESSOR}") else() message(STATUS "Configuring GNSS-SDR v${VERSION} to be built on GNU/Linux ${LINUX_DISTRIBUTION} ${LINUX_VER} ${ARCHITECTURE_STRING}") endif() @@ -329,25 +348,34 @@ set(GNSSSDR_MATIO_MIN_VERSION "1.5.3") set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0") set(GNSSSDR_PYTHON_MIN_VERSION "2.7") set(GNSSSDR_PYTHON3_MIN_VERSION "3.4") +set(GNSSSDR_ABSEIL_MIN_VERSION "20240116") ################################################################################ # Versions to download and build (but not to install system-wide) if not found ################################################################################ -set(GNSSSDR_ARMADILLO_LOCAL_VERSION "12.6.x") +set(GNSSSDR_ARMADILLO_LOCAL_VERSION "14.4.x") set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") -set(GNSSSDR_GLOG_LOCAL_VERSION "0.6.0") -set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.26") -set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "25.0") -set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.14") -set(GNSSSDR_GTEST_LOCAL_VERSION "1.13.0") -set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") -set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.0.0") -set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.8.3") +set(GNSSSDR_GLOG_LOCAL_VERSION "0.7.1") +set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.28") +set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "30.2") +set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.15") +set(GNSSSDR_GTEST_LOCAL_VERSION "1.16.0") +set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "origin/master") +set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.3.0") +set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.9.2") set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7") +set(GNSSSDR_ABSL_LOCAL_VERSION "origin/master") # live at head (see https://abseil.io/about/releases) # Downgrade versions if requirements are not met +if(CMAKE_VERSION VERSION_LESS "3.5") + set(GNSSSDR_ARMADILLO_LOCAL_VERSION "12.8.x") +endif() + +if(CMAKE_VERSION VERSION_LESS "3.22") + set(GNSSSDR_GLOG_LOCAL_VERSION "0.6.0") +endif() if(CMAKE_VERSION VERSION_LESS "3.16") set(GNSSSDR_GLOG_LOCAL_VERSION "0.5.0") endif() @@ -368,10 +396,25 @@ if(CMAKE_VERSION VERSION_LESS "3.4") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.10") endif() -if(CMAKE_CROSSCOMPILING OR CMAKE_VERSION VERSION_LESS "3.13") +if(CMAKE_VERSION VERSION_LESS "3.16") + set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "29.3") +endif() +if(CMAKE_CROSSCOMPILING OR CMAKE_VERSION VERSION_LESS "3.13" OR + ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0.0)) OR + ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0")) OR + ((CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11"))) set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "21.12") endif() +if(CMAKE_VERSION VERSION_LESS "3.16") + set(GNSSSDR_GTEST_LOCAL_VERSION "1.15.2") +endif() +if(CMAKE_VERSION VERSION_LESS "3.13" OR + (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3.1) OR + (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)) + set(GNSSSDR_GTEST_LOCAL_VERSION "1.13.0") +endif() + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR CMAKE_VERSION VERSION_LESS 3.5) @@ -570,6 +613,13 @@ set_package_properties(Threads PROPERTIES +################################################################################ +# Set GNSSSDR_LIB_PATHS and GNSSSDR_INCLUDE_PATHS +################################################################################ +include(GnsssdrFindPaths) + + + ################################################################################ # Googletest - https://github.com/google/googletest ################################################################################ @@ -714,6 +764,18 @@ endif() if(UNIX AND EXISTS "/usr/lib64") list(APPEND BOOST_LIBRARYDIR "/usr/lib64") # Fedora 64-bit fix endif() +if(NOT BOOST_ROOT) + # Workaround for Macports + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + if(${DETECT_MACPORTS} EQUAL 0) + if(EXISTS "${MACPORTS_PREFIX}/libexec/boost/1.76") + set(BOOST_ROOT "${MACPORTS_PREFIX}/libexec/boost/1.76") + elseif(EXISTS "${MACPORTS_PREFIX}/libexec/boost/1.71") + set(BOOST_ROOT "${MACPORTS_PREFIX}/libexec/boost/1.71") + endif() + endif() + endif() +endif() # Boost_ADDITIONAL_VERSIONS is only used internally by cmake to know the # formation of newer versions. No need to increase, not used anymore since newer # Boost provides its own CMake configuration files. @@ -729,8 +791,21 @@ set(BOOST_COMPONENTS atomic chrono date_time serialization system thread) if(NOT ${FILESYSTEM_FOUND}) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} filesystem) endif() -find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED) - +if(CMAKE_VERSION VERSION_LESS 3.30) + find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED) +else() + find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS}) + if(Boost_FOUND) + get_filename_component(BOOST_PREFIX ${Boost_INCLUDE_DIRS} DIRECTORY) + message(STATUS "Found Boost v${Boost_VERSION_STRING} at ${BOOST_PREFIX}") + else() + message(STATUS "Trying deprecated FindBoost Module ...") + if(POLICY CMP0167) + cmake_policy(SET CMP0167 OLD) + find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + endif() + endif() +endif() if(NOT Boost_FOUND) message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.") endif() @@ -1036,6 +1111,15 @@ endif() +################################################################################ +# Detect availability of shm_open +################################################################################ +unset(HAVE_SHM_OPEN CACHE) +include(CheckFunctionExists) +check_function_exists(shm_open HAVE_SHM_OPEN) + + + ################################################################################ # volk_gnsssdr module - GNSS-SDR's own VOLK library ################################################################################ @@ -1071,7 +1155,7 @@ if(NOT VOLKGNSSSDR_FOUND) elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(STATUS " sudo zypper install ${PYTHON_NAME}-Mako") else() - message(STATUS " sudo apt-get install ${PYTHON_NAME}-mako") + message(STATUS " sudo apt install ${PYTHON_NAME}-mako") endif() endif() message(FATAL_ERROR "Mako templates required to build VOLK_GNSSSDR") @@ -1088,7 +1172,7 @@ if(NOT VOLKGNSSSDR_FOUND) elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(STATUS " sudo zypper install ${PYTHON_NAME}-six") else() - message(STATUS " sudo apt-get install ${PYTHON_NAME}-six") + message(STATUS " sudo apt install ${PYTHON_NAME}-six") endif() endif() message(FATAL_ERROR "six - python 2 and 3 compatibility library required to build VOLK_GNSSSDR") @@ -1145,7 +1229,7 @@ if(NOT VOLKGNSSSDR_FOUND) if(CMAKE_GENERATOR STREQUAL Xcode) set(VOLK_GNSSSDR_BUILD_COMMAND "xcodebuild" - "-configuration" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel> + "-configuration" $<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug>:RelWithDebInfo>$<$:Debug> ) endif() @@ -1223,9 +1307,6 @@ if(NOT VOLKGNSSSDR_FOUND) CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch") set(SUPPORTED_CPU_FEATURES_ARCH TRUE) endif() - if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64) - set(VOLK_GNSSSDR_LIB_SUFFIX 64) - endif() if(CMAKE_VERSION VERSION_LESS 3.2) ExternalProject_Add(volk_gnsssdr_module PREFIX ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module @@ -1243,7 +1324,7 @@ if(NOT VOLKGNSSSDR_FOUND) else() if(SUPPORTED_CPU_FEATURES_ARCH) set(VOLK_GNSSSDR_BUILD_BYPRODUCTS - ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX} + ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX} ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile ) if(ENABLE_CPUFEATURES) @@ -1266,7 +1347,7 @@ if(NOT VOLKGNSSSDR_FOUND) set_package_properties(CPUFEATURES PROPERTIES DESCRIPTION "A cross platform C99 library to get CPU features at runtime" ) - if((DEFINED VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3") OR (CMAKE_VERSION VERSION_LESS "3.13")) # avoid clash with volk's cpufeatures. + if((DEFINED VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3" AND VOLK_VERSION VERSION_LESS "3.1") OR (CMAKE_VERSION VERSION_LESS "3.13")) # avoid clash with volk's cpufeatures. set(ENABLE_CPUFEATURES OFF) else() set_package_properties(CPUFEATURES PROPERTIES @@ -1311,7 +1392,7 @@ if(NOT VOLKGNSSSDR_FOUND) UPDATE_COMMAND "" PATCH_COMMAND "" BUILD_COMMAND ${VOLK_GNSSSDR_BUILD_COMMAND} - BUILD_BYPRODUCTS ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX} + BUILD_BYPRODUCTS ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX} ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr-config-info INSTALL_DIR ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install @@ -1325,7 +1406,7 @@ if(NOT VOLKGNSSSDR_FOUND) endif() add_library(volk_gnsssdr UNKNOWN IMPORTED) - set_property(TARGET volk_gnsssdr PROPERTY IMPORTED_LOCATION ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}) + set_property(TARGET volk_gnsssdr PROPERTY IMPORTED_LOCATION ${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}) set(VOLK_GNSSSDR_INCLUDE_DIRS "${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/build/include/;${GNSSSDR_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/include;${ORC_INCLUDE_DIRS}") set(VOLK_GNSSSDR_LIBRARIES volk_gnsssdr ${ORC_LIBRARIES_STATIC}) if(CPUFEATURES_FOUND) @@ -1338,7 +1419,7 @@ if(NOT VOLKGNSSSDR_FOUND) add_dependencies(Volkgnsssdr::volkgnsssdr volk_gnsssdr_module) set_target_properties(Volkgnsssdr::volkgnsssdr PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION "${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}" + IMPORTED_LOCATION "${GNSSSDR_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}" INCLUDE_DIRECTORIES "${VOLK_GNSSSDR_INCLUDE_DIRS}" INTERFACE_INCLUDE_DIRECTORIES "${VOLK_GNSSSDR_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${VOLK_GNSSSDR_LIBRARIES}" @@ -1380,316 +1461,457 @@ endif() ################################################################################ -# gflags - https://github.com/gflags/gflags +# Abseil C++ - https://abseil.io/docs/cpp/ ################################################################################ -set(LOCAL_GFLAGS FALSE) -if(ENABLE_OWN_GLOG) - unset(Glog::glog CACHE) - unset(GLOG_FOUND CACHE) - unset(Gflags::gflags CACHE) - unset(GLAGS_FOUND CACHE) - set(GFLAGS_GREATER_20 TRUE) -else() - unset(Glog::glog CACHE) - unset(GLOG_FOUND CACHE) - find_package(GLOG) - if(GLOG_FOUND) - unset(GFLAGS_GREATER_20 CACHE) - find_package(GFLAGS) - endif() -endif() -set_package_properties(GFLAGS PROPERTIES - PURPOSE "Used for commandline flags management." - TYPE REQUIRED -) -if(NOT GFLAGS_FOUND) - set(ENABLE_OWN_GLOG ON) - if(GFLAGS_VERSION) - message(STATUS " A version of the gflags library equal or higher than v${GNSSSDR_GFLAGS_MIN_VERSION} has not been found.") - else() - message(STATUS " The gflags library has not been found.") - endif() - message(STATUS " gflags v${GNSSSDR_GFLAGS_LOCAL_VERSION} will be downloaded, built, and statically linked automatically") - message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.") - set(GFLAGS_BUILD_COMMAND ${CMAKE_COMMAND} - "--build" "${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}" - "--config" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> - ) - if(CMAKE_GENERATOR STREQUAL Xcode) - set(GFLAGS_BUILD_COMMAND "xcodebuild" "-configuration" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>) - endif() - if(CMAKE_TOOLCHAIN_FILE) - set(GFLAGS_TOOLCHAIN_FILE -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) - endif() +if(NOT CMAKE_VERSION VERSION_LESS 3.24 + AND NOT CMAKE_CXX_STANDARD VERSION_LESS 17 + AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3.1) + AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0) + AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12) + AND NOT ENABLE_OWN_GLOG + AND NOT ENABLE_GLOG_AND_GFLAGS) + # See https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md - if(CMAKE_VERSION VERSION_LESS 3.2) - ExternalProject_Add(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - PREFIX ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/gflags/gflags.git - GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} - SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - BINARY_DIR ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF - -DBUILD_STATIC_LIBS=ON - -DBUILD_gflags_LIB=ON - -DBUILD_gflags_nothreads_LIB=ON - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - ${GFLAGS_TOOLCHAIN_FILE} - -DGFLAGS_NAMESPACE=google - -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> - BUILD_COMMAND ${GFLAGS_BUILD_COMMAND} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" + if(ENABLE_OWN_ABSEIL) + include(FetchContent) + set(ABSEIL_BUILD_COMMAND ${CMAKE_COMMAND} + "--build" "${GNSSSDR_BINARY_DIR}/abseil-cpp" + "--config" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + "--target" "install" ) - else() - set(GFLAGS_BUILD_BYPRODUCTS ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX}) - if((CMAKE_BUILD_TYPE STREQUAL Debug) OR (CMAKE_BUILD_TYPE STREQUAL NoOptWithASM) OR - (CMAKE_BUILD_TYPE STREQUAL Coverage) OR (CMAKE_BUILD_TYPE STREQUAL ASAN)) # Workaround for Ninja generator - set(GFLAGS_BUILD_BYPRODUCTS ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags_debug${CMAKE_STATIC_LIBRARY_SUFFIX}) + if(CMAKE_GENERATOR STREQUAL Xcode) + set(ABSEIL_BUILD_COMMAND "xcodebuild" "-configuration" $<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug>) endif() - if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode)) - set(PARALLEL_BUILD "--parallel 2") + if(CMAKE_TOOLCHAIN_FILE) + set(ABSEIL_TOOLCHAIN_FILE -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) endif() - ExternalProject_Add(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - PREFIX ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/gflags/gflags.git - GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} - SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - BINARY_DIR ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} - CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF - -DBUILD_STATIC_LIBS=ON - -DBUILD_gflags_LIB=ON - -DBUILD_gflags_nothreads_LIB=ON - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - ${GFLAGS_TOOLCHAIN_FILE} - -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> - BUILD_COMMAND "${GFLAGS_BUILD_COMMAND} ${PARALLEL_BUILD}" - BUILD_BYPRODUCTS ${GFLAGS_BUILD_BYPRODUCTS} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" + set(ABSL_PROPAGATE_CXX_STD ON) + FetchContent_Declare( + absl + GIT_REPOSITORY https://github.com/abseil/abseil-cpp + GIT_TAG ${GNSSSDR_ABSL_LOCAL_VERSION} + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/abseil-cpp + CMAKE_ARGS -DABSL_PROPAGATE_CXX_STD=ON -ABSL_BUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/abseil-cpp ${ABSEIL_TOOLCHAIN_FILE} + BINARY_DIR ${GNSSSDR_BINARY_DIR}/abseil-cpp + BUILD_COMMAND ${ABSEIL_BUILD_COMMAND} + OVERRIDE_FIND_PACKAGE # Requires CMake 3.24 ) - endif() - # Note: -DBUILD_gflags_nothreads_LIB=ON is required as a workaround to a bug in gflags 2.2.2. This is fixed in gflags master branch - - set(GFlags_INCLUDE_DIRS - ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/include CACHE PATH "Local Gflags headers" - ) - - if(CMAKE_VERSION VERSION_LESS "3.0.2") - set(GFlags_LIBS - ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} + FetchContent_MakeAvailable(absl) + set(absl_FOUND TRUE) + set(ENABLE_GLOG_AND_GFLAGS OFF) + else() + find_package(absl) + set_package_properties(absl PROPERTIES + URL "https://github.com/abseil/abseil-cpp" + PURPOSE "Making use of Abseil's log and flags libraries." + TYPE OPTIONAL ) - endif() - - if(NOT TARGET Gflags::gflags) - file(MAKE_DIRECTORY ${GFlags_INCLUDE_DIRS}) - add_library(Gflags::gflags STATIC IMPORTED) - add_dependencies(Gflags::gflags gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) - set_target_properties(Gflags::gflags PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_CONFIGURATIONS "None;Debug;Release;RelWithDebInfo;MinSizeRel" - MAP_IMPORTED_CONFIG_NOOPTWITHASM Debug - MAP_IMPORTED_CONFIG_COVERAGE Debug - MAP_IMPORTED_CONFIG_O2WITHASM RelWithDebInfo - MAP_IMPORTED_CONFIG_O3WITHASM RelWithDebInfo - MAP_IMPORTED_CONFIG_ASAN Debug - IMPORTED_LOCATION_NONE ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags_debug${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES ${GFlags_INCLUDE_DIRS} - INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags$<$:_debug>${CMAKE_STATIC_LIBRARY_SUFFIX} - ) - if((CMAKE_GENERATOR STREQUAL Xcode) OR MSVC) - if(MSVC) - set(MSVC_POSTFIX _static) - endif() - set_target_properties(Gflags::gflags PROPERTIES - IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}_debug${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/Release/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/$<$:Debug/>$<$:Release/>$<$:RelWithDebInfo/>$<$:MinSizeRel/>${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}$<$:_debug>${CMAKE_STATIC_LIBRARY_SUFFIX} + if(absl_FOUND) + set_package_properties(absl PROPERTIES + DESCRIPTION "A collection of C++ library code designed to augment the C++ standard library (found: v${absl_VERSION})" + ) + get_target_property(ABSL_BASE_LIBRARY absl::base INTERFACE_INCLUDE_DIRECTORIES) + get_filename_component(ABSL_ROOT_PATH "${ABSL_BASE_LIBRARY}" DIRECTORY) + message(STATUS "Found Abseil C++ libraries installed at ${ABSL_ROOT_PATH} (found version: v${absl_VERSION})") + else() + set_package_properties(absl PROPERTIES + DESCRIPTION "A collection of C++ library code designed to augment the C++ standard library" + ) + endif() + if("${absl_VERSION}" VERSION_LESS ${GNSSSDR_ABSEIL_MIN_VERSION}) + unset(absl_FOUND CACHE) + set(absl_FOUND FALSE) + set(ENABLE_GLOG_AND_GFLAGS ON) + set_package_properties(absl PROPERTIES + DESCRIPTION "A collection of C++ library code designed to augment the C++ standard library (found: v${absl_VERSION}, but it is too old and it will not be used)" ) endif() endif() +endif() - if(MSVC) - target_link_libraries(Gflags::gflags INTERFACE shlwapi.lib) +# Workaround for Clang 18+ +if(absl_FOUND AND NOT ENABLE_OWN_ABSEIL) + if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "17.99")) + add_compile_options(-fclang-abi-compat=17) endif() +endif() - set(LOCAL_GFLAGS TRUE CACHE STRING "GFlags downloaded, built, and statically linked automatically" FORCE) +if(NOT absl_FOUND) + set(ENABLE_GLOG_AND_GFLAGS ON) + ################################################################################ + # gflags - https://github.com/gflags/gflags + ################################################################################ + set(LOCAL_GFLAGS FALSE) + if(ENABLE_OWN_GLOG) + unset(Glog::glog CACHE) + unset(GLOG_FOUND CACHE) + unset(Gflags::gflags CACHE) + unset(GLAGS_FOUND CACHE) + set(GFLAGS_GREATER_20 TRUE) + else() + unset(Glog::glog CACHE) + unset(GLOG_FOUND CACHE) + find_package(GLOG) + if(GLOG_FOUND) + unset(GFLAGS_GREATER_20 CACHE) + find_package(GFLAGS) + endif() + endif() set_package_properties(GFLAGS PROPERTIES - PURPOSE "Gflags v${GNSSSDR_GFLAGS_LOCAL_VERSION} and Glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded, built, and statically linked when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." + PURPOSE "Used for commandline flags management." + TYPE REQUIRED ) - if(CMAKE_VERSION VERSION_LESS 3.2) - set_property(TARGET Gflags::gflags APPEND PROPERTY - INTERFACE_COMPILE_DEFINITIONS GFLAGS_OLD_NAMESPACE=1 - ) - endif() -endif() - - - -################################################################################ -# glog - https://github.com/google/glog -################################################################################ -set_package_properties(GLOG PROPERTIES - PURPOSE "Used for runtime internal logging." - TYPE REQUIRED -) -if(NOT GLOG_FOUND OR ${LOCAL_GFLAGS}) - message(STATUS " glog library has not been found") if(NOT GFLAGS_FOUND) - message(STATUS " or it is likely not linked to gflags.") - endif() - message(STATUS " glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded, built, and statically linked automatically") - message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.") - find_package(LIBUNWIND) - set_package_properties(LIBUNWIND PROPERTIES - PURPOSE "Needed by glog." - TYPE OPTIONAL - ) - if(NOT ${LOCAL_GFLAGS}) - if(NOT TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) - add_library(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} UNKNOWN IMPORTED) + set(ENABLE_OWN_GLOG ON) + if(GFLAGS_VERSION) + message(STATUS " A version of the gflags library equal or higher than v${GNSSSDR_GFLAGS_MIN_VERSION} has not been found.") + else() + message(STATUS " The gflags library has not been found.") endif() - set_property(TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} PROPERTY IMPORTED_LOCATION "${GFlags_LIBS}") - string(REPLACE /include "" GFLAGS_PREFIX_PATH ${GFlags_INCLUDE_DIRS}) - else() - set(GFLAGS_PREFIX_PATH ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) - endif() - set(TARGET_GFLAGS gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) - set(GLOG_MAKE_PROGRAM ${CMAKE_COMMAND} - "--build" "${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}" - "--config" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> - ) - if(CMAKE_GENERATOR STREQUAL Xcode) - set(GLOG_MAKE_PROGRAM "xcodebuild" "-configuration" - $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel> + message(STATUS " gflags v${GNSSSDR_GFLAGS_LOCAL_VERSION} will be downloaded, built, and statically linked automatically") + message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.") + set(GFLAGS_BUILD_COMMAND ${CMAKE_COMMAND} + "--build" "${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}" + "--config" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> ) - endif() - if(CMAKE_TOOLCHAIN_FILE) - set(GLOG_TOOLCHAIN_FILE -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) - endif() + if(CMAKE_GENERATOR STREQUAL Xcode) + set(GFLAGS_BUILD_COMMAND "xcodebuild" "-configuration" $<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug>) + endif() + if(CMAKE_TOOLCHAIN_FILE) + set(GFLAGS_TOOLCHAIN_FILE -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) + endif() - if(CMAKE_VERSION VERSION_LESS 3.3) - if(CMAKE_VERSION VERSION_LESS 3.0) - set(GLOG_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM}) - set(GFLAGS_LIBRARIES_TO_LINK ${GFlags_LIBS}) - if(${LOCAL_GFLAGS}) - set(GFLAGS_LIBRARY_DIR_TO_LINK ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib) - else() - set(GFLAGS_LIBRARY_DIR_TO_LINK ${GFlags_LIBRARY_DIRS}) - endif() - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(GFLAGS_LIBRARIES_TO_LINK "${GFLAGS_LIBRARIES_TO_LINK} -lc++") - set(GLOG_EXPORT_CXX_LIBRARIES "export CXXFLAGS=\"-stdlib=libc++\"") - endif() - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(GLOG_EXPORT_C_COMPILER "export CC=clang") - set(GLOG_EXPORT_CXX_COMPILER "export CXX=clang++") - endif() - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(GLOG_EXPORT_C_COMPILER "export CC=gcc") - set(GLOG_EXPORT_CXX_COMPILER "export CXX=g++") - endif() - file(WRITE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags -"#!/bin/sh -export CPPFLAGS=-I${GFlags_INCLUDE_DIRS} -export LDFLAGS=-L${GFLAGS_LIBRARY_DIR_TO_LINK} -export LIBS=\"${GFLAGS_LIBRARIES_TO_LINK}\" -${GLOG_EXPORT_CXX_LIBRARIES} -${GLOG_EXPORT_C_COMPILER} -${GLOG_EXPORT_CXX_COMPILER} -cd ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/ -aclocal -automake --add-missing -autoreconf -vfi -cd ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} -${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure --enable-shared=no" - ) - - file(COPY ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags - DESTINATION ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ - GROUP_EXECUTE WORLD_READ WORLD_EXECUTE - ) - - set(GLOG_CONFIGURE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure_with_gflags) - - # Ensure that aclocal and libtool are present - if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") - if(EXISTS "/usr/bin/libtoolize") - if(EXISTS "/usr/bin/aclocal" OR - EXISTS "/usr/bin/aclocal-1.16" OR - EXISTS "/usr/bin/aclocal-1.15" OR - EXISTS "/usr/bin/aclocal-1.14" OR - EXISTS "/usr/bin/aclocal-1.13" OR - EXISTS "/usr/bin/aclocal-1.11" OR - EXISTS "/usr/bin/aclocal-1.10") - # Everything ok, we can move on - else() - message(" aclocal has not been found.") - message(" You can try to install it by typing:") - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo yum groupinstall 'Development Tools'") - elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(" sudo zypper install automake") - else() - message(" sudo apt-get install automake") - endif() - message(FATAL_ERROR "aclocal is required to build glog from source") - endif() - else() - message(" libtool has not been found.") - message(" You can try to install it by typing:") - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo yum groupinstall 'Development Tools'") - elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(" sudo zypper install libtoool") - else() - message(" sudo apt-get install libtool") - endif() - message(FATAL_ERROR "libtool is required to build glog from source") - endif() - endif() - - if(GLOG_MAKE_PROGRAM MATCHES "ninja") - find_program(GLOG_MAKE_EXECUTABLE make - PATHS - /usr/bin - /usr/local/bin - ) - if(NOT GLOG_MAKE_EXECUTABLE) - message(FATAL_ERROR "make is required to build Glog from source.") - endif() - set(GLOG_MAKE_PROGRAM ${GLOG_MAKE_EXECUTABLE}) - endif() - ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} - DEPENDS ${TARGET_GFLAGS} - PREFIX ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/google/glog/ - GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} - SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - BINARY_DIR ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - CONFIGURE_COMMAND ${GLOG_CONFIGURE} --prefix= - BUILD_COMMAND "${GLOG_MAKE_PROGRAM}" + if(CMAKE_VERSION VERSION_LESS 3.2) + ExternalProject_Add(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + PREFIX ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/gflags/gflags.git + GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + BINARY_DIR ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF + -DBUILD_STATIC_LIBS=ON + -DBUILD_gflags_LIB=ON + -DBUILD_gflags_nothreads_LIB=ON + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + ${GFLAGS_TOOLCHAIN_FILE} + -DGFLAGS_NAMESPACE=google + -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + BUILD_COMMAND ${GFLAGS_BUILD_COMMAND} UPDATE_COMMAND "" PATCH_COMMAND "" INSTALL_COMMAND "" ) - set(GLOG_LIBRARIES - ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/.libs/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + else() + set(GFLAGS_BUILD_BYPRODUCTS ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX}) + if((CMAKE_BUILD_TYPE STREQUAL Debug) OR (CMAKE_BUILD_TYPE STREQUAL NoOptWithASM) OR + (CMAKE_BUILD_TYPE STREQUAL Coverage) OR (CMAKE_BUILD_TYPE STREQUAL ASAN)) # Workaround for Ninja generator + set(GFLAGS_BUILD_BYPRODUCTS ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags_debug${CMAKE_STATIC_LIBRARY_SUFFIX}) + endif() + if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode)) + set(PARALLEL_BUILD "--parallel 2") + endif() + if(CMAKE_VERSION VERSION_LESS 4.0) + ExternalProject_Add(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + PREFIX ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/gflags/gflags.git + GIT_TAG v${GNSSSDR_GFLAGS_LOCAL_VERSION} + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + BINARY_DIR ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF + -DBUILD_STATIC_LIBS=ON + -DBUILD_gflags_LIB=ON + -DBUILD_gflags_nothreads_LIB=ON + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + ${GFLAGS_TOOLCHAIN_FILE} + -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + BUILD_COMMAND "${GFLAGS_BUILD_COMMAND} ${PARALLEL_BUILD}" + BUILD_BYPRODUCTS ${GFLAGS_BUILD_BYPRODUCTS} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + # Note: -DBUILD_gflags_nothreads_LIB=ON is required as a workaround to a bug in gflags 2.2.2. This is fixed in gflags master branch + else() + ExternalProject_Add(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + PREFIX ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/gflags/gflags.git + GIT_TAG 52e94563eba1968783864942fedf6e87e3c611f4 + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gflags/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + BINARY_DIR ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} + CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF + -DBUILD_STATIC_LIBS=ON + -DBUILD_gflags_LIB=ON + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + ${GFLAGS_TOOLCHAIN_FILE} + -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + BUILD_COMMAND "${GFLAGS_BUILD_COMMAND} ${PARALLEL_BUILD}" + BUILD_BYPRODUCTS ${GFLAGS_BUILD_BYPRODUCTS} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" ) - set(GLOG_INCLUDE_DIRS - ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src - ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src + endif() + endif() + + set(GFlags_INCLUDE_DIRS + ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/include CACHE PATH "Local Gflags headers" + ) + + if(CMAKE_VERSION VERSION_LESS "3.0.2") + set(GFlags_LIBS + ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} ) - else() # CMake > 3.0 but < 3.3 + endif() + + if(NOT TARGET Gflags::gflags) + file(MAKE_DIRECTORY ${GFlags_INCLUDE_DIRS}) + add_library(Gflags::gflags STATIC IMPORTED) + add_dependencies(Gflags::gflags gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + set_target_properties(Gflags::gflags PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_CONFIGURATIONS "None;Debug;Release;RelWithDebInfo;MinSizeRel" + MAP_IMPORTED_CONFIG_NOOPTWITHASM Debug + MAP_IMPORTED_CONFIG_COVERAGE Debug + MAP_IMPORTED_CONFIG_O2WITHASM RelWithDebInfo + MAP_IMPORTED_CONFIG_O3WITHASM RelWithDebInfo + MAP_IMPORTED_CONFIG_ASAN Debug + IMPORTED_LOCATION_NONE ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags_debug${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${CMAKE_STATIC_LIBRARY_SUFFIX} + INTERFACE_INCLUDE_DIRECTORIES ${GFlags_INCLUDE_DIRS} + INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gflags$<$:_debug>${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + if((CMAKE_GENERATOR STREQUAL Xcode) OR MSVC) + if(MSVC) + set(MSVC_POSTFIX _static) + endif() + set_target_properties(Gflags::gflags PROPERTIES + IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}_debug${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/Release/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} + INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib/$<$:Debug/>$<$:Release/>$<$:RelWithDebInfo/>$<$:MinSizeRel/>${CMAKE_FIND_LIBRARY_PREFIXES}gflags${MSVC_POSTFIX}$<$:_debug>${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + endif() + endif() + + if(MSVC) + target_link_libraries(Gflags::gflags INTERFACE shlwapi.lib) + endif() + + set(LOCAL_GFLAGS TRUE CACHE STRING "GFlags downloaded, built, and statically linked automatically" FORCE) + set_package_properties(GFLAGS PROPERTIES + PURPOSE "Gflags v${GNSSSDR_GFLAGS_LOCAL_VERSION} and Glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded, built, and statically linked when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." + ) + if(CMAKE_VERSION VERSION_LESS 3.2) + set_property(TARGET Gflags::gflags APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS GFLAGS_OLD_NAMESPACE=1 + ) + endif() + endif() + + + + ################################################################################ + # glog - https://github.com/google/glog + ################################################################################ + set_package_properties(GLOG PROPERTIES + PURPOSE "Used for runtime internal logging." + TYPE REQUIRED + ) + if(NOT GLOG_FOUND OR ${LOCAL_GFLAGS}) + message(STATUS " glog library has not been found") + if(NOT GFLAGS_FOUND) + message(STATUS " or it is likely not linked to gflags.") + endif() + message(STATUS " glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded, built, and statically linked automatically") + message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.") + find_package(LIBUNWIND) + set_package_properties(LIBUNWIND PROPERTIES + PURPOSE "Needed by glog." + TYPE OPTIONAL + ) + if(NOT ${LOCAL_GFLAGS}) + if(NOT TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + add_library(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} UNKNOWN IMPORTED) + endif() + set_property(TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} PROPERTY IMPORTED_LOCATION "${GFlags_LIBS}") + string(REPLACE /include "" GFLAGS_PREFIX_PATH ${GFlags_INCLUDE_DIRS}) + else() + set(GFLAGS_PREFIX_PATH ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + endif() + set(TARGET_GFLAGS gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + set(GLOG_MAKE_PROGRAM ${CMAKE_COMMAND} + "--build" "${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}" + "--config" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + ) + if(CMAKE_GENERATOR STREQUAL Xcode) + set(GLOG_MAKE_PROGRAM "xcodebuild" "-configuration" + $<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug> + ) + endif() + if(CMAKE_TOOLCHAIN_FILE) + set(GLOG_TOOLCHAIN_FILE -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) + endif() + + if(CMAKE_VERSION VERSION_LESS 3.3) + if(CMAKE_VERSION VERSION_LESS 3.0) + set(GLOG_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM}) + set(GFLAGS_LIBRARIES_TO_LINK ${GFlags_LIBS}) + if(${LOCAL_GFLAGS}) + set(GFLAGS_LIBRARY_DIR_TO_LINK ${GNSSSDR_BINARY_DIR}/gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}/lib) + else() + set(GFLAGS_LIBRARY_DIR_TO_LINK ${GFlags_LIBRARY_DIRS}) + endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(GFLAGS_LIBRARIES_TO_LINK "${GFLAGS_LIBRARIES_TO_LINK} -lc++") + set(GLOG_EXPORT_CXX_LIBRARIES "export CXXFLAGS=\"-stdlib=libc++\"") + endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(GLOG_EXPORT_C_COMPILER "export CC=clang") + set(GLOG_EXPORT_CXX_COMPILER "export CXX=clang++") + endif() + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(GLOG_EXPORT_C_COMPILER "export CC=gcc") + set(GLOG_EXPORT_CXX_COMPILER "export CXX=g++") + endif() + file(WRITE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags + "#!/bin/sh + export CPPFLAGS=-I${GFlags_INCLUDE_DIRS} + export LDFLAGS=-L${GFLAGS_LIBRARY_DIR_TO_LINK} + export LIBS=\"${GFLAGS_LIBRARIES_TO_LINK}\" + ${GLOG_EXPORT_CXX_LIBRARIES} + ${GLOG_EXPORT_C_COMPILER} + ${GLOG_EXPORT_CXX_COMPILER} + cd ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/ + aclocal + automake --add-missing + autoreconf -vfi + cd ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure --enable-shared=no" + ) + + file(COPY ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags + DESTINATION ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ + GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + + set(GLOG_CONFIGURE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure_with_gflags) + + # Ensure that aclocal and libtool are present + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") + if(EXISTS "/usr/bin/libtoolize") + if(EXISTS "/usr/bin/aclocal" OR + EXISTS "/usr/bin/aclocal-1.16" OR + EXISTS "/usr/bin/aclocal-1.15" OR + EXISTS "/usr/bin/aclocal-1.14" OR + EXISTS "/usr/bin/aclocal-1.13" OR + EXISTS "/usr/bin/aclocal-1.11" OR + EXISTS "/usr/bin/aclocal-1.10") + # Everything ok, we can move on + else() + message(" aclocal has not been found.") + message(" You can try to install it by typing:") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(" sudo yum groupinstall 'Development Tools'") + elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") + message(" sudo zypper install automake") + else() + message(" sudo apt install automake") + endif() + message(FATAL_ERROR "aclocal is required to build glog from source") + endif() + else() + message(" libtool has not been found.") + message(" You can try to install it by typing:") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(" sudo yum groupinstall 'Development Tools'") + elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") + message(" sudo zypper install libtoool") + else() + message(" sudo apt install libtool") + endif() + message(FATAL_ERROR "libtool is required to build glog from source") + endif() + endif() + + if(GLOG_MAKE_PROGRAM MATCHES "ninja") + find_program(GLOG_MAKE_EXECUTABLE make + PATHS + /usr/bin + /usr/local/bin + ) + if(NOT GLOG_MAKE_EXECUTABLE) + message(FATAL_ERROR "make is required to build Glog from source.") + endif() + set(GLOG_MAKE_PROGRAM ${GLOG_MAKE_EXECUTABLE}) + endif() + ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} + DEPENDS ${TARGET_GFLAGS} + PREFIX ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/google/glog/ + GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + BINARY_DIR ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + CONFIGURE_COMMAND ${GLOG_CONFIGURE} --prefix= + BUILD_COMMAND "${GLOG_MAKE_PROGRAM}" + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + set(GLOG_LIBRARIES + ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/.libs/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + set(GLOG_INCLUDE_DIRS + ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src + ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src + ) + else() # CMake > 3.0 but < 3.3 + ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} + DEPENDS ${TARGET_GFLAGS} + PREFIX ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + GIT_REPOSITORY https://github.com/google/glog/ + GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + BINARY_DIR ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_PREFIX_PATH=${GFLAGS_PREFIX_PATH} + ${GLOG_TOOLCHAIN_FILE} + -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + BUILD_COMMAND ${GLOG_MAKE_PROGRAM} + UPDATE_COMMAND "" + PATCH_COMMAND "" + INSTALL_COMMAND "" + ) + set(GLOG_INCLUDE_DIRS + ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src + ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} + ${GFlags_INCLUDE_DIRS} + ) + endif() + else() # CMake > 3.3 + set(GLOG_BUILD_BYPRODUCTS + ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + if((CMAKE_BUILD_TYPE STREQUAL Debug) OR (CMAKE_BUILD_TYPE STREQUAL NoOptWithASM) OR + (CMAKE_BUILD_TYPE STREQUAL Coverage) OR (CMAKE_BUILD_TYPE STREQUAL ASAN)) # Workaround for Ninja generator + set(GLOG_BUILD_BYPRODUCTS + ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + endif() + if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode) AND NOT CMAKE_CROSSCOMPILING) + set(PARALLEL_BUILD "--parallel 2") + endif() + if(GNSSSDR_GLOG_LOCAL_VERSION VERSION_GREATER 0.5.0) + set(GLOG_GTEST -DWITH_GTEST=FALSE) + endif() + if(NOT (CMAKE_VERSION VERSION_LESS "3.22")) + set(GNSSSDR_GLOG_LOCAL_GFLAGS -DCMAKE_REQUIRED_INCLUDES=${GFlags_INCLUDE_DIRS}) + endif() ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} DEPENDS ${TARGET_GFLAGS} PREFIX ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} @@ -1698,11 +1920,15 @@ ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configu SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} BINARY_DIR ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_PREFIX_PATH=${GFLAGS_PREFIX_PATH} ${GLOG_TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> - BUILD_COMMAND ${GLOG_MAKE_PROGRAM} + -DBUILD_SHARED_LIBS=OFF + ${GLOG_GTEST} + -DBUILD_TESTING=OFF + "${GNSSSDR_GLOG_LOCAL_GFLAGS}" + BUILD_COMMAND "${GLOG_MAKE_PROGRAM} ${PARALLEL_BUILD}" + BUILD_BYPRODUCTS ${GLOG_BUILD_BYPRODUCTS} UPDATE_COMMAND "" PATCH_COMMAND "" INSTALL_COMMAND "" @@ -1713,111 +1939,64 @@ ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configu ${GFlags_INCLUDE_DIRS} ) endif() - else() # CMake > 3.3 - set(GLOG_BUILD_BYPRODUCTS - ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - ) - if((CMAKE_BUILD_TYPE STREQUAL Debug) OR (CMAKE_BUILD_TYPE STREQUAL NoOptWithASM) OR - (CMAKE_BUILD_TYPE STREQUAL Coverage) OR (CMAKE_BUILD_TYPE STREQUAL ASAN)) # Workaround for Ninja generator - set(GLOG_BUILD_BYPRODUCTS - ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} - ) - endif() - if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode) AND NOT CMAKE_CROSSCOMPILING) - set(PARALLEL_BUILD "--parallel 2") - endif() - if(GNSSSDR_GLOG_LOCAL_VERSION VERSION_GREATER 0.5.0) - set(GLOG_GTEST -DWITH_GTEST=FALSE) - endif() - ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} - DEPENDS ${TARGET_GFLAGS} - PREFIX ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - GIT_REPOSITORY https://github.com/google/glog/ - GIT_TAG v${GNSSSDR_GLOG_LOCAL_VERSION} - SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - BINARY_DIR ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_PREFIX_PATH=${GFLAGS_PREFIX_PATH} - ${GLOG_TOOLCHAIN_FILE} - -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> - -DBUILD_SHARED_LIBS=OFF - ${GLOG_GTEST} - -DBUILD_TESTING=OFF - BUILD_COMMAND "${GLOG_MAKE_PROGRAM} ${PARALLEL_BUILD}" - BUILD_BYPRODUCTS ${GLOG_BUILD_BYPRODUCTS} - UPDATE_COMMAND "" - PATCH_COMMAND "" - INSTALL_COMMAND "" - ) - set(GLOG_INCLUDE_DIRS - ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src - ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} - ${GFlags_INCLUDE_DIRS} - ) - endif() - add_dependencies(glog-${GNSSSDR_GLOG_LOCAL_VERSION} Gflags::gflags) + add_dependencies(glog-${GNSSSDR_GLOG_LOCAL_VERSION} Gflags::gflags) - # Create Glog::glog target - if(NOT TARGET Glog::glog) - file(MAKE_DIRECTORY ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src) - file(MAKE_DIRECTORY ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}) - add_library(Glog::glog STATIC IMPORTED) - add_dependencies(Glog::glog glog-${GNSSSDR_GLOG_LOCAL_VERSION}) - if(CMAKE_VERSION VERSION_LESS 3.0) - set_target_properties(Glog::glog PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION "${GLOG_LIBRARIES}" - INCLUDE_DIRECTORIES "${GLOG_INCLUDE_DIRS}" - INTERFACE_INCLUDE_DIRECTORIES "${GLOG_INCLUDE_DIRS}" - INTERFACE_LINK_LIBRARIES "${GLOG_LIBRARIES}" - ) - else() - set_target_properties(Glog::glog PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_CONFIGURATIONS "None;Debug;Release;RelWithDebInfo;MinSizeRel" - MAP_IMPORTED_CONFIG_NOOPTWITHASM Debug - MAP_IMPORTED_CONFIG_COVERAGE Debug - MAP_IMPORTED_CONFIG_O2WITHASM RelWithDebInfo - MAP_IMPORTED_CONFIG_O3WITHASM RelWithDebInfo - MAP_IMPORTED_CONFIG_ASAN Debug - IMPORTED_LOCATION_NONE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES "${GLOG_INCLUDE_DIRS}" - INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog$<$:d>${CMAKE_STATIC_LIBRARY_SUFFIX} - ) - if((CMAKE_GENERATOR STREQUAL Xcode) OR MSVC) + # Create Glog::glog target + if(NOT TARGET Glog::glog) + file(MAKE_DIRECTORY ${GNSSSDR_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/src) + file(MAKE_DIRECTORY ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}) + add_library(Glog::glog STATIC IMPORTED) + add_dependencies(Glog::glog glog-${GNSSSDR_GLOG_LOCAL_VERSION}) + if(CMAKE_VERSION VERSION_LESS 3.0) set_target_properties(Glog::glog PROPERTIES - IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/Release/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/$<$:Debug/>$<$:Release/>$<$:RelWithDebInfo/>$<$:MinSizeRel/>${CMAKE_FIND_LIBRARY_PREFIXES}glog$<$:d>${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GLOG_LIBRARIES}" + INCLUDE_DIRECTORIES "${GLOG_INCLUDE_DIRS}" + INTERFACE_INCLUDE_DIRECTORIES "${GLOG_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${GLOG_LIBRARIES}" ) + else() + set_target_properties(Glog::glog PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_CONFIGURATIONS "None;Debug;Release;RelWithDebInfo;MinSizeRel" + MAP_IMPORTED_CONFIG_NOOPTWITHASM Debug + MAP_IMPORTED_CONFIG_COVERAGE Debug + MAP_IMPORTED_CONFIG_O2WITHASM RelWithDebInfo + MAP_IMPORTED_CONFIG_O3WITHASM RelWithDebInfo + MAP_IMPORTED_CONFIG_ASAN Debug + IMPORTED_LOCATION_NONE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + INTERFACE_INCLUDE_DIRECTORIES "${GLOG_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glog$<$:d>${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + if((CMAKE_GENERATOR STREQUAL Xcode) OR MSVC) + set_target_properties(Glog::glog PROPERTIES + IMPORTED_LOCATION_DEBUG ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELEASE ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/Release/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_RELWITHDEBINFO ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + IMPORTED_LOCATION_MINSIZEREL ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}glog${CMAKE_STATIC_LIBRARY_SUFFIX} + INTERFACE_LINK_LIBRARIES ${GNSSSDR_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/$<$:Debug/>$<$:Release/>$<$:RelWithDebInfo/>$<$:MinSizeRel/>${CMAKE_FIND_LIBRARY_PREFIXES}glog$<$:d>${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + endif() endif() endif() - endif() + if(NOT (CMAKE_VERSION VERSION_LESS "3.22")) + set_target_properties(Glog::glog PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "GLOG_USE_GLOG_EXPORT;GLOG_USE_GFLAGS" + INTERFACE_COMPILE_FEATURES "cxx_std_14") + endif() - if(LIBUNWIND_FOUND) - target_link_libraries(Glog::glog INTERFACE Libunwind::libunwind) - endif() - set(LOCAL_GLOG TRUE CACHE STRING "Glog downloaded, built, and statically linked automatically" FORCE) + if(LIBUNWIND_FOUND) + target_link_libraries(Glog::glog INTERFACE Libunwind::libunwind) + endif() + set(LOCAL_GLOG TRUE CACHE STRING "Glog downloaded, built, and statically linked automatically" FORCE) - set_package_properties(GLOG PROPERTIES - PURPOSE "Glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded, built, and statically linked when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." - ) -endif() - -if(NOT ENABLE_LOG) - message(STATUS "Internal logging is not enabled") - if(CMAKE_VERSION VERSION_GREATER 3.11.0) - target_compile_definitions(Glog::glog INTERFACE -DGOOGLE_STRIP_LOG=1) - else() - set_property(TARGET Glog::glog APPEND PROPERTY - INTERFACE_COMPILE_DEFINITIONS GOOGLE_STRIP_LOG=1 + set_package_properties(GLOG PROPERTIES + PURPOSE "Glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded, built, and statically linked when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." ) endif() endif() @@ -1856,7 +2035,7 @@ if(NOT BLAS_FOUND) if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") message(" sudo yum install blas-devel") else() - message(" sudo apt-get install libblas-dev") + message(" sudo apt install libblas-dev") endif() endif() message(FATAL_ERROR "BLAS is required to build gnss-sdr") @@ -1893,7 +2072,7 @@ if(NOT LAPACK_FOUND) elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install lapack-devel") else() - message(" sudo apt-get install liblapack-dev") + message(" sudo apt install liblapack-dev") endif() endif() message(FATAL_ERROR "LAPACK is required to build gnss-sdr") @@ -1909,7 +2088,7 @@ endif() ################################################################################ -# Armadillo - http://arma.sourceforge.net/ +# Armadillo - https://arma.sourceforge.net/ ################################################################################ if(ENABLE_OWN_ARMADILLO) unset(Armadillo::armadillo CACHE) @@ -1921,7 +2100,7 @@ else() endif() set_package_properties(Armadillo PROPERTIES - URL "http://arma.sourceforge.net/" + URL "https://arma.sourceforge.net/" PURPOSE "Used for matrix computations." TYPE REQUIRED ) @@ -1972,7 +2151,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(STATUS " sudo zypper install gcc-fortran") else() - message(STATUS " sudo apt-get install gfortran") + message(STATUS " sudo apt install gfortran") endif() message(FATAL_ERROR "gfortran is required to build gnss-sdr") endif() @@ -2025,7 +2204,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/armadillo-${armadillo_RELEASE} - -DBUILD_SHARED_LIBS=OFF + -DSTATIC_LIB=ON -DBUILD_SMOKE_TEST=OFF -DALLOW_BLAS_LAPACK_MACOS=ON ${ARMADILLO_CXX_VERSION} @@ -2079,21 +2258,21 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) # Fix for macOS find_library(ARPACK_LIBRARY NAMES arpack - PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} /opt/local/lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/local/lib64 + PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} ${GNSSSDR_LIB_PATHS} ) if(ARPACK_LIBRARY) target_link_libraries(Armadillo::armadillo INTERFACE ${ARPACK_LIBRARY}) endif() find_library(FLEXIBLAS_LIBRARY NAMES flexiblas - PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} /opt/local/lib /lib64 /lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/local/lib64 + PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} ${GNSSSDR_LIB_PATHS} ) if(FLEXIBLAS_LIBRARY) target_link_libraries(Armadillo::armadillo INTERFACE ${FLEXIBLAS_LIBRARY}) endif() find_library(SUPERLU_LIBRARY NAMES superlu - PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} /opt/local/lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/local/lib64 + PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} ${GNSSSDR_LIB_PATHS} ) if(SUPERLU_LIBRARY) target_link_libraries(Armadillo::armadillo INTERFACE ${SUPERLU_LIBRARY}) @@ -2103,96 +2282,9 @@ endif() ################################################################################ -# GnuTLS - https://www.gnutls.org/ +# OpenSSL https://www.openssl.org/ or GnuTLS - https://www.gnutls.org/ ################################################################################ -find_package(GnuTLS) -set_package_properties(GnuTLS PROPERTIES - URL "https://www.gnutls.org/" - PURPOSE "Used for the SUPL protocol implementation." - TYPE REQUIRED -) -if(GnuTLS_FOUND AND GNUTLS_VERSION_STRING) - set_package_properties(GnuTLS PROPERTIES - DESCRIPTION "Transport Layer Security Library (found: v${GNUTLS_VERSION_STRING})" - ) -else() - set_package_properties(GnuTLS PROPERTIES - DESCRIPTION "Transport Layer Security Library" - ) -endif() -find_library(GNUTLS_OPENSSL_LIBRARY - NAMES gnutls-openssl libgnutls-openssl.so.27 - PATHS - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/i386-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib -) -if(NOT GNUTLS_OPENSSL_LIBRARY) - if(GnuTLS_FOUND) - message(STATUS " But it was not built with openssl compatibility.") - endif() - message(STATUS " Looking for OpenSSL instead...") - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) # Trick for Homebrew - endif() - find_package(OpenSSL) - set_package_properties(OpenSSL PROPERTIES - URL "https://www.openssl.org" - DESCRIPTION "Cryptography and SSL/TLS Toolkit (found: v${OPENSSL_VERSION})" - PURPOSE "Used for the SUPL protocol implementation." - TYPE REQUIRED - ) - if(OPENSSL_FOUND) - set_package_properties(GnuTLS PROPERTIES - PURPOSE "Not found, but OpenSSL can replace it." - ) - set(GNUTLS_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR}) - set(GNUTLS_LIBRARIES "") - set(GNUTLS_OPENSSL_LIBRARY ${OPENSSL_SSL_LIBRARY}) - else() - message(" The GnuTLS library with openssl compatibility enabled has not been found.") - message(" You can try to install the required libraries by typing:") - if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo yum install openssl-devel") - else() - message(" sudo apt-get install libgnutls28-dev") - endif() - endif() - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - message(" 'sudo port install gnutls', if you are using Macports, or") - message(" 'brew install openssl', if you are using Homebrew.") - endif() - message(FATAL_ERROR "GnuTLS libraries with openssl compatibility are required to build gnss-sdr") - endif() -endif() +include(GnsssdrCrypto) @@ -2263,7 +2355,7 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(STATUS " sudo zypper install hdf5-devel") else() - message(STATUS " sudo apt-get install libhdf5-dev") + message(STATUS " sudo apt install libhdf5-dev") endif() endif() message(FATAL_ERROR "*** The hdf5 library is required to build Matio from source.") @@ -2280,7 +2372,7 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install libtoool") else() - message(" sudo apt-get install libtool") + message(" sudo apt install libtool") endif() message(FATAL_ERROR "libtool is required to build matio from source.") endif() @@ -2300,30 +2392,30 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install automake") else() - message(" sudo apt-get install automake") + message(" sudo apt install automake") endif() message(FATAL_ERROR "aclocal is required to build matio from source.") endif() endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - if((NOT EXISTS /usr/local/bin/glibtoolize AND NOT EXISTS /opt/local/bin/glibtoolize) OR - (NOT EXISTS /usr/local/bin/aclocal AND NOT EXISTS /opt/local/bin/aclocal)) + if((NOT EXISTS /usr/local/bin/glibtoolize AND NOT EXISTS ${MACOS_PACKAGES_PREFIX}/bin/glibtoolize) OR + (NOT EXISTS /usr/local/bin/aclocal AND NOT EXISTS ${MACOS_PACKAGES_PREFIX}/bin/aclocal)) message(" libtool/automake tools have not been found.") message(" You can try to install them by typing:") message(" 'sudo port install libtool automake', if you use Macports, or 'brew install libtool automake', if you use Homebrew") message(FATAL_ERROR "libtool/automake tools are required to build matio from source") endif() if(CMAKE_GENERATOR STREQUAL Xcode) - if(EXISTS /opt/local/bin/glibtoolize OR EXISTS /opt/local/bin/aclocal) + if(EXISTS ${MACOS_PACKAGES_PREFIX}/bin/glibtoolize OR EXISTS ${MACOS_PACKAGES_PREFIX}/bin/aclocal) if(NOT EXISTS /usr/local/bin/glibtoolize OR NOT EXISTS /usr/local/bin/aclocal) message(" WARNING: libtool/atomake binaries cannot be found by Xcode. Please do:") - message("sudo ln -s /opt/local/bin/glibtoolize /usr/local/bin/") - message("sudo ln -s /opt/local/bin/aclocal /usr/local/bin/") - message("sudo ln -s /opt/local/bin/autom4te /usr/local/bin/") - message("sudo ln -s /opt/local/bin/automake /usr/local/bin/") - message("sudo ln -s /opt/local/bin/autoconf /usr/local/bin/") - message("sudo ln -s /opt/local/bin/autoreconf /usr/local/bin/") # not needed by Matio, but by Protocol Buffers + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/glibtoolize /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/aclocal /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/autom4te /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/automake /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/autoconf /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/autoreconf /usr/local/bin/") # not needed by Matio, but by Protocol Buffers message(FATAL_ERROR "libtool/automake tools cannot be found by Xcode") endif() endif() @@ -2334,8 +2426,8 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS get_filename_component(HDF5_BASE_DIR2 ${HDF5_FIRST_DIR} DIRECTORY) get_filename_component(HDF5_BASE_DIR ${HDF5_BASE_DIR2} DIRECTORY) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - if(EXISTS /opt/local/include/hdf5.h) - set(HDF5_BASE_DIR /opt/local) + if(EXISTS ${MACOS_PACKAGES_PREFIX}/include/hdf5.h) + set(HDF5_BASE_DIR ${MACOS_PACKAGES_PREFIX}) endif() if(EXISTS /usr/local/include/hdf5.h) set(HDF5_BASE_DIR /usr/local) @@ -2386,6 +2478,7 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS -DHDF5_USE_STATIC_LIBRARIES=OFF -DMATIO_DEFAULT_FILE_VERSION:STRING=7.3 -DMATIO_MAT73=ON + -DMATIO_BUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/matio BUILD_COMMAND ${CMAKE_COMMAND} "--build" "${GNSSSDR_BINARY_DIR}/matio" @@ -2517,9 +2610,29 @@ endif() ################################################################################ # Protocol Buffers https://github.com/protocolbuffers/protobuf ################################################################################ -find_package(Protobuf) +if(((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0")) OR + ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0")) OR + ((CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11"))) + if(CMAKE_VERSION VERSION_LESS 3.19) + find_package(Protobuf) + else() + find_package(Protobuf 3.0...21.12) + endif() +else() + find_package(Protobuf) + + if((CMAKE_BUILD_TYPE STREQUAL "Debug") AND Protobuf_FOUND AND absl_FOUND) + # This Regular Expression is used to convert the version string provided by `find_package(Protobuf)` into the + # appropriate binary version string. So, for instance, "4.25.3" becomes "25.3.0". + string(REGEX REPLACE "^[0-9]+\.([0-9]+\.[0-9]+)$" "\\1.0" PROTOBUF_LIBRARY_VERSION "${Protobuf_VERSION}") + if((PROTOBUF_LIBRARY_VERSION VERSION_GREATER_EQUAL "22") AND (PROTOBUF_LIBRARY_VERSION VERSION_LESS "26")) + pkg_check_modules(protobuf REQUIRED IMPORTED_TARGET protobuf=${PROTOBUF_LIBRARY_VERSION}) + target_link_libraries(protobuf::libprotobuf INTERFACE PkgConfig::protobuf) + endif() + endif() +endif() set_package_properties(Protobuf PROPERTIES - URL "https://developers.google.com/protocol-buffers/" + URL "https://protobuf.dev/" PURPOSE "Used to serialize output data in a way that can be read by other applications." TYPE REQUIRED ) @@ -2624,12 +2737,6 @@ if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSI endif() else() if(CMAKE_VERSION VERSION_GREATER "3.13") - find_package(absl) - set_package_properties(absl PROPERTIES - URL "https://github.com/abseil/abseil-cpp" - PURPOSE "Abseil-cpp >= 20230117 required to be installed before building Protocol Buffers >22.x on the fly." - TYPE OPTIONAL - ) if(absl_FOUND) if(absl_VERSION) if(${absl_VERSION} VERSION_LESS "20230117") @@ -2641,6 +2748,10 @@ if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSI set(absl_FOUND OFF) endif() endif() + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0")) + unset(absl_FOUND CACHE) + set(absl_FOUND OFF) + endif() if(absl_FOUND) set_package_properties(absl PROPERTIES DESCRIPTION "An open-source collection of C++ code designed to augment the C++ standard library (found: v${absl_VERSION})" @@ -2655,7 +2766,9 @@ if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSI DESCRIPTION "An open-source collection of C++ code designed to augment the C++ standard library" ) endif() - message(STATUS "The Abseil library (https://github.com/abseil/abseil-cpp) >= v20230117 is required to be installed before building Protocol Buffers >22.x on the fly.") + if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0.0")) + message(STATUS "The Abseil library (https://github.com/abseil/abseil-cpp) >= v20230117 is required to be installed before building Protocol Buffers >22.x on the fly.") + endif() message(STATUS " Instead, Protocol Buffers v21.12 will be built, which does not require Abseil.") set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "21.12") endif() @@ -2670,7 +2783,7 @@ if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSI elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install libtoool") else() - message(" sudo apt-get install libtool") + message(" sudo apt install libtool") endif() message(FATAL_ERROR "libtool is required to build Protocol Buffers from source") endif() @@ -2690,29 +2803,29 @@ if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSI elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(" sudo zypper install automake") else() - message(" sudo apt-get install automake") + message(" sudo apt install automake") endif() message(FATAL_ERROR "aclocal is required to build Protocol Buffers from source") endif() endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - if((NOT EXISTS /usr/local/bin/glibtoolize AND NOT EXISTS /opt/local/bin/glibtoolize) OR - (NOT EXISTS /usr/local/bin/aclocal AND NOT EXISTS /opt/local/bin/aclocal)) + if((NOT EXISTS /usr/local/bin/glibtoolize AND NOT EXISTS ${MACOS_PACKAGES_PREFIX}/bin/glibtoolize) OR + (NOT EXISTS /usr/local/bin/aclocal AND NOT EXISTS ${MACOS_PACKAGES_PREFIX}/bin/aclocal)) message(" libtool/automake tools have not been found.") message(" You can try to install them by typing:") message(" 'sudo port install libtool automake', if you use Macports, or 'brew install libtool automake', if you use Homebrew") message(FATAL_ERROR "libtool/automake tools are required to build Protocol Buffers from source") endif() if(CMAKE_GENERATOR STREQUAL Xcode) - if(EXISTS /opt/local/bin/glibtoolize OR EXISTS /opt/local/bin/aclocal) + if(EXISTS ${MACOS_PACKAGES_PREFIX}/bin/glibtoolize OR EXISTS ${MACOS_PACKAGES_PREFIX}/bin/aclocal) if(NOT EXISTS /usr/local/bin/glibtoolize OR NOT EXISTS /usr/local/bin/aclocal) message(" WARNING: libtool/automake binaries cannot be found by Xcode. Please do:") - message("sudo ln -s /opt/local/bin/glibtoolize /usr/local/bin/") - message("sudo ln -s /opt/local/bin/aclocal /usr/local/bin/") - message("sudo ln -s /opt/local/bin/autom4te /usr/local/bin/") - message("sudo ln -s /opt/local/bin/automake /usr/local/bin/") - message("sudo ln -s /opt/local/bin/autoconf /usr/local/bin/") - message("sudo ln -s /opt/local/bin/autoreconf /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/glibtoolize /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/aclocal /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/autom4te /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/automake /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/autoconf /usr/local/bin/") + message("sudo ln -s ${MACOS_PACKAGES_PREFIX}/bin/autoreconf /usr/local/bin/") message(FATAL_ERROR "libtool/automake tools cannot be found by Xcode") endif() endif() @@ -2768,8 +2881,8 @@ if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSI if(NOT TARGET protobuf::protoc) add_executable(protobuf::protoc IMPORTED) - add_dependencies(protobuf::protoc protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}) endif() + add_dependencies(protobuf::protoc protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}) unset(Protobuf_PROTOC_EXECUTABLE) set(PROTOBUF_PROTOC_EXECUTABLE "${GNSSSDR_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/bin/protoc") set_target_properties(protobuf::protoc PROPERTIES @@ -2952,7 +3065,7 @@ else() if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") message(STATUS " or simply by doing 'sudo yum install doxygen-latex'.") else() - message(STATUS " or simply by doing 'sudo apt-get install doxygen-latex'.") + message(STATUS " or simply by doing 'sudo apt install doxygen-latex'.") endif() endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") @@ -3205,7 +3318,7 @@ set_package_properties(LIBIIO PROPERTIES PURPOSE "Used for communication with the AD9361 chipset." TYPE OPTIONAL ) -if(ENABLE_AD9361 OR ENABLE_FMCOMMS2) +if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR) if(NOT LIBIIO_FOUND) message(STATUS "libiio not found, its installation is required.") message(STATUS "Please build and install the following projects:") @@ -3219,6 +3332,151 @@ if(ENABLE_AD9361 OR ENABLE_FMCOMMS2) else() message(FATAL_ERROR "libiio is required for building gnss-sdr with -DENABLE_AD9361=ON.") endif() + else() + if(ENABLE_AD9361) + set(ENABLE_FPGA ON) + endif() + endif() +endif() + + + +################################################################################ +# ION GNSS-SDR Metadata Standard https://sdr.ion.org/ (OPTIONAL) +################################################################################ +if(CMAKE_VERSION VERSION_LESS 3.14) + set(ENABLE_ION OFF) # FetchContent_MakeAvailable is available from CMake 3.14 +endif() +if(ENABLE_ION) + include(FetchContent) + set(CMAKE_POLICY_DEFAULT_CMP0063 NEW) + FetchContent_Declare( + gnss_metadata_standard + GIT_REPOSITORY https://github.com/IonMetadataWorkingGroup/GNSS-Metadata-Standard + GIT_TAG 220d116e10db5e403e21b77a1fa25aa35feda198 + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/gnss-metadata-standard + BINARY_DIR ${GNSSSDR_BINARY_DIR}/gnss-metadata-standard + ) + FetchContent_MakeAvailable(gnss_metadata_standard) + + if(NOT TARGET ION::ion) + add_library(ION::ion STATIC IMPORTED) + add_dependencies(ION::ion gnss_metadata_standard) + if(CMAKE_GENERATOR STREQUAL "Xcode") + set_target_properties(ION::ion PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION_DEBUG "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + IMPORTED_LOCATION_RELEASE "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Release/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + IMPORTED_LOCATION_RELWITHDEBINFO "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + IMPORTED_LOCATION_MINSIZEREL "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + INTERFACE_INCLUDE_DIRECTORIES "${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc" + ) + set_property(TARGET ION::ion APPEND PROPERTY + INTERFACE_LINK_LIBRARIES + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Release/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Release/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + ) + else() + set_target_properties(ION::ion PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + INTERFACE_INCLUDE_DIRECTORIES "${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc" + INTERFACE_LINK_LIBRARIES "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}" + ) + endif() + endif() +endif() + + + +##################################################################### +# Check signal sources related to FPGA only. +##################################################################### +if(ENABLE_MAX2771 AND NOT ENABLE_FPGA) + message(STATUS "The SPIdev driver is enabled, but the FPGA is not enabled. The FPGA is required when using the SPIdev driver.") + if(ENABLE_PACKAGING) + set(ENABLE_MAX2771 OFF) + else() + message(FATAL_ERROR "ENABLE_MAX2771 can only be set when ENABLE_FPGA is also set.") + endif() +endif() +if(ENABLE_DMA_PROXY AND NOT ENABLE_FPGA) + message(STATUS "The DMA Proxy driver is enabled, but the FPGA is not enabled. The FPGA is required when using the DMA Proxy driver.") + if(ENABLE_PACKAGING) + set(ENABLE_DMA_PROXY OFF) + else() + message(FATAL_ERROR "ENABLE_DMA_PROXY can only be set when ENABLE_FPGA is also set.") + endif() +endif() + + + +##################################################################### +# spidev driver - OPTIONAL +# Linux kernel driver that provides user-space access to Serial +# Peripheral Interface) +##################################################################### +if(ENABLE_MAX2771) + if(DEFINED ENV{SDKTARGETSYSROOT}) + set(TARGET_ROOTFS_PATH $ENV{SDKTARGETSYSROOT}) + else() + string(REGEX MATCH "(.*/tmp-glibc)" MATCHED_PATH "${GNURADIO_RUNTIME_INCLUDE_DIRS}") + if(MATCHED_PATH) + set(TARGET_ROOTFS_PATH "${MATCHED_PATH}/sysroots-components") + else() + set(TARGET_ROOTFS_PATH "") + endif() + endif() + file(GLOB_RECURSE SPIDEV_FILE "${TARGET_ROOTFS_PATH}/*/spidev.h") + if(EXISTS "${SPIDEV_FILE}") + message(STATUS "SPIdev driver found: ${SPIDEV_FILE}") + set(ENABLE_FPGA ON) + else() + message(STATUS "SPIdev driver not found, its installation is required.") + if(ENABLE_PACKAGING) + set(ENABLE_MAX2771 OFF) + else() + message(FATAL_ERROR "SPIdev driver is required for building gnss-sdr with -DENABLE_MAX2271=ON.") + endif() + endif() +endif() + + + +##################################################################### +# DMA Proxy driver - OPTIONAL +# Simplified and efficient interface for user-space applications +# to leverage DMA capabilities for Xilinx FPGA and SoC systems +##################################################################### +if(ENABLE_DMA_PROXY) + if(DEFINED ENV{SDKTARGETSYSROOT}) + set(TARGET_ROOTFS_PATH $ENV{SDKTARGETSYSROOT}) + else() + string(REGEX MATCH "(.*/tmp-glibc)" MATCHED_PATH "${GNURADIO_RUNTIME_INCLUDE_DIRS}") + if(MATCHED_PATH) + set(TARGET_ROOTFS_PATH "${MATCHED_PATH}/sysroots-components") + else() + set(TARGET_ROOTFS_PATH "") + endif() + endif() + file(GLOB_RECURSE DMA_PROXY_FILE "${TARGET_ROOTFS_PATH}/*/dma-proxy.ko") + if(EXISTS "${DMA_PROXY_FILE}") + message(STATUS "Found dma-proxy.ko file: ${DMA_PROXY_FILE}") + set(ENABLE_FPGA ON) + else() + if(ENABLE_PACKAGING) + set(ENABLE_DMA_PROXY OFF) + else() + message(FATAL_ERROR "DMA Proxy driver is required for building gnss-sdr with -DENABLE_DMA_PROXY=ON.") + endif() endif() endif() @@ -3416,6 +3674,10 @@ add_custom_target(uninstall # Add subdirectories ################################################################################ add_subdirectory(src) +if(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING) + add_subdirectory(tests) +endif() +add_subdirectory(utils) @@ -3425,26 +3687,32 @@ add_subdirectory(src) add_feature_info(ENABLE_UHD ENABLE_UHD "Enables UHD_Signal_Source for using RF front-ends from the USRP family. Requires gr-uhd.") add_feature_info(ENABLE_OSMOSDR ENABLE_OSMOSDR "Enables Osmosdr_Signal_Source and RtlTcp_Signal_Source for using RF front-ends compatible with the OsmoSDR driver. Requires gr-osmosdr.") add_feature_info(ENABLE_LIMESDR ENABLE_LIMESDR "Enables Limesdr_Signal_Source. Requires gr-limesdr.") -add_feature_info(ENABLE_FMCOMMS2 ENABLE_FMCOMMS2 "Enables Fmcomms2_Signal_Source for FMCOMMS2/3/4 devices. Requires gr-iio and libad9361-dev.") -add_feature_info(ENABLE_PLUTOSDR ENABLE_PLUTOSDR "Enables Plutosdr_Signal_Source for using ADALM-PLUTO boards. Requires gr-iio.") -add_feature_info(ENABLE_AD9361 ENABLE_AD9361 "Enables Ad9361_Fpga_Signal_Source for devices with the AD9361 chipset. Requires libiio and libad9361-dev.") -add_feature_info(ENABLE_AD936X_SDR ENABLE_AD936X_SDR "Enables Ad936x_Iio_Signal_Source to access AD936X front-ends using libiio. Requires libiio and libad9361-dev.") +add_feature_info(ENABLE_FMCOMMS2 ENABLE_FMCOMMS2 "Enables Fmcomms2_Signal_Source for FMCOMMS2/3/4 devices. Requires libiio, libad9361-dev, and gr-iio.") +add_feature_info(ENABLE_PLUTOSDR ENABLE_PLUTOSDR "Enables Plutosdr_Signal_Source and Ad936x_Custom_Signal_Source for using ADALM-PLUTO boards. Requires libiio, libad9361-dev, and gr-iio.") +add_feature_info(ENABLE_AD936X_SDR ENABLE_AD936X_SDR "Enables Ad936x_Custom_Signal_Source for using ADALM-PLUTO boards with custom firmware. Requires libiio and libad9361-dev.") +add_feature_info(ENABLE_FPGA ENABLE_FPGA "Enables building of processing blocks for FPGA offloading.") +add_feature_info(ENABLE_AD9361 ENABLE_AD9361 "Enables ADRV9361_Z7035_Signal_Source_FPGA and the FMCOMMS5_Signal_Source_FPGA for FPGA SoC devices with the AD9361 chipset. Requires libiio, libad9361-dev, and -DENABLE_FPGA=ON.") +add_feature_info(ENABLE_MAX2771 ENABLE_MAX2771 "Enables FPGA_MAX2771_EVKIT_Signal_Source for FPGA SoC devices with the with the MAX2771 chipset. Requires the spidev driver and -DENABLE_FPGA=ON.") +add_feature_info(ENABLE_DMA_PROXY ENABLE_DMA_PROXY "Enables DMA_Signal_Source_FPGA for file post-processing in FPGA SoC devices. Requires the DMA Proxy driver and -DENABLE_FPGA=ON.") add_feature_info(ENABLE_RAW_UDP ENABLE_RAW_UDP "Enables Custom_UDP_Signal_Source for custom UDP packet sample source. Requires libpcap.") add_feature_info(ENABLE_FLEXIBAND ENABLE_FLEXIBAND "Enables Flexiband_Signal_Source for using Teleorbit's Flexiband RF front-end. Requires gr-teleorbit.") add_feature_info(ENABLE_ARRAY ENABLE_ARRAY "Enables Raw_Array_Signal_Source and Array_Signal_Conditioner for using CTTC's antenna array. Requires gr-dbfcttc.") add_feature_info(ENABLE_ZMQ ENABLE_ZMQ "Enables ZMQ_Signal_Source for GNU Radio ZeroMQ messages. Requires gr-zeromq.") +add_feature_info(ENABLE_ION ENABLE_ION "Enables ION_GSMS_Signal_Source for the ION Metadata Standard.") add_feature_info(ENABLE_GPERFTOOLS ENABLE_GPERFTOOLS "Enables performance analysis. Requires Gperftools.") add_feature_info(ENABLE_GPROF ENABLE_GPROF "Enables performance analysis with 'gprof'.") add_feature_info(ENABLE_CLANG_TIDY ENABLE_CLANG_TIDY "Runs clang-tidy along with the compiler. Requires Clang.") add_feature_info(ENABLE_PROFILING ENABLE_PROFILING "Runs volk_gnsssdr_profile at the end of the building.") add_feature_info(ENABLE_OPENCL ENABLE_OPENCL "Enables GPS_L1_CA_PCPS_OpenCl_Acquisition (experimental). Requires OpenCL.") add_feature_info(ENABLE_CUDA ENABLE_CUDA "Enables GPS_L1_CA_DLL_PLL_Tracking_GPU (experimental). Requires CUDA.") -add_feature_info(ENABLE_FPGA ENABLE_FPGA "Enables building of processing blocks for FPGA offloading.") add_feature_info(ENABLE_ARMA_NO_DEBUG ENABLE_ARMA_NO_DEBUG "Enables passing the ARMA_NO_DEBUG macro to Armadillo, hence disabling bound checking.") add_feature_info(ENABLE_PACKAGING ENABLE_PACKAGING "Enables software packaging.") add_feature_info(ENABLE_OWN_GLOG ENABLE_OWN_GLOG "Forces the downloading and building of Google glog.") +add_feature_info(ENABLE_GLOG_AND_GFLAGS ENABLE_GLOG_AND_GFLAGS "Forces the usage of Google glog and Gflags instead of Abseil.") +add_feature_info(ENABLE_OWN_ABSEIL ENABLE_OWN_ABSEIL "Forces downloading and building Abseil. Supersedes ENABLE_OWN_GLOG.") add_feature_info(ENABLE_OWN_ARMADILLO ENABLE_OWN_ARMADILLO "Forces the downloading and building of Armadillo.") -add_feature_info(ENABLE_LOG ENABLE_LOG "Enables runtime internal logging with Google glog.") +add_feature_info(ENABLE_GNUTLS ENABLE_GNUTLS "Forces linking against GnuTLS instead of OpenSSL.") +add_feature_info(ENABLE_LOG ENABLE_LOG "Enables runtime internal logging.") add_feature_info(ENABLE_ORC ENABLE_ORC "Use the Optimized Inner Loop Runtime Compiler (ORC) for building volk_gnsssdr.") add_feature_info(ENABLE_STRIP ENABLE_STRIP "Enables the generation of stripped binaries (without debugging symbols).") add_feature_info(ENABLE_UNIT_TESTING ENABLE_UNIT_TESTING "Enables building of Unit Tests.") @@ -3466,13 +3734,19 @@ message(STATUS "* SUMMARY REPORT *") message(STATUS "***************************************") message(STATUS "") if(CMAKE_CROSSCOMPILING) - message(STATUS "Cross-compiling on ${LINUX_DISTRIBUTION} ${LINUX_VER} (${CMAKE_HOST_SYSTEM_PROCESSOR}) for ${CMAKE_SYSTEM_PROCESSOR} ${ARCHITECTURE_STRING}") + message(STATUS "Cross-compiling on ${LINUX_DISTRIBUTION} ${LINUX_VER} (${CMAKE_HOST_SYSTEM_PROCESSOR}) for ${CMAKE_SYSTEM_PROCESSOR}") else() if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") message(STATUS "Building on GNU/Linux ${LINUX_DISTRIBUTION} ${LINUX_VER} ${ARCHITECTURE_STRING}") endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") message(STATUS "Building on ${MACOS_DISTRIBUTION}") + if(${DETECT_MACPORTS} EQUAL 0) + message(STATUS "Found Macports v${MACPORTS_VERSION} installed at ${MACPORTS_PREFIX}") + endif() + if(${DETECT_HOMEBREW} EQUAL 0) + message(STATUS "Found Homebrew v${HOMEBREW_VERSION} installed at ${HOMEBREW_PREFIX}") + endif() endif() endif() message(STATUS "CMake version: ${CMAKE_VERSION}") @@ -3489,7 +3763,7 @@ file(APPEND ${GNSSSDR_BINARY_DIR}/features.log "******************************** file(APPEND ${GNSSSDR_BINARY_DIR}/features.log "GNSS-SDR version: ${VERSION}\n") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") if(CMAKE_CROSSCOMPILING) - file(APPEND ${GNSSSDR_BINARY_DIR}/features.log "Cross-compiling on ${LINUX_DISTRIBUTION} ${LINUX_VER} (${CMAKE_HOST_SYSTEM_PROCESSOR}) for ${CMAKE_SYSTEM_PROCESSOR} ${ARCHITECTURE_STRING}\n") + file(APPEND ${GNSSSDR_BINARY_DIR}/features.log "Cross-compiling on ${LINUX_DISTRIBUTION} ${LINUX_VER} (${CMAKE_HOST_SYSTEM_PROCESSOR}) for ${CMAKE_SYSTEM_PROCESSOR}\n") else() file(APPEND ${GNSSSDR_BINARY_DIR}/features.log "Building on GNU/Linux ${LINUX_DISTRIBUTION} ${LINUX_VER} ${ARCHITECTURE_STRING}\n") endif() diff --git a/README.md b/README.md index 7e9fd62d9..de5550ef6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ SPDX-License-Identifier: GPL-3.0-or-later ) [comment]: # ( -SPDX-FileCopyrightText: 2011-2024 Carles Fernandez-Prades +SPDX-FileCopyrightText: 2011-2025 Carles Fernandez-Prades ) @@ -59,60 +59,59 @@ information about this open-source, software-defined GNSS receiver. (click to expand) -1. [Table of Contents](#table-of-contents) -2. [How to build GNSS-SDR](#how-to-build-gnss-sdr) - 1. [GNU/Linux](#gnulinux) - 1. [Alternative 1: Install dependencies using software packages](#alternative-1-install-dependencies-using-software-packages) - 1. [Debian / Ubuntu](#debian--ubuntu) - 2. [AlmaLinux](#almalinux) - 3. [Arch Linux](#arch-linux) - 4. [CentOS](#centos) - 5. [Fedora](#fedora) - 6. [openSUSE](#opensuse) - 7. [Rocky Linux](#rocky-linux) - 2. [Alternative 2: Install dependencies using PyBOMBS](#alternative-2-install-dependencies-using-pybombs) - 3. [Manual installation of other required dependencies](#manual-installation-of-other-required-dependencies) - 1. [Install Armadillo, a C++ linear algebra library](#install-armadillo-a-c-linear-algebra-library) - 2. [Install Gflags, a commandline flags processing module for C++](#install-gflags-a-commandline-flags-processing-module-for-c) - 3. [Install Glog, a library that implements application-level logging](#install-glog-a-library-that-implements-application-level-logging) - 4. [Install the GnuTLS or OpenSSL libraries](#install-the-gnutls-or-openssl-libraries) - 5. [Install Matio, MATLAB MAT file I/O library](#install-matio-matlab-mat-file-io-library) - 6. [Install Protocol Buffers, a portable mechanism for serialization of structured data](#install-protocol-buffers-a-portable-mechanism-for-serialization-of-structured-data) - 7. [Install Pugixml, a light-weight C++ XML processing library](#install-pugixml-a-light-weight-c-xml-processing-library) - 8. [Download GoogleTest](#download-googletest) - 4. [Clone GNSS-SDR's Git repository](#clone-gnss-sdrs-git-repository) - 5. [Build and install GNSS-SDR](#build-and-install-gnss-sdr) - 1. [Build OSMOSDR support (OPTIONAL)](#build-osmosdr-support-optional) - 2. [Build FMCOMMS2 based SDR Hardware support (OPTIONAL)](#build-fmcomms2-based-sdr-hardware-support-optional) - 3. [Build OpenCL support (OPTIONAL)](#build-opencl-support-optional) - 4. [Build CUDA support (OPTIONAL)](#build-cuda-support-optional) - 2. [macOS](#macos) - 1. [Macports](#macports) - 2. [Homebrew](#homebrew) - 3. [Other package managers](#other-package-managers) - 4. [Build GNSS-SDR](#build-gnss-sdr) - 3. [Other builds](#other-builds) -3. [Updating GNSS-SDR](#updating-gnss-sdr) -4. [Getting started](#getting-started) -5. [Using GNSS-SDR](#using-gnss-sdr) - 1. [Control plane](#control-plane) - 1. [Configuration](#configuration) - 2. [GNSS block factory](#gnss-block-factory) - 2. [Signal Processing plane](#signal-processing-plane) - 1. [Signal Source](#signal-source) - 2. [Signal Conditioner](#signal-conditioner) - 1. [Data type adapter](#data-type-adapter) - 2. [Input filter](#input-filter) - 3. [Resampler](#resampler) - 3. [Channel](#channel) - 1. [Acquisition](#acquisition) - 2. [Tracking](#tracking) - 3. [Decoding of the navigation message](#decoding-of-the-navigation-message) - 4. [Observables](#observables) - 5. [Computation of Position, Velocity, and Time](#computation-of-position-velocity-and-time) -6. [About the software license](#about-the-software-license) -7. [Publications and Credits](#publications-and-credits) -8. [Ok, now what?](#ok-now-what) +- [Table of Contents](#table-of-contents) +- [How to build GNSS-SDR](#how-to-build-gnss-sdr) + - [GNU/Linux](#gnulinux) + - [Alternative 1: Install dependencies using software packages](#alternative-1-install-dependencies-using-software-packages) + - [Debian / Ubuntu](#debian--ubuntu) + - [AlmaLinux](#almalinux) + - [Arch Linux](#arch-linux) + - [Fedora](#fedora) + - [openSUSE](#opensuse) + - [Rocky Linux](#rocky-linux) + - [Alternative 2: Install dependencies using PyBOMBS](#alternative-2-install-dependencies-using-pybombs) + - [Manual installation of other required dependencies](#manual-installation-of-other-required-dependencies) + - [Install Armadillo, a C++ linear algebra library](#install-armadillo-a-c-linear-algebra-library) + - [Install Gflags, a commandline flags processing module for C++](#install-gflags-a-commandline-flags-processing-module-for-c) + - [Install Glog, a library that implements application-level logging](#install-glog-a-library-that-implements-application-level-logging) + - [Install the OpenSSL libraries](#install-the-openssl-libraries) + - [Install Matio, MATLAB MAT file I/O library](#install-matio-matlab-mat-file-io-library) + - [Install Protocol Buffers, a portable mechanism for serialization of structured data](#install-protocol-buffers-a-portable-mechanism-for-serialization-of-structured-data) + - [Install Pugixml, a light-weight C++ XML processing library](#install-pugixml-a-light-weight-c-xml-processing-library) + - [Download GoogleTest](#download-googletest) + - [Clone GNSS-SDR's Git repository](#clone-gnss-sdrs-git-repository) + - [Build and install GNSS-SDR](#build-and-install-gnss-sdr) + - [Build OSMOSDR support (OPTIONAL)](#build-osmosdr-support-optional) + - [Build FMCOMMS2 based SDR Hardware support (OPTIONAL)](#build-fmcomms2-based-sdr-hardware-support-optional) + - [Build OpenCL support (OPTIONAL)](#build-opencl-support-optional) + - [Build CUDA support (OPTIONAL)](#build-cuda-support-optional) + - [macOS](#macos) + - [Macports](#macports) + - [Homebrew](#homebrew) + - [Other package managers](#other-package-managers) + - [Build GNSS-SDR](#build-gnss-sdr) + - [Other builds](#other-builds) +- [Updating GNSS-SDR](#updating-gnss-sdr) +- [Getting started](#getting-started) +- [Using GNSS-SDR](#using-gnss-sdr) + - [Control plane](#control-plane) + - [Configuration](#configuration) + - [GNSS block factory](#gnss-block-factory) + - [Signal Processing plane](#signal-processing-plane) + - [Signal Source](#signal-source) + - [Signal Conditioner](#signal-conditioner) + - [Data type adapter](#data-type-adapter) + - [Input filter](#input-filter) + - [Resampler](#resampler) + - [Channel](#channel) + - [Acquisition](#acquisition) + - [Tracking](#tracking) + - [Decoding of the navigation message](#decoding-of-the-navigation-message) + - [Observables](#observables) + - [Computation of Position, Velocity, and Time](#computation-of-position-velocity-and-time) +- [About the software license](#about-the-software-license) +- [Publications and Credits](#publications-and-credits) +- [Ok, now what?](#ok-now-what) @@ -126,15 +125,17 @@ This section describes how to set up the compilation environment in GNU/Linux or ## GNU/Linux - Tested distributions: Ubuntu 14.04 LTS and above; Debian 9.0 "stretch" and - above; Arch Linux; CentOS 7; Fedora 26 and above; OpenSUSE 42.3 and above. + above; Arch Linux; Fedora 26 and above; OpenSUSE 42.3 and above. - Supported microprocessor architectures: - - i386: Intel x86 instruction set (32-bit microprocessors). - amd64: also known as x86-64, the 64-bit version of the x86 instruction set, originally created by AMD and implemented by AMD, Intel, VIA, and others. - armel: ARM embedded ABI, supported on ARM v4t and higher. - armhf: ARM hard float, ARMv7 + VFP3-D16 floating-point hardware extension + Thumb-2 instruction set and above. - - arm64: ARM 64 bits or ARMv8. + - arm64: ARM 64 bits or ARMv8. Also known as AArch64. + - i386: Intel x86 instruction set (32-bit microprocessors). + - loong64: 64-bit version of LoongArch, a RISC-style instruction set + architecture developed by Loongson Technology. - mips: MIPS architecture (big-endian, such as those manufactured by SGI). - mipsel: MIPS architecture (little-endian, such as Loongson 3). - mips64el: 64-bit version of MIPS architecture. @@ -164,20 +165,23 @@ If you are using Debian 9, Ubuntu 14.10 or above, this can be done by copying and pasting the following line in a terminal: ``` -$ sudo apt-get install build-essential cmake git pkg-config libboost-dev libboost-date-time-dev \ +$ sudo apt install build-essential cmake git pkg-config libboost-dev libboost-date-time-dev \ libboost-system-dev libboost-filesystem-dev libboost-thread-dev libboost-chrono-dev \ libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \ libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \ - libgnutls-openssl-dev libpcap-dev libmatio-dev libpugixml-dev libgtest-dev \ - libprotobuf-dev protobuf-compiler python3-mako + libssl-dev libpcap-dev libmatio-dev libpugixml-dev libgtest-dev \ + libprotobuf-dev libcpu-features-dev protobuf-compiler python3-mako ``` Please note that the required files from `libgtest-dev` were named `googletest` in Debian 9 "stretch" and Ubuntu 18.04 "bionic", and renamed to `libgtest-dev` in Debian 10 "buster" and above. -Since Ubuntu 21.04 Hirsute / Debian 11, the package `libcpu-features-dev` is -also required. +In distributions older than Ubuntu 21.04 Hirsute / Debian 11, the package +`libcpu-features-dev` is not required. + +In distributions older than Ubuntu 22.04 Jammy / Debian 12, the package +`libssl-dev` must be replaced by `libgnutls-openssl-dev`. **Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source and install GNU Radio manually, as explained below, since GNSS-SDR requires @@ -222,28 +226,9 @@ Once you have installed these packages, you can jump directly to If you are using Arch Linux: ``` -$ pacman -S gcc make cmake pkgconf git boost boost-libs log4cpp libvolk gnuradio \ - blas lapack gflags google-glog openssl pugixml libmatio protobuf \ - python-mako libpcap gtest -``` - -Once you have installed these packages, you can jump directly to -[download the source code and build GNSS-SDR](#clone-gnss-sdrs-git-repository). - -#### CentOS - -If you are using CentOS 7, you can install the dependencies via Extra Packages -for Enterprise Linux ([EPEL](https://fedoraproject.org/wiki/EPEL)): - -``` -$ sudo yum install wget -$ wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm -$ sudo rpm -Uvh epel-release-latest-7.noarch.rpm -$ sudo yum install make automake gcc gcc-c++ kernel-devel libtool \ - hdf5-devel cmake git boost-devel boost-date-time boost-system \ - boost-filesystem boost-thread boost-chrono boost-serialization \ - log4cpp-devel gnuradio-devel gr-osmosdr-devel blas-devel lapack-devel \ - armadillo-devel openssl-devel libpcap-devel python-mako python-six pugixml-devel +$ pacman -S gcc make cmake pkgconf git boost boost-libs libvolk gnuradio \ + blas lapack hdf5 openssl pugixml libmatio protobuf libpcap gtest \ + python-mako ``` Once you have installed these packages, you can jump directly to @@ -278,7 +263,7 @@ $ zypper install cmake git gcc-c++ boost-devel libboost_atomic-devel \ libboost_system-devel libboost_filesystem-devel libboost_chrono-devel \ libboost_thread-devel libboost_serialization-devel log4cpp-devel \ gnuradio-devel pugixml-devel libpcap-devel armadillo-devel libtool \ - automake hdf5-devel openssl-devel python3-Mako protobuf-devel + automake hdf5-devel openssl-devel python3-Mako libmatio-devel ``` If you are using openSUSE Tumbleweed: @@ -330,7 +315,7 @@ tutorial. First of all, install some basic packages: ``` -$ sudo apt-get install git python3-pip +$ sudo apt install git python3-pip ``` Download, build and install PyBOMBS: @@ -396,16 +381,16 @@ or manually as explained below, and then please follow instructions on how to ### Manual installation of other required dependencies -#### Install [Armadillo](http://arma.sourceforge.net/ "Armadillo's Homepage"), a C++ linear algebra library +#### Install [Armadillo](https://arma.sourceforge.net/ "Armadillo's Homepage"), a C++ linear algebra library ``` -$ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/LinuxMint -$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL +$ sudo apt install libblas-dev liblapack-dev # For Debian/Ubuntu/LinuxMint +$ sudo yum install lapack-devel blas-devel # For Fedora/RHEL $ sudo zypper install lapack-devel blas-devel # For OpenSUSE $ sudo pacman -S blas lapack # For Arch Linux -$ wget https://sourceforge.net/projects/arma/files/armadillo-12.0.1.tar.xz -$ tar xvfz armadillo-12.0.1.tar.xz -$ cd armadillo-12.0.1 +$ wget https://sourceforge.net/projects/arma/files/armadillo-14.4.1.tar.xz +$ tar xvfz armadillo-14.4.1.tar.xz +$ cd armadillo-14.4.1 $ cmake . $ make $ sudo make install @@ -430,12 +415,16 @@ $ sudo make install $ sudo ldconfig ``` +Please note that GFlags is replaced by the +[Abseil Flags Library](https://abseil.io/docs/cpp/guides/flags) if Abseil >= +v20240116 is available in your system. + #### Install [Glog](https://github.com/google/glog "Glog's Homepage"), a library that implements application-level logging ``` -$ wget https://github.com/google/glog/archive/v0.6.0.tar.gz -$ tar xvfz v0.6.0.tar.gz -$ cd glog-0.6.0 +$ wget https://github.com/google/glog/archive/v0.7.1.tar.gz +$ tar xvfz v0.7.1.tar.gz +$ cd glog-0.7.1 $ mkdir build && cd build $ cmake .. $ make @@ -443,33 +432,32 @@ $ sudo make install $ sudo ldconfig ``` -#### Install the GnuTLS or OpenSSL libraries +Please note that Glog is replaced by the +[Abseil Logging Library](https://abseil.io/docs/cpp/guides/logging) if Abseil >= +v20240116 is available in your system. + +#### Install the OpenSSL libraries ``` -$ sudo apt-get install libgnutls-openssl-dev # For Debian/Ubuntu/LinuxMint -$ sudo yum install openssl-devel # For Fedora/CentOS/RHEL -$ sudo zypper install openssl-devel # For OpenSUSE -$ sudo pacman -S openssl # For Arch Linux +$ sudo apt install libssl-dev # For Debian/Ubuntu/LinuxMint +$ sudo yum install openssl-devel # For Fedora/CentOS/RHEL +$ sudo zypper install openssl-devel # For OpenSUSE +$ sudo pacman -S openssl # For Arch Linux ``` -In case the [GnuTLS](https://www.gnutls.org/ "GnuTLS's Homepage") library with -openssl extensions package is not available in your GNU/Linux distribution, -GNSS-SDR can also work well with -[OpenSSL](https://www.openssl.org/ "OpenSSL's Homepage"). - #### Install [Matio](https://github.com/tbeu/matio "Matio's Homepage"), MATLAB MAT file I/O library ``` -$ wget https://github.com/tbeu/matio/releases/download/v1.5.23/matio-1.5.23.tar.gz -$ tar xvfz matio-1.5.23.tar.gz -$ cd matio-1.5.23 +$ wget https://github.com/tbeu/matio/releases/download/v1.5.28/matio-1.5.28.tar.gz +$ tar xvfz matio-1.5.28.tar.gz +$ cd matio-1.5.28 $ ./configure $ make $ sudo make install $ sudo ldconfig ``` -#### Install [Protocol Buffers](https://developers.google.com/protocol-buffers/ "Protocol Buffers' Homepage"), a portable mechanism for serialization of structured data +#### Install [Protocol Buffers](https://protobuf.dev/ "Protocol Buffers' Homepage"), a portable mechanism for serialization of structured data GNSS-SDR requires Protocol Buffers v3.0.0 or later. If the packages that come with your distribution are older than that (_e.g._, Ubuntu 16.04 Xenial came @@ -489,9 +477,9 @@ For more options, please check the #### Install [Pugixml](https://pugixml.org/ "Pugixml's Homepage"), a light-weight C++ XML processing library ``` -$ wget https://github.com/zeux/pugixml/releases/download/v1.13/pugixml-1.13.tar.gz -$ tar xvfz pugixml-1.13.tar.gz -$ cd pugixml-1.13 +$ wget https://github.com/zeux/pugixml/releases/download/v1.15/pugixml-1.15.tar.gz +$ tar xvfz pugixml-1.15.tar.gz +$ cd pugixml-1.15 $ mkdir build && cd build $ cmake .. $ make @@ -502,8 +490,8 @@ $ sudo ldconfig #### Download [GoogleTest](https://github.com/google/googletest "Googletest Homepage") ``` -$ wget https://github.com/google/googletest/archive/refs/tags/v1.13.0.zip -$ unzip v1.13.0.zip +$ wget https://github.com/google/googletest/archive/refs/tags/v1.16.0.zip +$ unzip v1.16.0.zip ``` Please **DO NOT build or install** Google Test. Every user needs to compile @@ -527,10 +515,10 @@ downloaded resides. Just type in your terminal (or add it to your `$HOME/.bashrc` file for a permanent solution) the following line: ``` -export GTEST_DIR=/home/username/googletest-1.13.0 +export GTEST_DIR=/home/username/googletest-1.16.0 ``` -changing `/home/username/googletest-1.13.0` by the actual path where you +changing `/home/username/googletest-1.16.0` by the actual path where you unpacked Google Test. If the CMake script does not find that folder, or the environment variable is not defined, or the source code is not installed by a package, then it will download a fresh copy of the Google Test source code and @@ -549,18 +537,16 @@ gnss-sdr with the following structure: ``` |-gnss-sdr - |---build <- where gnss-sdr is built. |---cmake <- CMake-related files. |---conf <- Configuration files. Each file defines one particular receiver. - |---data <- Populate this folder with your captured data. |---docs <- Contains documentation-related files. |---install <- Executables will be placed here. |---src <- Source code folder. |-----algorithms <- Signal processing blocks. |-----core <- Control plane, interfaces, systems' parameters. |-----main <- Main function of the C++ program. - |-----tests <- QA code. - |-----utils <- some utilities (e.g. Matlab scripts). + |---tests <- QA code. + |---utils <- some utilities (e.g. Matlab scripts). ``` By default, you will be in the 'main' branch of the Git repository, which @@ -581,14 +567,14 @@ readings can be found at our Go to GNSS-SDR's build directory: ``` -$ cd gnss-sdr/build +$ cd gnss-sdr ``` Configure and build the application: ``` -$ cmake .. -$ make +$ cmake -S . -B build +$ cmake --build build ``` By default, CMake will build the Release version, meaning that the compiler will @@ -599,8 +585,8 @@ information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing: ``` -$ cmake -DCMAKE_BUILD_TYPE=Debug .. -$ make +$ cmake -S . -B build-debug -DCMAKE_BUILD_TYPE=Debug +$ cmake --build build-debug ``` This will create four executables at gnss-sdr/install, namely `gnss-sdr`, @@ -609,7 +595,7 @@ that folder, but if you prefer to install `gnss-sdr` on your system and have it available anywhere else, do: ``` -$ sudo make install +$ sudo cmake --install build ``` This will also make a copy of the conf/ folder into @@ -618,24 +604,24 @@ directory at your preferred location and store your own configuration and data files there. You could be interested in creating the documentation (requires: -`sudo apt-get install doxygen-latex` in Ubuntu/Debian) by doing: +`sudo apt install doxygen-latex` in Ubuntu/Debian) by doing: ``` -$ make doc +$ cmake --build build --target doc ``` -from the gnss-sdr/build folder. This will generate HTML documentation that can -be retrieved pointing your browser of preference to build/docs/html/index.html. -If a LaTeX installation is detected in your system, +This will generate HTML documentation that can be retrieved pointing your +browser of preference to `build/docs/html/index.html`. If a LaTeX installation +is detected in your system, ``` -$ make pdfmanual +$ cmake --build build --target pdfmanual ``` will create a PDF manual at build/docs/GNSS-SDR_manual.pdf. Finally, ``` -$ make doc-clean +$ cmake --build build --target doc-clean ``` will remove the content of previously generated documentation. @@ -653,30 +639,6 @@ the function to execute. It mimics GNU Radio's [VOLK](https://www.libvolk.org/) library, so if you still have not run `volk_profile`, this is a good moment to do so. -If you are using [Eclipse](https://www.eclipse.org/ide/) as your development -environment, CMake can create the project for you. However, if the build -directory is a subdirectory of the source directory (as is the case of the -`gnss-sdr/build` folder), this is not supported well by Eclipse. It is strongly -recommended to use a build directory which is a sibling of the source directory. -Hence, type from the `gnss-sdr` root folder: - -``` -$ cd .. -$ mkdir eclipse && cd eclipse -$ cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_ECLIPSE_VERSION=4.5 ../gnss-sdr -``` - -and then import the created project into Eclipse: - -1. Import project using Menu File -> Import. -2. Select General -> Existing projects into workspace. -3. Select your root directory: Browse and select your newly created `eclipse/` - directory. Keep "Copy projects into workspace" unchecked. -4. Click on "Finish" and you will get a fully functional Eclipse project. - -After building the project, you will find the generated binaries at -`eclipse/install`. - #### Build OSMOSDR support (OPTIONAL) Install the [OsmoSDR](https://osmocom.org/projects/sdr "OsmoSDR's Homepage") @@ -705,9 +667,9 @@ $ sudo ldconfig Then, configure GNSS-SDR to build the `Osmosdr_Signal_Source` by: ``` -$ cmake -DENABLE_OSMOSDR=ON .. -$ make -$ sudo make install +$ cmake -S . -B build -DENABLE_OSMOSDR=ON +$ cmake --build build +$ sudo cmake --install build ``` (in order to disable the `Osmosdr_Signal_Source` compilation, you can pass @@ -721,7 +683,7 @@ libraries and [gr-iio](https://github.com/analogdevicesinc/gr-iio.git) (>v0.3) gnuradio block: ``` -$ sudo apt-get install libxml2-dev bison flex +$ sudo apt install libxml2-dev bison flex $ git clone https://github.com/analogdevicesinc/libiio.git $ cd libiio $ mkdir build @@ -748,18 +710,18 @@ $ cd ../.. Then configure GNSS-SDR to build the `Fmcomms2_Signal_Source` implementation: ``` -$ cd gnss-sdr/build -$ cmake -DENABLE_FMCOMMS2=ON .. -$ make -$ sudo make install +$ cd gnss-sdr +$ cmake -S . -B build -DENABLE_FMCOMMS2=ON +$ cmake --build build +$ sudo cmake --install build ``` or configure it to build `Plutosdr_Signal_Source`: ``` -$ cmake -DENABLE_PLUTOSDR=ON .. -$ make -$ sudo make install +$ cmake -S . -B build -DENABLE_PLUTOSDR=ON +$ cmake --build build +$ sudo cmake --install build ``` With `Fmcomms2_Signal_Source` you can use any SDR hardware based on @@ -774,9 +736,9 @@ devices. In order to enable the building of blocks that use OpenCL, type: ``` -$ cmake -DENABLE_OPENCL=ON .. -$ make -$ sudo make install +$ cmake -S . -B build -DENABLE_OPENCL=ON +$ cmake --build build +$ sudo cmake --install build ``` #### Build CUDA support (OPTIONAL) @@ -788,9 +750,9 @@ data-parallel computations, first you need to install the CUDA Toolkit from Make sure that the SDK samples build well. Then, build GNSS-SDR by doing: ``` -$ cmake -DENABLE_CUDA=ON .. -$ make -$ sudo make install +$ cmake -S . -B build -DENABLE_CUDA=ON +$ cmake --build build +$ sudo cmake --install build ``` Of course, you will also need a GPU that @@ -830,10 +792,10 @@ In a terminal, type: ``` $ sudo port selfupdate $ sudo port upgrade outdated -$ sudo port install armadillo cmake pkgconfig protobuf3-cpp pugixml gnutls +$ sudo port install armadillo cmake pkgconfig protobuf3-cpp pugixml openssl3 $ sudo port install gnuradio +uhd +grc +zeromq -$ sudo port install boost matio libad9361-iio libiio google-glog +gflags -$ sudo port install py311-mako +$ sudo port install boost matio libad9361-iio libiio abseil +$ sudo port install py313-mako $ sudo port install doxygen +docs ``` @@ -853,7 +815,7 @@ $ port select --list python and you can activate a certain version by typing: ``` -$ sudo port select --set python python311 +$ sudo port select --set python python313 ``` ### Homebrew @@ -867,22 +829,14 @@ $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/inst The script explains what it will do, and then it pauses before doing it. There are more installation options [here](https://docs.brew.sh/Installation.html). -Install pip3: - -``` -$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py -$ sudo python3 get-pip.py -``` - Install the required dependencies: ``` $ brew update && brew upgrade -$ brew install armadillo cmake hdf5 gflags glog gnuradio libmatio log4cpp \ - openssl pkg-config protobuf pugixml -$ pip3 install mako +$ brew install armadillo cmake hdf5 gnuradio libmatio openssl pkg-config protobuf pugixml boost $ brew install --cask mactex # when completed, restart Terminal $ brew install graphviz doxygen +¢ pip3 install mako ``` For macOS versions older than Sonoma, you will also need LAPACK: @@ -894,20 +848,20 @@ $ brew install lapack ### Other package managers GNU Radio and other dependencies can also be installed using other package -managers than Macports, such as [Fink](http://www.finkproject.org/ "Fink"). +managers than Macports, such as [Fink](https://www.finkproject.org/ "Fink"). Since the version of Python that ships with OS X is great for learning but it is not good for development, you could have another Python executable in a non-standard location. If that is the case, you need to inform GNSS-SDR's configuration system by defining the `PYTHON_EXECUTABLE` variable as: ``` -$ cmake -DPYTHON_EXECUTABLE=/path/to/bin/python3 .. +$ cmake -S . -B build -DPYTHON_EXECUTABLE=/path/to/bin/python3 ``` In case you have installed Macports in a non-standard location, you can use: ``` -$ cmake -DCMAKE_PREFIX_PATH=/opt/local -DUSE_MACPORTS_PYTHON=/opt/local/bin/python .. +$ cmake -S . -B build -DCMAKE_PREFIX_PATH=/opt/local -DUSE_MACPORTS_PYTHON=/opt/local/bin/python ``` changing `/opt/local` by the base directory in which your software is installed. @@ -923,17 +877,23 @@ software: ``` $ git clone https://github.com/gnss-sdr/gnss-sdr -$ cd gnss-sdr/build -$ cmake .. -$ make +$ cd gnss-sdr +$ cmake -S . -B build +$ cmake --build build ``` -This will create three executables at gnss-sdr/install, namely `gnss-sdr`, +This will create three executables at `gnss-sdr/install`, namely `gnss-sdr`, `run_tests` and `volk_gnsssdr_profile`. You can install the software receiver on your system by doing: ``` -$ sudo make install +$ sudo cmake --install build +``` + +and uninstall it with: + +``` +$ sudo cmake --build build --target uninstall ``` Note, it is advisable not to run the install step in a homebrew environment. @@ -941,7 +901,7 @@ Note, it is advisable not to run the install step in a homebrew environment. The documentation can be built by: ``` -$ make doc +$ cmake --build build --target doc ``` and can be viewed doing: @@ -984,7 +944,7 @@ do so.

- **GNSS-SDR in embedded platforms**: we provide a Software Development Kit - (SDK) based on [OpenEmbedded](http://www.openembedded.org/wiki/Main_Page) for + (SDK) based on [OpenEmbedded](https://www.openembedded.org/wiki/Main_Page) for cross-compiling GNSS-SDR in your desktop computer and for producing executables that can run in embedded platforms, such as Xilinx's Zynq and ZynqMP architectures, Raspberry Pi, and many others. Please check @@ -1016,7 +976,7 @@ $ git pull upstream next ``` Before rebuilding the source code, it is safe (and recommended) to remove the -remainders of old compilations: +remainders of old compilations, _e.g._: ``` $ rm -rf gnss-sdr/build/* @@ -1112,7 +1072,7 @@ You can use a single configuration file for processing different data files, specifying the file to be processed with the `--signal_source` flag: ``` -$ gnss-sdr --config_file=../conf/my_receiver.conf --signal_source=../data/my_captured_data.dat +$ gnss-sdr --config_file=../conf/my_receiver.conf --signal_source=./my_captured_data.dat ``` This will override the `SignalSource.filename` specified in the configuration @@ -1497,7 +1457,7 @@ SignalSource.port=1234 SignalSource.swap_iq=false SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ``` Example for a dual-frequency receiver: @@ -1591,7 +1551,7 @@ The block can be configured like this: ;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz. InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false ; #dump: Dump the filtered data to a file. -InputFilter.dump_filename=../data/input_filter.dat ; #dump_filename: Log path and filename. +InputFilter.dump_filename=./input_filter.dat ; #dump_filename: Log path and filename. InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -1644,7 +1604,7 @@ implements a nearest neighbourhood interpolation: ;#[Pass_Through] disables this block Resampler.implementation=Direct_Resampler Resampler.dump=false ; Dumps the resampled data to a file. -Resampler.dump_filename=../data/resampler.dat ; log path and filename. +Resampler.dump_filename=./resampler.dat ; log path and filename. Resampler.item_type=gr_complex Resampler.sample_freq_in=8000000 ; sample frequency of the input signal Resampler.sample_freq_out=4000000 ; desired sample frequency of the output signal @@ -1872,7 +1832,7 @@ Tracking_1B.dll_filter_order=2 ; DLL loop filter order [1], [2] or [3] Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ``` More documentation at the @@ -1999,11 +1959,11 @@ PVT.rtcm_MT1077_rate_ms=1000 Notation (JSON) supported by numerous mapping and GIS software packages, including [OpenLayers](https://openlayers.org), [Leaflet](https://leafletjs.com), [MapServer](https://mapserver.org/), - [GeoServer](http://geoserver.org), [GeoDjango](https://www.djangoproject.com), - [GDAL](https://gdal.org/), and [CartoDB](https://cartodb.com). It is also - possible to use GeoJSON with [PostGIS](https://postgis.net/) and - [Mapnik](https://mapnik.org/), both of which handle the format via the GDAL - OGR conversion library. The + [GeoServer](https://geoserver.org/), + [GeoDjango](https://www.djangoproject.com), [GDAL](https://gdal.org/), and + [CartoDB](https://cartodb.com). It is also possible to use GeoJSON with + [PostGIS](https://postgis.net/) and [Mapnik](https://mapnik.org/), both of + which handle the format via the GDAL OGR conversion library. The [Google Maps Javascript API](https://developers.google.com/maps/documentation/javascript/) v3 directly supports the [integration of GeoJSON data layers](https://developers.google.com/maps/documentation/javascript/examples/layer-data-simple), @@ -2016,8 +1976,9 @@ PVT.rtcm_MT1077_rate_ms=1000 (OGC KML), and it is maintained by the Open Geospatial Consortium, Inc. (OGC). KML files can be displayed in geobrowsers such as [Google Earth](https://www.google.com/earth/), - [Marble](https://marble.kde.org), [osgEarth](http://osgearth.org), or used - with the [NASA World Wind SDK for Java](https://worldwind.arc.nasa.gov/java/). + [Marble](https://marble.kde.org), + [osgEarth](https://github.com/gwaldron/osgearth), or used with the + [NASA World Wind SDK for Java](https://worldwind.arc.nasa.gov/java/). - **GPX** (the GPS Exchange Format) is a lightweight XML data format for the interchange of GPS data (waypoints, routes, and tracks) between applications @@ -2052,9 +2013,11 @@ PVT.rtcm_MT1077_rate_ms=1000 (usually with other data unknown to the original receiver, such as better models of the atmospheric conditions at time of measurement). RINEX files can be used by software packages such as - [GNSSTK](https://github.com/SGL-UT/gnsstk), [RTKLIB](http://www.rtklib.com/), - and [gLAB](https://gage.upc.edu/gLAB/). GNSS-SDR by default generates RINEX - version [3.02](ftp://igs.org/pub/data/format/rinex302.pdf). If + [GNSSTK](https://github.com/SGL-UT/gnsstk), [RTKLIB](https://www.rtklib.com/), + and + [gLAB](https://gage.upc.edu/en/learning-materials/software-tools/glab-tool-suite). + GNSS-SDR by default generates RINEX version + [3.02](ftp://igs.org/pub/data/format/rinex302.pdf). If [2.11](ftp://igs.org/pub/data/format/rinex211.txt) is needed, it can be requested through the `rinex_version` parameter in the configuration file: diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index 08e486f4d..000000000 --- a/build/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/cmake/Modules/AvoidAccelerate.cmake b/cmake/Modules/AvoidAccelerate.cmake index 5d052296d..27d9bd6b5 100644 --- a/cmake/Modules/AvoidAccelerate.cmake +++ b/cmake/Modules/AvoidAccelerate.cmake @@ -7,6 +7,10 @@ # Avoid using the BLAS and LAPACK implementations that comes with the Accelerate # framework, which causes a bug when the BeiDou constellation is enabled +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(NOT BLAS_ROOT) set(BLAS_ROOT_USER_DEFINED /usr/local/lib) else() @@ -24,8 +28,8 @@ find_library(BLAS_LIBRARIES PATHS ${BLAS_ROOT_USER_DEFINED} ${BLAS_ROOT_USER_DEFINED}/lapack - /opt/local/lib/lapack - /opt/local/lib/ + ${GNSSSDR_LIB_PATHS}/lapack + ${GNSSSDR_LIB_PATHS} /usr/local/opt/lapack/lib /opt/homebrew/opt/lapack/lib NO_DEFAULT_PATH @@ -46,7 +50,7 @@ find_library(LAPACK_LIBRARIES PATHS ${BLAS_ROOT_USER_DEFINED} ${BLAS_ROOT_USER_DEFINED}/lapack - /opt/local/lib/lapack + ${GNSSSDR_LIB_PATHS}/lapack /usr/local/opt/lapack/lib /opt/homebrew/opt/lapack/lib NO_DEFAULT_PATH diff --git a/cmake/Modules/BuildProtobuf.cmake b/cmake/Modules/BuildProtobuf.cmake index 5590943db..8f7c60278 100644 --- a/cmake/Modules/BuildProtobuf.cmake +++ b/cmake/Modules/BuildProtobuf.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2023 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2023-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # Downloads and builds the protoc compiler and static libraries of Protocol @@ -13,7 +13,7 @@ if(NOT GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION) - set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "25.0") + set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "30.2") endif() if(NOT GNSSSDR_BINARY_DIR) @@ -55,6 +55,11 @@ list(APPEND UTF8_LIBRARIES ${GNSSSDR_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}utf8_range${CMAKE_STATIC_LIBRARY_SUFFIX} ) +set(ABSL_OPTION "") +if(CMAKE_VERSION VERSION_LESS "3.16" OR GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION VERSION_LESS "30.0") + set(ABSL_OPTION "-Dprotobuf_ABSL_PROVIDER=package") +endif() + ExternalProject_Add(protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION} PREFIX ${GNSSSDR_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION} GIT_REPOSITORY https://github.com/protocolbuffers/protobuf @@ -73,7 +78,7 @@ ExternalProject_Add(protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION} -DCMAKE_VISIBILITY_INLINES_HIDDEN=1 -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION} -Dprotobuf_BUILD_TESTS=OFF - -Dprotobuf_ABSL_PROVIDER=package + ${ABSL_OPTION} ${USE_ZLIB} BUILD_COMMAND ${CMAKE_COMMAND} "--build" "${GNSSSDR_BINARY_DIR}/protobuf-${GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION}" diff --git a/cmake/Modules/DetectLinuxDistro.cmake b/cmake/Modules/DetectLinuxDistro.cmake index 3fa556ba4..014b2a8d3 100644 --- a/cmake/Modules/DetectLinuxDistro.cmake +++ b/cmake/Modules/DetectLinuxDistro.cmake @@ -4,10 +4,14 @@ # SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCHITECTURE_STRING "(64 bits)") +if(CMAKE_VERSION VERSION_LESS 3.19) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCHITECTURE_STRING "(64 bits)") + else() + set(ARCHITECTURE_STRING "(32 bits)") + endif() else() - set(ARCHITECTURE_STRING "(32 bits)") + set(ARCHITECTURE_STRING "(${CMAKE_HOST_SYSTEM_PROCESSOR})") endif() if(EXISTS "/etc/lsb-release") diff --git a/cmake/Modules/DetectMacOSVersion.cmake b/cmake/Modules/DetectMacOSVersion.cmake index ac986ba6d..361d3422f 100644 --- a/cmake/Modules/DetectMacOSVersion.cmake +++ b/cmake/Modules/DetectMacOSVersion.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause execute_process(COMMAND uname -v OUTPUT_VARIABLE DARWIN_VERSION) @@ -77,3 +77,24 @@ endif() if(NOT MACOS_DISTRIBUTION) set(MACOS_DISTRIBUTION "macOS (Unknown version)") endif() + +set(MACOS_PACKAGES_PREFIX "") +# Detect if MacPorts is installed on this system; if so, return base path and version +execute_process(COMMAND which port RESULT_VARIABLE DETECT_MACPORTS OUTPUT_VARIABLE MACPORTS_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) +if(${DETECT_MACPORTS} EQUAL 0) + # "/opt/local/bin/port", so we get the parent directory + get_filename_component(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY) + # "/opt/local/bin", so we get the parent directory + get_filename_component(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY) + execute_process(COMMAND port version RESULT_VARIABLE DETECT_MACPORTS_VERSION OUTPUT_VARIABLE MACPORTS_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" MACPORTS_VERSION "${MACPORTS_VERSION}") + set(MACOS_PACKAGES_PREFIX ${MACPORTS_PREFIX}) +endif() + +# Detect if Homebrew is installed on this system; if so, return base path and version +execute_process(COMMAND brew --prefix RESULT_VARIABLE DETECT_HOMEBREW OUTPUT_VARIABLE HOMEBREW_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) +if(${DETECT_HOMEBREW} EQUAL 0) + execute_process(COMMAND brew --version RESULT_VARIABLE DETECT_HOMEBREW_VERSION OUTPUT_VARIABLE HOMEBREW_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" HOMEBREW_VERSION "${HOMEBREW_VERSION}") + set(MACOS_PACKAGES_PREFIX ${HOMEBREW_PREFIX}) +endif() diff --git a/cmake/Modules/FindCPUFEATURES.cmake b/cmake/Modules/FindCPUFEATURES.cmake index 6f25e91d2..89587e6eb 100644 --- a/cmake/Modules/FindCPUFEATURES.cmake +++ b/cmake/Modules/FindCPUFEATURES.cmake @@ -1,54 +1,24 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2021-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause set(FPHSA_NAME_MISMATCHED ON) +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + find_library(CPUFEATURES_LIBRARIES NAMES cpu_features - PATHS /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + PATHS ${GNSSSDR_LIB_PATHS} ) find_path(CPUFEATURES_INCLUDE_DIR cpu_features_macros.h PATHS $ENV{CPUFEATURES_DIR}/include $ENV{CPUFEATURES_DIR} - /usr/include - /usr/local/include - ~/Library/Frameworks - /Library/Frameworks - /sw/include # Fink - /opt/local/include # MacPorts - /opt/csw/include # Blastwave + ${GNSSSDR_INCLUDE_PATHS} PATH_SUFFIXES cpu_features ) diff --git a/cmake/Modules/FindGFLAGS.cmake b/cmake/Modules/FindGFLAGS.cmake index 2649380c9..afc7ebb68 100644 --- a/cmake/Modules/FindGFLAGS.cmake +++ b/cmake/Modules/FindGFLAGS.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # - Try to find GFlags @@ -25,6 +25,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(NOT GFLAGS_ROOT) set(GFLAGS_ROOT_USER_PROVIDED /usr/local) else() @@ -42,9 +46,8 @@ if(APPLE) libgflags.dylib PATHS ${GFLAGS_ROOT_USER_PROVIDED}/lib - /usr/local/lib - /opt/local/lib - /opt/homebrew/opt/gflags/lib + ${GNSSSDR_LIB_PATHS} + ${GNSSSDR_LIB_PATHS}/opt/gflags/lib ) else() find_path(GFlags_ROOT_DIR @@ -52,35 +55,7 @@ else() PATHS ${GFLAGS_ROOT_USER_PROVIDED}/lib ${GFLAGS_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) endif() @@ -92,10 +67,8 @@ if(GFlags_ROOT_DIR) PATHS ${GFlags_ROOT_DIR}/src ${GFLAGS_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include - /opt/homebrew/opt/gflags/include + ${GNSSSDR_INCLUDE_PATHS} + ${GNSSSDR_INCLUDE_PATHS}/opt/gflags/include ) # Find the libraries diff --git a/cmake/Modules/FindGFORTRAN.cmake b/cmake/Modules/FindGFORTRAN.cmake index a6eb38a53..c6e175b41 100644 --- a/cmake/Modules/FindGFORTRAN.cmake +++ b/cmake/Modules/FindGFORTRAN.cmake @@ -1,13 +1,17 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(NOT GFORTRAN_ROOT) set(GFORTRAN_ROOT_USER_DEFINED /usr/lib) else() @@ -20,13 +24,12 @@ if(DEFINED ENV{GFORTRAN_ROOT}) ) endif() -set(GCC_MAJOR_SERIES 14 13 12 11 10 9 8 7 6 5) +set(GCC_MAJOR_SERIES 15 14 13 12 11 10 9 8 7 6 5) set(GCC4_SERIES 4.9.1 4.9 4.8.3 4.8.1 4.7.2 4.7 4.8.2 4.8 4.7 4.6 4.5 4.4.4 4.4) set(GCC_SERIES ${GCC_MAJOR_SERIES} ${GCC4_SERIES}) find_library(GFORTRAN NAMES gfortran PATHS ${GFORTRAN_ROOT_USER_DEFINED} - /usr/lib64 /usr/lib/gcc/x86_64-linux-gnu # Debian /usr/lib/gcc/i386-linux-gnu /usr/lib/gcc/i486-linux-gnu @@ -55,6 +58,7 @@ find_library(GFORTRAN NAMES gfortran /usr/lib/gcc/sh4-linux-gnu /usr/lib/gcc/i686-redhat-linux # Fedora /usr/lib64/gcc/x86_64-redhat-linux + /usr/lib/gcc/x86_64-redhat-linux /usr/lib/gcc/armv7hl-redhat-linux-gnueabi /usr/lib/gcc/aarch64-redhat-linux /usr/lib/gcc/ppc64le-redhat-linux @@ -64,34 +68,13 @@ find_library(GFORTRAN NAMES gfortran /usr/lib/gcc/x86_64-suse-linux /usr/lib/gcc/armv6hl-suse-linux-gnueabi /usr/lib/gcc/armv7hl-suse-linux-gnueabi + /usr/lib/gcc/loongarch64-linux-gnu /usr/lib64/gcc/aarch64-suse-linux /usr/lib64/gcc/powerpc64-suse-linux /usr/lib64/gcc/powerpc64le-suse-linux /usr/lib64/gcc/riscv64-suse-linux /usr/lib64/gcc/s390x-suse-linux - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/aarch64-linux-gnu - /usr/lib/i386-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /usr/local/lib/i386 + ${GNSSSDR_LIB_PATHS} PATH_SUFFIXES ${GCC_SERIES} ) diff --git a/cmake/Modules/FindGLOG.cmake b/cmake/Modules/FindGLOG.cmake index eb0f9d700..ef7878a10 100644 --- a/cmake/Modules/FindGLOG.cmake +++ b/cmake/Modules/FindGLOG.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # - Try to find the Google Glog library @@ -28,6 +28,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(NOT DEFINED GLOG_ROOT) set(GLOG_ROOT /usr /usr/local) endif() @@ -45,36 +49,7 @@ macro(_FIND_GLOG_LIBRARIES _var) NAMES ${ARGN} HINTS ${PC_GLOG_LIBDIR} PATHS ${LIB_PATHS} - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/loongarch64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ${GLOG_ROOT}/lib $ENV{GLOG_ROOT}/lib ${GLOG_ROOT}/lib64 @@ -99,7 +74,7 @@ if(MSVC) ${PC_GLOG_INCLUDEDIR} PATHS ${GLOG_ROOT}/src/windows - ${GLOG_ROOT}/src/windows/glog + PATH_SUFFIXES glog ) else() # Linux/OS X builds @@ -107,11 +82,10 @@ else() HINTS ${PC_GLOG_INCLUDEDIR} PATHS - /usr/include/glog - /usr/local/include/glog - /opt/local/include/glog # default location in Macports - /opt/homebrew/opt/glog/include/glog - ${GLOG_ROOT}/include/glog + ${GNSSSDR_INCLUDE_PATHS} + ${GNSSSDR_INCLUDE_PATHS}/opt/glog/include + ${GLOG_ROOT}/include + PATH_SUFFIXES glog ) endif() @@ -183,4 +157,4 @@ endif() # Fix for glog 0.7.0 if(EXISTS ${GLOG_INCLUDE_DIRS}/export.h) set_target_properties(Glog::glog PROPERTIES INTERFACE_COMPILE_DEFINITIONS "GLOG_USE_GLOG_EXPORT") -endif() +endif() \ No newline at end of file diff --git a/cmake/Modules/FindGMP.cmake b/cmake/Modules/FindGMP.cmake new file mode 100644 index 000000000..840324f44 --- /dev/null +++ b/cmake/Modules/FindGMP.cmake @@ -0,0 +1,72 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2024-2025 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT COMMAND feature_summary) + include(FeatureSummary) +endif() + +if(NOT PKG_CONFIG_FOUND) + include(FindPkgConfig) +endif() +pkg_check_modules(PC_GMP "gmp") + +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + +set(GMP_DEFINITIONS ${PC_GMP_CFLAGS_OTHER}) + +find_path(GMP_INCLUDE_DIR + NAMES gmpxx.h + HINTS ${PC_GMP_INCLUDEDIR} + PATHS ${GNSSSDR_INCLUDE_PATHS} +) + +set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) +set(GMP_PC_ADD_CFLAGS "-I${GMP_INCLUDE_DIR}") + +find_library(GMPXX_LIBRARY + NAMES gmpxx + HINTS ${PC_GMP_LIBDIR} + PATHS ${GNSSSDR_LIB_PATHS} +) + +find_library(GMP_LIBRARY + NAMES gmp + HINTS ${PC_GMP_LIBDIR} + PATHS ${GNSSSDR_LIB_PATHS} +) + +set(GMP_LIBRARIES ${GMPXX_LIBRARY} ${GMP_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GMP DEFAULT_MSG GMPXX_LIBRARY GMP_LIBRARY GMP_INCLUDE_DIR) + +if(GMP_FOUND AND NOT TARGET Gmp::gmp) + add_library(Gmp::gmp SHARED IMPORTED) + set_target_properties(Gmp::gmp PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GMPXX_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GMP_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${GMP_LIBRARIES}" + ) +endif() + +set_package_properties(GMP PROPERTIES + URL "https://gmplib.org/" +) + +if(PC_GMP_VERSION) + set_package_properties(GMP PROPERTIES + DESCRIPTION "The GNU Multiple Precision Arithmetic Library (found: v.${PC_GMP_VERSION})" + ) +else() + set_package_properties(GMP PROPERTIES + DESCRIPTION "The GNU Multiple Precision Arithmetic Library" + ) +endif() + +mark_as_advanced(GMPXX_LIBRARY GMP_LIBRARY GMP_INCLUDE_DIR) diff --git a/cmake/Modules/FindGNSSSIMULATOR.cmake b/cmake/Modules/FindGNSSSIMULATOR.cmake index 6a193746d..abeee05ce 100644 --- a/cmake/Modules/FindGNSSSIMULATOR.cmake +++ b/cmake/Modules/FindGNSSSIMULATOR.cmake @@ -1,9 +1,13 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2021 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(GNSSSIMULATOR_ROOT) set(GNSSSIMULATOR_ROOT_USER_DEFINED ${GNSSSIMULATOR_ROOT}) else() @@ -25,7 +29,8 @@ find_program(SW_GENERATOR_BIN gnss_sim ${GNSSSIMULATOR_ROOT_USER_DEFINED} /usr /usr/local - /opt/local + ${CMAKE_SYSTEM_PREFIX_PATH} + ${CMAKE_INSTALL_FULL_BINDIR} PATH_SUFFIXES bin ONLY_CMAKE_FIND_ROOT_PATH ) diff --git a/cmake/Modules/FindGNSSTK.cmake b/cmake/Modules/FindGNSSTK.cmake index e810ebee7..d49a1bc53 100644 --- a/cmake/Modules/FindGNSSTK.cmake +++ b/cmake/Modules/FindGNSSTK.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2022 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2022-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # - Find gnsstk library @@ -19,6 +19,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(NOT GNSSTK_ROOT) set(GNSSTK_ROOT_USER_DEFINED /usr/local) else() @@ -35,17 +39,13 @@ unset(GNSSTK_INCLUDE_DIR CACHE) unset(GNSSTK_USES_GPSTK_NAMESPACE CACHE) find_path(GNSSTK_INCLUDE_DIR gnsstk/Rinex3ObsBase.hpp PATHS ${GNSSTK_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) set(GNSSTK_NAMES ${CMAKE_FIND_LIBRARY_PREFIXES}gnsstk${CMAKE_SHARED_LIBRARY_SUFFIX}) if(NOT GNSSTK_INCLUDE_DIR) find_path(GNSSTK_INCLUDE_DIR gpstk/Rinex3ObsBase.hpp PATHS ${GNSSTK_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) if(GNSSTK_INCLUDE_DIR) set(GNSSTK_NAMES gpstk ${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_SHARED_LIBRARY_SUFFIX}) @@ -56,12 +56,8 @@ endif() include(GNUInstallDirs) find_library(GNSSTK_LIBRARY NAMES ${GNSSTK_NAMES} - PATHS ${GNSSTK_ROOT_USER_DEFINED}/lib - ${GNSSTK_ROOT_USER_DEFINED}/${CMAKE_INSTALL_LIBDIR} - /usr/local/lib - /usr/${CMAKE_INSTALL_LIBDIR} - /usr/local/${CMAKE_INSTALL_LIBDIR} - /opt/local/lib + PATHS ${GNSSTK_ROOT_USER_DEFINED}/${CMAKE_INSTALL_LIBDIR} + ${GNSSSDR_LIB_PATHS} ) if(GNSSTK_LIBRARY AND GNSSTK_INCLUDE_DIR) diff --git a/cmake/Modules/FindGNUPLOT.cmake b/cmake/Modules/FindGNUPLOT.cmake index c464bc6b6..dbbcd04f7 100644 --- a/cmake/Modules/FindGNUPLOT.cmake +++ b/cmake/Modules/FindGNUPLOT.cmake @@ -1,18 +1,19 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2021-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() find_program(GNUPLOT_EXECUTABLE NAMES gnuplot pgnuplot PATHS - /usr/bin - /usr/local/bin - /opt/local/bin + ${GNSSSDR_BIN_PATHS} ONLY_CMAKE_FIND_ROOT_PATH ) diff --git a/cmake/Modules/FindGNURADIO.cmake b/cmake/Modules/FindGNURADIO.cmake index 5ce37cba6..01553d725 100644 --- a/cmake/Modules/FindGNURADIO.cmake +++ b/cmake/Modules/FindGNURADIO.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2022 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause ######################################################################## @@ -16,6 +16,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + include(FindPackageHandleStandardArgs) # if GR_REQUIRED_COMPONENTS is not defined, it will be set to the following list @@ -93,9 +97,7 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) NAMES ${INCFILE} HINTS ${PC_INCDIR} PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) # look for libs @@ -103,37 +105,8 @@ function(GR_MODULE EXTVAR PCNAME INCFILE LIBFILE) find_library(${LIBVAR_NAME}_${libname} NAMES ${libname} ${libname}-${PC_GNURADIO_RUNTIME_VERSION} HINTS ${PC_LIBDIR} - PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib - ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/${CMAKE_INSTALL_LIBDIR} + ${GNSSSDR_LIB_PATHS} ) list(APPEND ${LIBVAR_NAME} ${${LIBVAR_NAME}_${libname}}) endforeach() @@ -221,9 +194,7 @@ if(NOT PC_GNURADIO_RUNTIME_VERSION) find_file(GNURADIO_VERSION_GREATER_THAN_373 NAMES gnuradio/blocks/tsb_vector_sink_f.h PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) if(GNURADIO_VERSION_GREATER_THAN_373) set(PC_GNURADIO_RUNTIME_VERSION "3.7.4+") @@ -232,9 +203,7 @@ if(NOT PC_GNURADIO_RUNTIME_VERSION) find_file(GNURADIO_VERSION_GREATER_THAN_38 NAMES gnuradio/filter/mmse_resampler_cc.h PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) if(GNURADIO_VERSION_GREATER_THAN_38) set(PC_GNURADIO_RUNTIME_VERSION "3.8.0+") @@ -302,9 +271,7 @@ if(GNURADIO_VERSION VERSION_GREATER 3.8.99) NAMES gnuradio/iio/api.h HINTS ${PC_GNURADIO_IIO_INCLUDEDIR} PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) # look for libs @@ -313,35 +280,7 @@ if(GNURADIO_VERSION VERSION_GREATER 3.8.99) HINTS ${PC_GNURADIO_IIO_LIBDIR} PATHS ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib ${GNURADIO_INSTALL_PREFIX_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) if(GNURADIO_IIO_LIBRARIES) @@ -418,8 +357,10 @@ if(GNURADIO_RUNTIME_INCLUDE_DIRS) ) if(CMAKE_VERSION VERSION_GREATER 3.13) target_link_libraries(Gnuradio::filter INTERFACE Log4cpp::log4cpp) + target_link_libraries(Gnuradio::runtime INTERFACE Log4cpp::log4cpp) else() set_target_properties(Gnuradio::filter PROPERTIES INTERFACE_LINK_LIBRARIES Log4cpp::log4cpp) + set_target_properties(Gnuradio::runtime PROPERTIES INTERFACE_LINK_LIBRARIES Log4cpp::log4cpp) endif() endif() if(${_uses_spdlog}) diff --git a/cmake/Modules/FindGOOGLETEST.cmake b/cmake/Modules/FindGOOGLETEST.cmake index cf47a7062..268d8580a 100644 --- a/cmake/Modules/FindGOOGLETEST.cmake +++ b/cmake/Modules/FindGOOGLETEST.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause @@ -23,6 +23,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_GTEST gtest) if(NOT GTEST_DIR) @@ -44,10 +48,11 @@ find_path(LIBGTEST_DEV_DIR ${GTEST_DIR_USER_PROVIDED}/googletest /usr/src/googletest/googletest /usr/src/gtest - /usr/include/gtest - /usr/local/src/googletest/googletest - /opt/local/src/gtest-1.7.0 - /opt/homebrew/opt/googletest/include/googletest/googletest + ${GNSSSDR_INCLUDE_PATHS}/gtest + ${GNSSSDR_INCLUDE_PATHS}/googletest + ${CMAKE_SYSTEM_PREFIX_PATH}/src/googletest/googletest + ${CMAKE_SYSTEM_PREFIX_PATH}/src/gtest-1.7.0 + ${CMAKE_SYSTEM_PREFIX_PATH}/opt/googletest/include/googletest/googletest ) find_path(GTEST_INCLUDE_DIRS @@ -55,10 +60,9 @@ find_path(GTEST_INCLUDE_DIRS HINTS ${PC_GTEST_INCLUDEDIR} PATHS ${GTEST_DIR_USER_PROVIDED}/googletest/include - /usr/include - /usr/local/include - /opt/local/src/gtest-1.7.0/include - /opt/homebrew/opt/googletest/include + ${GNSSSDR_INCLUDE_PATHS} + ${CMAKE_SYSTEM_PREFIX_PATH}/src/gtest-1.7.0/include + ${CMAKE_SYSTEM_PREFIX_PATH}/opt/googletest/include ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindGPERFTOOLS.cmake b/cmake/Modules/FindGPERFTOOLS.cmake index 4d6dd135b..63516e9a2 100644 --- a/cmake/Modules/FindGPERFTOOLS.cmake +++ b/cmake/Modules/FindGPERFTOOLS.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # Tries to find Gperftools. @@ -33,6 +33,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(NOT GPERFTOOLS_ROOT) set(GPERFTOOLS_ROOT_USER_DEFINED /usr/local) else() @@ -56,41 +60,27 @@ find_library(GPERFTOOLS_TCMALLOC NAMES tcmalloc PATHS ${GPERFTOOLS_ROOT_USER_DEFINED}/lib ${GPERFTOOLS_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) find_library(GPERFTOOLS_PROFILER NAMES profiler PATHS ${GPERFTOOLS_ROOT_USER_DEFINED}/lib ${GPERFTOOLS_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) find_library(GPERFTOOLS_TCMALLOC_AND_PROFILER NAMES tcmalloc_and_profiler PATHS ${GPERFTOOLS_ROOT_USER_DEFINED}/lib ${GPERFTOOLS_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h - PATHS /usr/include - /usr/local/include - /opt/local/include - ${GPERFTOOLS_ROOT_USER_DEFINED}/include + PATHS ${GPERFTOOLS_ROOT_USER_DEFINED}/include + ${GNSSSDR_INCLUDE_PATHS} ) set(GPERFTOOLS_LIBRARIES ${GPERFTOOLS_TCMALLOC_AND_PROFILER}) diff --git a/cmake/Modules/FindGRDBFCTTC.cmake b/cmake/Modules/FindGRDBFCTTC.cmake index 72bbe8d90..09a4bbd2b 100644 --- a/cmake/Modules/FindGRDBFCTTC.cmake +++ b/cmake/Modules/FindGRDBFCTTC.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause ######################################################################## @@ -17,6 +17,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_GR_DBFCTTC gr-dbfcttc) if(NOT GRDBFCTTC_ROOT) @@ -46,9 +50,7 @@ find_path( NAMES dbfcttc/api.h HINTS ${PC_GR_DBFCTTC_INCLUDEDIR} PATHS ${GRDBFCTTC_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library( @@ -57,11 +59,7 @@ find_library( HINTS ${PC_GR_DBFCTTC_LIBDIR} PATHS ${GRDBFCTTC_ROOT_USER_DEFINED}/lib ${GRDBFCTTC_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindGRIIO.cmake b/cmake/Modules/FindGRIIO.cmake index e08290252..600401c42 100644 --- a/cmake/Modules/FindGRIIO.cmake +++ b/cmake/Modules/FindGRIIO.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -17,6 +17,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_IIO gnuradio-iio) if(NOT GRIIO_ROOT) @@ -24,31 +28,31 @@ if(NOT GRIIO_ROOT) else() set(GRIIO_ROOT_USER_DEFINED ${GRIIO_ROOT}) endif() + if(DEFINED ENV{GRIIO_ROOT}) set(GRIIO_ROOT_USER_DEFINED ${GRIIO_ROOT_USER_DEFINED} $ENV{GRIIO_ROOT} ) endif() + if(DEFINED ENV{IIO_DIR}) set(GRIIO_ROOT_USER_DEFINED ${GRIIO_ROOT_USER_DEFINED} $ENV{IIO_DIR} ) endif() + set(GRIIO_ROOT_USER_DEFINED ${GRIIO_ROOT_USER_DEFINED} ${CMAKE_INSTALL_PREFIX} ) - find_path(IIO_INCLUDE_DIRS NAMES gnuradio/iio/api.h HINTS ${PC_IIO_INCLUDEDIR} PATHS ${GRIIO_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) if(IIO_INCLUDE_DIRS) @@ -58,9 +62,7 @@ else() NAMES iio/api.h HINTS ${PC_IIO_INCLUDEDIR} PATHS ${GRIIO_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) set(GR_IIO_INCLUDE_HAS_GNURADIO FALSE) endif() @@ -70,35 +72,7 @@ find_library(IIO_LIBRARIES HINTS ${PC_IIO_LIBDIR} PATHS ${GRIIO_ROOT_USER_DEFINED}/lib ${GRIIO_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindGRLIMESDR.cmake b/cmake/Modules/FindGRLIMESDR.cmake index cfd546feb..ff4615a14 100644 --- a/cmake/Modules/FindGRLIMESDR.cmake +++ b/cmake/Modules/FindGRLIMESDR.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # Tries to find gr-limesdr. @@ -35,6 +35,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(GRLIMESDR_PKG QUIET gnuradio-limesdr) if(NOT GRLIMESDR_ROOT) @@ -57,9 +61,7 @@ find_path(GRLIMESDR_INCLUDE_DIR ${GRLIMESDR_PKG_INCLUDEDIR} PATHS ${GRLIMESDR_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(GRLIMESDR_LIBRARIES @@ -70,35 +72,7 @@ find_library(GRLIMESDR_LIBRARIES PATHS ${GRLIMESDR_ROOT_USER_DEFINED}/lib ${GRLIMESDR_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/riscv64-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindGROSMOSDR.cmake b/cmake/Modules/FindGROSMOSDR.cmake index cfaef1494..5184fb548 100644 --- a/cmake/Modules/FindGROSMOSDR.cmake +++ b/cmake/Modules/FindGROSMOSDR.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # Tries to find gr-osmosdr. @@ -35,6 +35,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(GROSMOSDR_PKG gnuradio-osmosdr) if(NOT GROSMOSDR_ROOT) @@ -57,9 +61,7 @@ find_path(GROSMOSDR_INCLUDE_DIR ${GROSMOSDR_PKG_INCLUDEDIR} PATHS ${GROSMOSDR_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(GROSMOSDR_LIBRARIES @@ -70,35 +72,7 @@ find_library(GROSMOSDR_LIBRARIES PATHS ${GROSMOSDR_ROOT_USER_DEFINED}/lib ${GROSMOSDR_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/riscv64-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindLIBAD9361.cmake b/cmake/Modules/FindLIBAD9361.cmake index 80df49673..55fcd6e58 100644 --- a/cmake/Modules/FindLIBAD9361.cmake +++ b/cmake/Modules/FindLIBAD9361.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -17,6 +17,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_LIBAD9361 libad9361) if(NOT LIBAD9361_ROOT) @@ -39,9 +43,7 @@ find_path(LIBAD9361_INCLUDE_DIRS NAMES ad9361.h HINTS ${PC_LIBAD9361_INCLUDEDIR} PATHS ${LIBAD9361_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(LIBAD9361_LIBRARIES @@ -49,35 +51,7 @@ find_library(LIBAD9361_LIBRARIES HINTS ${PC_LIBAD9361_LIBDIR} PATHS ${LIBAD9361_ROOT_USER_DEFINED}/lib ${LIBAD9361_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} /Library/Frameworks/ad9361.framework ) diff --git a/cmake/Modules/FindLIBIIO.cmake b/cmake/Modules/FindLIBIIO.cmake index 31f152b6f..83aab4b81 100644 --- a/cmake/Modules/FindLIBIIO.cmake +++ b/cmake/Modules/FindLIBIIO.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -17,6 +17,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_LIBIIO libiio) if(NOT LIBIIO_ROOT) @@ -40,9 +44,7 @@ find_path( NAMES iio.h HINTS ${PC_LIBIIO_INCLUDEDIR} PATHS ${LIBIIO_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library( @@ -51,35 +53,7 @@ find_library( HINTS ${PC_LIBIIO_LIBDIR} PATHS ${LIBIIO_ROOT_USER_DEFINED}/lib ${LIBIIO_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i686-gnu - /usr/lib/i686-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i686-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/sh4-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} /Library/Frameworks/iio.framework/ ) diff --git a/cmake/Modules/FindLIBUNWIND.cmake b/cmake/Modules/FindLIBUNWIND.cmake index f2c88b569..8d6adbada 100644 --- a/cmake/Modules/FindLIBUNWIND.cmake +++ b/cmake/Modules/FindLIBUNWIND.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2022 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2022-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # Find the libunwind library @@ -17,30 +17,27 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + find_path(LIBUNWIND_INCLUDE_DIR NAMES libunwind.h unwind.h - HINTS - /usr - /usr/local - /opt/local PATH_SUFFIXES include PATHS "${LIBUNWIND_ROOT}/include" + ${GNSSSDR_INCLUDE_PATHS} ) find_library(LIBUNWIND_GENERIC_LIBRARY NAMES libunwind unwind - HINTS - /usr - /usr/local - /opt/local - PATH_SUFFIXES lib lib64 PATHS "${LIBUNWIND_ROOT}/lib" "${LIBUNWIND_ROOT}/lib64" + ${GNSSSDR_LIB_PATHS} ) if(LIBUNWIND_INCLUDE_DIR) @@ -70,12 +67,8 @@ if(LIBUNWIND_INCLUDE_DIR) NAMES libunwind-${LIBUNWIND_ARCH} "unwind-${LIBUNWIND_ARCH}" - HINTS - /usr - /usr/local - /opt/local - PATH_SUFFIXES lib lib64 PATHS "${LIBUNWIND_ROOT}" + ${GNSSSDR_LIB_PATHS} ) if(NOT LIBUNWIND_SPECIFIC_LIBRARY) message(STATUS " -- Failed to find unwind-${LIBUNWIND_ARCH}") diff --git a/cmake/Modules/FindLOG4CPP.cmake b/cmake/Modules/FindLOG4CPP.cmake index 73876d1da..d6d5eb9b4 100644 --- a/cmake/Modules/FindLOG4CPP.cmake +++ b/cmake/Modules/FindLOG4CPP.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # - Find Log4cpp @@ -23,6 +23,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_LOG4CPP log4cpp QUIET) if(LOG4CPP_INCLUDE_DIR) @@ -48,9 +52,7 @@ set(LOG4CPP_ROOT_USER_PROVIDED find_path(LOG4CPP_INCLUDE_DIR log4cpp/Category.hh ${LOG4CPP_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ${PC_LOG4CPP_INCLUDEDIR} ) @@ -73,36 +75,8 @@ find_library(LOG4CPP_LIBRARY NAMES ${LOG4CPP_NAMES} HINTS ${PC_LOG4CPP_LIBDIR} PATHS ${LOG4CPP_ROOT_USER_PROVIDED}/lib - ${LOG4CPP_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${LOG4CPP_ROOT_USER_PROVIDED}/lib64 + ${GNSSSDR_LIB_PATHS} ) if(LOG4CPP_INCLUDE_DIR AND LOG4CPP_LIBRARY) @@ -121,7 +95,7 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LOG4CPP DEFAULT_MSG LOG4CPP_INCLUDE_DIRS LOG4CPP_LIBRARIES) set_package_properties(LOG4CPP PROPERTIES - URL "http://log4cpp.sourceforge.net/" + URL "https://log4cpp.sourceforge.net/" ) if(LOG4CPP_FOUND AND PC_LOG4CPP_VERSION) diff --git a/cmake/Modules/FindMATIO.cmake b/cmake/Modules/FindMATIO.cmake index 49e0bf8cd..da256e21f 100644 --- a/cmake/Modules/FindMATIO.cmake +++ b/cmake/Modules/FindMATIO.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # FindMATIO @@ -55,6 +55,10 @@ if(NOT COMMAND feature_summary) include(FeatureSummary) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + if(NOT MATIO_ROOT) set(MATIO_ROOT_USER_DEFINED /usr) else() @@ -72,9 +76,7 @@ find_path(MATIO_INCLUDE_DIR NAMES matio.h PATHS ${MATIO_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include DOC "The MATIO include directory" ) @@ -85,32 +87,7 @@ find_library(MATIO_LIBRARY PATHS ${MATIO_ROOT_USER_DEFINED}/lib ${MATIO_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/alpha-linux-gnu - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib DOC "The MATIO library" ) diff --git a/cmake/Modules/FindORC.cmake b/cmake/Modules/FindORC.cmake index 97cd0e4a8..e16632c2b 100644 --- a/cmake/Modules/FindORC.cmake +++ b/cmake/Modules/FindORC.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause if(DEFINED __INCLUDED_GNSSSDR_CMAKE_FIND_ORC) @@ -17,6 +17,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_ORC "orc-0.4 > 0.4.22") if(NOT ORC_ROOT) @@ -43,18 +47,14 @@ endif() find_program(ORCC_EXECUTABLE orcc HINTS ${ORC_ROOT_USER_PROVIDED}/bin - PATHS /usr/bin - /usr/local/bin - /opt/local/bin + PATHS ${CMAKE_SYSTEM_PREFIX_PATH}/bin ) find_path(ORC_INCLUDE_DIR NAMES orc/orc.h HINTS ${PC_ORC_INCLUDEDIR} PATHS ${ORC_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} PATH_SUFFIXES orc-0.4 ) @@ -63,80 +63,23 @@ find_path(ORC_LIBRARY_DIR HINTS ${PC_ORC_LIBDIR} PATHS ${ORC_ROOT_USER_PROVIDED}/lib ${ORC_ROOT_USER_PROVIDED}/lib64 - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) find_library(ORC_LIB orc-0.4 HINTS ${PC_ORC_LIBRARY_DIRS} PATHS ${ORC_ROOT_USER_PROVIDED}/lib ${ORC_ROOT_USER_PROVIDED}/lib64 - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) find_library(ORC_LIBRARY_STATIC ${CMAKE_STATIC_LIBRARY_PREFIX}orc-0.4${CMAKE_STATIC_LIBRARY_SUFFIX} HINTS ${PC_ORC_LIBRARY_DIRS} PATHS ${ORC_ROOT}/lib ${ORC_ROOT}/lib64 - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 ${ORC_ROOT_USER_PROVIDED}/lib ${ORC_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) if(PC_ORC_VERSION) diff --git a/cmake/Modules/FindPCAP.cmake b/cmake/Modules/FindPCAP.cmake index b72b5f5d1..aba931218 100644 --- a/cmake/Modules/FindPCAP.cmake +++ b/cmake/Modules/FindPCAP.cmake @@ -6,7 +6,7 @@ # - Find pcap # Find the PCAP includes and library -# http://www.tcpdump.org/ +# https://www.tcpdump.org/ # # The environment variable PCAPDIR allows to specify where to find # libpcap in non standard location. @@ -27,6 +27,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_PCAP libpcap QUIET) if(NOT PCAP_ROOT) @@ -77,9 +81,7 @@ else() ${PC_PCAP_INCLUDEDIR} PATHS ${PCAP_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(PCAP_LIBRARY NAMES @@ -88,32 +90,7 @@ else() ${PC_PCAP_LIBDIR} PATHS ${PCAP_ROOT_USER_PROVIDED}/lib - /usr/lib - /usr/lib64 - /usr/lib/alpha-linux-gnu - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) endif() diff --git a/cmake/Modules/FindPUGIXML.cmake b/cmake/Modules/FindPUGIXML.cmake index c5c1ea637..6c6b34a63 100644 --- a/cmake/Modules/FindPUGIXML.cmake +++ b/cmake/Modules/FindPUGIXML.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # Find the pugixml XML parsing library. @@ -24,6 +24,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_PUGIXML pugixml QUIET) if(NOT PUGIXML_ROOT) @@ -50,11 +54,9 @@ find_path(PUGIXML_INCLUDE_DIR PATHS ${PUGIXML_ROOT_USER_DEFINED}/include ${PUGIXML_ROOT_USER_DEFINED}/include/pugixml-${PC_PUGIXML_VERSION} ${PUGIXML_ROOT_USER_DEFINED}/include/pugixml-1.9 - /usr/include - /usr/local/include - /usr/local/include/pugixml-${PC_PUGIXML_VERSION} - /usr/local/include/pugixml-1.9 - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} + ${GNSSSDR_INCLUDE_PATHS}/pugixml-${PC_PUGIXML_VERSION} + ${GNSSSDR_INCLUDE_PATHS}/pugixml-1.9 ) find_library(PUGIXML_LIBRARY @@ -66,35 +68,9 @@ find_library(PUGIXML_LIBRARY ${PUGIXML_ROOT_USER_DEFINED}/lib64/pugixml-${PC_PUGIXML_VERSION} ${PUGIXML_ROOT_USER_DEFINED}}/lib/pugixml-1.9 ${PUGIXML_ROOT_USER_DEFINED}/lib64/pugixml-1.9 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/i386-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/alpha-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/riscv64-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/local/lib - /usr/local/lib64 - /usr/local/lib/pugixml-${PC_PUGIXML_VERSION} - /usr/local/lib/pugixml-1.9 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} + ${GNSSSDR_LIB_PATHS}/pugixml-${PC_PUGIXML_VERSION} + ${GNSSSDR_LIB_PATHS}/pugixml-1.9 ) # Support the REQUIRED and QUIET arguments, and set PUGIXML_FOUND if found. diff --git a/cmake/Modules/FindTELEORBIT.cmake b/cmake/Modules/FindTELEORBIT.cmake index b0d5e6c20..fa315cd32 100644 --- a/cmake/Modules/FindTELEORBIT.cmake +++ b/cmake/Modules/FindTELEORBIT.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -17,6 +17,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_TELEORBIT teleorbit QUIET) if(NOT TELEORBIT_ROOT) @@ -38,10 +42,9 @@ set(TELEORBIT_ROOT_USER_DEFINED find_path(TELEORBIT_INCLUDE_DIRS NAMES teleorbit/api.h HINTS ${PC_TELEORBIT_INCLUDEDIR} + PATH_SUFFIXES gnuradio PATHS ${TELEORBIT_ROOT_USER_DEFINED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(TELEORBIT_LIBRARIES @@ -49,11 +52,7 @@ find_library(TELEORBIT_LIBRARIES HINTS ${PC_TELEORBIT_LIBDIR} PATHS ${TELEORBIT_ROOT_USER_DEFINED}/lib ${TELEORBIT_ROOT_USER_DEFINED}/lib64 - /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindUHD.cmake b/cmake/Modules/FindUHD.cmake index 772cf436a..356af6593 100644 --- a/cmake/Modules/FindUHD.cmake +++ b/cmake/Modules/FindUHD.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -20,6 +20,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_UHD uhd) if(NOT UHD_ROOT) @@ -50,9 +54,7 @@ find_path(UHD_INCLUDE_DIRS NAMES uhd/config.hpp HINTS ${PC_UHD_INCLUDEDIR} PATHS ${UHD_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(UHD_LIBRARIES @@ -60,35 +62,7 @@ find_library(UHD_LIBRARIES HINTS ${PC_UHD_LIBDIR} PATHS ${UHD_ROOT_USER_PROVIDED}/lib ${UHD_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindVOLK.cmake b/cmake/Modules/FindVOLK.cmake index f67efdfbb..70286fbf0 100644 --- a/cmake/Modules/FindVOLK.cmake +++ b/cmake/Modules/FindVOLK.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -20,6 +20,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_VOLK volk QUIET) if(NOT VOLK_ROOT) @@ -48,9 +52,7 @@ find_path(VOLK_INCLUDE_DIRS NAMES volk/volk.h HINTS ${PC_VOLK_INCLUDEDIR} PATHS ${VOLK_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(VOLK_LIBRARIES @@ -58,34 +60,7 @@ find_library(VOLK_LIBRARIES HINTS ${PC_VOLK_LIBDIR} PATHS ${VOLK_ROOT_USER_PROVIDED}/lib ${VOLK_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindVOLKGNSSSDR.cmake b/cmake/Modules/FindVOLKGNSSSDR.cmake index 64ab621d3..9de60ce30 100644 --- a/cmake/Modules/FindVOLKGNSSSDR.cmake +++ b/cmake/Modules/FindVOLKGNSSSDR.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,10 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + pkg_check_modules(PC_VOLK_GNSSSDR QUIET volk_gnsssdr) if(NOT VOLKGNSSSDR_ROOT) @@ -51,9 +55,7 @@ find_path(VOLK_GNSSSDR_INCLUDE_DIRS NAMES volk_gnsssdr/volk_gnsssdr.h HINTS ${PC_VOLK_GNSSSDR_INCLUDEDIR} PATHS ${VOLKGNSSSDR_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${GNSSSDR_INCLUDE_PATHS} ) find_library(VOLK_GNSSSDR_LIBRARIES @@ -61,11 +63,7 @@ find_library(VOLK_GNSSSDR_LIBRARIES HINTS ${PC_VOLK_GNSSSDR_LIBDIR} PATHS ${VOLKGNSSSDR_ROOT_USER_PROVIDED}/lib ${VOLKGNSSSDR_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/FindZEROMQ.cmake b/cmake/Modules/FindZEROMQ.cmake index 0ef937139..9d2254cd6 100644 --- a/cmake/Modules/FindZEROMQ.cmake +++ b/cmake/Modules/FindZEROMQ.cmake @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2023 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2024-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause # @@ -17,44 +17,23 @@ if(NOT PKG_CONFIG_FOUND) include(FindPkgConfig) endif() +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + find_package(PkgConfig) pkg_check_modules(PC_ZEROMQ "libzmq") find_path(ZEROMQ_INCLUDE_DIRS NAMES zmq.hpp - HINTS ${PC_ZEROMQ_INCLUDE_DIR} ${CMAKE_INSTALL_PREFIX}/include - PATHS /usr/local/include /usr/include /opt/local/include + HINTS ${PC_ZEROMQ_INCLUDE_DIR} + PATHS ${GNSSSDR_INCLUDE_PATHS} ) find_library(ZEROMQ_LIBRARIES NAMES zmq libzmq.so.5 ${ZEROMQ_LIBRARY_NAME} - HINTS ${PC_ZEROMQ_LIBDIR} ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib64 - PATHS /usr/lib - /usr/lib64 - /usr/lib/alpha-linux-gnu - /usr/lib/x86_64-linux-gnu - /usr/lib/aarch64-linux-gnu - /usr/lib/arm-linux-gnueabi - /usr/lib/arm-linux-gnueabihf - /usr/lib/hppa-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/mipsel-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + HINTS ${PC_ZEROMQ_LIBDIR} + PATHS ${GNSSSDR_LIB_PATHS} ) include(FindPackageHandleStandardArgs) diff --git a/cmake/Modules/GnsssdrCrypto.cmake b/cmake/Modules/GnsssdrCrypto.cmake new file mode 100644 index 000000000..db530a709 --- /dev/null +++ b/cmake/Modules/GnsssdrCrypto.cmake @@ -0,0 +1,188 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2024-2025 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT COMMAND feature_summary) + include(FeatureSummary) +endif() + +if(NOT GNSSSDR_LIB_PATHS) + include(GnsssdrFindPaths) +endif() + +################################################################################ +# OpenSSL https://www.openssl.org/ +################################################################################ +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) # Trick for Homebrew +endif() +unset(OPENSSL_FOUND CACHE) +unset(GnuTLS_FOUND CACHE) +unset(GMP_FOUND CACHE) +if(NOT ENABLE_GNUTLS) + find_package(OpenSSL) +endif() +set_package_properties(OpenSSL + PROPERTIES + URL "https://www.openssl.org" + PURPOSE "Used for the OSNMA and SUPL protocol implementations." + TYPE REQUIRED +) +if(OPENSSL_FOUND) + set_package_properties(OpenSSL + PROPERTIES + DESCRIPTION "Cryptography and SSL/TLS Toolkit (found: v${OPENSSL_VERSION})" + ) +else() + set_package_properties(OpenSSL + PROPERTIES + DESCRIPTION "OpenSSL has not been found, but GnuTLS with openssl compatibility can replace it" + ) + ################################################################################ + # GnuTLS - https://www.gnutls.org/ + ################################################################################ + find_package(GnuTLS) + set_package_properties(GnuTLS PROPERTIES + URL "https://www.gnutls.org/" + PURPOSE "Used for the OSNMA and SUPL protocol implementations." + TYPE REQUIRED + ) + if(GnuTLS_FOUND AND GNUTLS_VERSION_STRING) + set_package_properties(GnuTLS PROPERTIES + DESCRIPTION "Transport Layer Security Library (found: v${GNUTLS_VERSION_STRING})" + ) + else() + set_package_properties(GnuTLS PROPERTIES + DESCRIPTION "Transport Layer Security Library" + ) + endif() + find_library(GNUTLS_OPENSSL_LIBRARY + NAMES gnutls-openssl libgnutls-openssl.so.27 + PATHS ${GNSSSDR_LIB_PATHS} + ) + + find_path(GNUTLS_INCLUDE_DIR NAMES gnutls/gnutls.h + PATHS + ${GNSSSDR_INCLUDE_PATHS} + ${GNUTLS_ROOT_DIR}/include/ + ) + + if(NOT GNUTLS_OPENSSL_LIBRARY) + message(" The GnuTLS library with openssl compatibility enabled has not been found.") + message(" You can try to install the required libraries by typing:") + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(" sudo yum install openssl-devel") + else() + message(" sudo apt install libgnutls28-dev") + endif() + endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + message(" 'sudo port install openssl3', if you are using Macports, or") + message(" 'brew install openssl', if you are using Homebrew.") + endif() + message(FATAL_ERROR "OpenSSL or the GnuTLS libraries with openssl compatibility are required to build gnss-sdr") + endif() + + # Test GnuTLS capabilities + file(READ "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" gnutls_gnutls_file_contents) + if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA256") + set(GNUTLS_SIGN_ECDSA_SHA256 TRUE) + endif() + if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA512") + set(GNUTLS_SIGN_ECDSA_SHA512 TRUE) + endif() + if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_DIG_SHA3_256") + set(GNUTLS_DIG_SHA3_256 TRUE) + endif() + if("${gnutls_gnutls_file_contents}" MATCHES "#define GNUTLS_VERSION_MAJOR 2") + set(GNUTLS_HMAC_INIT_WITH_DIGEST TRUE) + endif() + if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_MAC_AES_CMAC_128") + set(GNUTLS_MAC_AES_CMAC_128 TRUE) + endif() + file(READ "${GNUTLS_INCLUDE_DIR}/gnutls/abstract.h" gnutls_abstract_file_contents) + if("${gnutls_abstract_file_contents}" MATCHES "gnutls_pubkey_export2") + set(GNUTLS_PUBKEY_EXPORT2 TRUE) + endif() + + find_package(GMP) + set_package_properties(GMP PROPERTIES + PURPOSE "Required to decompress cryptographic keys." + TYPE REQUIRED + ) + if(NOT GMP_FOUND) + message(FATAL_ERROR "GMP is required by gnss-sdr if linking against GnuTLS") + endif() +endif() + +################################################################################ + +function(link_to_crypto_dependencies target) + if(OPENSSL_FOUND) + if(TARGET OpenSSL::SSL) + target_link_libraries(${target} + PUBLIC + OpenSSL::SSL + ) + if(TARGET OpenSSL::Crypto) + target_link_libraries(${target} + PUBLIC + OpenSSL::Crypto + ) + endif() + else() + target_link_libraries(${target} + PUBLIC + ${OPENSSL_LIBRARIES} + "${OPENSSL_CRYPTO_LIBRARIES}" + ) + target_include_directories(${target} + PUBLIC + ${OPENSSL_INCLUDE_DIR} + ) + endif() + if(OPENSSL_VERSION) + if(OPENSSL_VERSION VERSION_GREATER "3.0.0") + target_compile_definitions(${target} PUBLIC -DUSE_OPENSSL_3=1) + else() + if(NOT OPENSSL_VERSION VERSION_LESS "1.1.1") + target_compile_definitions(${target} PUBLIC -DUSE_OPENSSL_111=1) + endif() + endif() + endif() + else() # GnuTLS + target_link_libraries(${target} + PUBLIC + ${GNUTLS_LIBRARIES} + ${GNUTLS_OPENSSL_LIBRARY} + PRIVATE + Gmp::gmp + ) + target_include_directories(${target} + PUBLIC + ${GNUTLS_INCLUDE_DIR} + ) + target_compile_definitions(${target} PUBLIC -DUSE_GNUTLS_FALLBACK=1) + if(GNUTLS_SIGN_ECDSA_SHA256) + target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA256=1) + endif() + if(GNUTLS_SIGN_ECDSA_SHA512) + target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA512=1) + endif() + if(GNUTLS_DIG_SHA3_256) + target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_DIG_SHA3_256=1) + endif() + if(GNUTLS_PUBKEY_EXPORT2) + target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_PUBKEY_EXPORT2=1) + endif() + if(GNUTLS_HMAC_INIT_WITH_DIGEST) + target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_HMAC_INIT_WITH_DIGEST=1) + endif() + if(GNUTLS_MAC_AES_CMAC_128) + target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_MAC_AES_CMAC_128=1) + endif() + endif() +endfunction() diff --git a/cmake/Modules/GnsssdrFindPaths.cmake b/cmake/Modules/GnsssdrFindPaths.cmake new file mode 100644 index 000000000..1ebda4f58 --- /dev/null +++ b/cmake/Modules/GnsssdrFindPaths.cmake @@ -0,0 +1,93 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(GNSSSDR_LIB_PATHS) + return() +endif() + +if(NOT CMAKE_INSTALL_LIBDIR) + include(GNUInstallDirs) +endif() + +set(GNSSSDR_LIB_PATHS + /usr/lib + /usr/lib64 + /usr/lib/aarch64-linux-gnu + /usr/lib/alpha-linux-gnu + /usr/lib/arm-linux-gnueabi + /usr/lib/arm-linux-gnueabihf + /usr/lib/hppa-linux-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/i386-gnu + /usr/lib/i386-kfreebsd-gnu + /usr/lib/i386-linux-gnu + /usr/lib/loongarch64-linux-gnu + /usr/lib/m68k-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc-linux-gnuspe + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/riscv64-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/sh4-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/x86_64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/local/lib + /usr/local/lib64 + /usr/local/lib/i386 + ${CMAKE_INSTALL_FULL_LIBDIR} + ${CMAKE_SYSTEM_PREFIX_PATH}/${CMAKE_INSTALL_LIBDIR} + ${CMAKE_INSTALL_PREFIX}/lib + ${CMAKE_INSTALL_PREFIX}/lib64 +) + +set(GNSSSDR_INCLUDE_PATHS + /usr/include + /usr/local/include + ${CMAKE_INSTALL_FULL_INCLUDEDIR} + ${CMAKE_SYSTEM_PREFIX_PATH}/include + ${CMAKE_INSTALL_PREFIX}/include +) + +set(GNSSSDR_BIN_PATHS + /usr/bin + /usr/local/bin + ${CMAKE_INSTALL_PREFIX}/bin + ${CMAKE_INSTALL_FULL_BINDIR} + ${CMAKE_SYSTEM_PREFIX_PATH}/bin + /bin + /sbin + /usr/sbin +) + +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + if(NOT MACOS_PACKAGES_PREFIX) + include(DetectMacOSVersion) + endif() + set(GNSSSDR_LIB_PATHS ${GNSSSDR_LIB_PATHS} + ${MACOS_PACKAGES_PREFIX}/${CMAKE_INSTALL_LIBDIR} + ${MACOS_PACKAGES_PREFIX}/lib + ${MACOS_PACKAGES_PREFIX}/lib64 + ) + set(GNSSSDR_INCLUDE_PATHS ${GNSSSDR_INCLUDE_PATHS} + ${MACOS_PACKAGES_PREFIX}/include + ~/Library/Frameworks + /Library/Frameworks + /sw/include # Fink + /opt/csw/include # Blastwave + ) + set(GNSSSDR_BIN_PATHS ${GNSSSDR_BIN_PATHS} + ${MACOS_PACKAGES_PREFIX}/bin + ) +endif() + +list(REMOVE_DUPLICATES GNSSSDR_LIB_PATHS) +list(REMOVE_DUPLICATES GNSSSDR_INCLUDE_PATHS) diff --git a/cmake/Modules/XcodeRemoveWarningDuplicates.cmake b/cmake/Modules/XcodeRemoveWarningDuplicates.cmake new file mode 100644 index 000000000..f4e150fcc --- /dev/null +++ b/cmake/Modules/XcodeRemoveWarningDuplicates.cmake @@ -0,0 +1,23 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2011-2024 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(DEFINED __INCLUDED_XCODE_REMOVE_WARNING_DUPLICATES_CMAKE) + return() +endif() +set(__INCLUDED_XCODE_REMOVE_WARNING_DUPLICATES_CMAKE TRUE) + +function(xcode_remove_warning_duplicates target) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0.0") + # A bug in Xcode 15 adds duplicate flags to the linker. In addition, the + # `-warn_duplicate_libraries` is now enabled by default which may result + # in several 'duplicate libraries warning'. + # - https://gitlab.kitware.com/cmake/cmake/-/issues/25297 and + # - https://indiestack.com/2023/10/xcode-15-duplicate-library-linker-warnings/ + target_link_options(${target} PUBLIC "LINKER:-no_warn_duplicate_libraries") + endif() + endif() +endfunction() \ No newline at end of file diff --git a/cmake/Toolchains/rv64gcv-linux-gnu.cmake b/cmake/Toolchains/rv64gcv-linux-gnu.cmake new file mode 100644 index 000000000..54be4cc5d --- /dev/null +++ b/cmake/Toolchains/rv64gcv-linux-gnu.cmake @@ -0,0 +1,32 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# Copyright (C) 2011-2025 (see AUTHORS file for a list of contributors) +# SPDX-License-Identifier: BSD-3-Clause + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) + +set(CMAKE_C_COMPILER $ENV{CC}) +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_CXX_COMPILER $ENV{CXX}) + +set(CMAKE_C_FLAGS "$ENV{CFLAGS} -march=rv64gcv" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "" FORCE) +set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -g" CACHE STRING "" FORCE) + +set(CMAKE_OBJCOPY + ${RISCV64_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}objcopy + CACHE INTERNAL "objcopy tool") +set(CMAKE_SIZE_UTIL + ${RISCV64_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}size + CACHE INTERNAL "size tool") + +set(CMAKE_FIND_ROOT_PATH ${BINUTILS_PATH}) + +set(QEMU_VLEN $ENV{VLEN}) +if(NOT QEMU_VLEN) + set(QEMU_VLEN "128") +endif() + +set(CMAKE_CROSSCOMPILING_EMULATOR "qemu-riscv64-static -L /usr/riscv64-linux-gnu/ -cpu rv64,zba=true,zbb=true,v=on,vlen=${QEMU_VLEN},rvv_ta_all_1s=on,rvv_ma_all_1s=on") diff --git a/conf/gnss-sdr_BDS_B1I_byte.conf b/conf/File_input/Beidou/gnss-sdr_BDS_B1I_byte.conf similarity index 97% rename from conf/gnss-sdr_BDS_B1I_byte.conf rename to conf/File_input/Beidou/gnss-sdr_BDS_B1I_byte.conf index a21547d24..e354a754d 100644 --- a/conf/gnss-sdr_BDS_B1I_byte.conf +++ b/conf/File_input/Beidou/gnss-sdr_BDS_B1I_byte.conf @@ -50,7 +50,7 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=25000000 InputFilter.IF=6250000 InputFilter.dump = false -InputFilter.dump_filename=/home/dmiralles/Documents/gnss-sdr/src/tests/signal_samples/BdsB1IStr01_fs25e6_if0_4ms.dat +InputFilter.dump_filename=/home/dmiralles/Documents/gnss-sdr/tests/signal_samples/BdsB1IStr01_fs25e6_if0_4ms.dat Resampler.implementation=Pass_Through Resampler.sample_freq_in=25000000 Resampler.sample_freq_out=25000000 diff --git a/conf/gnss-sdr_BDS_B3I_GPS_L1_CA_ibyte.conf b/conf/File_input/Beidou/gnss-sdr_BDS_B3I_GPS_L1_CA_ibyte.conf similarity index 100% rename from conf/gnss-sdr_BDS_B3I_GPS_L1_CA_ibyte.conf rename to conf/File_input/Beidou/gnss-sdr_BDS_B3I_GPS_L1_CA_ibyte.conf diff --git a/conf/gnss-sdr_BDS_B3I_byte.conf b/conf/File_input/Beidou/gnss-sdr_BDS_B3I_byte.conf similarity index 97% rename from conf/gnss-sdr_BDS_B3I_byte.conf rename to conf/File_input/Beidou/gnss-sdr_BDS_B3I_byte.conf index 8de1c685e..edd60bcd8 100644 --- a/conf/gnss-sdr_BDS_B3I_byte.conf +++ b/conf/File_input/Beidou/gnss-sdr_BDS_B3I_byte.conf @@ -51,7 +51,7 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=50000000 InputFilter.IF=12500000 InputFilter.dump = false -InputFilter.dump_filename=/home/dmiralles/Documents/gnss-sdr/src/tests/signal_samples/BdsB3IStr01_fs50e6_if0_4ms.dat +InputFilter.dump_filename=/home/dmiralles/Documents/gnss-sdr/tests/signal_samples/BdsB3IStr01_fs50e6_if0_4ms.dat Resampler.implementation=Pass_Through Resampler.sample_freq_in=50000000 Resampler.sample_freq_out=50000000 diff --git a/conf/gnss-sdr_BDS_B3I_ibyte.conf b/conf/File_input/Beidou/gnss-sdr_BDS_B3I_ibyte.conf similarity index 100% rename from conf/gnss-sdr_BDS_B3I_ibyte.conf rename to conf/File_input/Beidou/gnss-sdr_BDS_B3I_ibyte.conf diff --git a/conf/gnss-sdr_BDS_B3I_short.conf b/conf/File_input/Beidou/gnss-sdr_BDS_B3I_short.conf similarity index 95% rename from conf/gnss-sdr_BDS_B3I_short.conf rename to conf/File_input/Beidou/gnss-sdr_BDS_B3I_short.conf index a88c36092..01606f841 100644 --- a/conf/gnss-sdr_BDS_B3I_short.conf +++ b/conf/File_input/Beidou/gnss-sdr_BDS_B3I_short.conf @@ -12,7 +12,7 @@ GNSS-SDR.internal_fs_sps=30000000 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=File_Signal_Source -;SignalSource.filename=/home/dmiralles/Documents/gnss-sdr/src/tests/signal_samples/USRP_BDS_B2a_201805171115_fs_25e6_if0e3_ishort_200ms.bin +;SignalSource.filename=/home/dmiralles/Documents/gnss-sdr/tests/signal_samples/USRP_BDS_B2a_201805171115_fs_25e6_if0e3_ishort_200ms.bin SignalSource.filename=/archive/USRP_BDS_B3I_201805171118_fs_25e6_if0e3_ishort.bin SignalSource.item_type=ishort SignalSource.sampling_frequency=30000000 diff --git a/conf/gnss-sdr-L1-gaussian.conf b/conf/File_input/GPS/gnss-sdr-L1-gaussian.conf similarity index 95% rename from conf/gnss-sdr-L1-gaussian.conf rename to conf/File_input/GPS/gnss-sdr-L1-gaussian.conf index a208366e5..32b24bccc 100644 --- a/conf/gnss-sdr-L1-gaussian.conf +++ b/conf/File_input/GPS/gnss-sdr-L1-gaussian.conf @@ -39,7 +39,7 @@ Acquisition_1C.pfa=0.01 Acquisition_1C.doppler_max=10000 Acquisition_1C.doppler_step=250 Acquisition_1C.dump=false -Acquisition_1C.dump_filename=../data/kalman/acq_dump +Acquisition_1C.dump_filename=./kalman/acq_dump ;######### TRACKING GLOBAL CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_Gaussian_Tracking @@ -48,7 +48,7 @@ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=4.0; Tracking_1C.order=3; Tracking_1C.dump=true -Tracking_1C.dump_filename=../data/kalman/epl_tracking_ch_ +Tracking_1C.dump_filename=./kalman/epl_tracking_ch_ Tracking_1C.bce_run = true; Tracking_1C.p_transient = 0; Tracking_1C.s_transient = 100; diff --git a/conf/gnss-sdr_GPS_L1_CA_ibyte.conf b/conf/File_input/GPS/gnss-sdr_GPS_L1_CA_ibyte.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_CA_ibyte.conf rename to conf/File_input/GPS/gnss-sdr_GPS_L1_CA_ibyte.conf diff --git a/conf/gnss-sdr_GPS_L1_SPIR.conf b/conf/File_input/GPS/gnss-sdr_GPS_L1_SPIR.conf similarity index 96% rename from conf/gnss-sdr_GPS_L1_SPIR.conf rename to conf/File_input/GPS/gnss-sdr_GPS_L1_SPIR.conf index d83bd63d3..f0a90781b 100644 --- a/conf/gnss-sdr_GPS_L1_SPIR.conf +++ b/conf/File_input/GPS/gnss-sdr_GPS_L1_SPIR.conf @@ -34,7 +34,7 @@ DataTypeAdapter.item_type=float ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=float InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -64,7 +64,7 @@ Resampler.item_type=gr_complex Resampler.sample_freq_in=80000000 Resampler.sample_freq_out=4000000 Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ @@ -107,7 +107,7 @@ Tracking_1C.item_type=gr_complex Tracking_1C.pll_bw_hz=20.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_acq_QuickSync.conf b/conf/File_input/GPS/gnss-sdr_GPS_L1_acq_QuickSync.conf similarity index 95% rename from conf/gnss-sdr_GPS_L1_acq_QuickSync.conf rename to conf/File_input/GPS/gnss-sdr_GPS_L1_acq_QuickSync.conf index 356dde132..6961b3c3f 100644 --- a/conf/gnss-sdr_GPS_L1_acq_QuickSync.conf +++ b/conf/File_input/GPS/gnss-sdr_GPS_L1_acq_QuickSync.conf @@ -30,14 +30,14 @@ SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ DataTypeAdapter.implementation=Ishort_To_Complex DataTypeAdapter.dump=false -DataTypeAdapter.dump_filename=../data/data_type_adapter.dat +DataTypeAdapter.dump_filename=./data_type_adapter.dat ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Pass_Through InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -46,7 +46,7 @@ Resampler.item_type=gr_complex Resampler.sample_freq_in=4000000 Resampler.sample_freq_out=4000000 Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_gr_complex.conf b/conf/File_input/GPS/gnss-sdr_GPS_L1_gr_complex.conf similarity index 96% rename from conf/gnss-sdr_GPS_L1_gr_complex.conf rename to conf/File_input/GPS/gnss-sdr_GPS_L1_gr_complex.conf index 84179dbed..d61355a00 100644 --- a/conf/gnss-sdr_GPS_L1_gr_complex.conf +++ b/conf/File_input/GPS/gnss-sdr_GPS_L1_gr_complex.conf @@ -30,7 +30,7 @@ SignalConditioner.implementation=Signal_Conditioner DataTypeAdapter.implementation=Ishort_To_Complex DataTypeAdapter.dump=false -DataTypeAdapter.dump_filename=../data/DataTypeAdapter.dat +DataTypeAdapter.dump_filename=./DataTypeAdapter.dat InputFilter.implementation=Pass_Through InputFilter.input_item_type=gr_complex @@ -67,7 +67,7 @@ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=4.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_c +Tracking_1C.dump_filename=./epl_tracking_c ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_ishort.conf b/conf/File_input/GPS/gnss-sdr_GPS_L1_ishort.conf similarity index 98% rename from conf/gnss-sdr_GPS_L1_ishort.conf rename to conf/File_input/GPS/gnss-sdr_GPS_L1_ishort.conf index 1d76c2a2f..3a90a518d 100644 --- a/conf/gnss-sdr_GPS_L1_ishort.conf +++ b/conf/File_input/GPS/gnss-sdr_GPS_L1_ishort.conf @@ -24,7 +24,7 @@ SignalSource.sampling_frequency=4000000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf similarity index 96% rename from conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf index d7a72f476..8f3a44652 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_bin_file_III_1a.conf @@ -51,7 +51,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -86,7 +86,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Pass_Through InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter.dat +InputFilter1.dump_filename=./input_filter.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex @@ -103,7 +103,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex @@ -153,7 +153,7 @@ Tracking_1C.dll_bw_narrow_hz=2.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; Tracking_1C.dump=true -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf index 48727d42f..a543752ef 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1a.conf @@ -50,7 +50,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -85,7 +85,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Pass_Through InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter.dat +InputFilter1.dump_filename=./input_filter.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex @@ -102,7 +102,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf index 478cc875d..b86f734d4 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_III_1b.conf @@ -51,7 +51,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -85,7 +85,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Pass_Through InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter.dat +InputFilter1.dump_filename=./input_filter.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex @@ -102,7 +102,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf index 3ba4ba52d..ac8157f4e 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_II_3b.conf @@ -50,7 +50,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -85,7 +85,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Pass_Through InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter.dat +InputFilter1.dump_filename=./input_filter.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex @@ -102,7 +102,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex diff --git a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf index 73624bc73..f919973d2 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_Flexiband_realtime_I_1b.conf @@ -50,7 +50,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -85,7 +85,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Pass_Through InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter.dat +InputFilter1.dump_filename=./input_filter.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex @@ -102,7 +102,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf similarity index 98% rename from conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf index 9e77cb6ae..746330acf 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_L2_Flexiband_realtime_III_1b.conf @@ -54,7 +54,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -93,7 +93,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter1.implementation=Freq_Xlating_Fir_Filter InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter_ch1.dat +InputFilter1.dump_filename=./input_filter_ch1.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex InputFilter1.taps_item_type=float @@ -129,7 +129,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex diff --git a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf index f2a47b807..7e494914e 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L1_L2_Galileo_E1B_Flexiband_bin_file_III_1b.conf @@ -56,7 +56,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -95,7 +95,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter1.implementation=Freq_Xlating_Fir_Filter InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter_ch1.dat +InputFilter1.dump_filename=./input_filter_ch1.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex InputFilter1.taps_item_type=float @@ -131,7 +131,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex @@ -190,7 +190,7 @@ Acquisition_1C.dump_filename=./acq_dump.dat Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=1.5; Tracking_1C.order=3; @@ -215,7 +215,7 @@ Tracking_2S.dll_bw_hz=0.3; Tracking_2S.order=3; Tracking_2S.early_late_space_chips=0.5; Tracking_2S.dump=true -Tracking_2S.dump_filename=../data/epl_tracking_ch_ +Tracking_2S.dump_filename=./epl_tracking_ch_ ;# GALILEO E1B diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf index c6ca7e8e0..4017609f5 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b.conf @@ -56,7 +56,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter_ch0.dat +InputFilter0.dump_filename=./input_filter_ch0.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -95,7 +95,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter1.implementation=Freq_Xlating_Fir_Filter InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter_ch1.dat +InputFilter1.dump_filename=./input_filter_ch1.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex InputFilter1.taps_item_type=float @@ -136,7 +136,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Freq_Xlating_Fir_Filter InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter_ch2.dat +InputFilter2.dump_filename=./input_filter_ch2.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex InputFilter2.taps_item_type=float @@ -271,7 +271,7 @@ Acquisition_5X.doppler_max=5000 Acquisition_5X.doppler_step=125 Acquisition_5X.bit_transition_flag=false Acquisition_5X.max_dwells=1 -Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz +Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is deactivated. Recommended value 3000 Hz Acquisition_5X.Zero_padding=0 ; **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. Acquisition_5X.dump=false Acquisition_5X.dump_filename=./acq_dump.dat @@ -286,7 +286,7 @@ Tracking_1C.dll_bw_hz=3.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### GALILEO E1 TRK CONFIG ############ @@ -298,7 +298,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### GPS L2C GENERIC TRACKING CONFIG ############ diff --git a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf rename to conf/File_input/GPS/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf index 0abf4188c..0e0f9f289 100644 --- a/conf/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf +++ b/conf/File_input/GPS/gnss-sdr_multichannel_GPS_L2_M_Flexiband_bin_file_III_1b_real.conf @@ -56,7 +56,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter_ch0.dat +InputFilter0.dump_filename=./input_filter_ch0.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -94,7 +94,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter1.implementation=Freq_Xlating_Fir_Filter InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter_ch1.dat +InputFilter1.dump_filename=./input_filter_ch1.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex InputFilter1.taps_item_type=float @@ -130,7 +130,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Pass_Through InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter.dat +InputFilter2.dump_filename=./input_filter.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex @@ -212,7 +212,7 @@ Tracking_1C.dll_bw_hz=3.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### GPS L2C GENERIC TRACKING CONFIG ############ diff --git a/conf/gnss-sdr_Galileo_E1_acq_QuickSync.conf b/conf/File_input/Galileo/gnss-sdr_Galileo_E1_acq_QuickSync.conf similarity index 95% rename from conf/gnss-sdr_Galileo_E1_acq_QuickSync.conf rename to conf/File_input/Galileo/gnss-sdr_Galileo_E1_acq_QuickSync.conf index 3f3a9831e..5146a4f1b 100644 --- a/conf/gnss-sdr_Galileo_E1_acq_QuickSync.conf +++ b/conf/File_input/Galileo/gnss-sdr_Galileo_E1_acq_QuickSync.conf @@ -30,7 +30,7 @@ SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ DataTypeAdapter.implementation=Ishort_To_Complex DataTypeAdapter.dump=false -DataTypeAdapter.dump_filename=../data/data_type_adapter.dat +DataTypeAdapter.dump_filename=./data_type_adapter.dat ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Pass_Through @@ -39,7 +39,7 @@ InputFilter.implementation=Pass_Through ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat Resampler.item_type=gr_complex @@ -70,7 +70,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER CONFIG ############ TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder diff --git a/conf/gnss-sdr_Galileo_E1_ishort.conf b/conf/File_input/Galileo/gnss-sdr_Galileo_E1_ishort.conf similarity index 97% rename from conf/gnss-sdr_Galileo_E1_ishort.conf rename to conf/File_input/Galileo/gnss-sdr_Galileo_E1_ishort.conf index 257bd9091..2a9fedb8d 100644 --- a/conf/gnss-sdr_Galileo_E1_ishort.conf +++ b/conf/File_input/Galileo/gnss-sdr_Galileo_E1_ishort.conf @@ -41,7 +41,7 @@ Resampler.item_type=gr_complex Resampler.sample_freq_in=4000000 Resampler.sample_freq_out=4000000 Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ @@ -75,7 +75,7 @@ Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.track_pilot=true Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER CONFIG ############ diff --git a/conf/gnss-sdr_Galileo_E1_nsr.conf b/conf/File_input/Galileo/gnss-sdr_Galileo_E1_nsr.conf similarity index 96% rename from conf/gnss-sdr_Galileo_E1_nsr.conf rename to conf/File_input/Galileo/gnss-sdr_Galileo_E1_nsr.conf index 883927c8e..0b2dffd9b 100644 --- a/conf/gnss-sdr_Galileo_E1_nsr.conf +++ b/conf/File_input/Galileo/gnss-sdr_Galileo_E1_nsr.conf @@ -25,7 +25,7 @@ SignalSource.sampling_frequency=20480000 SignalSource.samples=0 ; 0 means the entire file SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -62,7 +62,7 @@ InputFilter.sampling_frequency=20480000 InputFilter.IF=5499998.47412109 InputFilter.decimation_factor=8 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -96,7 +96,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER CONFIG ############ diff --git a/conf/gnss-sdr_Galileo_E5a.conf b/conf/File_input/Galileo/gnss-sdr_Galileo_E5a.conf similarity index 100% rename from conf/gnss-sdr_Galileo_E5a.conf rename to conf/File_input/Galileo/gnss-sdr_Galileo_E5a.conf diff --git a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf b/conf/File_input/Galileo/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf similarity index 96% rename from conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf rename to conf/File_input/Galileo/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf index 9c2ea55cc..a6fb901ed 100644 --- a/conf/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf +++ b/conf/File_input/Galileo/gnss-sdr_Galileo_E5a_IFEN_CTTC.conf @@ -35,7 +35,7 @@ SignalSource.sampling_frequency=50000000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -68,13 +68,13 @@ InputFilter.sampling_frequency=50000000 InputFilter.IF=-15345000 InputFilter.decimation_factor=1 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ @@ -111,7 +111,7 @@ Acquisition_5X.doppler_max=10000 Acquisition_5X.doppler_step=250 Acquisition_5X.bit_transition_flag=false Acquisition_5X.max_dwells=1 -Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz +Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is deactivated. Recommended value 3000 Hz Acquisition_5X.Zero_padding=0 ; **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. Acquisition_5X.dump=false Acquisition_5X.dump_filename=./acq_dump.dat diff --git a/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf b/conf/File_input/Galileo/gnss-sdr_galileo_E1_extended_correlator_byte.conf similarity index 96% rename from conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf rename to conf/File_input/Galileo/gnss-sdr_galileo_E1_extended_correlator_byte.conf index a0715fba8..638a045d6 100644 --- a/conf/gnss-sdr_galileo_E1_extended_correlator_byte.conf +++ b/conf/File_input/Galileo/gnss-sdr_galileo_E1_extended_correlator_byte.conf @@ -81,7 +81,7 @@ Acquisition_1B.doppler_max=5000 Acquisition_1B.doppler_step=125 Acquisition_1B.bit_transition_flag=true Acquisition_1B.dump=false -Acquisition_1B.dump_filename=../data/acq_dump.dat +Acquisition_1B.dump_filename=./acq_dump.dat ;######### TRACKING GPS CONFIG ############ @@ -91,7 +91,7 @@ Tracking_1C.pll_bw_hz=30.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ @@ -109,7 +109,7 @@ Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.early_late_space_narrow_chips=0.06; Tracking_1B.very_early_late_space_narrow_chips=0.25; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf b/conf/File_input/Galileo/gnss-sdr_galileo_E1_extended_correlator_labsat.conf similarity index 95% rename from conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf rename to conf/File_input/Galileo/gnss-sdr_galileo_E1_extended_correlator_labsat.conf index 91387a875..cf17d5140 100644 --- a/conf/gnss-sdr_galileo_E1_extended_correlator_labsat.conf +++ b/conf/File_input/Galileo/gnss-sdr_galileo_E1_extended_correlator_labsat.conf @@ -25,7 +25,7 @@ SignalSource.sampling_frequency=16368000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -39,7 +39,7 @@ DataTypeAdapter.item_type=gr_complex ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex @@ -110,7 +110,7 @@ Acquisition_1B.doppler_max=5000 Acquisition_1B.doppler_step=125 Acquisition_1B.bit_transition_flag=true Acquisition_1B.dump=false -Acquisition_1B.dump_filename=../data/acq_dump.dat +Acquisition_1B.dump_filename=./acq_dump.dat ;######### TRACKING GPS CONFIG ############ @@ -120,7 +120,7 @@ Tracking_1C.pll_bw_hz=40.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking @@ -137,7 +137,7 @@ Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.early_late_space_narrow_chips=0.15; Tracking_1B.very_early_late_space_narrow_chips=0.30; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf similarity index 95% rename from conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf index 021b12ae8..12378e46f 100644 --- a/conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf +++ b/conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf @@ -11,7 +11,7 @@ GNSS-SDR.num_sources=2 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource0.implementation=File_Signal_Source -SignalSource0.filename=../data/NT1065_L1_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource0.filename=./NT1065_L1_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE SignalSource0.item_type=ibyte SignalSource0.sampling_frequency=6625000 SignalSource0.samples=0 @@ -19,7 +19,7 @@ SignalSource0.dump=false; SignalSource0.dump_filename=/archive/signal_glonass.bin SignalSource1.implementation=File_Signal_Source -SignalSource1.filename=../data/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource1.filename=./NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE SignalSource1.item_type=ibyte SignalSource1.sampling_frequency=6625000 SignalSource1.samples=0 diff --git a/conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf similarity index 100% rename from conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_ibyte.conf similarity index 100% rename from conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_ibyte.conf diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf similarity index 100% rename from conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf diff --git a/conf/gnss-sdr_GLONASS_L1_ibyte.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L1_ibyte.conf similarity index 97% rename from conf/gnss-sdr_GLONASS_L1_ibyte.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L1_ibyte.conf index 8f8baecfc..254196c30 100644 --- a/conf/gnss-sdr_GLONASS_L1_ibyte.conf +++ b/conf/File_input/Glonass/gnss-sdr_GLONASS_L1_ibyte.conf @@ -23,7 +23,7 @@ SignalSource.repeat=false SignalSource.sample_type=iq SignalSource.seconds_to_skip=0 SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -69,7 +69,7 @@ Acquisition_1R.tong_max_dwells=20 Tracking_1R.implementation=GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking Tracking_1R.item_type=cshort Tracking_1R.dump=false -Tracking_1R.dump_filename=../data/epl_tracking_ch_ +Tracking_1R.dump_filename=./epl_tracking_ch_ Tracking_1R.pll_bw_hz=40.0; Tracking_1R.dll_bw_hz=4.0; Tracking_1R.order=3; diff --git a/conf/gnss-sdr_GLONASS_L2_CA_GPS_L1_CA_ibyte.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_GPS_L1_CA_ibyte.conf similarity index 100% rename from conf/gnss-sdr_GLONASS_L2_CA_GPS_L1_CA_ibyte.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_GPS_L1_CA_ibyte.conf diff --git a/conf/gnss-sdr_GLONASS_L2_CA_GPS_L2C_ibyte.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_GPS_L2C_ibyte.conf similarity index 100% rename from conf/gnss-sdr_GLONASS_L2_CA_GPS_L2C_ibyte.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_GPS_L2C_ibyte.conf diff --git a/conf/gnss-sdr_GLONASS_L2_CA_ibyte.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_ibyte.conf similarity index 100% rename from conf/gnss-sdr_GLONASS_L2_CA_ibyte.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_ibyte.conf diff --git a/conf/gnss-sdr_GLONASS_L2_CA_ibyte_coh_trk.conf b/conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_ibyte_coh_trk.conf similarity index 100% rename from conf/gnss-sdr_GLONASS_L2_CA_ibyte_coh_trk.conf rename to conf/File_input/Glonass/gnss-sdr_GLONASS_L2_CA_ibyte_coh_trk.conf diff --git a/conf/gnss-sdr_Hybrid_byte.conf b/conf/File_input/MultiCons/gnss-sdr_Hybrid_byte.conf similarity index 95% rename from conf/gnss-sdr_Hybrid_byte.conf rename to conf/File_input/MultiCons/gnss-sdr_Hybrid_byte.conf index 3daee47ce..7e0df6bd2 100644 --- a/conf/gnss-sdr_Hybrid_byte.conf +++ b/conf/File_input/MultiCons/gnss-sdr_Hybrid_byte.conf @@ -35,7 +35,7 @@ InputFilter.implementation=Pass_Through InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -44,7 +44,7 @@ Resampler.item_type=gr_complex Resampler.sample_freq_in=20000000 Resampler.sample_freq_out=20000000 Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ @@ -113,7 +113,7 @@ Tracking_1C.dll_bw_hz=2.0; Tracking_1C.dll_bw_narrow_hz=1.5; Tracking_1C.order=2; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ @@ -125,7 +125,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_Hybrid_byte_sim.conf b/conf/File_input/MultiCons/gnss-sdr_Hybrid_byte_sim.conf similarity index 94% rename from conf/gnss-sdr_Hybrid_byte_sim.conf rename to conf/File_input/MultiCons/gnss-sdr_Hybrid_byte_sim.conf index b92bdc4a9..1360f71bf 100644 --- a/conf/gnss-sdr_Hybrid_byte_sim.conf +++ b/conf/File_input/MultiCons/gnss-sdr_Hybrid_byte_sim.conf @@ -22,7 +22,7 @@ SignalSource.sampling_frequency=4000000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -32,12 +32,12 @@ SignalConditioner.implementation=Signal_Conditioner ;######### DATA_TYPE_ADAPTER CONFIG ############ DataTypeAdapter.implementation=Ibyte_To_Complex DataTypeAdapter.dump=false -DataTypeAdapter.dump_filename=../data/DataTypeAdapter.dat +DataTypeAdapter.dump_filename=./DataTypeAdapter.dat ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Pass_Through InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex @@ -106,14 +106,14 @@ Tracking_1C.order=3; Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking Tracking_1B.item_type=gr_complex Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ Tracking_1B.pll_bw_hz=15.0; Tracking_1B.dll_bw_hz=2.0; Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_Hybrid_gr_complex.conf b/conf/File_input/MultiCons/gnss-sdr_Hybrid_gr_complex.conf similarity index 97% rename from conf/gnss-sdr_Hybrid_gr_complex.conf rename to conf/File_input/MultiCons/gnss-sdr_Hybrid_gr_complex.conf index b375cec21..aa404633c 100644 --- a/conf/gnss-sdr_Hybrid_gr_complex.conf +++ b/conf/File_input/MultiCons/gnss-sdr_Hybrid_gr_complex.conf @@ -85,7 +85,7 @@ Tracking_1C.dll_bw_hz=2.0; Tracking_1C.dll_bw_narrow_hz=2.0; Tracking_1C.order=3; Tracking_1C.dump=true -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ @@ -98,7 +98,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_Hybrid_ishort.conf b/conf/File_input/MultiCons/gnss-sdr_Hybrid_ishort.conf similarity index 97% rename from conf/gnss-sdr_Hybrid_ishort.conf rename to conf/File_input/MultiCons/gnss-sdr_Hybrid_ishort.conf index 3931754e0..c9f0de8f5 100644 --- a/conf/gnss-sdr_Hybrid_ishort.conf +++ b/conf/File_input/MultiCons/gnss-sdr_Hybrid_ishort.conf @@ -56,7 +56,7 @@ InputFilter.output_item_type=gr_complex Resampler.implementation=Pass_Through Resampler.item_type=gr_complex Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ @@ -111,7 +111,7 @@ Tracking_1C.pll_bw_hz=50.0; Tracking_1C.dll_bw_hz=5.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ @@ -123,7 +123,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_labsat_kf.conf b/conf/File_input/MultiCons/gnss-sdr_labsat_kf.conf similarity index 100% rename from conf/gnss-sdr_labsat_kf.conf rename to conf/File_input/MultiCons/gnss-sdr_labsat_kf.conf diff --git a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf b/conf/File_input/MultiCons/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf similarity index 97% rename from conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf rename to conf/File_input/MultiCons/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf index a9ec9e564..14e813a27 100644 --- a/conf/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf +++ b/conf/File_input/MultiCons/gnss-sdr_multichannel_all_in_one_Flexiband_bin_file_III_1b.conf @@ -57,7 +57,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter_ch0.dat +InputFilter0.dump_filename=./input_filter_ch0.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -96,7 +96,7 @@ DataTypeAdapter1.item_type=gr_complex ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Freq_Xlating_Fir_Filter InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter_ch1.dat +InputFilter1.dump_filename=./input_filter_ch1.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex InputFilter1.taps_item_type=float @@ -135,7 +135,7 @@ DataTypeAdapter2.item_type=gr_complex ;######### INPUT_FILTER 2 CONFIG ############ InputFilter2.implementation=Freq_Xlating_Fir_Filter InputFilter2.dump=false -InputFilter2.dump_filename=../data/input_filter_ch2.dat +InputFilter2.dump_filename=./input_filter_ch2.dat InputFilter2.input_item_type=gr_complex InputFilter2.output_item_type=gr_complex InputFilter2.taps_item_type=float @@ -266,7 +266,7 @@ Acquisition_5X.doppler_max=5000 Acquisition_5X.doppler_step=125 Acquisition_5X.bit_transition_flag=false Acquisition_5X.max_dwells=1 -Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is desactivated. Recommended value 3000 Hz +Acquisition_5X.CAF_window_hz=0 ; **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is deactivated. Recommended value 3000 Hz Acquisition_5X.Zero_padding=0 ; **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. Acquisition_5X.dump=false Acquisition_5X.dump_filename=./acq_dump.dat @@ -294,7 +294,7 @@ Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### GALILEO E1 TRK CONFIG ############ Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking @@ -305,7 +305,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### GPS L2C GENERIC TRACKING CONFIG ############ diff --git a/conf/gnss-sdr_multisource_Hybrid_ishort.conf b/conf/File_input/MultiCons/gnss-sdr_multisource_Hybrid_ishort.conf similarity index 95% rename from conf/gnss-sdr_multisource_Hybrid_ishort.conf rename to conf/File_input/MultiCons/gnss-sdr_multisource_Hybrid_ishort.conf index 5838a3b88..04070f0b7 100644 --- a/conf/gnss-sdr_multisource_Hybrid_ishort.conf +++ b/conf/File_input/MultiCons/gnss-sdr_multisource_Hybrid_ishort.conf @@ -45,7 +45,7 @@ DataTypeAdapter0.implementation=Ishort_To_Complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Pass_Through InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex @@ -54,7 +54,7 @@ InputFilter0.output_item_type=gr_complex ;######### RESAMPLER 1 CONFIG ############ Resampler1.implementation=Pass_Through Resampler1.dump=false -Resampler1.dump_filename=../data/resampler.dat +Resampler1.dump_filename=./resampler.dat Resampler1.item_type=gr_complex Resampler1.sample_freq_in=4000000 Resampler1.sample_freq_out=4000000 @@ -73,7 +73,7 @@ InputFilter1.dump=false ;######### RESAMPLER 1 CONFIG ############ Resampler1.implementation=Pass_Through Resampler1.dump=false -Resampler1.dump_filename=../data/resampler.dat. +Resampler1.dump_filename=./resampler.dat. Resampler1.item_type=gr_complex Resampler1.sample_freq_in=4000000 Resampler1.sample_freq_out=4000000 @@ -126,7 +126,7 @@ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=4.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ @@ -138,7 +138,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_multisource_Hybrid_nsr.conf b/conf/File_input/MultiCons/gnss-sdr_multisource_Hybrid_nsr.conf similarity index 97% rename from conf/gnss-sdr_multisource_Hybrid_nsr.conf rename to conf/File_input/MultiCons/gnss-sdr_multisource_Hybrid_nsr.conf index c5c5e9134..671dd346d 100644 --- a/conf/gnss-sdr_multisource_Hybrid_nsr.conf +++ b/conf/File_input/MultiCons/gnss-sdr_multisource_Hybrid_nsr.conf @@ -48,7 +48,7 @@ DataTypeAdapter0.item_type=float ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Freq_Xlating_Fir_Filter InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=float InputFilter0.output_item_type=gr_complex InputFilter0.taps_item_type=float @@ -83,7 +83,7 @@ DataTypeAdapter1.item_type=float ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Freq_Xlating_Fir_Filter InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter.dat +InputFilter1.dump_filename=./input_filter.dat InputFilter1.input_item_type=float InputFilter1.output_item_type=gr_complex InputFilter1.taps_item_type=float @@ -184,7 +184,7 @@ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ @@ -196,7 +196,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_nsr.conf b/conf/Nsr_input/gnss-sdr_GPS_L1_nsr.conf similarity index 95% rename from conf/gnss-sdr_GPS_L1_nsr.conf rename to conf/Nsr_input/gnss-sdr_GPS_L1_nsr.conf index d0682aa30..0452136ec 100644 --- a/conf/gnss-sdr_GPS_L1_nsr.conf +++ b/conf/Nsr_input/gnss-sdr_GPS_L1_nsr.conf @@ -39,7 +39,7 @@ SignalSource.sampling_frequency=20480000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -53,7 +53,7 @@ DataTypeAdapter.item_type=float ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=float InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -80,7 +80,7 @@ InputFilter.decimation_factor=8 ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat Resampler.item_type=gr_complex @@ -120,7 +120,7 @@ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### GPS L2C GENERIC TRACKING CONFIG ############ Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking @@ -130,7 +130,7 @@ Tracking_2S.dll_bw_hz=0.4; Tracking_2S.order=2; Tracking_2S.early_late_space_chips=0.5; Tracking_2S.dump=true -Tracking_2S.dump_filename=../data/epl_tracking_ch_ +Tracking_2S.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_nsr_gauss.conf b/conf/Nsr_input/gnss-sdr_GPS_L1_nsr_gauss.conf similarity index 97% rename from conf/gnss-sdr_GPS_L1_nsr_gauss.conf rename to conf/Nsr_input/gnss-sdr_GPS_L1_nsr_gauss.conf index a127a5870..423bd7358 100644 --- a/conf/gnss-sdr_GPS_L1_nsr_gauss.conf +++ b/conf/Nsr_input/gnss-sdr_GPS_L1_nsr_gauss.conf @@ -37,7 +37,7 @@ SignalSource.repeat=false ;#dump: Dump the Signal source data to a file. Disable this option in this version SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;#enable_throttle_control: Enabling this option tells the signal source to keep the delay between samples in post processing. @@ -72,12 +72,12 @@ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false ;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation. ;#These options are based on parameters of gnuradio's function: gr_remez. ;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse -;#reponse given a set of band edges, the desired reponse on those bands, +;#response given a set of band edges, the desired response on those bands, ;#and the weight given to the error in those bands. ;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version. @@ -169,7 +169,7 @@ Tracking_1C.implementation=GPS_L1_CA_Gaussian_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.if=0 Tracking_1C.dump=true -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ Tracking_1C.pll_bw_hz=15.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; diff --git a/conf/gnss-sdr_Hybrid_nsr.conf b/conf/Nsr_input/gnss-sdr_Hybrid_nsr.conf similarity index 96% rename from conf/gnss-sdr_Hybrid_nsr.conf rename to conf/Nsr_input/gnss-sdr_Hybrid_nsr.conf index 91bbc1c69..8e2e10e7b 100644 --- a/conf/gnss-sdr_Hybrid_nsr.conf +++ b/conf/Nsr_input/gnss-sdr_Hybrid_nsr.conf @@ -22,7 +22,7 @@ SignalSource.sampling_frequency=20480000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -56,7 +56,7 @@ InputFilter.sampling_frequency=20480000 InputFilter.IF=5499998.47412109 InputFilter.decimation_factor=8 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -129,7 +129,7 @@ Tracking_1C.dll_bw_hz=2.0; Tracking_1C.dll_bw_narrow_hz=1.5; Tracking_1C.order=2; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TRACKING GALILEO CONFIG ############ @@ -141,7 +141,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/front-end-cal.conf b/conf/Other/front-end-cal.conf similarity index 93% rename from conf/front-end-cal.conf rename to conf/Other/front-end-cal.conf index af2a06a2f..2753abf6d 100644 --- a/conf/front-end-cal.conf +++ b/conf/Other/front-end-cal.conf @@ -17,19 +17,23 @@ ;GNSS-SDR.init_altitude_m=329.11968943169342 ; Barcelona CTTC -GNSS-SDR.init_latitude_deg=41.27719585553101 -GNSS-SDR.init_longitude_deg=1.988782985790802 -GNSS-SDR.init_altitude_m=10 +;GNSS-SDR.init_latitude_deg=41.27719585553101 +;GNSS-SDR.init_longitude_deg=1.988782985790802 +;GNSS-SDR.init_altitude_m=10 ; Mozoncillo ;GNSS-SDR.init_latitude_deg=41.14534824586196 ;GNSS-SDR.init_longitude_deg=-4.187125019737464 ;GNSS-SDR.init_altitude_m=900 +; ICEBAR - Jukkasjarvi +GNSS-SDR.init_latitude_deg=67.849722 +GNSS-SDR.init_longitude_deg=20.594444 +GNSS-SDR.init_altitude_m=325 ;######### GLOBAL OPTIONS ################## ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second]. -GNSS-SDR.internal_fs_sps=2000000 +GNSS-SDR.internal_fs_sps=2048000 ;######### SUPL RRLP GPS assistance configuration ##### ; Check https://www.mcc-mnc.com/ @@ -40,10 +44,10 @@ GNSS-SDR.SUPL_gps_ephemeris_server=supl.google.com GNSS-SDR.SUPL_gps_ephemeris_port=7275 GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com GNSS-SDR.SUPL_gps_acquisition_port=7275 -GNSS-SDR.SUPL_MCC=217 -GNSS-SDR.SUPL_MNC=7 -GNSS-SDR.SUPL_LAC=861 -GNSS-SDR.SUPL_CI=40184 +GNSS-SDR.SUPL_MCC=240 +GNSS-SDR.SUPL_MNC=08 +GNSS-SDR.SUPL_LAC=46003 +GNSS-SDR.SUPL_CI=425950 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=Osmosdr_Signal_Source @@ -52,7 +56,7 @@ SignalSource.freq=1575420000 ;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version. SignalSource.item_type=gr_complex ;#sampling_frequency: Original Signal sampling frequency in samples per second -SignalSource.sampling_frequency=2000000 +SignalSource.sampling_frequency=2048000 ;#gain: Front-end Gain in [dB] SignalSource.gain=40 SignalSource.rf_gain=40 @@ -81,7 +85,7 @@ SignalSource.repeat=false ;#dump: Dump the Signal source data to a file. SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ ;## It holds blocks to change data type, filter and resample input data. @@ -98,7 +102,7 @@ DataTypeAdapter.implementation=Pass_Through ;#dump: Dump the filtered data to a file. DataTypeAdapter.dump=false ;#dump_filename: Log path and filename. -DataTypeAdapter.dump_filename=../data/data_type_adapter.dat +DataTypeAdapter.dump_filename=./data_type_adapter.dat ;######### INPUT_FILTER CONFIG ############ ;## Filter the input data. Can be combined with frequency translation for IF signals @@ -172,7 +176,7 @@ InputFilter.decimation_factor=1 InputFilter.dump=false ;#dump_filename: Log path and filename. -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ ;## Resamples the input data. @@ -200,3 +204,4 @@ Acquisition.max_dwells=15 Acquisition.dump=false ;#filename: Log path and filename Acquisition.dump_filename=./acq_dump.dat + diff --git a/conf/gnss-sdr_GPS_L1_2ch_udp.conf b/conf/Other/gnss-sdr_GPS_L1_2ch_udp.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_2ch_udp.conf rename to conf/Other/gnss-sdr_GPS_L1_2ch_udp.conf diff --git a/conf/gnss-sdr_GPS_L1_FPGA.conf b/conf/Other/gnss-sdr_GPS_L1_FPGA.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_FPGA.conf rename to conf/Other/gnss-sdr_GPS_L1_FPGA.conf diff --git a/conf/gnss-sdr_GPS_L1_fifo.conf b/conf/Other/gnss-sdr_GPS_L1_fifo.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_fifo.conf rename to conf/Other/gnss-sdr_GPS_L1_fifo.conf diff --git a/conf/gnss-sdr_GPS_L1_gr_complex_gpu.conf b/conf/Other/gnss-sdr_GPS_L1_gr_complex_gpu.conf similarity index 96% rename from conf/gnss-sdr_GPS_L1_gr_complex_gpu.conf rename to conf/Other/gnss-sdr_GPS_L1_gr_complex_gpu.conf index c1b99441b..f920c7cb6 100644 --- a/conf/gnss-sdr_GPS_L1_gr_complex_gpu.conf +++ b/conf/Other/gnss-sdr_GPS_L1_gr_complex_gpu.conf @@ -21,7 +21,7 @@ SignalSource.item_type=gr_complex SignalSource.samples=250000000 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -51,7 +51,7 @@ Acquisition_1C.dump_filename=./acq_dump.dat Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking_GPU Tracking_1C.item_type=gr_complex Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; diff --git a/conf/gnss-sdr_GPS_L1_monitor.conf b/conf/Other/gnss-sdr_GPS_L1_monitor.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_monitor.conf rename to conf/Other/gnss-sdr_GPS_L1_monitor.conf diff --git a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf b/conf/Other/gnss-sdr_GPS_L1_nsr_twobit_packed.conf similarity index 95% rename from conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf rename to conf/Other/gnss-sdr_GPS_L1_nsr_twobit_packed.conf index 01209aefb..0e46e98b2 100644 --- a/conf/gnss-sdr_GPS_L1_nsr_twobit_packed.conf +++ b/conf/Other/gnss-sdr_GPS_L1_nsr_twobit_packed.conf @@ -40,7 +40,7 @@ SignalSource.item_type=byte ; endian. If it is big endian then the second byte should be output ; first in each short. ; SignalSource.big_endian_items=false -; big_endian_bytes: true if the most signficiant two bits in the byte +; big_endian_bytes: true if the most significant two bits in the byte ; are the first two to be output. SignalSource.big_endian_bytes=false ; sample_type: one of 'real' 'iq' or 'qi' @@ -54,7 +54,7 @@ SignalSource.sampling_frequency=20480000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -68,7 +68,7 @@ DataTypeAdapter.item_type=float ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=float InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float @@ -94,7 +94,7 @@ InputFilter.decimation_factor=8 ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat Resampler.item_type=gr_complex @@ -123,7 +123,7 @@ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf b/conf/Other/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf similarity index 97% rename from conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf rename to conf/Other/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf index b0d592f84..94ab55c7c 100644 --- a/conf/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf +++ b/conf/Other/gnss-sdr_GPS_L1_pulse_blanking_gr_complex.conf @@ -49,7 +49,7 @@ InputFilter.Pfa=0.001 InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### CHANNELS GLOBAL CONFIG ############ Channels_1C.count=8 @@ -80,7 +80,7 @@ Tracking_1C.dll_bw_narrow_hz=1.5; Tracking_1C.fll_bw_hz=2.0; Tracking_1C.order=3; Tracking_1C.dump=true -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf b/conf/Other/gnss-sdr_GPS_L1_two_bits_cpx.conf similarity index 96% rename from conf/gnss-sdr_GPS_L1_two_bits_cpx.conf rename to conf/Other/gnss-sdr_GPS_L1_two_bits_cpx.conf index 67c4d60e1..efef7d428 100644 --- a/conf/gnss-sdr_GPS_L1_two_bits_cpx.conf +++ b/conf/Other/gnss-sdr_GPS_L1_two_bits_cpx.conf @@ -36,7 +36,7 @@ SignalSource.sampling_frequency=19200000 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_throttle_control=false @@ -70,13 +70,13 @@ InputFilter.sampling_frequency=19200000 InputFilter.IF=4024000 InputFilter.decimation_factor=6 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat Resampler.item_type=gr_complex diff --git a/conf/gnss-sdr_GPS_L1_udp_with_monitor.conf b/conf/Other/gnss-sdr_GPS_L1_udp_with_monitor.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_udp_with_monitor.conf rename to conf/Other/gnss-sdr_GPS_L1_udp_with_monitor.conf diff --git a/conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf similarity index 98% rename from conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf index 3fc5c22d2..1b057e4aa 100644 --- a/conf/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L1_2ch_fmcomms2_realtime.conf @@ -31,7 +31,7 @@ SignalSource.gain_rx2=64 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.enable_dds_lo=false SignalSource.freq_rf_tx_hz=1260000000 SignalSource.freq_dds_tx_hz=1000 diff --git a/conf/gnss-sdr_GPS_L1_LimeSDR.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_LimeSDR.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_LimeSDR.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_LimeSDR.conf diff --git a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_USRP_X300_realtime.conf similarity index 96% rename from conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_USRP_X300_realtime.conf index f0ab33656..12c4bd0ee 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L1_USRP_X300_realtime.conf @@ -41,7 +41,7 @@ SignalSource.subdevice=A:0 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ @@ -73,7 +73,7 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ @@ -82,7 +82,7 @@ Resampler.item_type=gr_complex Resampler.sample_freq_in=4000000 Resampler.sample_freq_out=4000000 Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_USRP_realtime.conf similarity index 98% rename from conf/gnss-sdr_GPS_L1_USRP_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_USRP_realtime.conf index 04afb9a6c..e75b568dc 100644 --- a/conf/gnss-sdr_GPS_L1_USRP_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L1_USRP_realtime.conf @@ -40,7 +40,7 @@ SignalSource.subdevice=A:0 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_bladeRF.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_bladeRF.conf similarity index 98% rename from conf/gnss-sdr_GPS_L1_bladeRF.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_bladeRF.conf index e751730de..c2ec58cd6 100644 --- a/conf/gnss-sdr_GPS_L1_bladeRF.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L1_bladeRF.conf @@ -53,7 +53,7 @@ InputFilter.band2_error=1.0 InputFilter.filter_type=bandpass InputFilter.grid_density=16 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through diff --git a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_fmcomms2_realtime.conf similarity index 97% rename from conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_fmcomms2_realtime.conf index df763f64e..deef32d6f 100644 --- a/conf/gnss-sdr_GPS_L1_fmcomms2_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L1_fmcomms2_realtime.conf @@ -41,7 +41,7 @@ SignalSource.gain_rx1=64 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ SignalConditioner.implementation=Signal_Conditioner @@ -52,7 +52,7 @@ DataTypeAdapter.implementation=Pass_Through ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float diff --git a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_plutosdr_realtime.conf similarity index 100% rename from conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_plutosdr_realtime.conf diff --git a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf similarity index 98% rename from conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf index 370931cca..000e2cb18 100644 --- a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf @@ -43,7 +43,7 @@ SignalSource.AGC_enabled = false SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat SignalSource.address=127.0.0.1 SignalSource.port=1234 SignalSource.swap_iq=false @@ -58,7 +58,7 @@ DataTypeAdapter.implementation=Pass_Through ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float diff --git a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L1_rtlsdr_realtime.conf similarity index 98% rename from conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L1_rtlsdr_realtime.conf index 8994bb3f3..149aa8b13 100644 --- a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L1_rtlsdr_realtime.conf @@ -44,7 +44,7 @@ SignalSource.AGC_enabled = false SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;# Please note that the new RTL-SDR Blog V3 dongles ship a < 1 PPM ;# temperature compensated oscillator (TCXO), which is well suited for GNSS @@ -68,7 +68,7 @@ DataTypeAdapter.implementation=Pass_Through ;######### INPUT_FILTER CONFIG ############ InputFilter.implementation=Freq_Xlating_Fir_Filter InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat InputFilter.input_item_type=gr_complex InputFilter.output_item_type=gr_complex InputFilter.taps_item_type=float diff --git a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L2C_USRP1_realtime.conf similarity index 96% rename from conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L2C_USRP1_realtime.conf index cffb6f9b0..74e1fdbf0 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP1_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L2C_USRP1_realtime.conf @@ -39,7 +39,7 @@ SignalSource.subdevice=A:0 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ @@ -73,13 +73,13 @@ InputFilter.sampling_frequency=20000000 InputFilter.IF=-1600000 InputFilter.decimation_factor=1 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat Resampler.item_type=gr_complex Resampler.sample_freq_in=2000000 Resampler.sample_freq_out=2000000 diff --git a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf b/conf/RealTime_input/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf similarity index 96% rename from conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf rename to conf/RealTime_input/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf index a221b7169..9bf551da0 100644 --- a/conf/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_GPS_L2C_USRP_X300_realtime.conf @@ -42,7 +42,7 @@ SignalSource.subdevice=A:0 SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ @@ -79,12 +79,12 @@ InputFilter.sampling_frequency=4000000 InputFilter.IF=0 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat Resampler.item_type=gr_complex Resampler.sample_freq_in=4000000 Resampler.sample_freq_out=4000000 diff --git a/conf/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf b/conf/RealTime_input/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf similarity index 96% rename from conf/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf rename to conf/RealTime_input/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf index b49801d10..fe0ca55d2 100644 --- a/conf/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_Galileo_E1_USRP_X300_realtime.conf @@ -27,7 +27,7 @@ SignalSource.gain=50 SignalSource.subdevice=A:0 SignalSource.samples=0 SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat +SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ @@ -62,7 +62,7 @@ Tracking_1B.order=3; Tracking_1B.early_late_space_chips=0.15; Tracking_1B.very_early_late_space_chips=0.6; Tracking_1B.dump=false -Tracking_1B.dump_filename=../data/veml_tracking_ch_ +Tracking_1B.dump_filename=./veml_tracking_ch_ ;######### TELEMETRY DECODER CONFIG ############ diff --git a/conf/RealTime_input/gnss-sdr_multichannel_GPS_Galileo_Beidou_Glonass_L1_USRP_realtime.conf b/conf/RealTime_input/gnss-sdr_multichannel_GPS_Galileo_Beidou_Glonass_L1_USRP_realtime.conf new file mode 100644 index 000000000..6ed59bd79 --- /dev/null +++ b/conf/RealTime_input/gnss-sdr_multichannel_GPS_Galileo_Beidou_Glonass_L1_USRP_realtime.conf @@ -0,0 +1,281 @@ +; This is a GNSS-SDR configuration file +; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/ +; SPDX-License-Identifier: GPL-3.0-or-later +; SPDX-FileCopyrightText: (C) 2010-2020 (see AUTHORS file for a list of contributors) + +; You can define your own receiver and invoke it by doing +; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf +; + +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=8000000 +GNSS-SDR.Beidou_banned_prns=56,57,58 + + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=Osmosdr_Signal_Source +SignalSource.item_type=gr_complex +SignalSource.sampling_frequency=56000000 +SignalSource.freq=1584000000 +SignalSource.osmosdr_args=uhd,type=b200,num_recv_frames=256 +SignalSource.gain=50 +SignalSource.antenna=TX/RX +SignalSource.if_bw=56000000 +SignalSource.AGC_enabled=false +SignalSource.samples=0 +SignalSource.repeat=false +SignalSource.RF_channels=3 +SignalSource.enable_throttle_control=false +SignalSource.dump=false + + + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner0.implementation=Signal_Conditioner +SignalConditioner1.implementation=Signal_Conditioner +SignalConditioner2.implementation=Signal_Conditioner + +;######### DATA_TYPE_ADAPTER CONFIG ############ +DataTypeAdapter0.implementation=Pass_Through +DataTypeAdapter1.implementation=Pass_Through +DataTypeAdapter2.implementation=Pass_Through + +;######### INPUT_FILTER CONFIG ############ +InputFilter0.implementation=Freq_Xlating_Fir_Filter +InputFilter0.decimation_factor=7 +InputFilter0.input_item_type=gr_complex +InputFilter0.output_item_type=gr_complex +InputFilter0.taps_item_type=float +InputFilter0.filter_type=lowpass +InputFilter0.bw=7000000 +InputFilter0.tw=500000 +InputFilter0.IF=-22902000 +InputFilter0.sampling_frequency=56000000 +InputFilter0.dump=false +InputFilter0.dump_filename=./input_filter.dat + +;######### INPUT_FILTER CONFIG ############ +InputFilter1.implementation=Freq_Xlating_Fir_Filter +InputFilter1.decimation_factor=7 +InputFilter1.input_item_type=gr_complex +InputFilter1.output_item_type=gr_complex +InputFilter1.taps_item_type=float +InputFilter1.filter_type=lowpass +InputFilter1.bw=7000000 +InputFilter1.tw=500000 +InputFilter1.IF=-8580000 +InputFilter1.sampling_frequency=56000000 +InputFilter1.dump=false +InputFilter1.dump_filename=./input_filter.dat + +;######### INPUT_FILTER CONFIG ############ +InputFilter2.implementation=Freq_Xlating_Fir_Filter +InputFilter2.decimation_factor=7 +InputFilter2.input_item_type=gr_complex +InputFilter2.output_item_type=gr_complex +InputFilter2.taps_item_type=float +InputFilter2.filter_type=lowpass +InputFilter2.bw=7000000 +InputFilter2.tw=500000 +InputFilter2.IF=18000000 +InputFilter2.sampling_frequency=56000000 +InputFilter2.dump=false +InputFilter2.dump_filename=./input_filter.dat + +;######### RESAMPLER CONFIG ############ +Resampler0.implementation=Pass_Through +Resampler1.implementation=Pass_Through +Resampler2.implementation=Pass_Through + +;######### CHANNELS GLOBAL CONFIG ############ +Channels_1B.count=10 +Channels_1C.count=10 +Channels_B1.count=14 +Channels_1G.count=8 + +Channels_1B.RF_channel_ID=1 +Channels_1C.RF_channel_ID=1 +Channels_B1.RF_channel_ID=0 +Channels_1G.RF_channel_ID=2 + + +Channels.in_acquisition=2 + +;######### ACQUISITION BEIDOU CONFIG ############ +Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition +Acquisition_B1.item_type=gr_complex +Acquisition_B1.coherent_integration_time_ms=2 +;Acquisition_B1.max_dwells=2 +;Acquisition_B1.pfa=0.02 +Acquisition_B1.pfa=0.000002 +Acquisition_B1.doppler_max=6000 +Acquisition_B1.doppler_step=100 +Acquisition_B1.dump=false +Acquisition_B1.dump_filename=./bds_acq +;Acquisition_B1.blocking=true +Acquisition_B1.bit_transition_flag = false; + +;######### ACQUISITION GPS CONFIG ############ +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.item_type=gr_complex +Acquisition_1C.coherent_integration_time_ms=1 +Acquisition_1C.pfa=0.015 +Acquisition_1C.doppler_max=6000 +Acquisition_1C.doppler_step=200 +Acquisition_1C.max_dwells=4 +;Acquisition_1C.blocking=true +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + +;######### ACQUISITION GALILEO CONFIG ############ +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +Acquisition_1B.coherent_integration_time_ms=2 +;Acquisition_1B.pfa=0.000008 +Acquisition_1B.pfa=0.025 +Acquisition_1B.doppler_max=6000 +Acquisition_1B.doppler_step=200 +Acquisition_1B.max_dwells=4 +;Acquisition_1B.repeat_satellite=true +Acquisition_1B.cboc=true +;Acquisition_1B.blocking=true +Acquisition_1B.dump=false +Acquisition_1B.dump_filename=./acq_dump.dat + +;######### ACQUISITION GLONASS CONFIG ############ +Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition +Acquisition_1G.item_type=gr_complex +Acquisition_1G.coherent_integration_time_ms=1 +Acquisition_1G.max_dwells=4 +Acquisition_1G.pfa=0.02 +Acquisition_1G.doppler_max=6000 +Acquisition_1G.doppler_step=100 +Acquisition_1G.dump=false +Acquisition_1G.dump_filename=./G1_acq + + + +;######### TRACKING BEIDOU CONFIG ############ +Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking +Tracking_B1.item_type=gr_complex +Tracking_B1.extend_correlation_symbols=10 +Tracking_B1.pll_bw_hz=50.0 +Tracking_B1.dll_bw_hz=2.00 +Tracking_B1.pll_bw_narrow_hz=15.0 +Tracking_B1.dll_bw_narrow_hz=1.50 +;Tracking_B1.cn0_min=20 +;Tracking_B1.fll_bw_hz=20 +;Tracking_B1.enable_fll_pull_in=true +;Tracking_B1.enable_fll_steady_state=false +Tracking_B1.dump=false +Tracking_B1.dump_filename=./epl_tracking_ch_ + +;######### TRACKING GPS CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.extend_correlation_symbols=10 +Tracking_1C.early_late_space_chips=0.5 +Tracking_1C.early_late_space_narrow_chips=0.15 +Tracking_1C.pll_bw_hz=30.0 +Tracking_1C.dll_bw_hz=2.0 +Tracking_1C.pll_bw_narrow_hz=10.0 +Tracking_1C.dll_bw_narrow_hz=1.50 +Tracking_1C.fll_bw_hz=10 +Tracking_1C.enable_fll_pull_in=true +Tracking_1C.enable_fll_steady_state=false +Tracking_1C.dump=false +Tracking_1C.dump_filename=tracking_ch_ + +;######### TRACKING GALILEO CONFIG ############ +Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking +Tracking_1B.extend_correlation_symbols=4 +Tracking_1B.item_type=gr_complex +Tracking_1B.pll_bw_hz=30.0 +Tracking_1B.dll_bw_hz=2.0 +Tracking_1B.pll_bw_narrow_hz=20.0 +Tracking_1B.dll_bw_narrow_hz=1.50 +Tracking_1B.track_pilot=true +Tracking_1B.enable_fll_pull_in=true; +Tracking_1B.enable_fll_steady_state=false +Tracking_1B.fll_bw_hz=20 + +;######### TRACKING GLONASS CONFIG ############ +Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking +Tracking_1G.item_type=gr_complex +Tracking_1G.pll_bw_hz=40 +Tracking_1G.dll_bw_hz=2.5 +Tracking_1G.extend_correlation_ms=1 +Tracking_1G.pll_bw_narrow_hz=20 +Tracking_1G.dll_bw_narrow_hz=1.5 +Tracking_1G.dump=false +Tracking_1G.dump_filename=./epl_tracking_ch_ + + + +;######### TELEMETRY DECODER BEIDOU CONFIG ############ +TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder +TelemetryDecoder_B1.dump=false + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1C.dump=false + +;######### TELEMETRY DECODER GALILEO E1B CONFIG ############ +TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder +TelemetryDecoder_1B.dump=false + +;######### TELEMETRY DECODER GLONASS CONFIG ############ +TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1G.dump=false + + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false +Observables.dump_filename=./observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.threshold_reject_GDOP=100 +PVT.elevation_mask=3 +PVT.raim_fde=1 +PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX +PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.enable_rx_clock_correction=true +PVT.flag_rtcm_server=true +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=2 +PVT.flag_nmea_tty_port=true +PVT.nmea_dump_devname=/dev/pts/3 + +; To use gpsd with GNSS-SDR +; 1. run socat -d -d pty,raw,echo=0 pty,raw,echo=0 +; 2. Set PVT.nmea_dump_devname to first PTY from socat output +; 3. run gpsd -b -n -N /dev/pts/4 +; where /dev/pts/4 is the second PTY from socat output +; 4. run some gpsd client (xgps or other) + + + +PVT.enable_monitor=true +PVT.monitor_client_addresses=127.0.0.1 +PVT.monitor_udp_port=1111 + +Monitor.enable_monitor=true +Monitor.decimation_factor=4 +Monitor.client_addresses=127.0.0.1 +Monitor.udp_port=1112 + +;AcquisitionMonitor.enable_monitor=true +AcquisitionMonitor.client_addresses=127.0.0.1 +AcquisitionMonitor.udp_port=1112 + + diff --git a/conf/RealTime_input/gnss-sdr_multichannel_GPS_Galileo_Beidou_L1_hackrf_realtime.conf b/conf/RealTime_input/gnss-sdr_multichannel_GPS_Galileo_Beidou_L1_hackrf_realtime.conf new file mode 100644 index 000000000..05ff16b75 --- /dev/null +++ b/conf/RealTime_input/gnss-sdr_multichannel_GPS_Galileo_Beidou_L1_hackrf_realtime.conf @@ -0,0 +1,237 @@ +; This is a GNSS-SDR configuration file +; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/ +; SPDX-License-Identifier: GPL-3.0-or-later +; SPDX-FileCopyrightText: (C) 2010-2020 (see AUTHORS file for a list of contributors) + +; You can define your own receiver and invoke it by doing +; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf +; + +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=4000000 +GNSS-SDR.Beidou_banned_prns=56,57,58 + + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource.implementation=Osmosdr_Signal_Source +SignalSource.item_type=gr_complex +SignalSource.sampling_frequency=20000000 +SignalSource.freq=1567420000 +SignalSource.if_bw=18000000 +;# Next line enables the internal HackRF One bias (3.3 VDC) +SignalSource.osmosdr_args=hackrf=0,bias=1,buffers=256 +SignalSource.gain=0 +SignalSource.rf_gain=40 +SignalSource.if_gain=40 +SignalSource.AGC_enabled=false +SignalSource.samples=0 +SignalSource.repeat=false +SignalSource.RF_channels=2 +SignalSource.enable_throttle_control=false +SignalSource.dump=false + + + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner0.implementation=Signal_Conditioner +SignalConditioner1.implementation=Signal_Conditioner + +;######### DATA_TYPE_ADAPTER CONFIG ############ +DataTypeAdapter0.implementation=Pass_Through +DataTypeAdapter1.implementation=Pass_Through + +;######### INPUT_FILTER CONFIG ############ +InputFilter0.implementation=Freq_Xlating_Fir_Filter +;InputFilter0.implementation=Pass_Through +InputFilter0.decimation_factor=5 +InputFilter0.input_item_type=gr_complex +InputFilter0.output_item_type=gr_complex +InputFilter0.taps_item_type=float +InputFilter0.filter_type=lowpass +InputFilter0.bw=3000000 +InputFilter0.tw=1000000 +InputFilter0.IF=-6322000 +InputFilter0.sampling_frequency=20000000 +InputFilter0.dump=false +InputFilter0.dump_filename=./input_filter.dat + +;######### INPUT_FILTER CONFIG ############ +InputFilter1.implementation=Freq_Xlating_Fir_Filter +;InputFilter1.implementation=Pass_Through +InputFilter1.decimation_factor=5 +InputFilter1.input_item_type=gr_complex +InputFilter1.output_item_type=gr_complex +InputFilter1.taps_item_type=float +InputFilter1.filter_type=lowpass +InputFilter1.bw=3000000 +InputFilter1.tw=1000000 +InputFilter1.IF=8000000 +InputFilter1.sampling_frequency=20000000 +InputFilter1.dump=false +InputFilter1.dump_filename=./input_filter.dat + + + + + +;######### RESAMPLER CONFIG ############ +Resampler0.implementation=Pass_Through +Resampler1.implementation=Pass_Through + +;######### CHANNELS GLOBAL CONFIG ############ +Channels_1B.count=10 +Channels_1C.count=10 +Channels_B1.count=14 + +Channels_1B.RF_channel_ID=1 +Channels_1C.RF_channel_ID=1 +Channels_B1.RF_channel_ID=0 + + + +Channels.in_acquisition=10 + +;######### ACQUISITION BEIDOU CONFIG ############ +Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition +Acquisition_B1.item_type=gr_complex +Acquisition_B1.coherent_integration_time_ms=2 +;Acquisition_B1.max_dwells=2 +;Acquisition_B1.pfa=0.02 +Acquisition_B1.pfa=0.000002 +Acquisition_B1.doppler_max=3800 +Acquisition_B1.doppler_step=100 +Acquisition_B1.dump=false +Acquisition_B1.dump_filename=./bds_acq +;Acquisition_B1.blocking=true +Acquisition_B1.bit_transition_flag = false; + +;######### ACQUISITION GPS CONFIG ############ +Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition +Acquisition_1C.item_type=gr_complex +Acquisition_1C.coherent_integration_time_ms=1 +Acquisition_1C.pfa=0.015 +Acquisition_1C.doppler_max=5000 +Acquisition_1C.doppler_step=200 +Acquisition_1C.max_dwells=4 +;Acquisition_1C.blocking=true +Acquisition_1C.dump=false +Acquisition_1C.dump_filename=./acq_dump.dat + +;######### ACQUISITION GALILEO CONFIG ############ +Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition +Acquisition_1B.coherent_integration_time_ms=2 +;Acquisition_1B.pfa=0.000008 +Acquisition_1B.pfa=0.025 +Acquisition_1B.doppler_max=5000 +Acquisition_1B.doppler_step=200 +Acquisition_1B.max_dwells=4 +;Acquisition_1B.repeat_satellite=true +Acquisition_1B.cboc=true +;Acquisition_1B.blocking=true +Acquisition_1B.dump=false +Acquisition_1B.dump_filename=./acq_dump.dat + + + + +;######### TRACKING BEIDOU CONFIG ############ +Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking +Tracking_B1.item_type=gr_complex +Tracking_B1.extend_correlation_symbols=10 +Tracking_B1.pll_bw_hz=30.0 +Tracking_B1.dll_bw_hz=2.00 +Tracking_B1.pll_bw_narrow_hz=15.0 +Tracking_B1.dll_bw_narrow_hz=0.50 +;Tracking_B1.cn0_min=20 +Tracking_B1.fll_bw_hz=20 +Tracking_B1.enable_fll_pull_in=true +Tracking_B1.enable_fll_steady_state=false +Tracking_B1.dump=false +Tracking_B1.dump_filename=./epl_tracking_ch_ + +;######### TRACKING GPS CONFIG ############ +Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking +Tracking_1C.item_type=gr_complex +Tracking_1C.extend_correlation_symbols=10 +Tracking_1C.early_late_space_chips=0.5 +Tracking_1C.early_late_space_narrow_chips=0.15 +Tracking_1C.pll_bw_hz=30.0 +Tracking_1C.dll_bw_hz=2.0 +Tracking_1C.pll_bw_narrow_hz=10.0 +Tracking_1C.dll_bw_narrow_hz=0.50 +Tracking_1C.fll_bw_hz=10 +Tracking_1C.enable_fll_pull_in=true +Tracking_1C.enable_fll_steady_state=false +Tracking_1C.dump=false +Tracking_1C.dump_filename=tracking_ch_ + +;######### TRACKING GALILEO CONFIG ############ +Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking +Tracking_1B.extend_correlation_symbols=4 +Tracking_1B.item_type=gr_complex +Tracking_1B.pll_bw_hz=30.0 +Tracking_1B.dll_bw_hz=2.0 +Tracking_1B.pll_bw_narrow_hz=20.0 +Tracking_1B.dll_bw_narrow_hz=0.50 +Tracking_1B.track_pilot=true +Tracking_1B.enable_fll_pull_in=true; +Tracking_1B.enable_fll_steady_state=false +Tracking_1B.fll_bw_hz=20 + + +;######### TELEMETRY DECODER BEIDOU CONFIG ############ +TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder +TelemetryDecoder_B1.dump=false + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder +TelemetryDecoder_1C.dump=false + +;######### TELEMETRY DECODER GALILEO E1B CONFIG ############ +TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder +TelemetryDecoder_1B.dump=false + + + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false +Observables.dump_filename=./observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.threshold_reject_GDOP=100 +PVT.elevation_mask=4 +PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX +PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.enable_rx_clock_correction=true +PVT.flag_rtcm_server=true +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=2 +PVT.flag_nmea_tty_port=true +PVT.nmea_dump_devname=/dev/pts/3 + + +PVT.enable_monitor=true +PVT.monitor_client_addresses=127.0.0.1 +PVT.monitor_udp_port=1111 + +Monitor.enable_monitor=true +Monitor.decimation_factor=4 +Monitor.client_addresses=127.0.0.1 +Monitor.udp_port=1112 + +AcquisitionMonitor.enable_monitor=true +AcquisitionMonitor.client_addresses=127.0.0.1 +AcquisitionMonitor.udp_port=1112 + + diff --git a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf b/conf/RealTime_input/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf similarity index 97% rename from conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf rename to conf/RealTime_input/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf index 61f18e09f..de70827ed 100644 --- a/conf/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf +++ b/conf/RealTime_input/gnss-sdr_multichannel_GPS_L1_USRP_X300_realtime.conf @@ -59,7 +59,7 @@ DataTypeAdapter0.item_type=gr_complex ;######### INPUT_FILTER 0 CONFIG ############ InputFilter0.implementation=Pass_Through InputFilter0.dump=false -InputFilter0.dump_filename=../data/input_filter.dat +InputFilter0.dump_filename=./input_filter.dat InputFilter0.input_item_type=gr_complex InputFilter0.output_item_type=gr_complex @@ -74,7 +74,7 @@ SignalConditioner1.implementation=Pass_Through ;######### INPUT_FILTER 1 CONFIG ############ InputFilter1.implementation=Pass_Through InputFilter1.dump=false -InputFilter1.dump_filename=../data/input_filter.dat +InputFilter1.dump_filename=./input_filter.dat InputFilter1.input_item_type=gr_complex InputFilter1.output_item_type=gr_complex diff --git a/conf/gnss-sdr.conf b/conf/gnss-sdr.conf index 3f4b61766..16cb1e865 100644 --- a/conf/gnss-sdr.conf +++ b/conf/gnss-sdr.conf @@ -68,13 +68,13 @@ InputFilter.grid_density=16 InputFilter.sampling_frequency=4000000 InputFilter.IF=0 InputFilter.dump=false -InputFilter.dump_filename=../data/input_filter.dat +InputFilter.dump_filename=./input_filter.dat ;######### RESAMPLER CONFIG ############ Resampler.implementation=Pass_Through Resampler.dump=false -Resampler.dump_filename=../data/resampler.dat +Resampler.dump_filename=./resampler.dat ;######### CHANNELS GLOBAL CONFIG ############ @@ -113,7 +113,7 @@ Tracking_1C.pll_bw_hz=45.0; Tracking_1C.dll_bw_hz=3.0; Tracking_1C.order=3; Tracking_1C.dump=false -Tracking_1C.dump_filename=../data/epl_tracking_ch_ +Tracking_1C.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ diff --git a/data/.gitignore b/data/.gitignore deleted file mode 100644 index 08e486f4d..000000000 --- a/data/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 20d3ae65d..09f08e120 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,7 +4,7 @@ SPDX-License-Identifier: GPL-3.0-or-later ) [comment]: # ( -SPDX-FileCopyrightText: 2011-2024 Carles Fernandez-Prades +SPDX-FileCopyrightText: 2011-2025 Carles Fernandez-Prades ) @@ -12,6 +12,145 @@ SPDX-FileCopyrightText: 2011-2024 Carles Fernandez-Prades = 3.24, otherwise it has no effect). This change has a downside in + maintainability, since the source code becomes plagued with preprocessor + directives required to maintain compatibility both with gflags and glog, and + with Abseil. +- Historically, GNSS-SDR linked against the GnuTLS library for cryptographic + functions. If GnuTLS was not found, then the building system looked for and + linked against OpenSSL as a fallback. This was due to the OpenSSL 1.x dual + license scheme, which was incompatible with GPL v3.0 license, preventing it + from being a mandatory dependency for GNSS-SDR in most GNU/Linux + distributions. This issue was solved with the release of OpenSSL 3.0.0, which + transitioned to the Apache License 2.0, fully compatible with GPL v3.0. + Accordingly, the GNSS-SDR building system now looks for OpenSSL in the first + place and, if not found, then it looks for GnuTLS as a fallback. The new CMake + configuration option `-DENABLE_GNUTLS=ON` allows linking against GnuTLS + instead of OpenSSL. +- Allow linking against Boost 1.87.0. +- Replace the System V queues by boost::interprocess, improving portability. +- Improve detection of Homebrew or Macports in macOS. + +### Improvements in Reliability + +- Implementation of the Galileo Open Service Navigation Message Authentication + (OSNMA), a data authentication function for the Galileo Open Service worldwide + users, freely accessible to all. OSNMA provides receivers with the assurance + that the received Galileo navigation message is coming from the system itself + and has not been modified. OSNMA is enabled by default if the receiver + configuration defines Galileo E1 OS channels. More details can be found in + [Introducing GNSS Navigation Message Authentication](https://gnss-sdr.org/osnma). + +### Improvements in Usability: + +- Tidy up the `conf/` folder. +- Add `install` and `uninstall` targets to the `nav_msg_listener` utility. +- **Potential Breaking Change**: The source tree has been refactored to follow a + more conventional folder structure. This may disrupt user pipelines that + relied on the previous structure and could break development branches that + were branched off from `next` before this change. The key changes are: + + - The `tests` and `utils` directories have been moved from the `src` folder to + the root of the source tree. + - The empty `build` and `data` folders have been removed. Users can create a + building folder using `mkdir build` or by having CMake handle it: + `cmake -S . -B build`. + - All default names for dump or input files starting with `../data/` + have been changed to `./`. + +See the definitions of concepts and metrics at +https://gnss-sdr.org/design-forces/ + +  + +## [GNSS-SDR v0.0.19.1](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.19.1) - 2024-01-26 + +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.10579595.svg)](https://doi.org/10.5281/zenodo.10579595) + +- Fix formatting of the `CITATION.cff` file. + ## [GNSS-SDR v0.0.19](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.19) - 2024-01-23 ### Improvements in Efficiency: @@ -83,14 +222,14 @@ All notable changes to GNSS-SDR will be documented in this file. user pressing Ctrl+C, or another user application sending an interruption signal). - The estimated CN0 value is now printed in the terminal when navigation data is - succesfully decoded. + successfully decoded. - Fixed GPS navigation message satellite validation. - Latitude and longitude are now reported in the terminal with six decimal places (the sixth decimal place worths up to 0.11 m), instead of the overkilling nine (the ninth decimal place worths up to 110 microns). Similarly, height in meters is now reported with two decimal places instead of three, and velocity in m/s also with two decimal places instead of three. -- Fixed the rate at which KLM, GPX, GeoJSON, and NMEA annotations are made. The +- Fixed the rate at which KML, GPX, GeoJSON, and NMEA annotations are made. The rate is now set by `PVT.output_rate_ms` (`500` ms by default), and can be particularized by `PVT.kml_rate_ms`, `PVT.gpx_rate_ms`, `PVT.geojson_rate_ms`, and `PVT.nmea_rate_ms`. Those values should be multiples of @@ -167,22 +306,22 @@ https://gnss-sdr.org/design-forces/ - Fixed linking against libunwind when the glog library is built locally. - The configuration options at building time `-DENABLE_OWN_GLOG`, `-DENABLE_OWN_ARMADILLO`, and `-DENABLE_OWN_GNSSTK` can now be switched `ON` - and `OFF` without the need to start from an empty buiding folder. + and `OFF` without the need to start from an empty building folder. - Improved CMake handling of the spdlog library used by GNU Radio >= 3.10. - Make use of the C++20 standard if the environment allows for it. - Improved passing of compiler flags to `volk_gnsssdr` if the corresponding environment variables are defined. This fixes warnings in some packaging systems. - Improved support for the RISC-V architecture. -- Test files are now donwloaded at configuration time instead of being included +- Test files are now downloaded at configuration time instead of being included in the source tree. This allows for a smaller package and fixes Lintian `very-long-line-length-in-source-file` warnings since those files were not recognized as binaries. The configuration flag `-DENABLE_PACKAGING=ON` passed to CMake deactivates file downloading. - The `ENABLE_GENERIC_ARCH` building option was removed, simplifying the process - of buiding the software in non-x86 processor architectures. + of building the software in non-x86 processor architectures. - If the Protocol Buffers dependency is not found, it is downloaded, built and - statically linked at buiding time. If CMake >= 3.13 and the + statically linked at building time. If CMake >= 3.13 and the [Abseil C++ libraries](https://github.com/abseil/abseil-cpp) >= 20230117 are installed on your system, Protocol Buffers v22.2 will be used. If those requirements are not met, Protocol Buffers v21.4 will be used instead @@ -306,7 +445,7 @@ https://gnss-sdr.org/design-forces/ - Fixed building against GNU Radio v3.10.X.Y, which does not support the C++20 standard. - Fixed building against GNU Radio v3.10.X.Y, which replaced - [log4cpp](http://log4cpp.sourceforge.net/) by the + [log4cpp](https://log4cpp.sourceforge.net/) by the [spdlog](https://github.com/gabime/spdlog) and [fmt](https://github.com/fmtlib/fmt) libraries. - Updated `cpu_features` library for improved processor detection. @@ -453,8 +592,7 @@ https://gnss-sdr.org/design-forces/ inconsistencies in the configuration file. - Fix segmentation fault if the RINEX output was disabled. - Added a feature that optionally enables the remote monitoring of GPS and - Galileo ephemeris using UDP and - [Protocol Buffers](https://developers.google.com/protocol-buffers). + Galileo ephemeris using UDP and [Protocol Buffers](https://protobuf.dev/). - Now building the software passing the `-DENABLE_FPGA=ON` to CMake does not make the receiver unusable when running on non-FPGA-enabled platforms. On FPGA-enabled platforms, now it is possible to run non-FPGA-enabled diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 0968c3eb9..d5de316d6 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -77,19 +77,19 @@ As outputs, it provides: In principle, GNSS-SDR can be built in any Unix-like system. In practice, it depends on being able to install all the required dependencies. See the building guide page for details about the project's dependencies and build process. Mainly, it consists on installing GNU Radio plus some few more libraries: -\li Armadillo, a C++ linear algebra library, +\li Armadillo, a C++ linear algebra library, \li Boost, a set of free peer-reviewed portable C++ source libraries, \li Gflags, a library that implements commandline flags processing, \li Glog, a library that implements application-level logging, \li Googletest, Google's framework for writing C++ tests, \li Mako, a template library written in Python, \li Matio, a MATLAB MAT File I/O Library, -\li Protocol Buffers, a language-neutral, platform-neutral extensible mechanism for serializing structured data, +\li Protocol Buffers, a language-neutral, platform-neutral extensible mechanism for serializing structured data, \li PugiXML, a light-weight, simple and fast XML parser for C++ with XPath support, \li Volk, a Vector-Optimized Library of Kernels which provides an abstraction of optimized math routines targeting several SIMD processors, and, optionally, -\li GNU Radio modules for hardware interface (gr-uhd, gr-osmosdr, gr-iio), +\li GNU Radio modules for hardware interface (gr-uhd, gr-osmosdr, gr-iio), \li Benchmark, a library to benchmark code snippets, \li Gperftools, which provides fast, multi-threaded malloc() and performance analysis tools. @@ -101,10 +101,8 @@ $ git clone https://github.com/gnss-sdr/gnss-sdr This will create a folder named gnss-sdr with the following structure: \verbatim |-gnss-sdr - |---build <- where gnss-sdr is built |---cmake <- CMake-related files |---conf <- Configuration files. Each file represents one receiver. - |---data <- Populate this folder with your captured data. |---docs <- Contains documentation-related files |---install <- Executables |---src <- Source code folder @@ -127,13 +125,13 @@ This will create a folder named gnss-sdr with the following structure: |-------receiver |-------system_parameters |-----main - |-----tests - |-----utils <- some utilities (e.g. Matlab scripts) + |---tests + |---utils <- some utilities (e.g. Matlab scripts) \endverbatim You are now ready to build GNSS-SDR by using CMake as building tool: \verbatim -$ cd gnss-sdr/build +$ cd gnss-sdr && mkdir build && cd build $ cmake .. $ make \endverbatim @@ -153,10 +151,10 @@ You can create the documentation by doing: $ make doc \endverbatim -from the gnss-sdr/build folder. In both cases, Doxygen will generate HTML documentation that can be +from the building folder. In both cases, Doxygen will generate HTML documentation that can be retrieved pointing your browser of preference to gnss-sdr/docs/html/index.html. -There are two more extra targets available. From the gnss-sdr/build folder: +There are two more extra targets available. In the building folder: \verbatim $ make doc-clean \endverbatim @@ -167,7 +165,7 @@ $ make pdfmanual will create a PDF manual at gnss-sdr/docs/GNSS-SDR_manual.pdf. Please note that the PDF generation requires some fonts to be installed on the host system. In Ubuntu, those fonts do not come by default. You can install them by doing: \verbatim -$ sudo apt-get install texlive-fonts-recommended +$ sudo apt install texlive-fonts-recommended \endverbatim and then run cmake ../ and make pdfmanual again. @@ -177,10 +175,9 @@ By default, CMake will build the Release version, meaning that the compiler will a RF front-end and you need to attain real time. If working with a file (and thus without real-time constraints), you may want to obtain more information about the internals of the receiver, as well as more fine-grained logging. This can be done by building the Debug version, by doing: \verbatim -$ cd gnss-sdr/build +$ cd gnss-sdr && mkdir build-debug && cd build-debug $ cmake -DCMAKE_BUILD_TYPE=Debug .. $ make -$ sudo make install \endverbatim \subsection updating_gnss-sdr Updating GNSS-SDR @@ -189,10 +186,10 @@ If you checked out GNSS-SDR some days ago, it is possible that some developer ha $ git checkout next $ git pull https://github.com/gnss-sdr/gnss-sdr next \endverbatim -Before rebuiling the source code, it is safe (and recommended) to remove the remainders of old builds: +Before rebuilding the source code, it is safe (and recommended) to remove the remainders of old builds: \verbatim -$ cd gnss-sdr/build -$ sudo make uninstall +$ cd +$ sudo make uninstall ; if you installed it before $ rm -rf * \endverbatim @@ -215,7 +212,7 @@ and we will be happy to upload it to the server. You can use a single configuration file for processing different data files, specifying the file to be processed with the --signal_source flag: \verbatim -$ gnss-sdr --config_file=../conf/my_receiver.conf --signal_source=../data/my_captured_data.dat +$ gnss-sdr --config_file=../conf/my_receiver.conf --signal_source=./my_captured_data.dat \endverbatim This will override the SignalSource.filename specified in the configuration file. @@ -636,7 +633,7 @@ More papers related to GNSS-SDR are available at the gnss-sdr/install folder, running ./gnss-sdr, and see how the file is processed. Please ask the Developer Team for a signal sample if you need one, and they will do their best ;-) diff --git a/docs/doxygen/other/reference_docs.dox b/docs/doxygen/other/reference_docs.dox index 00af2e1a2..5871776d5 100644 --- a/docs/doxygen/other/reference_docs.dox +++ b/docs/doxygen/other/reference_docs.dox @@ -153,7 +153,7 @@ automatically selected by the CMake script): You can get it from ISO, IEC - or ANSI. The closest free working document available is ISO, IEC - or ANSI. The closest free working document available is N4659.
  • C++14: A former ISO C++ standard was officially known as ISO International Standard ISO/IEC 14882:2014 – Programming languages – C++. You can get it from ISO or ANSI. The closest free working document available is N4296.
  • C++11: An older ISO C++ standard was ISO/IEC 14882:2011. You can get it from ISO. The closest free working document available is N3337.
  • @@ -207,7 +207,7 @@ User plane protocols: \li Open Mobile Alliance (OMA), Secure User Plane Location Architecture Version 2 (SUPL 2.0), April 2012. LTE Release 9 introduced extension hooks in LPP messages, so that the bodies external to 3GPP could extend the LPP feature set. OMA LPP extensions (LPPe), supported in SUPL 3.0, build on top of the 3GPP LPP reusing its procedures and data types. -Check the OMA Specifications webpage for updated information about LPP Extensions (LPPe) Specification. +Check the OMA Specifications webpage for updated information about LPP Extensions (LPPe) Specification. \li The OMA Mobile Location Protocol (MLP) V3.5 is an application-level protocol for getting the position of mobile stations diff --git a/docs/manpage/gnss-sdr-manpage b/docs/manpage/gnss-sdr-manpage index 60e2564e4..958ffbe6a 100644 --- a/docs/manpage/gnss-sdr-manpage +++ b/docs/manpage/gnss-sdr-manpage @@ -2,7 +2,7 @@ .\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-FileCopyrightText: Carles Fernandez-Prades .\" Contact carles.fernandez@cttc.es to correct errors or typos. -.TH gnss\-sdr 1 "23 Jan 2024" "0.0.19" "gnss\-sdr man page" +.TH gnss\-sdr 1 "1 Apr 2025" "0.0.20" "gnss\-sdr man page" .SH NAME \fBgnss\-sdr\fR \- GNSS Software Defined Receiver. .SH SYNOPSIS diff --git a/docs/protobuf/README.md b/docs/protobuf/README.md index a555ae44c..438a9d66d 100644 --- a/docs/protobuf/README.md +++ b/docs/protobuf/README.md @@ -11,9 +11,8 @@ SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades Files in this folder describe structured data formats that are generated by -GNSS-SDR. They use -[Protocol Buffers](https://developers.google.com/protocol-buffers/)' -[proto3](https://developers.google.com/protocol-buffers/docs/proto3) syntax. +GNSS-SDR. They use [Protocol Buffers](https://protobuf.dev/)' +[proto3](https://protobuf.dev/programming-guides/proto3/) syntax. From those files, the protocol buffer compiler creates classes that implement automatic encoding and parsing of the protocol buffer data with an efficient diff --git a/docs/xml-schemas/README.md b/docs/xml-schemas/README.md index eae9b1a70..1966290f6 100644 --- a/docs/xml-schemas/README.md +++ b/docs/xml-schemas/README.md @@ -51,6 +51,6 @@ Please check https://gnss-sdr.org/docs/sp-blocks/global-parameters/ for more information about the usage of XML files in GNSS-SDR. You could find useful the utility program -[rinex2assist](https://github.com/gnss-sdr/gnss-sdr/tree/next/src/utils/rinex2assist) +[rinex2assist](https://github.com/gnss-sdr/gnss-sdr/tree/next/utils/rinex2assist) for the generation of compatible XML files from recent, publicly available RINEX navigation data files. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ab56014db..7b3c36c7b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,3 @@ add_subdirectory(algorithms) add_subdirectory(core) add_subdirectory(main) -if(ENABLE_UNIT_TESTING OR ENABLE_SYSTEM_TESTING) - add_subdirectory(tests) -endif() -add_subdirectory(utils) diff --git a/src/algorithms/PVT/adapters/CMakeLists.txt b/src/algorithms/PVT/adapters/CMakeLists.txt index 658e493ac..415fb13d4 100644 --- a/src/algorithms/PVT/adapters/CMakeLists.txt +++ b/src/algorithms/PVT/adapters/CMakeLists.txt @@ -23,10 +23,16 @@ target_link_libraries(pvt_adapters pvt_gr_blocks PRIVATE gnss_sdr_flags - Glog::glog pvt_libs ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(pvt_adapters PRIVATE Glog::glog) + target_compile_definitions(pvt_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(pvt_adapters PRIVATE absl::flags absl::log) +endif() + target_include_directories(pvt_adapters PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index 93166877d..51b3977a1 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -26,8 +26,13 @@ #include "gps_ephemeris.h" // for Gps_Ephemeris #include "pvt_conf.h" // for Pvt_Conf #include "rtklib_rtkpos.h" // for rtkfree, rtkinit -#include // for LOG #include // for std::cout +#include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif #if USE_STD_COMMON_FACTOR #include namespace bc = std; @@ -88,6 +93,7 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration, // RINEX version pvt_output_parameters.rinex_version = configuration->property(role + ".rinex_version", 3); +#if USE_GLOG_AND_GFLAGS if (FLAGS_RINEX_version == "3.01" || FLAGS_RINEX_version == "3.02" || FLAGS_RINEX_version == "3") { pvt_output_parameters.rinex_version = 3; @@ -96,13 +102,29 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration, { pvt_output_parameters.rinex_version = 2; } +#else + if (absl::GetFlag(FLAGS_RINEX_version) == "3.01" || absl::GetFlag(FLAGS_RINEX_version) == "3.02" || absl::GetFlag(FLAGS_RINEX_version) == "3") + { + pvt_output_parameters.rinex_version = 3; + } + else if (absl::GetFlag(FLAGS_RINEX_version) == "2.10" || absl::GetFlag(FLAGS_RINEX_version) == "2.11" || absl::GetFlag(FLAGS_RINEX_version) == "2") + { + pvt_output_parameters.rinex_version = 2; + } +#endif pvt_output_parameters.rinexobs_rate_ms = bc::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), pvt_output_parameters.output_rate_ms); pvt_output_parameters.rinex_name = configuration->property(role + ".rinex_name", std::string("-")); +#if USE_GLOG_AND_GFLAGS if (FLAGS_RINEX_name != "-") { pvt_output_parameters.rinex_name = FLAGS_RINEX_name; } - +#else + if (absl::GetFlag(FLAGS_RINEX_name) != "-") + { + pvt_output_parameters.rinex_name = absl::GetFlag(FLAGS_RINEX_name); + } +#endif // RTCM Printer settings pvt_output_parameters.flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false); pvt_output_parameters.rtcm_dump_devname = configuration->property(role + ".rtcm_dump_devname", default_rtcm_dump_devname); @@ -866,7 +888,7 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration, // Read PVT MONITOR Configuration pvt_output_parameters.monitor_enabled = configuration->property(role + ".enable_monitor", false); pvt_output_parameters.udp_addresses = configuration->property(role + ".monitor_client_addresses", std::string("127.0.0.1")); - pvt_output_parameters.udp_port = configuration->property(role + ".monitor_udp_port", 1234); + pvt_output_parameters.udp_ports = configuration->property(role + ".monitor_udp_port", std::string("1234")); pvt_output_parameters.protobuf_enabled = configuration->property(role + ".enable_protobuf", true); if (configuration->property("Monitor.enable_protobuf", false) == true) { @@ -898,6 +920,17 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration, // Use unhealthy satellites pvt_output_parameters.use_unhealthy_sats = configuration->property(role + ".use_unhealthy_sats", pvt_output_parameters.use_unhealthy_sats); + // OSNMA + if (gal_1B_count > 0) + { + std::string osnma_mode = configuration->property("GNSS-SDR.osnma_mode", std::string("")); + bool enable_osnma = configuration->property("GNSS-SDR.osnma_enable", true); + if (enable_osnma && osnma_mode == "strict") + { + pvt_output_parameters.osnma_strict = true; + } + } + // make PVT object pvt_ = rtklib_make_pvt_gs(in_streams_, pvt_output_parameters, rtk); DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")"; diff --git a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt index ae1b728bf..f516dea42 100644 --- a/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/PVT/gnuradio_blocks/CMakeLists.txt @@ -21,17 +21,23 @@ endif() target_link_libraries(pvt_gr_blocks PUBLIC algorithms_libs_rtklib + Boost::headers Boost::date_time Gnuradio::pmt Gnuradio::runtime PRIVATE algorithms_libs pvt_libs - Gflags::gflags - Glog::glog Boost::serialization ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(pvt_gr_blocks PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(pvt_gr_blocks PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(pvt_gr_blocks PRIVATE absl::log) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(pvt_gr_blocks PUBLIC -DGNURADIO_USES_STD_POINTERS=1 diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index 80b41440a..2bc2ae41a 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -52,6 +52,7 @@ #include "monitor_pvt.h" #include "monitor_pvt_udp_sink.h" #include "nmea_printer.h" +#include "osnma_data.h" #include "pvt_conf.h" #include "rinex_printer.h" #include "rtcm_printer.h" @@ -64,7 +65,6 @@ #include #include #include // for nvp, make_nvp -#include // for LOG #include // for io_signature #include // for mp #include // for sort, unique @@ -77,11 +77,15 @@ #include // for locale #include // for ostringstream #include // for length_error -#include // for IPC_CREAT -#include // for msgctl #include // for std::type_info, typeid #include // for pair +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -124,6 +128,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, : gr::sync_block("rtklib_pvt_gs", gr::io_signature::make(nchannels, nchannels, sizeof(Gnss_Synchro)), gr::io_signature::make(0, 0, 0)), + d_queue_name("gnss_sdr_ttff_message_queue"), d_dump_filename(conf_.dump_filename), d_geohash(std::make_unique()), d_gps_ephemeris_sptr_type_hash_code(typeid(std::shared_ptr).hash_code()), @@ -179,7 +184,8 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, d_an_printer_enabled(conf_.an_output_enabled), d_log_timetag(conf_.log_source_timetag), d_use_has_corrections(conf_.use_has_corrections), - d_use_unhealthy_sats(conf_.use_unhealthy_sats) + d_use_unhealthy_sats(conf_.use_unhealthy_sats), + d_osnma_strict(conf_.osnma_strict) { // Send feedback message to observables block with the receiver clock offset this->message_port_register_out(pmt::mp("pvt_to_observables")); @@ -212,6 +218,19 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, #else boost::bind(&rtklib_pvt_gs::msg_handler_has_data, this, _1)); #endif +#endif + + // Galileo OSNMA messages port in + this->message_port_register_in(pmt::mp("OSNMA_to_PVT")); + this->set_msg_handler(pmt::mp("OSNMA_to_PVT"), +#if HAS_GENERIC_LAMBDA + [this](auto&& PH1) { msg_handler_osnma(PH1); }); +#else +#if USE_BOOST_BIND_PLACEHOLDERS + boost::bind(&rtklib_pvt_gs::msg_handler_osnma, this, boost::placeholders::_1)); +#else + boost::bind(&rtklib_pvt_gs::msg_handler_osnma, this, _1)); +#endif #endif d_initial_carrier_phase_offset_estimation_rads = std::vector(nchannels, 0.0); @@ -462,7 +481,12 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end()); - d_udp_sink_ptr = std::make_unique(udp_addr_vec, conf_.udp_port, conf_.protobuf_enabled); + std::string port_string = conf_.udp_ports; + std::vector udp_port_vec = split_string(port_string, '_'); + std::sort(udp_port_vec.begin(), udp_port_vec.end()); + udp_port_vec.erase(std::unique(udp_port_vec.begin(), udp_port_vec.end()), udp_port_vec.end()); + + d_udp_sink_ptr = std::make_unique(udp_addr_vec, udp_port_vec, conf_.protobuf_enabled); } else { @@ -484,14 +508,26 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, d_eph_udp_sink_ptr = nullptr; } - // Create Sys V message queue + // Create message queue d_first_fix = true; - d_sysv_msg_key = 1101; - const int msgflg = IPC_CREAT | 0666; - if ((d_sysv_msqid = msgget(d_sysv_msg_key, msgflg)) == -1) + const std::size_t max_num_messages = 100; + try { - std::cout << "GNSS-SDR cannot create System V message queues.\n"; - LOG(WARNING) << "The System V message queue is not available. Error: " << errno << " - " << strerror(errno); + // Remove any existing queue with the same name + boost::interprocess::message_queue::remove(d_queue_name.c_str()); + + // Create a new message queue + d_mq = std::make_unique( + boost::interprocess::create_only, // Create a new queue + d_queue_name.c_str(), // Queue name + max_num_messages, // Maximum number of messages + sizeof(double) // Maximum message size + ); + } + + catch (const boost::interprocess::interprocess_exception& e) + { + std::cerr << "Error creating message queue: " << e.what() << std::endl; } // Display time in local time zone @@ -576,9 +612,9 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels, rtklib_pvt_gs::~rtklib_pvt_gs() { DLOG(INFO) << "PVT block destructor called."; - if (d_sysv_msqid != -1) + if (d_mq) { - msgctl(d_sysv_msqid, IPC_RMID, nullptr); + boost::interprocess::message_queue::remove(d_queue_name.c_str()); } try { @@ -1629,6 +1665,28 @@ void rtklib_pvt_gs::msg_handler_has_data(const pmt::pmt_t& msg) } +void rtklib_pvt_gs::msg_handler_osnma(const pmt::pmt_t& msg) +{ + try + { + // Still not sure about what we should receive here. + // It should be a structure with the list of PRNs authenticated (NavData and utcData, + // so with ADKD0 and ADKD12 validated), their corresponding TOW at the beginning + // of the authenticated subframe, and maybe the COP. + const size_t msg_type_hash_code = pmt::any_ref(msg).type().hash_code(); + if (msg_type_hash_code == typeid(std::shared_ptr).hash_code()) + { + const auto osnma_data = wht::any_cast>(pmt::any_ref(msg)); + d_auth_nav_data_map[osnma_data->get_prn_d()].insert(osnma_data->get_IOD_nav()); + } + } + catch (const wht::bad_any_cast& e) + { + LOG(WARNING) << "msg_handler_osnma Bad any_cast: " << e.what(); + } +} + + std::map rtklib_pvt_gs::get_gps_ephemeris_map() const { return d_internal_pvt_solver->gps_ephemeris_map; @@ -1685,21 +1743,19 @@ void rtklib_pvt_gs::clear_ephemeris() } -bool rtklib_pvt_gs::send_sys_v_ttff_msg(d_ttff_msgbuf ttff) const +bool rtklib_pvt_gs::send_ttff_msg(double ttff) const { - if (d_sysv_msqid != -1) + if (d_mq) { - // Fill Sys V message structures - int msgsend_size; - d_ttff_msgbuf msg; - msg.ttff = ttff.ttff; - msgsend_size = sizeof(msg.ttff); - msg.mtype = 1; // default message ID - - // SEND SOLUTION OVER A MESSAGE QUEUE - // non-blocking Sys V message send - msgsnd(d_sysv_msqid, &msg, msgsend_size, IPC_NOWAIT); - return true; + try + { + d_mq->send(&ttff, sizeof(ttff), 0); // Priority 0 + return true; + } + catch (const boost::interprocess::interprocess_exception& e) + { + std::cerr << "Error sending message: " << e.what() << std::endl; + } } return false; } @@ -1987,7 +2043,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item bool store_valid_observable = false; - if (tmp_eph_iter_gps != d_internal_pvt_solver->gps_ephemeris_map.cend()) + if (!d_osnma_strict && tmp_eph_iter_gps != d_internal_pvt_solver->gps_ephemeris_map.cend()) { const uint32_t prn_aux = tmp_eph_iter_gps->second.PRN; if ((prn_aux == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal, 2) == std::string("1C")) && (d_use_unhealthy_sats || (tmp_eph_iter_gps->second.SV_health == 0))) @@ -2003,10 +2059,25 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item ((std::string(in[i][epoch].Signal, 2) == std::string("5X")) && (d_use_unhealthy_sats || ((tmp_eph_iter_gal->second.E5a_DVS == false) && (tmp_eph_iter_gal->second.E5a_HS == 0)))) || ((std::string(in[i][epoch].Signal, 2) == std::string("7X")) && (d_use_unhealthy_sats || ((tmp_eph_iter_gal->second.E5b_DVS == false) && (tmp_eph_iter_gal->second.E5b_HS == 0)))))) { - store_valid_observable = true; + if (d_osnma_strict && ((std::string(in[i][epoch].Signal, 2) == std::string("1B")) || ((std::string(in[i][epoch].Signal, 2) == std::string("7X"))))) + { + // Pick up only authenticated satellites + auto IOD_nav_list = d_auth_nav_data_map.find(tmp_eph_iter_gal->second.PRN); + if (IOD_nav_list != d_auth_nav_data_map.cend()) + { + if (IOD_nav_list->second.find(tmp_eph_iter_gal->second.IOD_nav) != IOD_nav_list->second.cend()) + { + store_valid_observable = true; + } + } + } + else + { + store_valid_observable = true; + } } } - if (tmp_eph_iter_cnav != d_internal_pvt_solver->gps_cnav_ephemeris_map.cend()) + if (!d_osnma_strict && tmp_eph_iter_cnav != d_internal_pvt_solver->gps_cnav_ephemeris_map.cend()) { const uint32_t prn_aux = tmp_eph_iter_cnav->second.PRN; if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal, 2) == std::string("2S")) || (std::string(in[i][epoch].Signal, 2) == std::string("L5"))))) @@ -2014,7 +2085,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item store_valid_observable = true; } } - if (tmp_eph_iter_glo_gnav != d_internal_pvt_solver->glonass_gnav_ephemeris_map.cend()) + if (!d_osnma_strict && tmp_eph_iter_glo_gnav != d_internal_pvt_solver->glonass_gnav_ephemeris_map.cend()) { const uint32_t prn_aux = tmp_eph_iter_glo_gnav->second.PRN; if ((prn_aux == in[i][epoch].PRN) && ((std::string(in[i][epoch].Signal, 2) == std::string("1G")) || (std::string(in[i][epoch].Signal, 2) == std::string("2G")))) @@ -2022,7 +2093,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item store_valid_observable = true; } } - if (tmp_eph_iter_bds_dnav != d_internal_pvt_solver->beidou_dnav_ephemeris_map.cend()) + if (!d_osnma_strict && tmp_eph_iter_bds_dnav != d_internal_pvt_solver->beidou_dnav_ephemeris_map.cend()) { const uint32_t prn_aux = tmp_eph_iter_bds_dnav->second.PRN; if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal, 2) == std::string("B1")) || (std::string(in[i][epoch].Signal, 2) == std::string("B3"))) && (d_use_unhealthy_sats || (tmp_eph_iter_bds_dnav->second.SV_health == 0)))) @@ -2032,7 +2103,14 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item } if (std::string(in[i][epoch].Signal, 2) == std::string("E6")) { - store_valid_observable = true; + if (d_osnma_strict) + { + // TODO + } + else + { + store_valid_observable = true; + } } if (store_valid_observable) @@ -2168,7 +2246,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item d_gnss_observables_map_t1 = d_gnss_observables_map; // ### select the rx_time and interpolate observables at that time - if (!d_gnss_observables_map_t0.empty()) + if (!d_gnss_observables_map_t0.empty() && !d_gnss_observables_map_t1.empty()) { const auto t0_int_ms = static_cast(d_gnss_observables_map_t0.cbegin()->second.RX_time * 1000.0); const uint32_t adjust_next_obs_interval_ms = d_observable_interval_ms - t0_int_ms % d_observable_interval_ms; @@ -2320,12 +2398,10 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item } std::cout << " is Lat = " << d_user_pvt_solver->get_latitude() << " [deg], Long = " << d_user_pvt_solver->get_longitude() << " [deg], Height= " << d_user_pvt_solver->get_height() << " [m]\n"; - d_ttff_msgbuf ttff; - ttff.mtype = 1; d_end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = d_end - d_start; - ttff.ttff = elapsed_seconds.count(); - send_sys_v_ttff_msg(ttff); + double ttff = elapsed_seconds.count(); + send_ttff_msg(ttff); d_first_fix = false; } if (d_kml_output_enabled) diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h index 83d1f830d..b54b3d670 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.h @@ -18,11 +18,14 @@ #define GNSS_SDR_RTKLIB_PVT_GS_H #include "gnss_block_interface.h" +#include "gnss_sdr_make_unique.h" #include "gnss_synchro.h" #include "gnss_time.h" +#include "osnma_data.h" #include "rtklib.h" #include #include +#include #include // for sync_block #include // for gr_vector_const_void_star #include // for pmt_t @@ -34,8 +37,8 @@ #include // for map #include // for shared_ptr, unique_ptr #include // for std::queue +#include // for std::set #include // for string -#include // for key_t #include // for vector /** \addtogroup PVT @@ -144,6 +147,8 @@ private: void msg_handler_has_data(const pmt::pmt_t& msg); + void msg_handler_osnma(const pmt::pmt_t& msg); + void initialize_and_apply_carrier_phase_offset(); void apply_rx_clock_offset(std::map& observables_map, @@ -162,13 +167,7 @@ private: std::vector split_string(const std::string& s, char delim) const; - typedef struct - { - long mtype; // NOLINT(google-runtime-int) - double ttff; - } d_ttff_msgbuf; - bool send_sys_v_ttff_msg(d_ttff_msgbuf ttff) const; - + bool send_ttff_msg(double ttff) const; bool save_gnss_synchro_map_xml(const std::string& file_name); // debug helper function bool load_gnss_synchro_map_xml(const std::string& file_name); // debug helper function @@ -177,6 +176,8 @@ private: std::shared_ptr d_internal_pvt_solver; std::shared_ptr d_user_pvt_solver; + std::unique_ptr d_mq; + std::unique_ptr d_rp; std::unique_ptr d_kml_dump; std::unique_ptr d_gpx_dump; @@ -191,6 +192,7 @@ private: std::chrono::time_point d_start; std::chrono::time_point d_end; + std::string d_queue_name; std::string d_dump_filename; std::string d_xml_base_path; std::string d_local_time_str; @@ -201,6 +203,7 @@ private: std::map d_gnss_observables_map; std::map d_gnss_observables_map_t0; std::map d_gnss_observables_map_t1; + std::map> d_auth_nav_data_map; std::queue d_TimeChannelTagTimestamps; @@ -233,9 +236,6 @@ private: uint64_t d_local_counter_ms; uint64_t d_timestamp_rx_clock_offset_correction_msg_ms; - key_t d_sysv_msg_key; - int d_sysv_msqid; - int32_t d_rinexobs_rate_ms; int32_t d_rtcm_MT1045_rate_ms; // Galileo Broadcast Ephemeris int32_t d_rtcm_MT1019_rate_ms; // GPS Broadcast Ephemeris (orbits) @@ -278,6 +278,7 @@ private: bool d_log_timetag; bool d_use_has_corrections; bool d_use_unhealthy_sats; + bool d_osnma_strict; }; diff --git a/src/algorithms/PVT/libs/CMakeLists.txt b/src/algorithms/PVT/libs/CMakeLists.txt index 07e905a2c..8f89f7033 100644 --- a/src/algorithms/PVT/libs/CMakeLists.txt +++ b/src/algorithms/PVT/libs/CMakeLists.txt @@ -92,11 +92,18 @@ target_link_libraries(pvt_libs algorithms_libs_rtklib PRIVATE algorithms_libs - Gflags::gflags - Glog::glog + gnss_sdr_flags Matio::matio ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(pvt_libs PUBLIC Glog::glog) + + target_compile_definitions(pvt_libs PUBLIC -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(pvt_libs PUBLIC absl::log) +endif() + get_filename_component(PROTO_INCLUDE_HEADERS_DIR ${PROTO_HDRS} DIRECTORY) # for concurrent_queue.h @@ -137,6 +144,21 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif() endif() +# Fixes for Boost Asio > 1.86. address::from_string was deprecated in Boost 1.71 +if(Boost_VERSION_STRING VERSION_LESS 1.71.0) + target_compile_definitions(pvt_libs + PRIVATE + -DBOOST_ASIO_USE_FROM_STRING=1 + ) + # resolver::iterator retired in Boost 1.87.0, alternative available since 1.71 + # boost::asio::io_context::post deprecated in 1.84 in favor of boost::asio::post + target_compile_definitions(pvt_libs + PUBLIC + -DBOOST_ASIO_USE_RESOLVER_ITERATOR=1 + -DBOOST_ASIO_USE_IOCONTEXT_POST=1 + ) +endif() + set_property(TARGET pvt_libs APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $ ) diff --git a/src/algorithms/PVT/libs/an_packet_printer.cc b/src/algorithms/PVT/libs/an_packet_printer.cc index 6618d6982..f14790b4d 100644 --- a/src/algorithms/PVT/libs/an_packet_printer.cc +++ b/src/algorithms/PVT/libs/an_packet_printer.cc @@ -20,7 +20,6 @@ #include "an_packet_printer.h" #include "rtklib_solver.h" // for Rtklib_Solver -#include // for DLOG #include // for M_PI #include // for memcpy #include // for fcntl @@ -29,6 +28,12 @@ #include // values for termios #include // for write(), read(), close() +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + An_Packet_Printer::An_Packet_Printer(const std::string& an_dump_devname) : d_start(std::chrono::system_clock::now()), @@ -102,8 +107,8 @@ void An_Packet_Printer::update_sdr_gnss_packet(sdr_gnss_packet_t* _packet, const const int max_reported_sats = *(&_packet->sats + 1) - _packet->sats; for (gnss_observables_iter = gnss_observables_map.cbegin(); - gnss_observables_iter != gnss_observables_map.cend(); - ++gnss_observables_iter) + gnss_observables_iter != gnss_observables_map.cend(); + ++gnss_observables_iter) { if (gnss_observables_iter->second.Flag_valid_pseudorange) { diff --git a/src/algorithms/PVT/libs/geohash.cc b/src/algorithms/PVT/libs/geohash.cc index ecc1f6f3a..44a06adda 100644 --- a/src/algorithms/PVT/libs/geohash.cc +++ b/src/algorithms/PVT/libs/geohash.cc @@ -135,7 +135,7 @@ std::array Geohash::decode(std::string geohash) const std::array Geohash::bounds(std::string geohash) const { - if (geohash.length() == 0) + if (geohash.empty()) { throw std::runtime_error("Invalid geohash"); } diff --git a/src/algorithms/PVT/libs/geojson_printer.cc b/src/algorithms/PVT/libs/geojson_printer.cc index f57e9d582..62c53e82c 100644 --- a/src/algorithms/PVT/libs/geojson_printer.cc +++ b/src/algorithms/PVT/libs/geojson_printer.cc @@ -20,13 +20,18 @@ #include "gnss_sdr_filesystem.h" #include "pvt_solution.h" #include -#include #include // for tm #include // for exception #include // for operator<< #include // for cout, cerr #include // for stringstream +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GeoJSON_Printer::GeoJSON_Printer(const std::string& base_path) : geojson_base_path(base_path), first_pos(true) diff --git a/src/algorithms/PVT/libs/gpx_printer.cc b/src/algorithms/PVT/libs/gpx_printer.cc index 699f92db5..c2a16bee4 100644 --- a/src/algorithms/PVT/libs/gpx_printer.cc +++ b/src/algorithms/PVT/libs/gpx_printer.cc @@ -20,13 +20,17 @@ #include "gnss_sdr_filesystem.h" #include "pvt_solution.h" #include -#include #include // for tm #include // for exception #include // for operator<< #include // for cout, cerr #include // for stringstream +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Gpx_Printer::Gpx_Printer(const std::string& base_path) : indent(" "), gpx_base_path(base_path), diff --git a/src/algorithms/PVT/libs/has_simple_printer.cc b/src/algorithms/PVT/libs/has_simple_printer.cc index e29df9809..d57aeb281 100644 --- a/src/algorithms/PVT/libs/has_simple_printer.cc +++ b/src/algorithms/PVT/libs/has_simple_printer.cc @@ -21,7 +21,6 @@ #include "galileo_has_data.h" #include "gnss_sdr_filesystem.h" #include -#include #include // for std::find, std::count #include // for std::bitset #include // for uint8_t, ... @@ -32,6 +31,12 @@ #include // for std::cout, std::cerr #include // for std::stringstream +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + Has_Simple_Printer::Has_Simple_Printer(const std::string& base_path, const std::string& filename, @@ -208,26 +213,29 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) } d_has_file << indent << indent << "Cell Mask Availability Flag: " << print_vector(has_data->cell_mask_availability_flag) << '\n'; - for (uint8_t i = 0; i < has_data->Nsys; i++) + if (has_data->header.code_bias_flag == true || has_data->header.phase_bias_flag == true) { - if (has_data->cell_mask_availability_flag[i] == true) + for (uint8_t i = 0; i < has_data->Nsys; i++) { - std::string text; - if (has_data->gnss_id_mask[i] == 0) + if (has_data->cell_mask_availability_flag[i] == true) { - text = "Cell Mask for GPS: "; + std::string text; + if (has_data->gnss_id_mask[i] == 0) + { + text = "Cell Mask for GPS: "; + } + else if (has_data->gnss_id_mask[i] == 2) + { + text = "Cell Mask for Galileo: "; + } + else + { + text = "Cell Mask for Reserved: "; + } + d_has_file << indent << indent << text; + const std::string filler(indent.length() * 2 + text.length(), ' '); + d_has_file << print_matrix(has_data->cell_mask[i], filler); } - else if (has_data->gnss_id_mask[i] == 2) - { - text = "Cell Mask for Galileo: "; - } - else - { - text = "Cell Mask for Reserved: "; - } - d_has_file << indent << indent << text; - const std::string filler(indent.length() * 2 + text.length(), ' '); - d_has_file << print_matrix(has_data->cell_mask[i], filler); } } d_has_file << indent << indent << "Nav message: " << print_vector(has_data->nav_message) << " (0: GPS LNAV or Galileo I/NAV)\n"; @@ -237,8 +245,8 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) d_has_file << '\n'; d_has_file << indent << indent << "Orbit Corrections Block\n"; d_has_file << indent << indent << "-----------------------\n"; - d_has_file << indent << indent << "Validity interval: " << static_cast(has_data->validity_interval_index_orbit_corrections) << '\n'; - d_has_file << indent << indent << "GNSS IOD: " << print_vector(has_data->gnss_iod) << '\n'; + d_has_file << indent << indent << "Validity interval [s]: " << static_cast(has_data->get_validity_interval_s(has_data->validity_interval_index_orbit_corrections)) << '\n'; + d_has_file << indent << indent << "GNSS IODref: " << print_vector(has_data->gnss_iod) << '\n'; d_has_file << indent << indent << "Delta Radial [m]: " << print_vector(has_data->delta_radial, HAS_MSG_DELTA_RADIAL_SCALE_FACTOR) << '\n'; d_has_file << indent << indent << "Delta In-Track [m]: " << print_vector(has_data->delta_in_track, HAS_MSG_DELTA_IN_TRACK_SCALE_FACTOR) << '\n'; d_has_file << indent << indent << "Delta Cross Track [m]: " << print_vector(has_data->delta_cross_track, HAS_MSG_DELTA_CROSS_TRACK_SCALE_FACTOR) << '\n'; @@ -249,7 +257,11 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) d_has_file << '\n'; d_has_file << indent << indent << "Clock Full-set Corrections Block\n"; d_has_file << indent << indent << "--------------------------------\n"; - d_has_file << indent << indent << "Validity interval: " << static_cast(has_data->validity_interval_index_clock_fullset_corrections) << '\n'; + d_has_file << indent << indent << "Validity interval [s]: " << static_cast(has_data->get_validity_interval_s(has_data->validity_interval_index_clock_fullset_corrections)) << '\n'; + if (!has_data->gnss_iod.empty()) + { + d_has_file << indent << indent << "GNSS IODref: " << print_vector(has_data->gnss_iod) << '\n'; + } d_has_file << indent << indent << "Delta Clock Multiplier: " << print_vector(has_data->delta_clock_multiplier) << '\n'; d_has_file << indent << indent << "Delta Clock Correction [m]: " << print_vector(has_data->delta_clock_correction, HAS_MSG_DELTA_CLOCK_SCALE_FACTOR) << '\n'; } @@ -259,7 +271,7 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) d_has_file << '\n'; d_has_file << indent << indent << "Clock Subset Corrections Block\n"; d_has_file << indent << indent << "------------------------------\n"; - d_has_file << indent << indent << "Validity interval: " << static_cast(has_data->validity_interval_index_clock_subset_corrections) << '\n'; + d_has_file << indent << indent << "Validity interval [s]: " << static_cast(has_data->get_validity_interval_s(has_data->validity_interval_index_clock_subset_corrections)) << '\n'; d_has_file << indent << indent << "Nsys_sub: " << static_cast(has_data->Nsys_sub) << '\n'; d_has_file << indent << indent << "GNSS ID: " << print_vector(has_data->gnss_id_clock_subset) << '\n'; d_has_file << indent << indent << "Delta Clock Multiplier: " << print_vector(has_data->delta_clock_multiplier_clock_subset) << '\n'; @@ -305,7 +317,7 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) d_has_file << '\n'; d_has_file << indent << indent << "Code Bias Block\n"; d_has_file << indent << indent << "---------------\n"; - d_has_file << indent << indent << "Validity interval: " << static_cast(has_data->validity_interval_index_code_bias_corrections) << '\n'; + d_has_file << indent << indent << "Validity interval [s]: " << static_cast(has_data->get_validity_interval_s(has_data->validity_interval_index_code_bias_corrections)) << '\n'; const std::string text("Code bias [m]: "); const std::string filler(indent.length() * 2 + text.length(), ' '); d_has_file << indent << indent << text << print_matrix(has_data->code_bias, filler, HAS_MSG_CODE_BIAS_SCALE_FACTOR); @@ -316,7 +328,7 @@ bool Has_Simple_Printer::print_message(const Galileo_HAS_data* const has_data) d_has_file << '\n'; d_has_file << indent << indent << "Phase Bias Block\n"; d_has_file << indent << indent << "----------------\n"; - d_has_file << indent << indent << "Validity interval: " << static_cast(has_data->validity_interval_index_phase_bias_corrections) << '\n'; + d_has_file << indent << indent << "Validity interval [s]: " << static_cast(has_data->get_validity_interval_s(has_data->validity_interval_index_phase_bias_corrections)) << '\n'; const std::string text("Phase bias [cycles]: "); const std::string filler(indent.length() * 2 + text.length(), ' '); d_has_file << indent << indent << text << print_matrix(has_data->phase_bias, filler, HAS_MSG_PHASE_BIAS_SCALE_FACTOR); diff --git a/src/algorithms/PVT/libs/kml_printer.cc b/src/algorithms/PVT/libs/kml_printer.cc index 72ea272d9..6394be27d 100644 --- a/src/algorithms/PVT/libs/kml_printer.cc +++ b/src/algorithms/PVT/libs/kml_printer.cc @@ -20,7 +20,6 @@ #include "gnss_sdr_filesystem.h" #include "pvt_solution.h" #include -#include #include // for mkstemp #include // for tm #include // for exception @@ -30,6 +29,11 @@ #include // for S_IXUSR | S_IRWXG | S_IRWXO #include // for mode_t +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Kml_Printer::Kml_Printer(const std::string& base_path) : kml_base_path(base_path), indent(" "), @@ -315,9 +319,13 @@ Kml_Printer::~Kml_Printer() { std::cerr << e.what() << '\n'; } + errorlib::error_code ec; + if (!fs::remove(fs::path(tmp_file_str), ec)) + { + LOG(INFO) << "Error deleting temporary file"; + } if (!positions_printed) { - errorlib::error_code ec; if (!fs::remove(fs::path(kml_filename), ec)) { LOG(INFO) << "Error deleting temporary KML file"; diff --git a/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc index ca4ac6fbd..d8f7aa89a 100644 --- a/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc +++ b/src/algorithms/PVT/libs/monitor_ephemeris_udp_sink.cc @@ -28,7 +28,11 @@ Monitor_Ephemeris_Udp_Sink::Monitor_Ephemeris_Udp_Sink(const std::vector +#include #include #include -Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink(const std::vector& addresses, - const uint16_t& port, +Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink( + const std::vector& addresses, + const std::vector& ports, bool protobuf_enabled) : socket{io_context}, use_protobuf(protobuf_enabled) { for (const auto& address : addresses) { - boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port); - endpoints.push_back(endpoint); + for (const auto& port : ports) + { +#if BOOST_ASIO_USE_FROM_STRING + boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), boost::lexical_cast(port)); +#else + boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::make_address(address, error), boost::lexical_cast(port)); +#endif + endpoints.push_back(endpoint); + } } if (use_protobuf) @@ -54,21 +63,23 @@ bool Monitor_Pvt_Udp_Sink::write_monitor_pvt(const Monitor_Pvt* const monitor_pv outbound_data = serdes.createProtobuffer(monitor_pvt); } - for (const auto& endpoint : endpoints) + try { - socket.open(endpoint.protocol(), error); - - try + for (const auto& endpoint : endpoints) { - if (socket.send_to(boost::asio::buffer(outbound_data), endpoint) == 0) + socket.open(endpoint.protocol(), error); // NOLINT(bugprone-unused-return-value) + + if (socket.send_to(boost::asio::buffer(outbound_data), endpoint) == 0) // this can throw { return false; } } - catch (boost::system::system_error const& e) - { - return false; - } } + catch (boost::system::system_error const& e) + { + std::cerr << "Error sending PVT data: " << e.what() << '\n'; + return false; + } + return true; } diff --git a/src/algorithms/PVT/libs/monitor_pvt_udp_sink.h b/src/algorithms/PVT/libs/monitor_pvt_udp_sink.h index 1fbe3219d..393e4e5e2 100644 --- a/src/algorithms/PVT/libs/monitor_pvt_udp_sink.h +++ b/src/algorithms/PVT/libs/monitor_pvt_udp_sink.h @@ -40,7 +40,10 @@ using b_io_context = boost::asio::io_service; class Monitor_Pvt_Udp_Sink { public: - Monitor_Pvt_Udp_Sink(const std::vector& addresses, const uint16_t& port, bool protobuf_enabled); + Monitor_Pvt_Udp_Sink( + const std::vector& addresses, + const std::vector& ports, + bool protobuf_enabled); bool write_monitor_pvt(const Monitor_Pvt* const monitor_pvt); private: diff --git a/src/algorithms/PVT/libs/nmea_printer.cc b/src/algorithms/PVT/libs/nmea_printer.cc index 20c876059..d41eb7146 100644 --- a/src/algorithms/PVT/libs/nmea_printer.cc +++ b/src/algorithms/PVT/libs/nmea_printer.cc @@ -23,7 +23,6 @@ #include "gnss_sdr_filesystem.h" #include "rtklib_solution.h" #include "rtklib_solver.h" -#include #include #include #include @@ -32,6 +31,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + Nmea_Printer::Nmea_Printer(const std::string& filename, bool flag_nmea_output_file, diff --git a/src/algorithms/PVT/libs/pvt_conf.h b/src/algorithms/PVT/libs/pvt_conf.h index 37d9b5aac..f014325ba 100644 --- a/src/algorithms/PVT/libs/pvt_conf.h +++ b/src/algorithms/PVT/libs/pvt_conf.h @@ -48,6 +48,7 @@ public: std::string rtcm_output_file_path = std::string("."); std::string has_output_file_path = std::string("."); std::string udp_addresses; + std::string udp_ports; std::string udp_eph_addresses; std::string log_source_timetag_file; @@ -64,7 +65,6 @@ public: int32_t rinexobs_rate_ms = 0; int32_t an_rate_ms = 20; int32_t max_obs_block_rx_clock_offset_ms = 40; - int udp_port = 0; int udp_eph_port = 0; int rtk_trace_level = 0; @@ -95,6 +95,7 @@ public: bool use_e6_for_pvt = true; bool use_has_corrections = true; bool use_unhealthy_sats = false; + bool osnma_strict = false; // PVT KF parameters bool enable_pvt_kf = false; diff --git a/src/algorithms/PVT/libs/pvt_kf.cc b/src/algorithms/PVT/libs/pvt_kf.cc index 805a53a57..b75e5e17f 100644 --- a/src/algorithms/PVT/libs/pvt_kf.cc +++ b/src/algorithms/PVT/libs/pvt_kf.cc @@ -16,8 +16,12 @@ */ #include "pvt_kf.h" -#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif void Pvt_Kf::init_Kf(const arma::vec& p, const arma::vec& v, diff --git a/src/algorithms/PVT/libs/pvt_solution.cc b/src/algorithms/PVT/libs/pvt_solution.cc index c97a12d70..da14f8be4 100644 --- a/src/algorithms/PVT/libs/pvt_solution.cc +++ b/src/algorithms/PVT/libs/pvt_solution.cc @@ -17,10 +17,14 @@ #include "pvt_solution.h" #include "MATH_CONSTANTS.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif int Pvt_Solution::cart2geo(double X, double Y, double Z, int elipsoid_selection) { diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 6c2d322d5..6abca2750 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -42,7 +42,6 @@ #include #include #include -#include #include // for min and max #include #include // for floor @@ -55,6 +54,11 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path, @@ -4938,8 +4942,8 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map::const_iterator gps_ephemeris_iter; for (gps_ephemeris_iter = eph_map.cbegin(); - gps_ephemeris_iter != eph_map.cend(); - gps_ephemeris_iter++) + gps_ephemeris_iter != eph_map.cend(); + gps_ephemeris_iter++) { // -------- SV / EPOCH / SV CLK const boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_GPS_time(gps_ephemeris_iter->second, gps_ephemeris_iter->second.toc); @@ -5325,8 +5329,8 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map::const_iterator gps_ephemeris_iter; for (gps_ephemeris_iter = eph_map.cbegin(); - gps_ephemeris_iter != eph_map.cend(); - gps_ephemeris_iter++) + gps_ephemeris_iter != eph_map.cend(); + gps_ephemeris_iter++) { // -------- SV / EPOCH / SV CLK const boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_GPS_time(gps_ephemeris_iter->second, gps_ephemeris_iter->second.toc); @@ -5493,8 +5497,8 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map::const_iterator galileo_ephemeris_iter; line.clear(); for (galileo_ephemeris_iter = eph_map.cbegin(); - galileo_ephemeris_iter != eph_map.cend(); - galileo_ephemeris_iter++) + galileo_ephemeris_iter != eph_map.cend(); + galileo_ephemeris_iter++) { // -------- SV / EPOCH / SV CLK const boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_Galileo_time(galileo_ephemeris_iter->second, galileo_ephemeris_iter->second.toe); @@ -5684,8 +5688,8 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map::const_iterator glonass_gnav_ephemeris_iter; for (glonass_gnav_ephemeris_iter = eph_map.cbegin(); - glonass_gnav_ephemeris_iter != eph_map.cend(); - glonass_gnav_ephemeris_iter++) + glonass_gnav_ephemeris_iter != eph_map.cend(); + glonass_gnav_ephemeris_iter++) { // -------- SV / EPOCH / SV CLK const boost::posix_time::ptime p_utc_time = glonass_gnav_ephemeris_iter->second.glot_to_utc(glonass_gnav_ephemeris_iter->second.d_t_b, 0.0); @@ -5929,8 +5933,8 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map::const_iterator bds_ephemeris_iter; for (bds_ephemeris_iter = eph_map.cbegin(); - bds_ephemeris_iter != eph_map.cend(); - bds_ephemeris_iter++) + bds_ephemeris_iter != eph_map.cend(); + bds_ephemeris_iter++) { // -------- SV / EPOCH / SV CLK const boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_BDS_time(bds_ephemeris_iter->second, bds_ephemeris_iter->second.toc); @@ -10274,15 +10278,15 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri int32_t numSatellitesObserved = 0; std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { numSatellitesObserved++; } line += Rinex_Printer::rightJustify(std::to_string(numSatellitesObserved), 3); for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const auto satsys = satelliteSystem.find("GLONASS"); if (satsys != satelliteSystem.cend()) @@ -10302,8 +10306,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri out << line << '\n'; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { std::string lineObs; lineObs.clear(); @@ -10388,8 +10392,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri int32_t numSatellitesObserved = 0; std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { numSatellitesObserved++; } @@ -10404,8 +10408,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri const auto satsys = satelliteSystem.find("GLONASS"); for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { std::string lineObs; lineObs.clear(); @@ -10570,8 +10574,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -10593,8 +10597,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::set available_glo_prns; std::set::iterator it; for (observables_iter = observablesR1C.cbegin(); - observables_iter != observablesR1C.cend(); - observables_iter++) + observables_iter != observablesR1C.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_glo_map.insert(std::pair(prn_, observables_iter->second)); @@ -10606,8 +10610,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesR2C.cbegin(); - observables_iter != observablesR2C.cend(); - observables_iter++) + observables_iter != observablesR2C.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_glo_map.insert(std::pair(prn_, observables_iter->second)); @@ -10627,8 +10631,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // Add list of GPS satellites const auto satsys_gps = satelliteSystem.find("GPS"); for (observables_iter = observablesG1C.cbegin(); - observables_iter != observablesG1C.cend(); - observables_iter++) + observables_iter != observablesG1C.cend(); + observables_iter++) { if (satsys_gps != satelliteSystem.cend()) { @@ -10643,8 +10647,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep // Add list of GLONASS L1 satellites const auto satsys_glo = satelliteSystem.find("GLONASS"); for (observables_iter = observablesR1C.cbegin(); - observables_iter != observablesR1C.cend(); - observables_iter++) + observables_iter != observablesR1C.cend(); + observables_iter++) { if (satsys_glo != satelliteSystem.cend()) { @@ -10658,8 +10662,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } // Add list of GLONASS L2 satellites for (observables_iter = observablesR2C.cbegin(); - observables_iter != observablesR2C.cend(); - observables_iter++) + observables_iter != observablesR2C.cend(); + observables_iter++) { if (satsys_glo != satelliteSystem.cend()) { @@ -10680,8 +10684,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::string s; std::string lineObs; for (observables_iter = observablesG1C.cbegin(); - observables_iter != observablesG1C.cend(); - observables_iter++) + observables_iter != observablesG1C.cend(); + observables_iter++) { lineObs.clear(); @@ -10766,8 +10770,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::pair::iterator, std::multimap::iterator> ret; for (it = available_glo_prns.cbegin(); - it != available_glo_prns.cend(); - it++) + it != available_glo_prns.cend(); + it++) { lineObs.clear(); if (d_version == 3) @@ -10894,8 +10898,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -10917,8 +10921,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g std::set available_glo_prns; std::set::iterator it; for (observables_iter = observablesR1C.cbegin(); - observables_iter != observablesR1C.cend(); - observables_iter++) + observables_iter != observablesR1C.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_glo_map.insert(std::pair(prn_, observables_iter->second)); @@ -10930,8 +10934,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g } for (observables_iter = observablesR2C.cbegin(); - observables_iter != observablesR2C.cend(); - observables_iter++) + observables_iter != observablesR2C.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_glo_map.insert(std::pair(prn_, observables_iter->second)); @@ -10957,8 +10961,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g const auto satsys_gps = satelliteSystem.find("GPS"); const auto satsys = satelliteSystem.find("GLONASS"); for (observables_iter = observablesG2S.cbegin(); - observables_iter != observablesG2S.cend(); - observables_iter++) + observables_iter != observablesG2S.cend(); + observables_iter++) { lineObs.clear(); @@ -11038,8 +11042,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& g std::pair::iterator, std::multimap::iterator> ret; for (it = available_glo_prns.cbegin(); - it != available_glo_prns.cend(); - it++) + it != available_glo_prns.cend(); + it++) { lineObs.clear(); if (satsys != satelliteSystem.cend()) @@ -11163,8 +11167,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -11186,8 +11190,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga std::set available_glo_prns; std::set::iterator it; for (observables_iter = observablesR1C.cbegin(); - observables_iter != observablesR1C.cend(); - observables_iter++) + observables_iter != observablesR1C.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_glo_map.insert(std::pair(prn_, observables_iter->second)); @@ -11198,8 +11202,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga } } for (observables_iter = observablesR2C.cbegin(); - observables_iter != observablesR2C.cend(); - observables_iter++) + observables_iter != observablesR2C.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_glo_map.insert(std::pair(prn_, observables_iter->second)); @@ -11227,8 +11231,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga const auto satsys_gal = satelliteSystem.find("Galileo"); const auto satsys = satelliteSystem.find("GLONASS"); for (observables_iter = observablesE1B.cbegin(); - observables_iter != observablesE1B.cend(); - observables_iter++) + observables_iter != observablesE1B.cend(); + observables_iter++) { lineObs.clear(); @@ -11305,8 +11309,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga std::pair::iterator, std::multimap::iterator> ret; for (it = available_glo_prns.cbegin(); - it != available_glo_prns.cend(); - it++) + it != available_glo_prns.cend(); + it++) { lineObs.clear(); if (satsys_gal != satelliteSystem.cend()) @@ -11435,15 +11439,15 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, d int32_t numSatellitesObserved = 0; std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { numSatellitesObserved++; } line += Rinex_Printer::rightJustify(std::to_string(numSatellitesObserved), 3); for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const auto satsys = satelliteSystem.find("GPS"); if (satsys != satelliteSystem.cend()) @@ -11463,8 +11467,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, d out << line << '\n'; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { std::string lineObs; lineObs.clear(); @@ -11550,8 +11554,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, d int32_t numSatellitesObserved = 0; std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { numSatellitesObserved++; } @@ -11566,8 +11570,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, d const auto satsys_gps = satelliteSystem.find("GPS"); for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { std::string lineObs; lineObs.clear(); @@ -11681,8 +11685,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e int32_t numSatellitesObserved = 0; std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { numSatellitesObserved++; } @@ -11697,8 +11701,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e const auto satsys_gps = satelliteSystem.find("GPS"); for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { std::string lineObs; lineObs.clear(); @@ -11822,8 +11826,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c std::multimap total_mmap; std::multimap::iterator mmap_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -11861,8 +11865,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c std::multimap mmap_aux; mmap_aux = total_mmap; for (mmap_iter = mmap_aux.begin(); - mmap_iter != mmap_aux.end(); - mmap_iter++) + mmap_iter != mmap_aux.end(); + mmap_iter++) { if ((total_mmap.count(mmap_iter->second.PRN)) == 1 && (mmap_iter->second.PRN != 0)) { @@ -11879,8 +11883,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c std::set available_prns; std::set::iterator it; for (observables_iter = observablesL1.cbegin(); - observables_iter != observablesL1.cend(); - observables_iter++) + observables_iter != observablesL1.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); @@ -11891,8 +11895,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } for (observables_iter = observablesL2.cbegin(); - observables_iter != observablesL2.cend(); - observables_iter++) + observables_iter != observablesL2.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); @@ -11903,8 +11907,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c } for (observables_iter = observablesL5.cbegin(); - observables_iter != observablesL5.cend(); - observables_iter++) + observables_iter != observablesL5.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); @@ -11926,8 +11930,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& eph, c const auto satsys_gps = satelliteSystem.find("GPS"); std::pair::iterator, std::multimap::iterator> ret; for (it = available_prns.cbegin(); - it != available_prns.cend(); - it++) + it != available_prns.cend(); + it++) { lineObs.clear(); if (satsys_gps != satelliteSystem.cend()) @@ -12059,8 +12063,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -12092,8 +12096,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep if (found_1B != std::string::npos) { for (observables_iter = observablesE1B.cbegin(); - observables_iter != observablesE1B.cend(); - observables_iter++) + observables_iter != observablesE1B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_map.insert(std::pair(prn_, observables_iter->second)); @@ -12107,8 +12111,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep if (found_E5a != std::string::npos) { for (observables_iter = observablesE5A.cbegin(); - observables_iter != observablesE5A.cend(); - observables_iter++) + observables_iter != observablesE5A.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); @@ -12132,8 +12136,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep if (found_E5b != std::string::npos) { for (observables_iter = observablesE5B.cbegin(); - observables_iter != observablesE5B.cend(); - observables_iter++) + observables_iter != observablesE5B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); @@ -12158,8 +12162,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep if (found_E6b != std::string::npos) { for (observables_iter = observablesE6B.cbegin(); - observables_iter != observablesE6B.cend(); - observables_iter++) + observables_iter != observablesE6B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_map.insert(std::pair(prn_, observables_iter->second)); @@ -12183,8 +12187,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ep std::pair::iterator, std::multimap::iterator> ret; const auto satsys_gal = satelliteSystem.find("Galileo"); for (it = available_prns.cbegin(); - it != available_prns.cend(); - it++) + it != available_prns.cend(); + it++) { lineObs.clear(); if (satsys_gal != satelliteSystem.cend()) @@ -12307,8 +12311,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -12338,8 +12342,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::set available_gal_prns; std::set::iterator it; for (observables_iter = observablesE1B.cbegin(); - observables_iter != observablesE1B.cend(); - observables_iter++) + observables_iter != observablesE1B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12351,8 +12355,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesE5A.cbegin(); - observables_iter != observablesE5A.cend(); - observables_iter++) + observables_iter != observablesE5A.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12364,8 +12368,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesE5B.cbegin(); - observables_iter != observablesE5B.cend(); - observables_iter++) + observables_iter != observablesE5B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12377,8 +12381,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesE6B.cbegin(); - observables_iter != observablesE6B.cend(); - observables_iter++) + observables_iter != observablesE6B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12407,8 +12411,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep const auto satsys_gal = satelliteSystem.find("Galileo"); for (observables_iter = observablesG1C.cbegin(); - observables_iter != observablesG1C.cend(); - observables_iter++) + observables_iter != observablesG1C.cend(); + observables_iter++) { lineObs.clear(); @@ -12485,8 +12489,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::pair::iterator, std::multimap::iterator> ret; for (it = available_gal_prns.cbegin(); - it != available_gal_prns.cend(); - it++) + it != available_gal_prns.cend(); + it++) { lineObs.clear(); if (satsys_gal != satelliteSystem.cend()) @@ -12610,8 +12614,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -12647,8 +12651,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e std::set available_gps_prns; std::set::iterator it; for (observables_iter = observablesE1B.cbegin(); - observables_iter != observablesE1B.cend(); - observables_iter++) + observables_iter != observablesE1B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12660,8 +12664,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e } for (observables_iter = observablesE5A.cbegin(); - observables_iter != observablesE5A.cend(); - observables_iter++) + observables_iter != observablesE5A.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12673,8 +12677,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e } for (observables_iter = observablesE5B.cbegin(); - observables_iter != observablesE5B.cend(); - observables_iter++) + observables_iter != observablesE5B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12686,8 +12690,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e } for (observables_iter = observablesE6B.cbegin(); - observables_iter != observablesE6B.cend(); - observables_iter++) + observables_iter != observablesE6B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12699,8 +12703,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e } for (observables_iter = observablesG2S.cbegin(); - observables_iter != observablesG2S.cend(); - observables_iter++) + observables_iter != observablesG2S.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gps_map.insert(std::pair(prn_, observables_iter->second)); @@ -12712,8 +12716,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e } for (observables_iter = observablesGL5.cbegin(); - observables_iter != observablesGL5.cend(); - observables_iter++) + observables_iter != observablesGL5.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gps_map.insert(std::pair(prn_, observables_iter->second)); @@ -12742,8 +12746,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e const auto satsys_gps = satelliteSystem.find("GPS"); std::pair::iterator, std::multimap::iterator> ret; for (it = available_gps_prns.cbegin(); - it != available_gps_prns.cend(); - it++) + it != available_gps_prns.cend(); + it++) { lineObs.clear(); if (satsys_gps != satelliteSystem.cend()) @@ -12808,8 +12812,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& e const auto satsys_gal = satelliteSystem.find("Galileo"); for (it = available_gal_prns.cbegin(); - it != available_gal_prns.cend(); - it++) + it != available_gal_prns.cend(); + it++) { lineObs.clear(); if (satsys_gal != satelliteSystem.cend()) @@ -12934,8 +12938,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -12975,8 +12979,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::set available_gps_prns; std::set::iterator it; for (observables_iter = observablesE1B.cbegin(); - observables_iter != observablesE1B.cend(); - observables_iter++) + observables_iter != observablesE1B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -12988,8 +12992,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesE5A.cbegin(); - observables_iter != observablesE5A.cend(); - observables_iter++) + observables_iter != observablesE5A.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -13001,8 +13005,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesE5B.cbegin(); - observables_iter != observablesE5B.cend(); - observables_iter++) + observables_iter != observablesE5B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -13014,8 +13018,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesE6B.cbegin(); - observables_iter != observablesE6B.cend(); - observables_iter++) + observables_iter != observablesE6B.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gal_map.insert(std::pair(prn_, observables_iter->second)); @@ -13027,8 +13031,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesG1C.cbegin(); - observables_iter != observablesG1C.cend(); - observables_iter++) + observables_iter != observablesG1C.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gps_map.insert(std::pair(prn_, observables_iter->second)); @@ -13040,8 +13044,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesG2S.cbegin(); - observables_iter != observablesG2S.cend(); - observables_iter++) + observables_iter != observablesG2S.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gps_map.insert(std::pair(prn_, observables_iter->second)); @@ -13053,8 +13057,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } for (observables_iter = observablesGL5.cbegin(); - observables_iter != observablesGL5.cend(); - observables_iter++) + observables_iter != observablesGL5.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_gps_map.insert(std::pair(prn_, observables_iter->second)); @@ -13083,8 +13087,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep const auto satsys_gps = satelliteSystem.find("GPS"); std::pair::iterator, std::multimap::iterator> ret; for (it = available_gps_prns.cbegin(); - it != available_gps_prns.cend(); - it++) + it != available_gps_prns.cend(); + it++) { lineObs.clear(); if (satsys_gps != satelliteSystem.cend()) @@ -13160,8 +13164,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep const auto satsys_gal = satelliteSystem.find("Galileo"); for (it = available_gal_prns.cbegin(); - it != available_gal_prns.cend(); - it++) + it != available_gal_prns.cend(); + it++) { lineObs.clear(); if (satsys_gal != satelliteSystem.cend()) @@ -13276,8 +13280,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -13299,8 +13303,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris if (found_B1 != std::string::npos) { for (observables_iter = observablesB1I.cbegin(); - observables_iter != observablesB1I.cend(); - observables_iter++) + observables_iter != observablesB1I.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; total_map.insert(std::pair(prn_, observables_iter->second)); @@ -13314,8 +13318,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris if (found_B3 != std::string::npos) { for (observables_iter = observablesB3I.cbegin(); - observables_iter != observablesB3I.cend(); - observables_iter++) + observables_iter != observablesB3I.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; it = available_prns.find(prn_); @@ -13349,8 +13353,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris const auto satsys_bds = satelliteSystem.find("Beidou"); std::pair::iterator, std::multimap::iterator> ret; for (it = available_prns.cbegin(); - it != available_prns.cend(); - it++) + it != available_prns.cend(); + it++) { lineObs.clear(); if (satsys_bds != satelliteSystem.cend()) diff --git a/src/algorithms/PVT/libs/rtcm.cc b/src/algorithms/PVT/libs/rtcm.cc index 5854b4eb8..37dd0d664 100644 --- a/src/algorithms/PVT/libs/rtcm.cc +++ b/src/algorithms/PVT/libs/rtcm.cc @@ -486,8 +486,8 @@ std::string Rtcm::print_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, co std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -501,8 +501,8 @@ std::string Rtcm::print_MT1001(const Gps_Ephemeris& gps_eph, double obs_time, co std::string data = header.to_string(); for (observables_iter = observablesL1.cbegin(); - observables_iter != observablesL1.cend(); - observables_iter++) + observables_iter != observablesL1.cend(); + observables_iter++) { const std::bitset<58> content = Rtcm::get_MT1001_sat_content(gps_eph, obs_time, observables_iter->second); data += content.to_string(); @@ -535,8 +535,8 @@ std::string Rtcm::print_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, co std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -550,8 +550,8 @@ std::string Rtcm::print_MT1002(const Gps_Ephemeris& gps_eph, double obs_time, co std::string data = header.to_string(); for (observables_iter = observablesL1.cbegin(); - observables_iter != observablesL1.cend(); - observables_iter++) + observables_iter != observablesL1.cend(); + observables_iter++) { const std::bitset<74> content = Rtcm::get_MT1002_sat_content(gps_eph, obs_time, observables_iter->second); data += content.to_string(); @@ -608,8 +608,8 @@ std::string Rtcm::print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::map::const_iterator observables_iter2; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -629,13 +629,13 @@ std::string Rtcm::print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::map observablesL1_with_L2; for (observables_iter = observablesL1.cbegin(); - observables_iter != observablesL1.cend(); - observables_iter++) + observables_iter != observablesL1.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.cbegin(); - observables_iter2 != observablesL2.cend(); - observables_iter2++) + observables_iter2 != observablesL2.cend(); + observables_iter2++) { if (observables_iter2->second.PRN == prn_) { @@ -653,8 +653,8 @@ std::string Rtcm::print_MT1003(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::string data = header.to_string(); for (common_observables_iter = common_observables.cbegin(); - common_observables_iter != common_observables.cend(); - common_observables_iter++) + common_observables_iter != common_observables.cend(); + common_observables_iter++) { std::bitset<101> content = Rtcm::get_MT1003_sat_content(ephL1, ephL2, obs_time, common_observables_iter->first, common_observables_iter->second); data += content.to_string(); @@ -717,8 +717,8 @@ std::string Rtcm::print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::map::const_iterator observables_iter2; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -738,13 +738,13 @@ std::string Rtcm::print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::map observablesL1_with_L2; for (observables_iter = observablesL1.cbegin(); - observables_iter != observablesL1.cend(); - observables_iter++) + observables_iter != observablesL1.cend(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.cbegin(); - observables_iter2 != observablesL2.cend(); - observables_iter2++) + observables_iter2 != observablesL2.cend(); + observables_iter2++) { if (observables_iter2->second.PRN == prn_) { @@ -762,8 +762,8 @@ std::string Rtcm::print_MT1004(const Gps_Ephemeris& ephL1, const Gps_CNAV_Epheme std::string data = header.to_string(); for (common_observables_iter = common_observables.cbegin(); - common_observables_iter != common_observables.cend(); - common_observables_iter++) + common_observables_iter != common_observables.cend(); + common_observables_iter++) { std::bitset<125> content = Rtcm::get_MT1004_sat_content(ephL1, ephL2, obs_time, common_observables_iter->first, common_observables_iter->second); data += content.to_string(); @@ -1164,8 +1164,8 @@ std::string Rtcm::print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, d std::map::const_iterator observables_iter; for (observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) + observables_iter != observables.end(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -1179,8 +1179,8 @@ std::string Rtcm::print_MT1009(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, d std::string data = header.to_string(); for (observables_iter = observablesL1.begin(); - observables_iter != observablesL1.end(); - observables_iter++) + observables_iter != observablesL1.end(); + observables_iter++) { const std::bitset<64> content = Rtcm::get_MT1009_sat_content(glonass_gnav_eph, obs_time, observables_iter->second); data += content.to_string(); @@ -1213,8 +1213,8 @@ std::string Rtcm::print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, d std::map::const_iterator observables_iter; for (observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) + observables_iter != observables.end(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -1228,8 +1228,8 @@ std::string Rtcm::print_MT1010(const Glonass_Gnav_Ephemeris& glonass_gnav_eph, d std::string data = header.to_string(); for (observables_iter = observablesL1.begin(); - observables_iter != observablesL1.end(); - observables_iter++) + observables_iter != observablesL1.end(); + observables_iter++) { const std::bitset<79> content = Rtcm::get_MT1010_sat_content(glonass_gnav_eph, obs_time, observables_iter->second); data += content.to_string(); @@ -1290,8 +1290,8 @@ std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::map::const_iterator observables_iter2; for (observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) + observables_iter != observables.end(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -1311,13 +1311,13 @@ std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::map observablesL1_with_L2; for (observables_iter = observablesL1.begin(); - observables_iter != observablesL1.end(); - observables_iter++) + observables_iter != observablesL1.end(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.begin(); - observables_iter2 != observablesL2.end(); - observables_iter2++) + observables_iter2 != observablesL2.end(); + observables_iter2++) { if (observables_iter2->second.PRN == prn_) { @@ -1335,8 +1335,8 @@ std::string Rtcm::print_MT1011(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::string data = header.to_string(); for (common_observables_iter = common_observables.begin(); - common_observables_iter != common_observables.end(); - common_observables_iter++) + common_observables_iter != common_observables.end(); + common_observables_iter++) { const std::bitset<107> content = Rtcm::get_MT1011_sat_content(ephL1, ephL2, obs_time, common_observables_iter->first, common_observables_iter->second); data += content.to_string(); @@ -1401,8 +1401,8 @@ std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::map::const_iterator observables_iter2; for (observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) + observables_iter != observables.end(); + observables_iter++) { const std::string system_(&observables_iter->second.System, 1); const std::string sig_(observables_iter->second.Signal); @@ -1422,13 +1422,13 @@ std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::map observablesL1_with_L2; for (observables_iter = observablesL1.begin(); - observables_iter != observablesL1.end(); - observables_iter++) + observables_iter != observablesL1.end(); + observables_iter++) { const uint32_t prn_ = observables_iter->second.PRN; for (observables_iter2 = observablesL2.begin(); - observables_iter2 != observablesL2.end(); - observables_iter2++) + observables_iter2 != observablesL2.end(); + observables_iter2++) { if (observables_iter2->second.PRN == prn_) { @@ -1446,8 +1446,8 @@ std::string Rtcm::print_MT1012(const Glonass_Gnav_Ephemeris& ephL1, const Glonas std::string data = header.to_string(); for (common_observables_iter = common_observables.begin(); - common_observables_iter != common_observables.end(); - common_observables_iter++) + common_observables_iter != common_observables.end(); + common_observables_iter++) { const std::bitset<130> content = Rtcm::get_MT1012_sat_content(ephL1, ephL2, obs_time, common_observables_iter->first, common_observables_iter->second); data += content.to_string(); @@ -2387,8 +2387,8 @@ std::string Rtcm::get_MSM_1_content_sat_data(const std::map::iterator it; for (gnss_synchro_iter = observables.cbegin(); - gnss_synchro_iter != observables.cend(); - gnss_synchro_iter++) + gnss_synchro_iter != observables.cend(); + gnss_synchro_iter++) { it = std::find(pos.begin(), pos.end(), 65 - gnss_synchro_iter->second.PRN); if (it == pos.end()) @@ -2420,8 +2420,8 @@ std::string Rtcm::get_MSM_1_content_signal_data(const std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); - map_iter != observables.cend(); - map_iter++) + map_iter != observables.cend(); + map_iter++) { observables_vector.emplace_back(*map_iter); } @@ -2529,8 +2529,8 @@ std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris& ephNAV, std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); - map_iter != observables.cend(); - map_iter++) + map_iter != observables.cend(); + map_iter++) { observables_vector.emplace_back(*map_iter); } @@ -2644,8 +2644,8 @@ std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris& ephNAV, std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); - map_iter != observables.cend(); - map_iter++) + map_iter != observables.cend(); + map_iter++) { observables_vector.emplace_back(*map_iter); } @@ -2759,8 +2759,8 @@ std::string Rtcm::get_MSM_4_content_sat_data(const std::map::iterator it; for (gnss_synchro_iter = observables.cbegin(); - gnss_synchro_iter != observables.cend(); - gnss_synchro_iter++) + gnss_synchro_iter != observables.cend(); + gnss_synchro_iter++) { it = std::find(pos.begin(), pos.end(), 65 - gnss_synchro_iter->second.PRN); if (it == pos.end()) @@ -2805,8 +2805,8 @@ std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris& ephNAV, std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); - map_iter != observables.cend(); - map_iter++) + map_iter != observables.cend(); + map_iter++) { observables_vector.emplace_back(*map_iter); } @@ -2924,8 +2924,8 @@ std::string Rtcm::get_MSM_5_content_sat_data(const std::map::iterator it; for (gnss_synchro_iter = observables.cbegin(); - gnss_synchro_iter != observables.cend(); - gnss_synchro_iter++) + gnss_synchro_iter != observables.cend(); + gnss_synchro_iter++) { it = std::find(pos.begin(), pos.end(), 65 - gnss_synchro_iter->second.PRN); if (it == pos.end()) @@ -2975,8 +2975,8 @@ std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris& ephNAV, std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); - map_iter != observables.cend(); - map_iter++) + map_iter != observables.cend(); + map_iter++) { observables_vector.emplace_back(*map_iter); } @@ -3097,8 +3097,8 @@ std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris& ephNAV, std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); - map_iter != observables.cend(); - map_iter++) + map_iter != observables.cend(); + map_iter++) { observables_vector.emplace_back(*map_iter); } @@ -3218,8 +3218,8 @@ std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV, std::map::const_iterator map_iter; for (map_iter = observables.cbegin(); - map_iter != observables.cend(); - map_iter++) + map_iter != observables.cend(); + map_iter++) { observables_vector.emplace_back(*map_iter); } @@ -3342,7 +3342,7 @@ std::vector Rtcm::print_IGM01(const Galileo_HAS_data& has_data) { rtcm_message_queue->push(message); } - msgs.push_back(message); + msgs.push_back(std::move(message)); } return msgs; } @@ -3366,7 +3366,7 @@ std::vector Rtcm::print_IGM02(const Galileo_HAS_data& has_data) { rtcm_message_queue->push(message); } - msgs.push_back(message); + msgs.push_back(std::move(message)); } return msgs; } @@ -3390,7 +3390,7 @@ std::vector Rtcm::print_IGM03(const Galileo_HAS_data& has_data) { rtcm_message_queue->push(message); } - msgs.push_back(message); + msgs.push_back(std::move(message)); } return msgs; } @@ -3416,7 +3416,7 @@ std::vector Rtcm::print_IGM05(const Galileo_HAS_data& has_data) { rtcm_message_queue->push(message); } - msgs.push_back(message); + msgs.push_back(std::move(message)); } } return msgs; @@ -3881,8 +3881,8 @@ std::vector> Rtcm::sort_by_PRN_mask(const std:: } has_lower_pos; for (synchro_map_iter = synchro_map.cbegin(); - synchro_map_iter != synchro_map.cend(); - synchro_map_iter++) + synchro_map_iter != synchro_map.cend(); + synchro_map_iter++) { std::pair p(synchro_map_iter->first, synchro_map_iter->second); @@ -3939,8 +3939,8 @@ std::vector> Rtcm::sort_by_signal(const std::ve for (synchro_map_iter = synchro_map.cbegin(); - synchro_map_iter != synchro_map.cend(); - synchro_map_iter++) + synchro_map_iter != synchro_map.cend(); + synchro_map_iter++) { std::pair p(synchro_map_iter->first, synchro_map_iter->second); @@ -4346,8 +4346,8 @@ int32_t Rtcm::set_DF006(const std::map& observables) uint16_t nsats = 0; std::map::const_iterator observables_iter; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { nsats++; } @@ -4606,8 +4606,8 @@ int32_t Rtcm::set_DF035(const std::map& observables) uint16_t nsats = 0; std::map::const_iterator observables_iter; for (observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) + observables_iter != observables.end(); + observables_iter++) { nsats++; } @@ -5674,8 +5674,8 @@ int32_t Rtcm::set_DF394(const std::map& gnss_synchro) std::map::const_iterator gnss_synchro_iter; uint32_t mask_position; for (gnss_synchro_iter = gnss_synchro.cbegin(); - gnss_synchro_iter != gnss_synchro.cend(); - gnss_synchro_iter++) + gnss_synchro_iter != gnss_synchro.cend(); + gnss_synchro_iter++) { mask_position = 64 - gnss_synchro_iter->second.PRN; DF394.set(mask_position, true); @@ -5695,8 +5695,8 @@ int32_t Rtcm::set_DF395(const std::map& gnss_synchro) std::string sig; uint32_t mask_position; for (gnss_synchro_iter = gnss_synchro.cbegin(); - gnss_synchro_iter != gnss_synchro.cend(); - gnss_synchro_iter++) + gnss_synchro_iter != gnss_synchro.cend(); + gnss_synchro_iter++) { const std::string sig_(gnss_synchro_iter->second.Signal); sig = sig_.substr(0, 2); @@ -5772,8 +5772,8 @@ std::string Rtcm::set_DF396(const std::map& observables) std::vector list_of_signals; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { list_of_sats.push_back(observables_iter->second.PRN); @@ -5826,8 +5826,8 @@ std::string Rtcm::set_DF396(const std::map& observables) { value = false; for (observables_iter = observables.cbegin(); - observables_iter != observables.cend(); - observables_iter++) + observables_iter != observables.cend(); + observables_iter++) { const std::string sig_(observables_iter->second.Signal); sig = sig_.substr(0, 2); @@ -6006,32 +6006,37 @@ int32_t Rtcm::set_DF401(const Gnss_Synchro& gnss_synchro) { lambda = SPEED_OF_LIGHT_M_S / GPS_L1_FREQ_HZ; } - if ((sig == "2S") && (sys == "G")) + else if ((sig == "2S") && (sys == "G")) { lambda = SPEED_OF_LIGHT_M_S / GPS_L2_FREQ_HZ; } - if ((sig == "5X") && (sys == "E")) + else if ((sig == "5X") && (sys == "E")) { lambda = SPEED_OF_LIGHT_M_S / GALILEO_E5A_FREQ_HZ; } - if ((sig == "1B") && (sys == "E")) + else if ((sig == "1B") && (sys == "E")) { lambda = SPEED_OF_LIGHT_M_S / GALILEO_E1_FREQ_HZ; } - if ((sig == "7X") && (sys == "E")) + else if ((sig == "7X") && (sys == "E")) { lambda = SPEED_OF_LIGHT_M_S / GALILEO_E5B_FREQ_HZ; } - if ((sig == "1C") && (sys == "R")) + else if ((sig == "1C") && (sys == "R")) { lambda = SPEED_OF_LIGHT_M_S / ((GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_DFREQ_HZ * GLONASS_PRN.at(gnss_synchro.PRN)))); } - if ((sig == "2C") && (sys == "R")) + else if ((sig == "2C") && (sys == "R")) { // TODO Need to add slot number and freq number to gnss_syncro lambda = SPEED_OF_LIGHT_M_S / (GLONASS_L2_CA_FREQ_HZ); } - + else + { + // should not happen + LOG(WARNING) << "Unknown signal in the generation of RTCM message DF401"; + lambda = SPEED_OF_LIGHT_M_S / GPS_L1_FREQ_HZ; + } double phrng_m = (gnss_synchro.Carrier_phase_rads / TWO_PI) * lambda - rough_range_m; /* Subtract phase - pseudorange integer cycle offset */ @@ -6182,31 +6187,37 @@ int32_t Rtcm::set_DF406(const Gnss_Synchro& gnss_synchro) { lambda = SPEED_OF_LIGHT_M_S / GPS_L1_FREQ_HZ; } - if ((sig_ == "2S") && (sys_ == "G")) + else if ((sig_ == "2S") && (sys_ == "G")) { lambda = SPEED_OF_LIGHT_M_S / GPS_L2_FREQ_HZ; } - if ((sig_ == "5X") && (sys_ == "E")) + else if ((sig_ == "5X") && (sys_ == "E")) { lambda = SPEED_OF_LIGHT_M_S / GALILEO_E5A_FREQ_HZ; } - if ((sig_ == "1B") && (sys_ == "E")) + else if ((sig_ == "1B") && (sys_ == "E")) { lambda = SPEED_OF_LIGHT_M_S / GALILEO_E1_FREQ_HZ; } - if ((sig_ == "7X") && (sys_ == "E")) + else if ((sig_ == "7X") && (sys_ == "E")) { lambda = SPEED_OF_LIGHT_M_S / GALILEO_E5B_FREQ_HZ; } - if ((sig_ == "1C") && (sys_ == "R")) + else if ((sig_ == "1C") && (sys_ == "R")) { lambda = SPEED_OF_LIGHT_M_S / (GLONASS_L1_CA_FREQ_HZ + (GLONASS_L1_CA_DFREQ_HZ * GLONASS_PRN.at(gnss_synchro.PRN))); } - if ((sig_ == "2C") && (sys_ == "R")) + else if ((sig_ == "2C") && (sys_ == "R")) { // TODO Need to add slot number and freq number to gnss syncro lambda = SPEED_OF_LIGHT_M_S / (GLONASS_L2_CA_FREQ_HZ); } + else + { + // should not happen + LOG(WARNING) << "Unknown signal in the generation of RTCM message DF406"; + lambda = SPEED_OF_LIGHT_M_S / GPS_L1_FREQ_HZ; + } phrng_m = (gnss_synchro.Carrier_phase_rads / TWO_PI) * lambda - rough_range_m; /* Subtract phase - pseudorange integer cycle offset */ diff --git a/src/algorithms/PVT/libs/rtcm.h b/src/algorithms/PVT/libs/rtcm.h index c7011eec3..0d7996590 100644 --- a/src/algorithms/PVT/libs/rtcm.h +++ b/src/algorithms/PVT/libs/rtcm.h @@ -29,7 +29,6 @@ #include "gps_ephemeris.h" #include #include -#include #include // for std::max, std::min, std::copy_n #include #include @@ -47,6 +46,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + /** \addtogroup PVT * \{ */ /** \addtogroup PVT_libs @@ -723,10 +728,10 @@ private: { if (first == true) { - LOG(INFO) << "Client says:"; + DLOG(INFO) << "Client says:"; first = false; } - LOG(INFO) << client_says; + DLOG(INFO) << client_says; client_says = client_says.substr(80, client_says.length() - 80); } do_read_message_header(); @@ -796,21 +801,38 @@ private: { public: Tcp_Internal_Client(b_io_context& io_context, +#if BOOST_ASIO_USE_RESOLVER_ITERATOR boost::asio::ip::tcp::resolver::iterator endpoint_iterator) : io_context_(io_context), socket_(io_context) { do_connect(std::move(endpoint_iterator)); } +#else + boost::asio::ip::tcp::resolver::results_type endpoints) + : io_context_(io_context), socket_(io_context) + { + do_connect(std::move(endpoints)); + } +#endif inline void close() { +#if BOOST_ASIO_USE_IOCONTEXT_POST io_context_.post([this]() { socket_.close(); }); +#else + boost::asio::post(io_context_, [this]() { socket_.close(); }); +#endif } inline void write(const Rtcm_Message& msg) { +#if BOOST_ASIO_USE_IOCONTEXT_POST io_context_.post( [this, &msg]() { +#else + boost::asio::post(io_context_, + [this, &msg]() { +#endif bool write_in_progress = !write_msgs_.empty(); write_msgs_.push_back(msg); if (!write_in_progress) @@ -821,10 +843,17 @@ private: } private: +#if BOOST_ASIO_USE_RESOLVER_ITERATOR inline void do_connect(boost::asio::ip::tcp::resolver::iterator endpoint_iterator) { boost::asio::async_connect(socket_, std::move(endpoint_iterator), [this](boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator) { +#else + inline void do_connect(boost::asio::ip::tcp::resolver::results_type endpoints) + { + boost::asio::async_connect(socket_, std::move(endpoints), + [this](boost::system::error_code ec, boost::asio::ip::tcp::endpoint) { +#endif if (!ec) { do_read_message(); @@ -888,8 +917,13 @@ private: boost::asio::ip::tcp::resolver resolver(io_context); std::string host("localhost"); std::string port_str = std::to_string(port); +#if BOOST_ASIO_USE_RESOLVER_ITERATOR auto queue_endpoint_iterator = resolver.resolve({host.c_str(), port_str.c_str()}); c = std::make_shared(io_context, queue_endpoint_iterator); +#else + auto endpoints = resolver.resolve(host, port_str); + c = std::make_shared(io_context, endpoints); +#endif } inline void do_read_queue() diff --git a/src/algorithms/PVT/libs/rtcm_printer.cc b/src/algorithms/PVT/libs/rtcm_printer.cc index cb07b9eea..f6e382259 100644 --- a/src/algorithms/PVT/libs/rtcm_printer.cc +++ b/src/algorithms/PVT/libs/rtcm_printer.cc @@ -30,7 +30,6 @@ #include "rtcm.h" #include "rtklib_solver.h" #include -#include #include // for tm #include // for exception #include // for O_RDWR @@ -39,6 +38,11 @@ #include // for close, write #include // for std::vector +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Rtcm_Printer::Rtcm_Printer(const std::string& filename, bool flag_rtcm_file_dump, diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index ef3e46647..08dcaa2ec 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -35,7 +35,6 @@ #include "gnss_sdr_filesystem.h" #include "rtklib_rtkpos.h" #include "rtklib_solution.h" -#include #include #include #include @@ -43,6 +42,11 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Rtklib_Solver::Rtklib_Solver(const rtk_t &rtk, const Pvt_Conf &conf, @@ -929,8 +933,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ bool band2 = false; for (gnss_observables_iter = gnss_observables_map.cbegin(); - gnss_observables_iter != gnss_observables_map.cend(); - ++gnss_observables_iter) + gnss_observables_iter != gnss_observables_map.cend(); + ++gnss_observables_iter) { switch (gnss_observables_iter->second.System) { @@ -958,8 +962,8 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ } for (gnss_observables_iter = gnss_observables_map.cbegin(); - gnss_observables_iter != gnss_observables_map.cend(); - ++gnss_observables_iter) // CHECK INCONSISTENCY when combining GLONASS + other system + gnss_observables_iter != gnss_observables_map.cend(); + ++gnss_observables_iter) // CHECK INCONSISTENCY when combining GLONASS + other system { switch (gnss_observables_iter->second.System) { @@ -1602,7 +1606,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ ecef2pos(pvt_sol.rr, pos.data()); ecef2enu(pos.data(), &pvt_sol.rr[3], enuv.data()); this->set_speed_over_ground(norm_rtk(enuv.data(), 2)); - double new_cog = -9999.0; // COG not estimated due to insuficient velocity + double new_cog = -9999.0; // COG not estimated due to insufficient velocity if (ground_speed_ms >= 1.0) { new_cog = atan2(enuv[0], enuv[1]) * R2D; @@ -1692,7 +1696,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ // Course Over Ground (cog) [deg] d_monitor_pvt.cog = new_cog; - // Galileo HAS status: 1- HAS messages decoded and applied, 0 - HAS not avaliable + // Galileo HAS status: 1- HAS messages decoded and applied, 0 - HAS not available if (d_has_obs_corr_map.empty()) { d_monitor_pvt.galhas_status = 0; diff --git a/src/algorithms/acquisition/adapters/CMakeLists.txt b/src/algorithms/acquisition/adapters/CMakeLists.txt index 41cfe8a8a..85eb8672e 100644 --- a/src/algorithms/acquisition/adapters/CMakeLists.txt +++ b/src/algorithms/acquisition/adapters/CMakeLists.txt @@ -104,9 +104,15 @@ target_link_libraries(acquisition_adapters PRIVATE gnss_sdr_flags Boost::headers - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(acquisition_adapters PRIVATE Glog::glog) + target_compile_definitions(acquisition_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(acquisition_adapters PRIVATE absl::flags absl::log) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(acquisition_adapters PUBLIC -DGNURADIO_USES_STD_POINTERS=1 diff --git a/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc index 180a95795..2e293af43 100644 --- a/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/beidou_b1i_pcps_acquisition.cc @@ -23,10 +23,15 @@ #include "beidou_b1i_signal_replica.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -52,10 +57,17 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition( LOG(INFO) << "role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); fs_in_ = acq_parameters_.fs_in; diff --git a/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc index a8204a24e..a5e41a125 100644 --- a/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/beidou_b3i_pcps_acquisition.cc @@ -21,9 +21,14 @@ #include "beidou_b3i_signal_replica.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -48,10 +53,17 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition( LOG(INFO) << "role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc index 4ba572b17..1efbcfe4d 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.cc @@ -21,9 +21,14 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_flags.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -52,16 +57,23 @@ GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition( dump_(configuration_->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_filename("../data/acquisition.dat"); + const std::string default_dump_filename("./acquisition.dat"); item_type_ = configuration_->property(role_ + ".item_type", default_item_type); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); dump_filename_ = configuration_->property(role_ + ".dump_filename", default_dump_filename); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif if (sampled_ms_ % 4 != 0) { diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h index 7548d1274..9e29e67a8 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_8ms_ambiguous_acquisition.h @@ -137,9 +137,9 @@ public: */ void stop_acquisition() override; - void set_state(int state __attribute__((unused))) override{}; + void set_state(int state __attribute__((unused))) override {}; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc index f4097b600..cace01b94 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition.cc @@ -22,9 +22,14 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_flags.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -51,10 +56,17 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( acq_parameters_.ms_per_code = 4; acq_parameters_.SetFromConfiguration(configuration_, role_, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_OPT_ACQ_FS_SPS); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc index 87e4c2d06..12c0426f8 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -21,7 +21,6 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_fft.h" #include "gnss_sdr_flags.h" -#include #include // for fft_complex #include // for gr_complex #include // for volk_32fc_conjugate_32fc @@ -30,6 +29,12 @@ #include // for abs, pow, floor #include // for complex +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, @@ -44,94 +49,41 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( out_streams_(out_streams), acquire_pilot_(configuration->property(role + ".acquire_pilot", false)) { - acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_B_CODE_LENGTH_CHIPS); + // Set acquisition parameters + acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_B_CODE_LENGTH_CHIPS); + // Query the capabilities of the instantiated FPGA Acquisition IP Core + std::vector> downsampling_filter_specs; + uint32_t max_FFT_size; + acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_0, downsampling_filter_specs, max_FFT_size); + + // Configure the automatic resampler according to the capabilities of the instantiated FPGA Acquisition IP Core. + // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + bool acq_configuration_valid = acq_parameters_.ConfigureAutomaticResampler(downsampling_filter_specs, max_FFT_size, GALILEO_E1_OPT_ACQ_FS_SPS); + + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L1/E1 band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } + + DLOG(INFO) << "role " << role; + + generate_galileo_e1_prn_codes(); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); - fs_in_ = acq_parameters_.fs_in; - - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.samples_per_code; - - // compute all the GALILEO E1 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time - // a channel is assigned) - auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT - volk_gnsssdr::vector> code(nsamples_total); // buffer for the local code - volk_gnsssdr::vector fft_codes_padded(nsamples_total); - d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * GALILEO_E1_NUMBER_OF_CODES); // memory containing all the possible fft codes for PRN 0 to 32 - - float max; // temporary maxima search - int32_t tmp; - int32_t tmp2; - int32_t local_code; - int32_t fft_data; - - for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++) - { - bool cboc = false; // cboc is set to 0 when using the FPGA - - if (acquire_pilot_ == true) - { - // set local signal generator to Galileo E1 pilot component (1C) - std::array pilot_signal = {{'1', 'C', '\0'}}; - galileo_e1_code_gen_complex_sampled(code, pilot_signal, - cboc, PRN, fs_in_, 0, false); - } - else - { - std::array data_signal = {{'1', 'B', '\0'}}; - galileo_e1_code_gen_complex_sampled(code, data_signal, - cboc, PRN, fs_in_, 0, false); - } - - for (uint32_t s = code_length; s < 2 * code_length; s++) - { - code[s] = code[s - code_length]; - } - - // fill in zero padding - for (uint32_t s = 2 * code_length; s < nsamples_total; s++) - { - code[s] = std::complex(0.0, 0.0); - } - - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values - - // normalize the code - max = 0; // initialize maximum value - for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima - { - if (std::abs(fft_codes_padded[i].real()) > max) - { - max = std::abs(fft_codes_padded[i].real()); - } - if (std::abs(fft_codes_padded[i].imag()) > max) - { - max = std::abs(fft_codes_padded[i].imag()); - } - } - // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs - // and package codes in a format that is ready to be written to the FPGA - for (uint32_t i = 0; i < nsamples_total; i++) - { - tmp = static_cast(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - tmp2 = static_cast(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part - fft_data = local_code & select_all_code_bits; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; - } - } - - acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); - - DLOG(INFO) << "role " << role_; - acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters_); if (in_streams_ > 1) { @@ -143,6 +95,81 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( } } +void GalileoE1PcpsAmbiguousAcquisitionFpga::generate_galileo_e1_prn_codes() +{ + uint32_t code_length = acq_parameters_.code_length; + uint32_t nsamples_total = acq_parameters_.fft_size; + + // compute all the GALILEO E1 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT + volk_gnsssdr::vector> code(nsamples_total); // buffer for the local code + volk_gnsssdr::vector fft_code(nsamples_total); + d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * GALILEO_E1_NUMBER_OF_CODES); // memory containing all the possible fft codes for PRN 0 to 32 + + float max; + int32_t tmp; + int32_t tmp2; + int32_t local_code; + int32_t fft_data; + for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++) + { + bool cboc = false; // cboc is set to 0 when using the FPGA + + if (acquire_pilot_ == true) + { + // set local signal generator to Galileo E1 pilot component (1C) + std::array pilot_signal = {{'1', 'C', '\0'}}; + galileo_e1_code_gen_complex_sampled(code, pilot_signal, + cboc, PRN, acq_parameters_.resampled_fs, 0, false); + } + else + { + std::array data_signal = {{'1', 'B', '\0'}}; + galileo_e1_code_gen_complex_sampled(code, data_signal, + cboc, PRN, acq_parameters_.resampled_fs, 0, false); + } + + if (acq_parameters_.enable_zero_padding) + { + // Duplicate the code sequence + std::copy(code.begin(), code.begin() + code_length, code.begin() + code_length); + // Fill in zero padding for the rest + std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); + } + + + std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_code.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values + + // normalize the code + max = 0; // initialize maximum value + for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_code[i].real()) > max) + { + max = std::abs(fft_code[i].real()); + } + if (std::abs(fft_code[i].imag()) > max) + { + max = std::abs(fft_code[i].imag()); + } + } + // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + // and package codes in a format that is ready to be written to the FPGA + for (uint32_t i = 0; i < nsamples_total; i++) + { + tmp = static_cast(floor(fft_code[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part + fft_data = local_code & SELECT_ALL_CODE_BITS; + d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + } + } + + acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); +} void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() { diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h index 09829267c..6e660fa7c 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -66,11 +66,11 @@ public: } /*! - * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga" + * \brief Returns "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA" */ inline std::string implementation() override { - return "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"; + return "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA"; } /*! @@ -179,20 +179,18 @@ public: /*! * \brief Set resampler latency */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: - static const uint32_t downsampling_factor_default = 4; - static const uint32_t fpga_buff_num = 0; // L1/E1 band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t ACQ_BUFF_0 = 0; // FPGA Acquisition IP buffer containing L1/E1 frequency band samples by default. + static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent + static const uint32_t QUANT_BITS_LOCAL_CODE = 16; + static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word + static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word + static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word + static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - // the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA - // expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking. - static const uint32_t quant_bits_local_code = 16; - static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t shl_code_bits = 65536; // shift left by 10 bits + void generate_galileo_e1_prn_codes(); pcps_acquisition_fpga_sptr acquisition_fpga_; volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts @@ -200,7 +198,6 @@ private: Gnss_Synchro* gnss_synchro_; Acq_Conf_Fpga acq_parameters_; std::string role_; - int64_t fs_in_; int32_t doppler_center_; uint32_t channel_; uint32_t doppler_max_; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc index c7af648aa..dab9dcc47 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.cc @@ -21,8 +21,12 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_flags.h" #include -#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition( const ConfigurationInterface* configuration, @@ -44,16 +48,23 @@ GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition dump_(configuration_->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_filename("../data/acquisition.dat"); + const std::string default_dump_filename("./acquisition.dat"); item_type_ = configuration_->property(role_ + ".item_type", default_item_type); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); dump_filename_ = configuration_->property(role_ + ".dump_filename", default_dump_filename); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif if (sampled_ms_ % 4 != 0) { diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h index ee0e56abb..bcda0172f 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_cccwsr_ambiguous_acquisition.h @@ -140,7 +140,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: float calculate_threshold(float pfa); diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc index 2632418a7..0e207b800 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.cc @@ -21,9 +21,14 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_flags.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -52,16 +57,23 @@ GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcqui dump_(configuration_->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_filename("../data/acquisition.dat"); + const std::string default_dump_filename("./acquisition.dat"); item_type_ = configuration_->property(role + ".item_type", default_item_type); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 4000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif /* --- Find number of samples per spreading code (4 ms) -----------------*/ code_length_ = static_cast(round( @@ -72,7 +84,7 @@ GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcqui DLOG(INFO) << "role " << role; /*Calculate the folding factor value based on the formula described in the paper. This may be a bug, but acquisition also work by variying the folding factor at va- - lues different that the expressed in the paper. In adition, it is important to point + lues different that the expressed in the paper. In addition, it is important to point out that by making the folding factor smaller we were able to get QuickSync work with Galileo. Future work should be directed to test this assumption statistically.*/ diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h index 8eb96a5e0..9bfd524c2 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_quicksync_ambiguous_acquisition.h @@ -143,7 +143,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: float calculate_threshold(float pfa) const; diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc index 59bd0e2a0..27a60b479 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.cc @@ -21,9 +21,14 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_flags.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -54,7 +59,7 @@ GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition( dump_(configuration_->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_filename("../data/acquisition.dat"); + const std::string default_dump_filename("./acquisition.dat"); DLOG(INFO) << "role " << role_; @@ -71,10 +76,17 @@ GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition( << sampled_ms_ << " ms will be used."; } +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif bool enable_monitor_output = configuration_->property("AcquisitionMonitor.enable_monitor", false); diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h index 7d9245148..786723ea8 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_tong_ambiguous_acquisition.h @@ -143,7 +143,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: float calculate_threshold(float pfa) const; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc index b51d12a73..153412bc0 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.cc @@ -27,9 +27,14 @@ #include "galileo_e5_signal_replica.h" #include "gnss_sdr_flags.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -61,16 +66,23 @@ GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf( dump_(configuration_->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_filename("../data/acquisition.dat"); + const std::string default_dump_filename("./acquisition.dat"); item_type_ = configuration_->property(role_ + ".item_type", default_item_type); dump_filename_ = configuration_->property(role_ + ".dump_filename", default_dump_filename); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 32000000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif DLOG(INFO) << "role " << role_; if (sampled_ms_ > 3) diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h index 4a5655080..805799f49 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_noncoherent_iq_acquisition_caf.h @@ -145,7 +145,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: float calculate_threshold(float pfa) const; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc index 3d9eee1fa..c18aa48c2 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition.cc @@ -21,10 +21,15 @@ #include "configuration_interface.h" #include "galileo_e5_signal_replica.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -51,10 +56,17 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition( acq_parameters_.ms_per_code = 1; acq_parameters_.SetFromConfiguration(configuration, role_, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_OPT_ACQ_FS_SPS); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc index f3c041952..c43787c84 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc @@ -21,7 +21,6 @@ #include "galileo_e5_signal_replica.h" #include "gnss_sdr_fft.h" #include "gnss_sdr_flags.h" -#include #include // for gr_complex #include // for volk_32fc_conjugate_32fc #include @@ -29,6 +28,12 @@ #include // for abs, pow, floor #include // for complex +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, @@ -43,24 +48,62 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga( acq_pilot_(configuration->property(role + ".acquire_pilot", false)), acq_iq_(configuration->property(role + ".acquire_iq", false)) { - acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_CODE_LENGTH_CHIPS); + // Set acquisition parameters + acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_CODE_LENGTH_CHIPS); + // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + std::vector> downsampling_filter_specs; + uint32_t max_FFT_size; + acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); + + // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + // Check whether the acquisition configuration is supported by the FPGA. + bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); + + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L5/E5a band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } + + DLOG(INFO) << "role " << role; + + generate_galileo_e5a_prn_codes(); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); - fs_in_ = acq_parameters_.fs_in; + if (in_streams_ > 1) + { + LOG(ERROR) << "This implementation only supports one input stream"; + } + if (out_streams_ > 0) + { + LOG(ERROR) << "This implementation does not provide an output stream"; + } +} + +void GalileoE5aPcpsAcquisitionFpga::generate_galileo_e5a_prn_codes() +{ uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.samples_per_code; + uint32_t nsamples_total = acq_parameters_.fft_size; // compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT volk_gnsssdr::vector> code(nsamples_total); - volk_gnsssdr::vector> fft_codes_padded(nsamples_total); + volk_gnsssdr::vector> fft_code(nsamples_total); d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * GALILEO_E5A_NUMBER_OF_CODES); // memory containing all the possible fft codes for PRN 0 to 32 if (acq_iq_) @@ -68,7 +111,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga( acq_pilot_ = false; } - float max; // temporary maxima search + float max; int32_t tmp; int32_t tmp2; int32_t local_code; @@ -93,63 +136,48 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga( signal_[1] = 'I'; } - galileo_e5_a_code_gen_complex_sampled(code, PRN, signal_, fs_in_, 0); + galileo_e5_a_code_gen_complex_sampled(code, PRN, signal_, acq_parameters_.fs_in, 0); - for (uint32_t s = code_length; s < 2 * code_length; s++) + if (acq_parameters_.enable_zero_padding) { - code[s] = code[s - code_length]; + // Duplicate the code sequence + std::copy(code.begin(), code.begin() + code_length, code.begin() + code_length); + // Fill in zero padding for the rest + std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); } - // fill in zero padding - for (uint32_t s = 2 * code_length; s < nsamples_total; s++) - { - code[s] = std::complex(0.0, 0.0); - } - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values + std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_code.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values max = 0; // initialize maximum value for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima { - if (std::abs(fft_codes_padded[i].real()) > max) + if (std::abs(fft_code[i].real()) > max) { - max = std::abs(fft_codes_padded[i].real()); + max = std::abs(fft_code[i].real()); } - if (std::abs(fft_codes_padded[i].imag()) > max) + if (std::abs(fft_code[i].imag()) > max) { - max = std::abs(fft_codes_padded[i].imag()); + max = std::abs(fft_code[i].imag()); } } // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs // and package codes in a format that is ready to be written to the FPGA for (uint32_t i = 0; i < nsamples_total; i++) { - tmp = static_cast(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - tmp2 = static_cast(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part - fft_data = local_code & select_all_code_bits; + tmp = static_cast(floor(fft_code[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part + fft_data = local_code & SELECT_ALL_CODE_BITS; d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); - - DLOG(INFO) << "role " << role_; - acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters_); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } - void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() { // stop the acquisition and the other FPGA modules. diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h index 12d38bf34..2b210c729 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -66,11 +66,11 @@ public: } /*! - * \brief Returns "Galileo_E5a_Pcps_Acquisition_Fpga" + * \brief Returns "Galileo_E5a_Pcps_Acquisition_FPGA" */ inline std::string implementation() override { - return "Galileo_E5a_Pcps_Acquisition_Fpga"; + return "Galileo_E5a_Pcps_Acquisition_FPGA"; } /*! @@ -186,20 +186,18 @@ public: /*! * \brief Set resampler latency */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: - static const uint32_t downsampling_factor_default = 1; - static const uint32_t fpga_buff_num = 1; // L5/E5a band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. + static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent + static const uint32_t QUANT_BITS_LOCAL_CODE = 16; + static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word + static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word + static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word + static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - // the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA - // expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking. - static const uint32_t quant_bits_local_code = 16; - static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t shl_code_bits = 65536; // shift left by 10 bits + void generate_galileo_e5a_prn_codes(); pcps_acquisition_fpga_sptr acquisition_fpga_; std::weak_ptr channel_fsm_; @@ -207,7 +205,6 @@ private: Gnss_Synchro* gnss_synchro_; Acq_Conf_Fpga acq_parameters_; std::string role_; - int64_t fs_in_; int32_t doppler_center_; uint32_t channel_; uint32_t doppler_max_; diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc index 5f8af8baf..11ecebcdd 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition.cc @@ -22,10 +22,15 @@ #include "configuration_interface.h" #include "galileo_e5_signal_replica.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -51,10 +56,17 @@ GalileoE5bPcpsAcquisition::GalileoE5bPcpsAcquisition(const ConfigurationInterfac acq_parameters_.ms_per_code = 1; acq_parameters_.SetFromConfiguration(configuration, role_, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_OPT_ACQ_FS_SPS); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc index 83996b5c8..b83eb623c 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc @@ -22,13 +22,18 @@ #include "galileo_e5_signal_replica.h" #include "gnss_sdr_fft.h" #include "gnss_sdr_flags.h" -#include #include // for gr_complex #include // for volk_32fc_conjugate_32fc #include // for copy_n #include // for abs, pow, floor #include // for complex +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, @@ -43,23 +48,62 @@ GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const Configuration acq_pilot_(configuration->property(role + ".acquire_pilot", false)), acq_iq_(configuration->property(role + ".acquire_iq", false)) { - acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_CODE_LENGTH_CHIPS); + // Set acquisition parameters + acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_CODE_LENGTH_CHIPS); + + // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + std::vector> downsampling_filter_specs; + uint32_t max_FFT_size; + acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); + + // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + // Check whether the acquisition configuration is supported by the FPGA. + bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); + + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the E5b band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } + + DLOG(INFO) << "role " << role; + + generate_galileo_e5b_prn_codes(); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); - fs_in_ = acq_parameters_.fs_in; + if (in_streams_ > 1) + { + LOG(ERROR) << "This implementation only supports one input stream"; + } + if (out_streams_ > 0) + { + LOG(ERROR) << "This implementation does not provide an output stream"; + } +} + +void GalileoE5bPcpsAcquisitionFpga::generate_galileo_e5b_prn_codes() +{ uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.samples_per_code; + uint32_t nsamples_total = acq_parameters_.fft_size; // compute all the GALILEO E5b PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time // a channel is assigned) auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT volk_gnsssdr::vector> code(nsamples_total); // Buffer for local code - volk_gnsssdr::vector> fft_codes_padded(nsamples_total); + volk_gnsssdr::vector> fft_code(nsamples_total); d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * GALILEO_E5B_NUMBER_OF_CODES); // memory containing all the possible fft codes for PRN 0 to 32 if (acq_iq_) @@ -67,7 +111,7 @@ GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const Configuration acq_pilot_ = false; } - float max; // temporary maxima search + float max; int32_t tmp; int32_t tmp2; int32_t local_code; @@ -92,62 +136,48 @@ GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const Configuration signal_[1] = 'I'; } - galileo_e5_b_code_gen_complex_sampled(code, PRN, signal_, fs_in_, 0); + galileo_e5_b_code_gen_complex_sampled(code, PRN, signal_, acq_parameters_.fs_in, 0); - for (uint32_t s = code_length; s < 2 * code_length; s++) + if (acq_parameters_.enable_zero_padding) { - code[s] = code[s - code_length]; + // Duplicate the code sequence + std::copy(code.begin(), code.begin() + code_length, code.begin() + code_length); + // Fill in zero padding for the rest + std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); } - // fill in zero padding - for (uint32_t s = 2 * code_length; s < nsamples_total; s++) - { - code[s] = std::complex(0.0, 0.0); - } - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values + std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_code.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values max = 0; // initialize maximum value for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima { - if (std::abs(fft_codes_padded[i].real()) > max) + if (std::abs(fft_code[i].real()) > max) { - max = std::abs(fft_codes_padded[i].real()); + max = std::abs(fft_code[i].real()); } - if (std::abs(fft_codes_padded[i].imag()) > max) + if (std::abs(fft_code[i].imag()) > max) { - max = std::abs(fft_codes_padded[i].imag()); + max = std::abs(fft_code[i].imag()); } } // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs // and package codes in a format that is ready to be written to the FPGA for (uint32_t i = 0; i < nsamples_total; i++) { - tmp = static_cast(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - tmp2 = static_cast(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part - fft_data = local_code & select_all_code_bits; + tmp = static_cast(floor(fft_code[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part + fft_data = local_code & SELECT_ALL_CODE_BITS; d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; } } acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); - - acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters_); - - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 0) - { - LOG(ERROR) << "This implementation does not provide an output stream"; - } } - void GalileoE5bPcpsAcquisitionFpga::stop_acquisition() { // this command causes the SW to reset the HW. diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h index 8ae54e46a..68707647c 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h @@ -65,7 +65,7 @@ public: } /*! - * \brief Returns "Galileo_E5b_Pcps_Acquisition_Fpga" + * \brief Returns "Galileo_E5b_Pcps_Acquisition_FPGA" */ inline std::string implementation() override { @@ -185,20 +185,18 @@ public: /*! * \brief Set resampler latency */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: - static const uint32_t downsampling_factor_default = 1; - static const uint32_t fpga_buff_num = 1; // E5b band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. + static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent + static const uint32_t QUANT_BITS_LOCAL_CODE = 16; + static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word + static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word + static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word + static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - // the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA - // expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking. - static const uint32_t quant_bits_local_code = 16; - static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t shl_code_bits = 65536; // shift left by 10 bits + void generate_galileo_e5b_prn_codes(); pcps_acquisition_fpga_sptr acquisition_fpga_; volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts @@ -207,7 +205,6 @@ private: Gnss_Synchro* gnss_synchro_; Acq_Conf_Fpga acq_parameters_; std::string role_; - int64_t fs_in_; int32_t doppler_center_; uint32_t channel_; uint32_t doppler_max_; diff --git a/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc index eda68fb66..dd76d0d98 100644 --- a/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/galileo_e6_pcps_acquisition.cc @@ -21,9 +21,14 @@ #include "configuration_interface.h" #include "galileo_e6_signal_replica.h" #include "gnss_sdr_flags.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -51,10 +56,17 @@ GalileoE6PcpsAcquisition::GalileoE6PcpsAcquisition( DLOG(INFO) << "role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc index c63eb5ec7..628c96d25 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.cc @@ -23,9 +23,14 @@ #include "configuration_interface.h" #include "glonass_l1_signal_replica.h" #include "gnss_sdr_flags.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -51,10 +56,17 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( DLOG(INFO) << "role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h index 7a30d725d..533508fd7 100644 --- a/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l1_ca_pcps_acquisition.h @@ -147,7 +147,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc index 180f50747..46b6790a4 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.cc @@ -22,9 +22,14 @@ #include "configuration_interface.h" #include "glonass_l2_signal_replica.h" #include "gnss_sdr_flags.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -50,10 +55,17 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( DLOG(INFO) << "role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h index 5cce50b40..b8a6adf45 100644 --- a/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h +++ b/src/algorithms/acquisition/adapters/glonass_l2_ca_pcps_acquisition.h @@ -146,7 +146,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: pcps_acquisition_sptr acquisition_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc index 72994eebc..6992b7260 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition.cc @@ -25,9 +25,14 @@ #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -54,10 +59,17 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( DLOG(INFO) << "role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc index ffe4ca5d2..f119a60c4 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.cc @@ -24,8 +24,12 @@ #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" -#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler( const ConfigurationInterface* configuration, @@ -57,10 +61,17 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler( acq_parameters.dump = dump_; dump_filename_ = configuration->property(role_ + ".dump_filename", std::move(default_dump_filename)); acq_parameters.dump_filename = dump_filename_; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif acq_parameters.doppler_max = doppler_max_; acq_parameters.sampled_ms = sampled_ms_; acq_parameters.max_dwells = max_dwells_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h index c5e27ece5..9288a1ce6 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fine_doppler.h @@ -142,7 +142,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: pcps_acquisition_fine_doppler_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index cc2713d24..226078036 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -24,13 +24,18 @@ #include "gnss_sdr_fft.h" #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" -#include #include // for gr_complex #include // for volk_32fc_conjugate_32fc #include // for copy_n #include // for abs, pow, floor #include // for complex +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, @@ -43,81 +48,41 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( in_streams_(in_streams), out_streams_(out_streams) { - acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_CODE_LENGTH_CHIPS); + // set acquisition parameters + acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_CODE_LENGTH_CHIPS); + + // Query the capabilities of the instantiated FPGA Acquisition IP Core + std::vector> downsampling_filter_specs; + uint32_t max_FFT_size; + acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_0, downsampling_filter_specs, max_FFT_size); + + // Configure the automatic resampler according to the capabilities of the instantiated FPGA Acquisition IP Core. + // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + bool acq_configuration_valid = acq_parameters_.ConfigureAutomaticResampler(downsampling_filter_specs, max_FFT_size, GPS_L1_CA_OPT_ACQ_FS_SPS); + + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L1/E1 band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } DLOG(INFO) << "role " << role; + generate_gps_l1_ca_prn_codes(); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); - fs_in_ = acq_parameters_.fs_in; - - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.samples_per_code; - - // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time - // a channel is assigned) - auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); - // allocate memory to compute all the PRNs and compute all the possible codes - volk_gnsssdr::vector> code(nsamples_total); - volk_gnsssdr::vector> fft_codes_padded(nsamples_total); - d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32 - float max; - int32_t tmp; - int32_t tmp2; - int32_t local_code; - int32_t fft_data; - // temporary maxima search - for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) - { - gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in_, 0); // generate PRN code - - for (uint32_t s = code_length; s < 2 * code_length; s++) - { - code[s] = code[s - code_length]; - } - - // fill in zero padding - for (uint32_t s = 2 * code_length; s < nsamples_total; s++) - { - code[s] = std::complex(0.0, 0.0); - } - - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values - - max = 0; // initialize maximum value - for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima - { - if (std::abs(fft_codes_padded[i].real()) > max) - { - max = std::abs(fft_codes_padded[i].real()); - } - if (std::abs(fft_codes_padded[i].imag()) > max) - { - max = std::abs(fft_codes_padded[i].imag()); - } - } - // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs - // and package codes in a format that is ready to be written to the FPGA - for (uint32_t i = 0; i < nsamples_total; i++) - { - tmp = static_cast(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - tmp2 = static_cast(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part - fft_data = local_code & select_all_code_bits; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; - } - } - - // acq_parameters - acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); - - acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters_); if (in_streams_ > 1) { @@ -129,6 +94,66 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( } } +void GpsL1CaPcpsAcquisitionFpga::generate_gps_l1_ca_prn_codes() +{ + uint32_t code_length = acq_parameters_.code_length; + uint32_t nsamples_total = acq_parameters_.fft_size; + + // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); + // allocate memory to compute all the PRNs and compute all the possible codes + volk_gnsssdr::vector> code(nsamples_total); + volk_gnsssdr::vector> fft_code(nsamples_total); + d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32 + float max; + int32_t tmp; + int32_t tmp2; + int32_t local_code; + int32_t fft_data; + // temporary maxima search + for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) + { + gps_l1_ca_code_gen_complex_sampled(code, PRN, acq_parameters_.resampled_fs, 0); // generate PRN code + + if (acq_parameters_.enable_zero_padding) + { + // Duplicate the code sequence + std::copy(code.begin(), code.begin() + code_length, code.begin() + code_length); + // Fill in zero padding for the rest + std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); + } + + std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_code.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values + + max = 0; // initialize maximum value + for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_code[i].real()) > max) + { + max = std::abs(fft_code[i].real()); + } + if (std::abs(fft_code[i].imag()) > max) + { + max = std::abs(fft_code[i].imag()); + } + } + // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + // and package codes in a format that is ready to be written to the FPGA + for (uint32_t i = 0; i < nsamples_total; i++) + { + tmp = static_cast(floor(fft_code[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + tmp2 = static_cast(floor(fft_code[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part + fft_data = local_code & SELECT_ALL_CODE_BITS; + d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + } + } + + acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); +} void GpsL1CaPcpsAcquisitionFpga::stop_acquisition() { diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index cfc483cda..e0dc57672 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -67,11 +67,11 @@ public: } /*! - * \brief Returns "GPS_L1_CA_PCPS_Acquisition_Fpga" + * \brief Returns "GPS_L1_CA_PCPS_Acquisition_FPGA" */ inline std::string implementation() override { - return "GPS_L1_CA_PCPS_Acquisition_Fpga"; + return "GPS_L1_CA_PCPS_Acquisition_FPGA"; } /*! @@ -182,21 +182,19 @@ public: /*! * \brief Set Resampler Latency */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: + static const uint32_t ACQ_BUFF_0 = 0; // FPGA Acquisition IP buffer containing L1/E1 frequency band samples by default. + static const uint32_t DEFAULT_FPGA_BLK_EXP = 10; // default block exponent static const uint32_t NUM_PRNs = 32; - static const uint32_t downsampling_factor_default = 4; - static const uint32_t fpga_buff_num = 0; // L1/E1 band - static const uint32_t fpga_blk_exp = 10; // default block exponent + static const uint32_t QUANT_BITS_LOCAL_CODE = 16; + static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word + static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word + static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word + static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits - // the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA - // expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking. - static const uint32_t quant_bits_local_code = 16; - static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t shl_code_bits = 65536; // shift left by 10 bits + void generate_gps_l1_ca_prn_codes(); pcps_acquisition_fpga_sptr acquisition_fpga_; std::weak_ptr channel_fsm_; @@ -204,7 +202,6 @@ private: Gnss_Synchro* gnss_synchro_; Acq_Conf_Fpga acq_parameters_; std::string role_; - int64_t fs_in_; int32_t doppler_center_; uint32_t channel_; uint32_t doppler_max_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc index 98fb0b9c6..0bd82c2dc 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.cc @@ -23,8 +23,12 @@ #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" -#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition( const ConfigurationInterface* configuration, @@ -51,10 +55,17 @@ GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition( int64_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_min_ = configuration->property(role_ + ".doppler_min", -doppler_max_); bool enable_monitor_output = configuration->property("AcquisitionMonitor.enable_monitor", false); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h index 6a2cfde4c..e5acbed3f 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_assisted_acquisition.h @@ -130,14 +130,14 @@ public: * \brief Restart acquisition algorithm */ void reset() override; - void set_state(int state __attribute__((unused))) override{}; + void set_state(int state __attribute__((unused))) override {}; /*! * \brief Stop running acquisition */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: pcps_assisted_acquisition_cc_sptr acquisition_cc_; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc index 05d26212c..e0352f9b2 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.cc @@ -21,9 +21,14 @@ #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -58,10 +63,17 @@ GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition( fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); dump_ = configuration->property(role + ".dump", false); doppler_max_ = configuration->property(role + ".doppler_max", 5000); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif sampled_ms_ = configuration->property(role + ".coherent_integration_time_ms", 1); bit_transition_flag_ = configuration->property("Acquisition.bit_transition_flag", false); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h index 331f8c84b..084c0a5c4 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_opencl_acquisition.h @@ -131,14 +131,14 @@ public: * \brief Restart acquisition algorithm */ void reset() override; - void set_state(int state __attribute__((unused))) override{}; + void set_state(int state __attribute__((unused))) override {}; /*! * \brief Stop running acquisition */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; inline bool opencl_ready() const { diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc index db6451541..9fd146be2 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.cc @@ -22,9 +22,14 @@ #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -58,10 +63,17 @@ GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition( int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif // -- Find number of samples per spreading code ------------------------- code_length_ = static_cast(round(fs_in_ / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h index c148fa6c0..5ae294ae8 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_quicksync_acquisition.h @@ -145,7 +145,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: float calculate_threshold(float pfa) const; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc index 7dca40c3a..63efcab00 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.cc @@ -21,9 +21,14 @@ #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -63,10 +68,17 @@ GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition( fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); dump_filename_ = configuration_->property(role_ + ".dump_filename", std::move(default_dump_filename)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { doppler_max_ = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + doppler_max_ = absl::GetFlag(FLAGS_doppler_max); + } +#endif bool enable_monitor_output = configuration_->property("AcquisitionMonitor.enable_monitor", false); // -- Find number of samples per spreading code ------------------------- diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h index 336a1f1f9..8cba53e04 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_tong_acquisition.h @@ -143,7 +143,7 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: float calculate_threshold(float pfa) const; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc index f2e491690..0b61172b1 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition.cc @@ -23,9 +23,14 @@ #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include "gps_l2c_signal_replica.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -52,10 +57,17 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( DLOG(INFO) << "Role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); item_type_ = acq_parameters_.item_type; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc index ecce4df4c..91c90db90 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc @@ -23,7 +23,6 @@ #include "gnss_sdr_fft.h" #include "gnss_sdr_flags.h" #include "gps_l2c_signal_replica.h" -#include #include // for gr_complex #include // for volk_32fc_conjugate_32fc #include @@ -31,6 +30,12 @@ #include // for abs, pow, floor #include // for complex +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, @@ -43,76 +48,41 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( in_streams_(in_streams), out_streams_(out_streams) { - acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GPS_L2_M_CODE_RATE_CPS, GPS_L2_M_CODE_LENGTH_CHIPS); + // Set acquisition parameters + acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GPS_L2_M_CODE_RATE_CPS, GPS_L2_M_CODE_LENGTH_CHIPS); - LOG(INFO) << "role " << role; + // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + std::vector> downsampling_filter_specs; + uint32_t max_FFT_size; + acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); + // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + // Check whether the acquisition configuration is supported by the FPGA. + bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); + + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L2 band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } + + DLOG(INFO) << "role " << role; + + generate_gps_l2c_m_prn_codes(); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); - fs_in_ = acq_parameters_.fs_in; - - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.samples_per_code; - - // compute all the GPS L2C PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time - // a channel is assigned) - auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT - // allocate memory to compute all the PRNs and compute all the possible codes - volk_gnsssdr::vector> code(nsamples_total); - volk_gnsssdr::vector> fft_codes_padded(nsamples_total); - d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32 - - float max; // temporary maxima search - int32_t tmp; - int32_t tmp2; - int32_t local_code; - int32_t fft_data; - - for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) - { - gps_l2c_m_code_gen_complex_sampled(code, PRN, fs_in_); - // fill in zero padding - for (unsigned int s = code_length; s < nsamples_total; s++) - { - code[s] = std::complex(0.0, 0.0); - } - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values - max = 0; // initialize maximum value - for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima - { - if (std::abs(fft_codes_padded[i].real()) > max) - { - max = std::abs(fft_codes_padded[i].real()); - } - if (std::abs(fft_codes_padded[i].imag()) > max) - { - max = std::abs(fft_codes_padded[i].imag()); - } - } - // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs - // and package codes in a format that is ready to be written to the FPGA - for (uint32_t i = 0; i < nsamples_total; i++) - { - tmp = static_cast(floor(fft_codes_padded[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); - tmp2 = static_cast(floor(fft_codes_padded[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); - local_code = (tmp & SELECT_LSBits) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBbits); // put together the real part and the imaginary part - fft_data = local_code & SELECT_ALL_CODE_BITS; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; - - // d_all_fft_codes_[i + nsamples_total * (PRN - 1)] = lv_16sc_t(static_cast(floor(fft_codes_padded[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)), - // static_cast(floor(fft_codes_padded[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max))); - } - } - - acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); - - acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters_); if (in_streams_ > 1) { @@ -124,6 +94,66 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( } } +void GpsL2MPcpsAcquisitionFpga::generate_gps_l2c_m_prn_codes() +{ + uint32_t code_length = acq_parameters_.code_length; + uint32_t nsamples_total = acq_parameters_.fft_size; + + // compute all the GPS L2C PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT + // allocate memory to compute all the PRNs and compute all the possible codes + volk_gnsssdr::vector> code(nsamples_total); + volk_gnsssdr::vector> fft_codes(nsamples_total); + d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32 + + float max; + int32_t tmp; + int32_t tmp2; + int32_t local_code; + int32_t fft_data; + + for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) + { + gps_l2c_m_code_gen_complex_sampled(code, PRN, acq_parameters_.fs_in); + + if (acq_parameters_.enable_zero_padding) + { + // Duplicate the code sequence + std::copy(code.begin(), code.begin() + code_length, code.begin() + code_length); + // Fill in zero padding for the rest + std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); + } + + std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values + max = 0; // initialize maximum value + for (unsigned int i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes[i].real()) > max) + { + max = std::abs(fft_codes[i].real()); + } + if (std::abs(fft_codes[i].imag()) > max) + { + max = std::abs(fft_codes[i].imag()); + } + } + // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + // and package codes in a format that is ready to be written to the FPGA + for (uint32_t i = 0; i < nsamples_total; i++) + { + tmp = static_cast(floor(fft_codes[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + tmp2 = static_cast(floor(fft_codes[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part + fft_data = local_code & SELECT_ALL_CODE_BITS; + d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + } + } + + acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); +} void GpsL2MPcpsAcquisitionFpga::stop_acquisition() { @@ -210,7 +240,7 @@ void GpsL2MPcpsAcquisitionFpga::disconnect(gr::top_block_sptr top_block) if (top_block) { /* top_block is not null */ }; - // Nothing to diconnect + // Nothing to disconnect } diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h index 19acec8cb..4e1b8c8ac 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h @@ -60,11 +60,11 @@ public: } /*! - * \brief Returns "GPS_L2_M_PCPS_Acquisition_Fpga" + * \brief Returns "GPS_L2_M_PCPS_Acquisition_FPGA" */ inline std::string implementation() override { - return "GPS_L2_M_PCPS_Acquisition_Fpga"; + return "GPS_L2_M_PCPS_Acquisition_FPGA"; } inline size_t item_size() override @@ -147,27 +147,26 @@ public: */ void stop_acquisition() override; - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: - static const uint32_t downsampling_factor_default = 1; - static const uint32_t fpga_buff_num = 0; // L2 band - static const uint32_t fpga_blk_exp = 13; // default block exponent - + static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. + static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent static const uint32_t NUM_PRNs = 32; static const uint32_t QUANT_BITS_LOCAL_CODE = 16; - static const uint32_t SELECT_LSBits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word + static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word + static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits + void generate_gps_l2c_m_prn_codes(); + pcps_acquisition_fpga_sptr acquisition_fpga_; volk_gnsssdr::vector d_all_fft_codes_; // memory that contains all the code ffts std::weak_ptr channel_fsm_; Gnss_Synchro* gnss_synchro_; Acq_Conf_Fpga acq_parameters_; std::string role_; - int64_t fs_in_; float threshold_; unsigned int channel_; unsigned int doppler_max_; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc index 35b889994..b901c2db3 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition.cc @@ -23,8 +23,14 @@ #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include "gps_l5_signal_replica.h" -#include #include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_STD_SPAN #include namespace own = std; @@ -51,10 +57,17 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( DLOG(INFO) << "role " << role; +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc index a96bf531d..29b1a1887 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc @@ -24,7 +24,6 @@ #include "gnss_sdr_fft.h" #include "gnss_sdr_flags.h" #include "gps_l5_signal_replica.h" -#include #include // for gr_complex #include // for volk_32fc_conjugate_32fc #include @@ -32,6 +31,12 @@ #include // for abs, pow, floor #include // for complex +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( const ConfigurationInterface* configuration, const std::string& role, @@ -44,79 +49,41 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( in_streams_(in_streams), out_streams_(out_streams) { - acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GPS_L5I_CODE_RATE_CPS, GPS_L5I_CODE_LENGTH_CHIPS); + // Set acquisition parameters + acq_parameters_.SetFromConfiguration(configuration, role_, DEFAULT_FPGA_BLK_EXP, GPS_L5I_CODE_RATE_CPS, GPS_L5I_CODE_LENGTH_CHIPS); - LOG(INFO) << "role " << role; + // Query the capabilities of the instantiated FPGA Acquisition IP Core. When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + std::vector> downsampling_filter_specs; + uint32_t max_FFT_size; + acquisition_fpga_ = pcps_make_acquisition_fpga(&acq_parameters_, ACQ_BUFF_1, downsampling_filter_specs, max_FFT_size); + // When the FPGA is in use, the acquisition resampler operates only in the L1/E1 frequency band. + // Check whether the acquisition configuration is supported by the FPGA. + bool acq_configuration_valid = acq_parameters_.Is_acq_config_valid(max_FFT_size); + + if (!acq_configuration_valid) + { + std::cout << "The FPGA acquisition IP does not support the required sampling frequency of " << acq_parameters_.fs_in << " SPS for the L5/E5a band. Please update the sampling frequency in the configuration file." << std::endl; + exit(0); + } + + DLOG(INFO) << "role " << role; + + generate_gps_l5i_prn_codes(); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; } +#else + if (absl::GetFlag(FLAGS_doppler_max) != 0) + { + acq_parameters_.doppler_max = absl::GetFlag(FLAGS_doppler_max); + } +#endif doppler_max_ = acq_parameters_.doppler_max; doppler_step_ = static_cast(acq_parameters_.doppler_step); - fs_in_ = acq_parameters_.fs_in; - - uint32_t code_length = acq_parameters_.code_length; - uint32_t nsamples_total = acq_parameters_.samples_per_code; - - // compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time - // a channel is assigned) - auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT - volk_gnsssdr::vector> code(nsamples_total); - volk_gnsssdr::vector> fft_codes_padded(nsamples_total); - d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32 - - float max; // temporary maxima search - int32_t tmp; - int32_t tmp2; - int32_t local_code; - int32_t fft_data; - - for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) - { - gps_l5i_code_gen_complex_sampled(code, PRN, fs_in_); - - for (uint32_t s = code_length; s < 2 * code_length; s++) - { - code[s] = code[s - code_length]; - } - - for (uint32_t s = 2 * code_length; s < nsamples_total; s++) - { - // fill in zero padding - code[s] = std::complex(0.0, 0.0); - } - std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer - fft_if->execute(); // Run the FFT of local code - volk_32fc_conjugate_32fc(fft_codes_padded.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values - - max = 0; // initialize maximum value - for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima - { - if (std::abs(fft_codes_padded[i].real()) > max) - { - max = std::abs(fft_codes_padded[i].real()); - } - if (std::abs(fft_codes_padded[i].imag()) > max) - { - max = std::abs(fft_codes_padded[i].imag()); - } - } - // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs - // and package codes in a format that is ready to be written to the FPGA - for (uint32_t i = 0; i < nsamples_total; i++) - { - tmp = static_cast(floor(fft_codes_padded[i].real() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - tmp2 = static_cast(floor(fft_codes_padded[i].imag() * (pow(2, quant_bits_local_code - 1) - 1) / max)); - local_code = (tmp & select_lsbits) | ((tmp2 * shl_code_bits) & select_msbits); // put together the real part and the imaginary part - fft_data = local_code & select_all_code_bits; - d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; - } - } - - acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); - - acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters_); if (in_streams_ > 1) { @@ -128,6 +95,66 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( } } +void GpsL5iPcpsAcquisitionFpga::generate_gps_l5i_prn_codes() +{ + uint32_t code_length = acq_parameters_.code_length; + uint32_t nsamples_total = acq_parameters_.fft_size; + + // compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time + // a channel is assigned) + auto fft_if = gnss_fft_fwd_make_unique(nsamples_total); // Direct FFT + volk_gnsssdr::vector> code(nsamples_total); + volk_gnsssdr::vector> fft_codes(nsamples_total); + d_all_fft_codes_ = volk_gnsssdr::vector(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32 + + float max; + int32_t tmp; + int32_t tmp2; + int32_t local_code; + int32_t fft_data; + + for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) + { + gps_l5i_code_gen_complex_sampled(code, PRN, acq_parameters_.fs_in); + + if (acq_parameters_.enable_zero_padding) + { + // Duplicate the code sequence + std::copy(code.begin(), code.begin() + code_length, code.begin() + code_length); + // Fill in zero padding for the rest + std::fill(code.begin() + (acq_parameters_.enable_zero_padding ? 2 * code_length : code_length), code.end(), std::complex(0.0, 0.0)); + } + + std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer + fft_if->execute(); // Run the FFT of local code + volk_32fc_conjugate_32fc(fft_codes.data(), fft_if->get_outbuf(), nsamples_total); // conjugate values + + max = 0; // initialize maximum value + for (uint32_t i = 0; i < nsamples_total; i++) // search for maxima + { + if (std::abs(fft_codes[i].real()) > max) + { + max = std::abs(fft_codes[i].real()); + } + if (std::abs(fft_codes[i].imag()) > max) + { + max = std::abs(fft_codes[i].imag()); + } + } + // map the FFT to the dynamic range of the fixed point values an copy to buffer containing all FFTs + // and package codes in a format that is ready to be written to the FPGA + for (uint32_t i = 0; i < nsamples_total; i++) + { + tmp = static_cast(floor(fft_codes[i].real() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + tmp2 = static_cast(floor(fft_codes[i].imag() * (pow(2, QUANT_BITS_LOCAL_CODE - 1) - 1) / max)); + local_code = (tmp & SELECT_LSBITS) | ((tmp2 * SHL_CODE_BITS) & SELECT_MSBITS); // put together the real part and the imaginary part + fft_data = local_code & SELECT_ALL_CODE_BITS; + d_all_fft_codes_[i + (nsamples_total * (PRN - 1))] = fft_data; + } + } + + acq_parameters_.all_fft_codes = d_all_fft_codes_.data(); +} void GpsL5iPcpsAcquisitionFpga::stop_acquisition() { diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h index 497ab9b90..e3b97df39 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -69,11 +69,11 @@ public: } /*! - * \brief Returns "GPS_L5i_PCPS_Acquisition_Fpga" + * \brief Returns "GPS_L5i_PCPS_Acquisition_FPGA" */ inline std::string implementation() override { - return "GPS_L5i_PCPS_Acquisition_Fpga"; + return "GPS_L5i_PCPS_Acquisition_FPGA"; } /*! @@ -182,22 +182,19 @@ public: /*! * \brief Set resampler latency */ - void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; + void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override {}; private: + static const uint32_t ACQ_BUFF_1 = 1; // FPGA Acquisition IP buffer containing L2 or L5/E5 frequency band samples by default. + static const uint32_t DEFAULT_FPGA_BLK_EXP = 13; // default block exponent static const uint32_t NUM_PRNs = 32; - static const uint32_t downsampling_factor_default = 1; - static const uint32_t fpga_buff_num = 1; // L5/E5a band - static const uint32_t fpga_blk_exp = 13; // default block exponent - - // the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA - // expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking. - static const uint32_t quant_bits_local_code = 16; - static const uint32_t select_lsbits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t select_msbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t select_all_code_bits = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t shl_code_bits = 65536; // shift left by 10 bits + static const uint32_t QUANT_BITS_LOCAL_CODE = 16; + static const uint32_t SELECT_LSBITS = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word + static const uint32_t SELECT_MSBITS = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word + static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word + static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits + void generate_gps_l5i_prn_codes(); float calculate_threshold(float pfa); pcps_acquisition_fpga_sptr acquisition_fpga_; @@ -206,7 +203,6 @@ private: Gnss_Synchro* gnss_synchro_; Acq_Conf_Fpga acq_parameters_; std::string role_; - int64_t fs_in_; int32_t doppler_center_; uint32_t channel_; uint32_t doppler_max_; diff --git a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt index fdeb3981e..de689f5b3 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/acquisition/gnuradio_blocks/CMakeLists.txt @@ -65,11 +65,16 @@ target_link_libraries(acquisition_gr_blocks Volk::volk Volkgnsssdr::volkgnsssdr PRIVATE - Gflags::gflags - Glog::glog Matio::matio ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(acquisition_gr_blocks PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(acquisition_gr_blocks PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(acquisition_gr_blocks PRIVATE absl::flags absl::log) +endif() + target_include_directories(acquisition_gr_blocks PRIVATE ${GNSSSDR_SOURCE_DIR}/src/core/receiver diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc index 7851aff79..b9e962959 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_e5a_noncoherent_iq_acquisition_caf_cc.cc @@ -23,7 +23,6 @@ #include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h" #include "MATH_CONSTANTS.h" -#include #include #include #include @@ -32,6 +31,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc( unsigned int sampled_ms, @@ -238,8 +243,8 @@ void galileo_e5a_noncoherentIQ_acquisition_caf_cc::init() // Count the number of bins d_num_doppler_bins = 0; for (int doppler = -d_doppler_max; - doppler <= d_doppler_max; - doppler += d_doppler_step) + doppler <= d_doppler_max; + doppler += d_doppler_step) { d_num_doppler_bins++; } @@ -586,7 +591,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items std::stringstream filename; std::streamsize n = sizeof(float) * (d_fft_size); // noncomplex file write filename.str(""); - filename << "../data/test_statistics_E5a_sat_" + filename << "./test_statistics_E5a_sat_" << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); if (d_sampled_ms > 1) // If integration time > 1 code @@ -689,7 +694,7 @@ int galileo_e5a_noncoherentIQ_acquisition_caf_cc::general_work(int noutput_items std::stringstream filename; std::streamsize n = sizeof(float) * (d_num_doppler_bins); // noncomplex file write filename.str(""); - filename << "../data/test_statistics_E5a_sat_" << d_gnss_synchro->PRN << "_CAF.dat"; + filename << "./test_statistics_E5a_sat_" << d_gnss_synchro->PRN << "_CAF.dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); d_dump_file.write(reinterpret_cast(d_CAF_vector.data()), n); d_dump_file.close(); diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc index 7dad27c45..d684dd7da 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc @@ -17,7 +17,6 @@ #include "galileo_pcps_8ms_acquisition_cc.h" #include "MATH_CONSTANTS.h" -#include #include #include #include @@ -26,6 +25,11 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif galileo_pcps_8ms_acquisition_cc_sptr galileo_pcps_8ms_make_acquisition_cc( uint32_t sampled_ms, @@ -157,8 +161,8 @@ void galileo_pcps_8ms_acquisition_cc::init() // Count the number of bins d_num_doppler_bins = 0; for (auto doppler = static_cast(-d_doppler_max); - doppler <= static_cast(d_doppler_max); - doppler += d_doppler_step) + doppler <= static_cast(d_doppler_max); + doppler += d_doppler_step) { d_num_doppler_bins++; } @@ -332,7 +336,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, std::stringstream filename; std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write filename.str(""); - filename << "../data/test_statistics_" << d_gnss_synchro->System + filename << "./test_statistics_" << d_gnss_synchro->System << "_" << d_gnss_synchro->Signal[0] << d_gnss_synchro->Signal[1] << "_sat_" << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 5aa106bf3..231d3ee18 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -37,8 +37,15 @@ #include #include // for floor, fmod, rint, ceil #include +#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_) { @@ -523,7 +530,10 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t& { doppler = static_cast(d_doppler_center_step_two + (static_cast(index_doppler) - static_cast(floor(d_num_doppler_bins_step2 / 2.0))) * d_acq_parameters.doppler_step2); } - + if (d_input_power < std::numeric_limits::epsilon()) + { + return 0.0; + } return grid_maximum / d_input_power; } @@ -686,12 +696,14 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) d_gnss_synchro->Acq_delay_samples -= static_cast(d_acq_parameters.resampler_latency_samples); // account the resampler filter latency d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast(samp_count) * d_acq_parameters.resampler_ratio); + d_gnss_synchro->fs = d_acq_parameters.resampled_fs; } else { d_gnss_synchro->Acq_delay_samples = static_cast(std::fmod(static_cast(indext), d_acq_parameters.samples_per_code)); d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = samp_count; + d_gnss_synchro->fs = d_acq_parameters.fs_in; } } else @@ -745,6 +757,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast(samp_count) * d_acq_parameters.resampler_ratio); d_gnss_synchro->Acq_doppler_step = d_acq_parameters.doppler_step2; + d_gnss_synchro->fs = d_acq_parameters.resampled_fs; } else { @@ -752,6 +765,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count) d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); d_gnss_synchro->Acq_samplestamp_samples = samp_count; d_gnss_synchro->Acq_doppler_step = d_acq_parameters.doppler_step2; + d_gnss_synchro->fs = d_acq_parameters.fs_in; } } @@ -896,6 +910,18 @@ void pcps_acquisition::calculate_threshold() } +void pcps_acquisition::set_doppler_center(int32_t doppler_center) +{ + gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler + if (doppler_center != d_doppler_center) + { + DLOG(INFO) << " Doppler assistance for Channel: " << d_channel << " => Doppler: " << doppler_center << "[Hz]"; + d_doppler_center = doppler_center; + update_grid_doppler_wipeoffs(); + } +} + + int pcps_acquisition::general_work(int noutput_items __attribute__((unused)), gr_vector_int& ninput_items, gr_vector_const_void_star& input_items, diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h index 74fb8c114..673267f75 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.h @@ -46,7 +46,6 @@ #include "channel_fsm.h" #include "gnss_sdr_fft.h" #include -#include #include #include // for gr_complex #include // for scoped_lock @@ -60,6 +59,7 @@ #include #include + #if HAS_STD_SPAN #include namespace own = std; @@ -196,16 +196,7 @@ public: * \brief Set Doppler center frequency for the grid search. It will refresh the Doppler grid. * \param doppler_center - Frequency center of the search grid [Hz]. */ - inline void set_doppler_center(int32_t doppler_center) - { - gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler - if (doppler_center != d_doppler_center) - { - DLOG(INFO) << " Doppler assistance for Channel: " << d_channel << " => Doppler: " << doppler_center << "[Hz]"; - d_doppler_center = doppler_center; - update_grid_doppler_wipeoffs(); - } - } + void set_doppler_center(int32_t doppler_center); /*! * \brief Parallel Code Phase Search Acquisition signal processing. diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc index 28624f346..0efa83fa7 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fine_doppler_cc.cc @@ -21,7 +21,6 @@ #include "gnss_sdr_create_directory.h" #include "gnss_sdr_filesystem.h" #include "gps_sdr_signal_replica.h" -#include #include #include #include @@ -30,6 +29,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + pcps_acquisition_fine_doppler_cc_sptr pcps_make_acquisition_fine_doppler_cc(const Acq_Conf &conf_) { @@ -461,7 +466,7 @@ int pcps_acquisition_fine_doppler_cc::general_work(int noutput_items, * TODO: High sensitivity acquisition algorithm: * State Machine: * S0. StandBy. If d_active==1 -> S1 - * S1. ComputeGrid. Perform the FFT acqusition doppler and delay grid. + * S1. ComputeGrid. Perform the FFT acquisition doppler and delay grid. * Accumulate the search grid matrix (#doppler_bins x #fft_size) * Compare maximum to threshold and decide positive or negative * If T>=gamma -> S4 else diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc index 0414a2d79..d7b99b57a 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.cc @@ -21,19 +21,24 @@ #include "pcps_acquisition_fpga.h" #include "gnss_sdr_make_unique.h" // for std::make_unique in C++11 #include "gnss_synchro.h" -#include #include // for ceil #include // for operator<< #include // for move -pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(Acq_Conf_Fpga& conf_) +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(Acq_Conf_Fpga *conf, uint32_t acq_buff_num, std::vector> &downsampling_filter_specs, uint32_t &max_FFT_size) { - return pcps_acquisition_fpga_sptr(new pcps_acquisition_fpga(conf_)); + return pcps_acquisition_fpga_sptr(new pcps_acquisition_fpga(conf, acq_buff_num, downsampling_filter_specs, max_FFT_size)); } -pcps_acquisition_fpga::pcps_acquisition_fpga(Acq_Conf_Fpga& conf_) +pcps_acquisition_fpga::pcps_acquisition_fpga(Acq_Conf_Fpga *conf_, uint32_t acq_buff_num, std::vector> &downsampling_filter_specs, uint32_t &max_FFT_size) : d_acq_parameters(conf_), d_gnss_synchro(nullptr), d_sample_counter(0ULL), @@ -41,37 +46,34 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(Acq_Conf_Fpga& conf_) d_mag(0), d_input_power(0.0), d_test_statistics(0.0), - d_doppler_step2(d_acq_parameters.doppler_step2), + d_doppler_step2(d_acq_parameters->doppler_step2), d_doppler_center_step_two(0.0), d_doppler_center(0U), d_state(0), d_doppler_index(0U), d_channel(0U), d_doppler_step(0U), - d_doppler_max(d_acq_parameters.doppler_max), - d_fft_size(d_acq_parameters.samples_per_code), + d_doppler_max(d_acq_parameters->doppler_max), d_num_doppler_bins(0U), - d_downsampling_factor(d_acq_parameters.downsampling_factor), - d_select_queue_Fpga(d_acq_parameters.select_queue_Fpga), - d_total_block_exp(d_acq_parameters.total_block_exp), - d_num_doppler_bins_step2(d_acq_parameters.num_doppler_bins_step2), - d_max_num_acqs(d_acq_parameters.max_num_acqs), + d_total_block_exp(d_acq_parameters->total_block_exp), + d_num_doppler_bins_step2(d_acq_parameters->num_doppler_bins_step2), + d_max_num_acqs(d_acq_parameters->max_num_acqs), d_active(false), - d_make_2_steps(d_acq_parameters.make_2_steps) + d_make_2_steps(d_acq_parameters->make_2_steps) { - d_acquisition_fpga = std::make_unique(d_acq_parameters.device_name, d_acq_parameters.code_length, d_acq_parameters.doppler_max, d_fft_size, - d_acq_parameters.fs_in, d_acq_parameters.select_queue_Fpga, d_acq_parameters.all_fft_codes, d_acq_parameters.excludelimit); + d_acquisition_fpga = std::make_unique(d_acq_parameters->device_name, acq_buff_num, + downsampling_filter_specs, max_FFT_size); } - void pcps_acquisition_fpga::set_local_code() { d_acquisition_fpga->set_local_code(d_gnss_synchro->PRN); } - void pcps_acquisition_fpga::init() { + d_acquisition_fpga->init(d_acq_parameters->code_length, d_doppler_max, d_acq_parameters->fft_size, + d_acq_parameters->resampled_fs, d_acq_parameters->downsampling_filter_num, d_acq_parameters->excludelimit, d_acq_parameters->all_fft_codes); d_gnss_synchro->Flag_valid_acquisition = false; d_gnss_synchro->Flag_valid_symbol_output = false; d_gnss_synchro->Flag_valid_pseudorange = false; @@ -85,7 +87,6 @@ void pcps_acquisition_fpga::init() d_num_doppler_bins = static_cast(std::ceil(static_cast(static_cast(d_doppler_max) - static_cast(-d_doppler_max)) / static_cast(d_doppler_step))) + 1; } - void pcps_acquisition_fpga::set_state(int32_t state) { d_state = state; @@ -142,7 +143,7 @@ void pcps_acquisition_fpga::send_negative_acquisition() << ", magnitude " << d_mag << ", input signal power " << d_input_power; - if (d_acq_parameters.repeat_satellite == true) + if (d_acq_parameters->repeat_satellite == true) { d_channel_fsm.lock()->Event_failed_acquisition_repeat(); } @@ -159,14 +160,13 @@ void pcps_acquisition_fpga::acquisition_core(uint32_t num_doppler_bins, uint32_t float firstpeak = 0.0; float secondpeak = 0.0; uint32_t total_block_exp; - uint64_t initial_sample; d_acquisition_fpga->set_doppler_sweep(num_doppler_bins, doppler_step, doppler_min); d_acquisition_fpga->run_acquisition(); d_acquisition_fpga->read_acquisition_results(&indext, &firstpeak, &secondpeak, - &initial_sample, + &d_sample_counter, &d_input_power, &d_doppler_index, &total_block_exp); @@ -192,26 +192,8 @@ void pcps_acquisition_fpga::acquisition_core(uint32_t num_doppler_bins, uint32_t } d_gnss_synchro->Acq_doppler_hz = static_cast(doppler); - d_sample_counter = initial_sample; - - if (d_select_queue_Fpga == 0) - { - if (d_downsampling_factor > 1) - { - d_gnss_synchro->Acq_delay_samples = static_cast(d_downsampling_factor * (indext)); - d_gnss_synchro->Acq_samplestamp_samples = d_downsampling_factor * static_cast(d_sample_counter) - static_cast(44); // 33; // 41; // + 81*0.5; // delay due to the downsampling filter in the acquisition - } - else - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext); - d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition - } - } - else - { - d_gnss_synchro->Acq_delay_samples = static_cast(indext); - d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; // delay due to the downsampling filter in the acquisition - } + d_gnss_synchro->Acq_delay_samples = static_cast(indext); + d_gnss_synchro->Acq_samplestamp_samples = d_sample_counter; } @@ -288,6 +270,16 @@ void pcps_acquisition_fpga::set_active(bool active) } +void pcps_acquisition_fpga::set_doppler_center(int32_t doppler_center) +{ + if (doppler_center != d_doppler_center) + { + DLOG(INFO) << " Doppler assistance for Channel: " << d_channel << " => Doppler: " << doppler_center << "[Hz]"; + d_doppler_center = doppler_center; + } +} + + void pcps_acquisition_fpga::reset_acquisition() { // this function triggers a HW reset of the FPGA PL. diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h index 92ec51781..d1fca2179 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h @@ -29,11 +29,11 @@ #include "acq_conf_fpga.h" #include "channel_fsm.h" #include "fpga_acquisition.h" -#include #include // for uint32_t #include // for shared_ptr #include // for string -#include // for move +#include // for for std::move, std::pair +#include // for std::vector /** \addtogroup Acquisition * \{ */ @@ -47,7 +47,7 @@ class pcps_acquisition_fpga; using pcps_acquisition_fpga_sptr = std::shared_ptr; -pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(Acq_Conf_Fpga& conf_); +pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(Acq_Conf_Fpga* conf_, uint32_t acq_buff_num, std::vector>& downsampling_filter_specs, uint32_t& max_FFT_size); /*! * \brief This class implements a Parallel Code Phase Search Acquisition that uses the FPGA. @@ -156,14 +156,7 @@ public: * \brief Set Doppler center frequency for the grid search. It will refresh the Doppler grid. * \param doppler_center - Frequency center of the search grid [Hz]. */ - inline void set_doppler_center(int32_t doppler_center) - { - if (doppler_center != d_doppler_center) - { - DLOG(INFO) << " Doppler assistance for Channel: " << d_channel << " => Doppler: " << doppler_center << "[Hz]"; - d_doppler_center = doppler_center; - } - } + void set_doppler_center(int32_t doppler_center); /*! * \brief This function triggers a HW reset of the FPGA PL. @@ -176,8 +169,8 @@ public: void stop_acquisition(); private: - friend pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(Acq_Conf_Fpga& conf_); - explicit pcps_acquisition_fpga(Acq_Conf_Fpga& conf_); + friend pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(Acq_Conf_Fpga* conf, uint32_t acq_buff_num, std::vector>& downsampling_filter_specs, uint32_t& max_FFT_size); + explicit pcps_acquisition_fpga(Acq_Conf_Fpga* conf, uint32_t acq_buff_num, std::vector>& downsampling_filter_specs, uint32_t& max_FFT_size); void send_negative_acquisition(); void send_positive_acquisition(); @@ -187,7 +180,7 @@ private: std::shared_ptr d_acquisition_fpga; std::weak_ptr d_channel_fsm; - Acq_Conf_Fpga d_acq_parameters; + Acq_Conf_Fpga* d_acq_parameters; Gnss_Synchro* d_gnss_synchro; @@ -207,10 +200,7 @@ private: uint32_t d_channel; uint32_t d_doppler_step; uint32_t d_doppler_max; - uint32_t d_fft_size; uint32_t d_num_doppler_bins; - uint32_t d_downsampling_factor; - uint32_t d_select_queue_Fpga; uint32_t d_total_block_exp; uint32_t d_num_doppler_bins_step2; uint32_t d_max_num_acqs; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc index 3d919f87f..c6957957e 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_assisted_acquisition_cc.cc @@ -20,7 +20,6 @@ #include "MATH_CONSTANTS.h" #include "concurrent_map.h" #include "gps_acq_assist.h" -#include #include #include #include @@ -30,6 +29,11 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif extern Concurrent_Map global_gps_acq_assist_map; @@ -259,7 +263,7 @@ float pcps_assisted_acquisition_cc::search_maximum() std::stringstream filename; std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write filename.str(""); - filename << "../data/test_statistics_" << d_gnss_synchro->System + filename << "./test_statistics_" << d_gnss_synchro->System << "_" << d_gnss_synchro->Signal[0] << d_gnss_synchro->Signal[1] << "_sat_" << d_gnss_synchro->PRN << "_doppler_" << d_gnss_synchro->Acq_doppler_hz << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); @@ -334,7 +338,7 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items, * State Machine: * S0. StandBy. If d_active==1 -> S1 * S1. GetAssist. Define search grid with assistance information. Reset grid matrix -> S2 - * S2. ComputeGrid. Perform the FFT acqusition doppler and delay grid. + * S2. ComputeGrid. Perform the FFT acquisition doppler and delay grid. * Accumulate the search grid matrix (#doppler_bins x #fft_size) * Compare maximum to threshold and decide positive or negative * If T>=gamma -> S4 else diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc index e16d184a3..3e6860517 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc @@ -22,7 +22,6 @@ #include "pcps_cccwsr_acquisition_cc.h" #include "MATH_CONSTANTS.h" // TWO_PI -#include #include #include #include @@ -32,6 +31,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + pcps_cccwsr_acquisition_cc_sptr pcps_cccwsr_make_acquisition_cc( uint32_t sampled_ms, @@ -161,8 +166,8 @@ void pcps_cccwsr_acquisition_cc::init() // Count the number of bins d_num_doppler_bins = 0; for (auto doppler = static_cast(-d_doppler_max); - doppler <= static_cast(d_doppler_max); - doppler += d_doppler_step) + doppler <= static_cast(d_doppler_max); + doppler += d_doppler_step) { d_num_doppler_bins++; } @@ -347,7 +352,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, std::stringstream filename; std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write filename.str(""); - filename << "../data/test_statistics_" << d_gnss_synchro->System + filename << "./test_statistics_" << d_gnss_synchro->System << "_" << d_gnss_synchro->Signal[0] << d_gnss_synchro->Signal[1] << "_sat_" << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc index 2f0e3662a..7738a2b9e 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc @@ -38,7 +38,6 @@ #include "MATH_CONSTANTS.h" // TWO_PI #include "opencl/fft_base_kernels.h" #include "opencl/fft_internal.h" -#include #include #include #include @@ -50,6 +49,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + pcps_opencl_acquisition_cc_sptr pcps_make_opencl_acquisition_cc( uint32_t sampled_ms, uint32_t max_dwells, @@ -264,8 +269,8 @@ void pcps_opencl_acquisition_cc::init() // Count the number of bins d_num_doppler_bins = 0; for (int doppler = static_cast(-d_doppler_max); - doppler <= static_cast(d_doppler_max); - doppler += d_doppler_step) + doppler <= static_cast(d_doppler_max); + doppler += d_doppler_step) { d_num_doppler_bins++; } @@ -424,7 +429,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_volk() std::stringstream filename; std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write filename.str(""); - filename << "../data/test_statistics_" << d_gnss_synchro->System + filename << "./test_statistics_" << d_gnss_synchro->System << "_" << d_gnss_synchro->Signal[0] << d_gnss_synchro->Signal[1] << "_sat_" << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); @@ -585,7 +590,7 @@ void pcps_opencl_acquisition_cc::acquisition_core_opencl() std::stringstream filename; std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write filename.str(""); - filename << "../data/test_statistics_" << d_gnss_synchro->System + filename << "./test_statistics_" << d_gnss_synchro->System << "_" << d_gnss_synchro->Signal[0] << d_gnss_synchro->Signal[1] << "_sat_" << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc index 39bac577c..4966efb70 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc @@ -16,7 +16,6 @@ #include "pcps_quicksync_acquisition_cc.h" #include "MATH_CONSTANTS.h" -#include #include #include #include @@ -25,6 +24,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc( uint32_t folding_factor, @@ -178,8 +183,8 @@ void pcps_quicksync_acquisition_cc::init() // Count the number of bins d_num_doppler_bins = 0; for (auto doppler = static_cast(-d_doppler_max); - doppler <= static_cast(d_doppler_max); - doppler += d_doppler_step) + doppler <= static_cast(d_doppler_max); + doppler += d_doppler_step) { d_num_doppler_bins++; } @@ -314,7 +319,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) { // Ensure that the signal is going to start with all samples - // at zero. This is done to avoid over acumulation when performing + // at zero. This is done to avoid over accumulation when performing // the folding process to be stored in d_fft_if->get_inbuf() d_signal_folded = std::vector(d_fft_size, lv_cmake(0.0F, 0.0F)); std::copy(d_signal_folded.data(), d_signal_folded.data() + d_fft_size, d_fft_if->get_inbuf()); @@ -431,7 +436,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, std::stringstream filename; std::streamsize n = sizeof(float) * (d_fft_size); // complex file write filename.str(""); - filename << "../data/test_statistics_" << d_gnss_synchro->System + filename << "./test_statistics_" << d_gnss_synchro->System << "_" << d_gnss_synchro->Signal[0] << d_gnss_synchro->Signal[1] << "_sat_" << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc index f072dcd6a..dcabf4e22 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc @@ -36,7 +36,6 @@ #include "pcps_tong_acquisition_cc.h" #include "MATH_CONSTANTS.h" // for TWO_PI -#include #include #include #include @@ -45,6 +44,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + pcps_tong_acquisition_cc_sptr pcps_tong_make_acquisition_cc( uint32_t sampled_ms, @@ -166,8 +171,8 @@ void pcps_tong_acquisition_cc::init() // Count the number of bins d_num_doppler_bins = 0; for (auto doppler = static_cast(-d_doppler_max); - doppler <= static_cast(d_doppler_max); - doppler += d_doppler_step) + doppler <= static_cast(d_doppler_max); + doppler += d_doppler_step) { d_num_doppler_bins++; } @@ -337,7 +342,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, std::stringstream filename; std::streamsize n = 2 * sizeof(float) * (d_fft_size); // complex file write filename.str(""); - filename << "../data/test_statistics_" << d_gnss_synchro->System + filename << "./test_statistics_" << d_gnss_synchro->System << "_" << d_gnss_synchro->Signal[0] << d_gnss_synchro->Signal[1] << "_sat_" << d_gnss_synchro->PRN << "_doppler_" << doppler << ".dat"; d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); diff --git a/src/algorithms/acquisition/libs/CMakeLists.txt b/src/algorithms/acquisition/libs/CMakeLists.txt index 65437c649..a2eb01230 100644 --- a/src/algorithms/acquisition/libs/CMakeLists.txt +++ b/src/algorithms/acquisition/libs/CMakeLists.txt @@ -38,12 +38,17 @@ target_link_libraries(acquisition_libs INTERFACE Gnuradio::runtime PRIVATE - Gflags::gflags - Glog::glog algorithms_libs core_system_parameters ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(acquisition_libs PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(acquisition_libs PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(acquisition_libs PRIVATE absl::flags absl::log) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(acquisition_libs diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index 715b07f62..e0ad5d490 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -17,9 +17,14 @@ #include "acq_conf.h" #include "item_type_helpers.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + void Acq_Conf::SetFromConfiguration(const ConfigurationInterface *configuration, const std::string &role, double chip_rate, double opt_freq) diff --git a/src/algorithms/acquisition/libs/acq_conf_fpga.cc b/src/algorithms/acquisition/libs/acq_conf_fpga.cc index 838ab3ae6..1f77f0ff2 100644 --- a/src/algorithms/acquisition/libs/acq_conf_fpga.cc +++ b/src/algorithms/acquisition/libs/acq_conf_fpga.cc @@ -18,41 +18,58 @@ #include "acq_conf_fpga.h" #include "item_type_helpers.h" #include "uio_fpga.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configuration, - const std::string &role, uint32_t sel_queue_fpga, uint32_t blk_exp, uint32_t downsampling_factor_default, double chip_rate, double code_length_chips) + const std::string &role, uint32_t blk_exp, double code_chips_per_sec, double num_chips_per_code) { // sampling frequency const int64_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", fs_in); fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); + // resampling frequency + resampled_fs = fs_in; + // max doppler doppler_max = configuration->property(role + ".doppler_max", doppler_max); - // downsampling factor - downsampling_factor = configuration->property(role + ".downsampling_factor", downsampling_factor_default); + // code chips per second + code_rate_cps = code_chips_per_sec; - fs_in = fs_in / downsampling_factor; + // code length chips + code_length_chips = num_chips_per_code; // code length in samples - code_length = static_cast(std::round(static_cast(fs_in) / (chip_rate / code_length_chips))); + code_length = static_cast(std::round(static_cast(fs_in) / (code_rate_cps / code_length_chips))); - // The FPGA can only use FFT lengths that are a power of two. - float nbits = ceilf(log2f(static_cast(code_length) * 2.0F)); - samples_per_code = pow(2, nbits); + // zero padding + if (((code_length & (code_length - 1)) != 0)) + { + // If the code length (in samples) is not a power of two, zero padding is required. + enable_zero_padding = true; + } + + // FFT length + float zero_padding_adjustment = enable_zero_padding ? 2.0F : 1.0F; + fft_size = pow(2, ceilf(log2f(static_cast(code_length) * zero_padding_adjustment))); + + // Exclude limit value for the second maxima search + excludelimit = static_cast(1 + ceil((1.0 / code_rate_cps) * static_cast(resampled_fs))); // repeat satellite repeat_satellite = configuration->property(role + ".repeat_satellite", false); - // FPGA buffer number - select_queue_Fpga = configuration->property(role + ".select_queue_Fpga", sel_queue_fpga); - // UIO device file std::string device_io_name; + // find the uio device file corresponding to the acquisition if (find_uio_dev_file_name(device_io_name, acquisition_device_name, 0) < 0) { @@ -61,10 +78,7 @@ void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configura } device_name = std::move(device_io_name); - // exclusion limit - excludelimit = static_cast(1 + ceil((1.0 / chip_rate) * static_cast(fs_in))); - - // acquisition step 2 parameters + // parameters for the second acquisition step num_doppler_bins_step2 = configuration->property(role + ".second_nbins", num_doppler_bins_step2); doppler_step2 = configuration->property(role + ".second_doppler_step", doppler_step2); doppler_step = configuration->property(role + ".doppler_step", doppler_step); @@ -74,3 +88,61 @@ void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configura // reference for the FPGA FFT-IFFT attenuation factor total_block_exp = configuration->property(role + ".total_block_exp", blk_exp); } + +bool Acq_Conf_Fpga::ConfigureAutomaticResampler(std::vector> downsampling_filter_specs, uint32_t max_FFT_size, double opt_freq) +{ + bool acq_configuration_valid = false; + uint32_t optimal_downsampling_factor = fs_in / opt_freq; + + if (optimal_downsampling_factor > 1) + { + for (uint32_t k = 0; k < downsampling_filter_specs.size(); k++) + { + uint32_t dec_factor = downsampling_filter_specs[k].first; + uint32_t filter_delay = downsampling_filter_specs[k].second; + // Select the FPGA-supported downsampling factor that is the closest to, but smaller than, the target downsampling factor + if (optimal_downsampling_factor >= dec_factor) + { + // check if the required FFT size is supported in the FPGA + uint32_t fft_size_downsampled = (fft_size / dec_factor); + if (fft_size_downsampled <= max_FFT_size) + { + downsampling_filter_num = k + 1; + downsampling_factor = dec_factor; + downsampling_filter_delay = filter_delay; + + // update the resampling frequency, the code length, the FFT size, and the exclude limit parameter taking into account the downsampling factor + resampled_fs = fs_in / downsampling_factor; + code_length = static_cast(std::round(static_cast(resampled_fs) / (code_rate_cps / code_length_chips))); + float zero_padding_adjustment = enable_zero_padding ? 2.0F : 1.0F; + fft_size = pow(2, ceilf(log2f(static_cast(code_length) * zero_padding_adjustment))); + excludelimit = static_cast(1 + ceil((1.0 / code_rate_cps) * static_cast(resampled_fs))); + acq_configuration_valid = true; + } + break; + } + } + } + else + { + // the buffer containing L2 or L5/E5a frequency band samples by default does not implement a downsampling filter + if (fft_size <= max_FFT_size) + { + acq_configuration_valid = true; + } + } + + return acq_configuration_valid; +} + +bool Acq_Conf_Fpga::Is_acq_config_valid(uint32_t max_FFT_size) +{ + if (fft_size <= max_FFT_size) + { + return true; + } + else + { + return false; + } +} diff --git a/src/algorithms/acquisition/libs/acq_conf_fpga.h b/src/algorithms/acquisition/libs/acq_conf_fpga.h index 11a2c7856..379fdd3d4 100644 --- a/src/algorithms/acquisition/libs/acq_conf_fpga.h +++ b/src/algorithms/acquisition/libs/acq_conf_fpga.h @@ -22,6 +22,8 @@ #include #include #include +#include // for std::move, std::pair +#include // for std::vector /** \addtogroup Acquisition * \{ */ @@ -35,28 +37,33 @@ class Acq_Conf_Fpga public: Acq_Conf_Fpga() = default; - void SetFromConfiguration(const ConfigurationInterface *configuration, const std::string &role, uint32_t sel_queue_fpga, uint32_t blk_exp, uint32_t downsampling_factor_default, double chip_rate, double code_length_chips); + void SetFromConfiguration(const ConfigurationInterface *configuration, const std::string &role, uint32_t blk_exp, double code_chips_per_sec, double num_chips_per_code); + + bool ConfigureAutomaticResampler(std::vector> downsampling_filter_specs, uint32_t max_FFT_size, double opt_freq); + + bool Is_acq_config_valid(uint32_t max_FFT_size); /* PCPS Acquisition configuration */ std::string device_name = "uio0"; uint32_t *all_fft_codes = NULL; // pointer to memory that contains all the code ffts + double code_rate_cps; + double code_length_chips; int64_t fs_in{4000000LL}; - + int64_t resampled_fs{4000000LL}; float doppler_step{250.0}; float doppler_step2{125.0}; - uint32_t num_doppler_bins_step2{4U}; - int32_t doppler_max{5000}; - - uint32_t select_queue_Fpga{0U}; - uint32_t downsampling_factor{4U}; + uint32_t downsampling_filter_num{0U}; + uint32_t downsampling_factor{1U}; + uint32_t downsampling_filter_delay{0U}; uint32_t total_block_exp{13U}; uint32_t excludelimit{5U}; uint32_t max_num_acqs{2U}; - uint32_t samples_per_code{1U}; + uint32_t fft_size{1U}; uint32_t code_length{16000U}; bool make_2_steps{false}; + bool enable_zero_padding{false}; bool repeat_satellite{false}; private: diff --git a/src/algorithms/acquisition/libs/fpga_acquisition.cc b/src/algorithms/acquisition/libs/fpga_acquisition.cc index 667533c08..72fae5b51 100644 --- a/src/algorithms/acquisition/libs/fpga_acquisition.cc +++ b/src/algorithms/acquisition/libs/fpga_acquisition.cc @@ -21,14 +21,17 @@ #include "fpga_acquisition.h" #include "MATH_CONSTANTS.h" // for TWO_PI -#include // for LOG #include // for log2 #include // libraries used by the GIPO #include // for operator<< #include // libraries used by the GIPO #include // for write, close, read, ssize_t -#include // for move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif #ifndef TEMP_FAILURE_RETRY #define TEMP_FAILURE_RETRY(exp) \ @@ -43,36 +46,51 @@ }) #endif - Fpga_Acquisition::Fpga_Acquisition(std::string device_name, - uint32_t nsamples, - uint32_t doppler_max, - uint32_t nsamples_total, - int64_t fs_in, uint32_t select_queue, - uint32_t *all_fft_codes, - uint32_t excludelimit) : d_device_name(std::move(device_name)), - d_fs_in(fs_in), - d_fd(0), // driver descriptor - d_map_base(nullptr), // driver memory map - d_all_fft_codes(all_fft_codes), - d_vector_length(nsamples_total), - d_excludelimit(excludelimit), - d_nsamples_total(nsamples_total), - d_nsamples(nsamples), // number of samples not including padding - d_select_queue(select_queue), - d_doppler_max(doppler_max), - d_doppler_step(0), - d_PRN(0) + std::vector> &downsampling_filter_specs, + uint32_t &max_FFT_size) : d_device_name(device_name), + d_resampled_fs(0), + d_map_base(nullptr), // driver memory map + d_all_fft_codes(nullptr), + d_fd(0), // driver descriptor + d_fft_size(0), + d_excludelimit(0), + d_nsamples(0), // number of samples not including padding + d_filter_num(0), + d_downsampling_factor(1), + d_downsampling_filter_delay(0), + d_select_queue(select_queue), + d_doppler_max(0), + d_doppler_step(0), + d_PRN(0), + d_IP_core_version(0) { Fpga_Acquisition::open_device(); Fpga_Acquisition::reset_acquisition(); Fpga_Acquisition::fpga_acquisition_test_register(); + Fpga_Acquisition::read_ipcore_info(downsampling_filter_specs, max_FFT_size); Fpga_Acquisition::close_device(); - DLOG(INFO) << "Acquisition FPGA class created"; } +void Fpga_Acquisition::init(uint32_t nsamples, uint32_t doppler_max, uint32_t fft_size, + int64_t resampled_fs, uint32_t downsampling_filter_num, uint32_t excludelimit, uint32_t *all_fft_codes) +{ + d_resampled_fs = resampled_fs; + d_all_fft_codes = all_fft_codes; + d_fft_size = fft_size; + d_excludelimit = excludelimit; + d_nsamples = nsamples; + d_filter_num = downsampling_filter_num; + if (d_filter_num > 0) + { + d_downsampling_factor = d_downsampling_filter_specs[d_filter_num - 1].first; + d_downsampling_filter_delay = d_downsampling_filter_specs[d_filter_num - 1].second; + } + d_doppler_max = doppler_max; +} + bool Fpga_Acquisition::set_local_code(uint32_t PRN) { @@ -84,11 +102,11 @@ bool Fpga_Acquisition::set_local_code(uint32_t PRN) void Fpga_Acquisition::write_local_code() { - d_map_base[9] = LOCAL_CODE_CLEAR_MEM; + d_map_base[CLEAR_MEM_REG_ADDR] = LOCAL_CODE_CLEAR_MEM; // write local code - for (uint32_t k = 0; k < d_vector_length; k++) + for (uint32_t k = 0; k < d_fft_size; k++) { - d_map_base[6] = d_all_fft_codes[d_nsamples_total * (d_PRN - 1) + k]; + d_map_base[PROG_MEM_ADDR] = d_all_fft_codes[d_fft_size * (d_PRN - 1) + k]; } } @@ -114,15 +132,12 @@ void Fpga_Acquisition::open_device() void Fpga_Acquisition::fpga_acquisition_test_register() { - // sanity check : check test register - const uint32_t writeval = TEST_REG_SANITY_CHECK; - // write value to test register - d_map_base[15] = writeval; + d_map_base[TEST_REG_ADDR] = TEST_REG_SANITY_CHECK; // read value from test register - const uint32_t readval = d_map_base[15]; + const uint32_t readval = d_map_base[TEST_REG_ADDR]; - if (writeval != readval) + if (readval != TEST_REG_SANITY_CHECK) { LOG(WARNING) << "Acquisition test register sanity check failed"; } @@ -132,6 +147,50 @@ void Fpga_Acquisition::fpga_acquisition_test_register() } } +void Fpga_Acquisition::read_ipcore_info(std::vector> &downsampling_filter_specs, uint32_t &max_FFT_size) +{ + d_IP_core_version = d_map_base[FPGA_IP_CORE_VERSION_REG_ADDR]; + if (d_IP_core_version == FPGA_ACQ_IP_VERSION_1) + { + // FPGA acquisition IP core version FPGA_ACQ_IP_VERSION_1 + max_FFT_size = d_map_base[MAX_FFT_SIZE_REG_ADDR]; + if (d_select_queue == ACQ_BUFF_0) + { + // Check if the requested downsampling filter is available on the FPGA and read its implemented latency. + uint32_t downsampling_filter_dec_factors = d_map_base[DOWNSAMPLING_FILTER_DEC_FACTORS_REG_ADDR]; + uint32_t downsampling_filter_latencies = d_map_base[DOWNSAMPLING_FILTER_LATENCIES_REG_ADDR]; + for (uint32_t filt_num = 1; filt_num <= MAX_FILTERS_AVAILABLE; filt_num++) + { + // The information about the instantiated downsampling filters in the FPGA is ordered such that the largest downsampling factor is stored in the least significant bits (LSBs), while the smallest downsampling factor is stored in the most significant bits (MSBs). + uint32_t dec_factor = downsampling_filter_dec_factors & BIT_MASK_4; + downsampling_filter_dec_factors = downsampling_filter_dec_factors >> RSHIFT_4_BITS; + + uint32_t filter_latency = downsampling_filter_latencies & BIT_MASK_8; + downsampling_filter_latencies = downsampling_filter_latencies >> RSHIFT_8_BITS; + if (dec_factor != 0) + { + downsampling_filter_specs.emplace_back(dec_factor, filter_latency); + } + else + { + break; + } + } + } + } + else + { + // FPGA Acquisition IP core versions earlier than FPGA_ACQ_IP_VERSION_1 + max_FFT_size = DEFAULT_MAX_FFT_SIZE; + if (d_select_queue == ACQ_BUFF_0) + { + // An acquisition resampler with a downsampling factor of DEFAULT_DOWNSAMPLING_FACTOR is implemented in the L1/E1 frequency band + downsampling_filter_specs.emplace_back(DEFAULT_DOWNSAMPLING_FACTOR, DEFAULT_DOWNSAMPLING_FILTER_DELAY); + } + } + + d_downsampling_filter_specs = downsampling_filter_specs; +} void Fpga_Acquisition::run_acquisition() { @@ -145,7 +204,7 @@ void Fpga_Acquisition::run_acquisition() } // launch the acquisition process - d_map_base[8] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process + d_map_base[ACQ_COMMAND_FLAGS_REG_ADDR] = LAUNCH_ACQUISITION; // writing a 1 to reg 8 launches the acquisition process int32_t irq_count; // wait for interrupt @@ -160,7 +219,7 @@ void Fpga_Acquisition::run_acquisition() void Fpga_Acquisition::set_block_exp(uint32_t total_block_exp) { - d_map_base[11] = total_block_exp; + d_map_base[MAX_FFT_SCALING_FACTOR_REG_ADDR] = total_block_exp; } @@ -168,59 +227,47 @@ void Fpga_Acquisition::set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_s { // The doppler step can never be outside the range -pi to +pi, otherwise there would be aliasing // The FPGA expects phase_step_rad between -1 (-pi) to +1 (+pi) - float phase_step_rad_real = 2.0F * (doppler_min) / static_cast(d_fs_in); - auto phase_step_rad_int = static_cast(phase_step_rad_real * (POW_2_31)); - d_map_base[3] = phase_step_rad_int; + float phase_step_rad_real = 2.0F * (doppler_min) / static_cast(d_resampled_fs); + d_map_base[DOPPLER_MIN_REG_ADDR] = static_cast(phase_step_rad_real * (POW_2_31)); // repeat the calculation with the doppler step - phase_step_rad_real = 2.0F * (doppler_step) / static_cast(d_fs_in); - phase_step_rad_int = static_cast(phase_step_rad_real * (POW_2_31)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings - d_map_base[4] = phase_step_rad_int; + phase_step_rad_real = 2.0F * (doppler_step) / static_cast(d_resampled_fs); + d_map_base[DOPPLER_STEP_REG_ADDR] = static_cast(phase_step_rad_real * (POW_2_31)); // * 2^29 (in total it makes x2^31 in two steps to avoid the warnings // write number of doppler sweeps - d_map_base[5] = num_sweeps; + d_map_base[NUM_DOPPLER_SEARCH_STEPS_REG_ADDR] = num_sweeps; } void Fpga_Acquisition::configure_acquisition() { // Fpga_Acquisition::(); - d_map_base[0] = d_select_queue; - d_map_base[1] = d_vector_length; - d_map_base[2] = d_nsamples; - d_map_base[7] = static_cast(std::log2(static_cast(d_vector_length))); // log2 FFTlength - d_map_base[12] = d_excludelimit; + d_map_base[FREQ_BAND_DOWNSAMPLE_REG_ADDR] = d_select_queue | (d_filter_num << 4); + d_map_base[FFT_LENGTH_REG_ADDR] = d_fft_size; + d_map_base[CORR_NSAMPLES_REG_ADDR] = d_nsamples; + d_map_base[LOG2_FFT_LENGTH_REG_ADDR] = static_cast(std::log2(static_cast(d_fft_size))); // log2 FFTlength + d_map_base[EXCL_LIM_REG_ADDR] = d_excludelimit; } void Fpga_Acquisition::read_acquisition_results(uint32_t *max_index, float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp) { - uint32_t readval = d_map_base[1]; // read sample counter (LSW) - auto initial_sample_tmp = static_cast(readval); - - uint64_t readval_long = d_map_base[2]; // read sample counter (MSW) - uint64_t readval_long_shifted = readval_long << 32; // 2^32 - - initial_sample_tmp += readval_long_shifted; // 2^32 + uint64_t initial_sample_tmp = (static_cast(d_map_base[SAMPLESTAMP_MSW_REG_ADDR]) << 32) + (static_cast(d_map_base[SAMPLESTAMP_LSW_REG_ADDR])); + uint32_t max_index_tmp = d_map_base[ACQ_DELAY_SAMPLES_REG_ADDR]; // read max index position + if (d_downsampling_factor > 1) + { + initial_sample_tmp *= static_cast(d_downsampling_factor); // take into account the downsampling factor for the sample stamp + initial_sample_tmp -= static_cast(d_downsampling_filter_delay); // take into account the downsampling filter delay + max_index_tmp *= d_downsampling_factor; // take into account the downsampling factor for the acq. delay + } *initial_sample = initial_sample_tmp; - - readval = d_map_base[3]; // read first peak value - *firstpeak = static_cast(readval); - - readval = d_map_base[4]; // read second peak value - *secondpeak = static_cast(readval); - - readval = d_map_base[5]; // read max index position - *max_index = readval; - - *power_sum = 0; // power sum is not used - - readval = d_map_base[7]; // read doppler index -- this read releases the interrupt line - *doppler_index = readval; - - readval = d_map_base[8]; // read FFT block exponent - *total_blk_exp = readval; + *max_index = max_index_tmp; + *firstpeak = d_map_base[MAG_SQ_FIRST_PEAK_REG_ADDR]; // read first peak value + *secondpeak = d_map_base[MAG_SQ_SECOND_PEAK_REG_ADDR]; // read second peak value + *power_sum = 0; // The FPGA does not currently support power sum. + *doppler_index = d_map_base[DOPPLER_INDEX_REG_ADDR]; // read doppler index -- this read releases the interrupt line + *total_blk_exp = d_map_base[FFT_SCALING_FACTOR_REG_ADDR]; // read FFT block exponent } @@ -237,30 +284,13 @@ void Fpga_Acquisition::close_device() void Fpga_Acquisition::reset_acquisition() { - d_map_base[8] = RESET_ACQUISITION; // setting bit 2 of d_map_base[8] resets the acquisition. This causes a reset of all - // the FPGA HW modules including the multicorrelators + d_map_base[ACQ_COMMAND_FLAGS_REG_ADDR] = RESET_ACQUISITION; // setting bit 2 resets the acquisition. This causes a reset of all + // the FPGA HW modules including the multicorrelators } void Fpga_Acquisition::stop_acquisition() { - d_map_base[8] = STOP_ACQUISITION; // setting bit 3 of d_map_base[8] stops the acquisition module. This stops all - // the FPGA HW modules including the multicorrelators -} - - -// this function is only used for the unit tests -void Fpga_Acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor) -{ - uint32_t readval = d_map_base[8]; - *total_scale_factor = readval; - // only the total scale factor is used for the tests (fw scale factor to be removed) - *fw_scale_factor = 0; -} - - -void Fpga_Acquisition::read_result_valid(uint32_t *result_valid) -{ - uint32_t readval = d_map_base[0]; - *result_valid = readval; + d_map_base[ACQ_COMMAND_FLAGS_REG_ADDR] = STOP_ACQUISITION; // setting bit 3 stops the acquisition module. This stops all + // the FPGA HW modules including the multicorrelators } diff --git a/src/algorithms/acquisition/libs/fpga_acquisition.h b/src/algorithms/acquisition/libs/fpga_acquisition.h index 5a0b633f9..4cada480b 100644 --- a/src/algorithms/acquisition/libs/fpga_acquisition.h +++ b/src/algorithms/acquisition/libs/fpga_acquisition.h @@ -24,6 +24,8 @@ #include #include +#include // for std::move, std::pair +#include // for std::vector /** \addtogroup Acquisition * \{ */ @@ -42,19 +44,22 @@ public: */ Fpga_Acquisition( std::string device_name, - uint32_t nsamples, - uint32_t doppler_max, - uint32_t nsamples_total, - int64_t fs_in, uint32_t select_queue, - uint32_t *all_fft_codes, - uint32_t excludelimit); + std::vector> &downsampling_filter_specs, + uint32_t &max_FFT_size); /*! * \brief Destructor */ ~Fpga_Acquisition() = default; + /*! + * \brief Initialize acquisition parameters + */ + // void init(uint32_t samples_per_code, uint32_t code_length, int64_t resampled_fs, uint32_t *all_fft_codes); + void init(uint32_t nsamples, uint32_t doppler_max, uint32_t d_fft_size, + int64_t resampled_fs, uint32_t downsampling_filter_num, uint32_t excludelimit, uint32_t *all_fft_codes); + /*! * \brief Select the code with the chosen PRN */ @@ -110,11 +115,6 @@ public: */ void stop_acquisition(); - /*! - * \brief Read the scaling factor that has been used by the FFT-IFFT - */ - void read_fpga_total_scale_factor(uint32_t *total_scale_factor, uint32_t *fw_scale_factor); - /*! * \brief Set the block exponent of the FFT in the FPGA. */ @@ -141,6 +141,42 @@ public: void close_device(); private: + // FPGA IP Core version + static const uint32_t FPGA_ACQ_IP_VERSION_1 = 0x0001; // FPGA IP core version + + // FPGA register addresses + + // write-only registers + static const uint32_t FREQ_BAND_DOWNSAMPLE_REG_ADDR = 0; // Select frequency band and downsampling filter + static const uint32_t FFT_LENGTH_REG_ADDR = 1; // Length of the FFT + static const uint32_t CORR_NSAMPLES_REG_ADDR = 2; // Correlation length + static const uint32_t DOPPLER_MIN_REG_ADDR = 3; // Doppler min + static const uint32_t DOPPLER_STEP_REG_ADDR = 4; // Doppler step + static const uint32_t NUM_DOPPLER_SEARCH_STEPS_REG_ADDR = 5; // Number of Doppler search steps + static const uint32_t PROG_MEM_ADDR = 6; // Access to the memory storing the PRN code of the target satellite. + static const uint32_t LOG2_FFT_LENGTH_REG_ADDR = 7; // Log2(FFT_LENGTH) + static const uint32_t ACQ_COMMAND_FLAGS_REG_ADDR = 8; // Flags that reset, start, and stop the acquisition process. + static const uint32_t CLEAR_MEM_REG_ADDR = 9; // Flag that resets the write address of the PRN code memory. + static const uint32_t MAX_FFT_SCALING_FACTOR_REG_ADDR = 11; // Reference FFT scaling factor + static const uint32_t EXCL_LIM_REG_ADDR = 12; // Exclude Limit value for the second FFT peak search process + + // read-write registers + static const uint32_t TEST_REG_ADDR = 15; + + // read-only registers + static const uint32_t RESULT_VALID_REG_ADDR = 0; // Flag that indicates a valid result + static const uint32_t SAMPLESTAMP_LSW_REG_ADDR = 1; // Sample stamp LSW + static const uint32_t SAMPLESTAMP_MSW_REG_ADDR = 2; // Sample stamp MSW + static const uint32_t MAG_SQ_FIRST_PEAK_REG_ADDR = 3; // magnitude squared of the first peak + static const uint32_t MAG_SQ_SECOND_PEAK_REG_ADDR = 4; // magnitude squared of the second peak + static const uint32_t ACQ_DELAY_SAMPLES_REG_ADDR = 5; // acquisition delay in samples + static const uint32_t DOPPLER_INDEX_REG_ADDR = 7; // Doppler index + static const uint32_t FFT_SCALING_FACTOR_REG_ADDR = 8; // Scaling factor applied by the FFT + static const uint32_t MAX_FFT_SIZE_REG_ADDR = 9; // Maximum FFT size supported by the FPGA + static const uint32_t DOWNSAMPLING_FILTER_DEC_FACTORS_REG_ADDR = 10; // Available decimation factors + static const uint32_t DOWNSAMPLING_FILTER_LATENCIES_REG_ADDR = 11; // Available downsampling filter latencies + static const uint32_t FPGA_IP_CORE_VERSION_REG_ADDR = 14; // FPGA acquisition IP core version + // FPGA register parameters static const uint32_t FPGA_PAGE_SIZE = 0x1000; // default page size for the multicorrelator memory map static const uint32_t LAUNCH_ACQUISITION = 1; // command to launch the acquisition process @@ -151,31 +187,42 @@ private: static const uint32_t MEM_LOCAL_CODE_WR_ENABLE = 0x0C000000; // command to enable the ENA and WR pins of the internal memory of the multicorrelator static const uint32_t POW_2_2 = 4; // 2^2 (used for the conversion of floating point numbers to integers) static const uint32_t POW_2_31 = 2147483648; // 2^31 (used for the conversion of floating point numbers to integers) + static const uint32_t MAX_FILTERS_AVAILABLE = 2; // maximum number of downsampling filters available in the FPGA by default + static const uint32_t DEFAULT_MAX_FFT_SIZE = 32768; // default maximum FFT size supported by the FPGA + static const uint32_t ACQ_BUFF_0 = 0; // FPGA Acquisition IP buffer containing L1/E1 frequency band samples by default. + static const uint32_t ACQ_BUFF_1 = 0; // FPGA Acquisition IP buffer containing L2 or L5/E5a frequency band samples by default. - static const uint32_t SELECT_LSBits = 0x0000FFFF; // Select the 10 LSbits out of a 20-bit word - static const uint32_t SELECT_MSBbits = 0xFFFF0000; // Select the 10 MSbits out of a 20-bit word - static const uint32_t SELECT_ALL_CODE_BITS = 0xFFFFFFFF; // Select a 20 bit word - static const uint32_t SHL_CODE_BITS = 65536; // shift left by 10 bits + // bit manipulation + static const uint32_t RSHIFT_4_BITS = 0x4; + static const uint32_t RSHIFT_8_BITS = 0x8; + static const uint32_t BIT_MASK_4 = 0xF; + static const uint32_t BIT_MASK_8 = 0xFF; - // FPGA private functions + // Downsampling default constants + const uint32_t DEFAULT_DOWNSAMPLING_FILTER_DELAY = 40; // default downsampling filter delay (for FPGA Acquisition IP core versions earlier than FPGA_ACQ_IP_VERSION_1) + const uint32_t DEFAULT_DOWNSAMPLING_FACTOR = 4; // default downsampling factor (for FPGA Acquisition IP core versions earlier than FPGA_ACQ_IP_VERSION_1) + + // private methods void fpga_acquisition_test_register(void); - void read_result_valid(uint32_t *result_valid); + void read_ipcore_info(std::vector> &downsampling_filter_specs, uint32_t &max_FFT_size); - std::string d_device_name; // HW device name - - int64_t d_fs_in; - // data related to the hardware module and the driver - int32_t d_fd; // driver descriptor + std::vector> d_downsampling_filter_specs; + std::string d_device_name; // HW device name + int64_t d_resampled_fs; // sampling frequency volatile uint32_t *d_map_base; // driver memory map uint32_t *d_all_fft_codes; // memory that contains all the code ffts - uint32_t d_vector_length; // number of samples including padding and number of ms + int32_t d_fd; // driver descriptor + uint32_t d_fft_size; // number of samples including padding uint32_t d_excludelimit; - uint32_t d_nsamples_total; // number of samples including padding - uint32_t d_nsamples; // number of samples not including padding - uint32_t d_select_queue; // queue selection - uint32_t d_doppler_max; // max doppler - uint32_t d_doppler_step; // doppler step - uint32_t d_PRN; // PRN + uint32_t d_nsamples; // number of samples not including padding + uint32_t d_filter_num; // Selected downsampling filter + uint32_t d_downsampling_factor; // downsampling_factor + uint32_t d_downsampling_filter_delay; // Impulse response delay of the downsampling filter + uint32_t d_select_queue; // queue selection + uint32_t d_doppler_max; // max doppler + uint32_t d_doppler_step; // doppler step + uint32_t d_PRN; // PRN + uint32_t d_IP_core_version; // FPGA acquisition IP core version }; diff --git a/src/algorithms/channel/adapters/CMakeLists.txt b/src/algorithms/channel/adapters/CMakeLists.txt index 7d9ddcf83..4d1fda6ba 100644 --- a/src/algorithms/channel/adapters/CMakeLists.txt +++ b/src/algorithms/channel/adapters/CMakeLists.txt @@ -26,9 +26,15 @@ target_link_libraries(channel_adapters channel_libs PRIVATE gnss_sdr_flags - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(channel_adapters PRIVATE Glog::glog) + target_compile_definitions(channel_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(channel_adapters PRIVATE absl::flags absl::log) +endif() + target_include_directories(channel_adapters PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/channel/adapters/channel.cc b/src/algorithms/channel/adapters/channel.cc index 444eef958..f69743398 100644 --- a/src/algorithms/channel/adapters/channel.cc +++ b/src/algorithms/channel/adapters/channel.cc @@ -22,10 +22,14 @@ #include "gnss_sdr_flags.h" #include "telemetry_decoder_interface.h" #include "tracking_interface.h" -#include #include // for std::invalid_argument #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Channel::Channel(const ConfigurationInterface* configuration, uint32_t channel, @@ -77,10 +81,17 @@ Channel::Channel(const ConfigurationInterface* configuration, { doppler_step = configuration->property("Acquisition_" + signal_str + ".doppler_step", 500); } +#if USE_GLOG_AND_GFLAGS if (FLAGS_doppler_step != 0) { doppler_step = static_cast(FLAGS_doppler_step); } +#else + if (absl::GetFlag(FLAGS_doppler_step) != 0) + { + doppler_step = static_cast(absl::GetFlag(FLAGS_doppler_step)); + } +#endif DLOG(INFO) << "Channel " << channel_ << " Doppler_step = " << doppler_step; acq_->set_doppler_step(doppler_step); diff --git a/src/algorithms/channel/libs/CMakeLists.txt b/src/algorithms/channel/libs/CMakeLists.txt index 63e0d72d8..dc5715abb 100644 --- a/src/algorithms/channel/libs/CMakeLists.txt +++ b/src/algorithms/channel/libs/CMakeLists.txt @@ -39,10 +39,15 @@ target_link_libraries(channel_libs PRIVATE core_libs Boost::headers - Gflags::gflags - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(channel_libs PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(channel_libs PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(channel_libs PRIVATE absl::flags absl::log) +endif() + target_include_directories(channel_libs PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/receiver diff --git a/src/algorithms/channel/libs/channel_fsm.cc b/src/algorithms/channel/libs/channel_fsm.cc index 48f001238..c092c77a8 100644 --- a/src/algorithms/channel/libs/channel_fsm.cc +++ b/src/algorithms/channel/libs/channel_fsm.cc @@ -18,9 +18,14 @@ #include "channel_fsm.h" #include "channel_event.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + ChannelFsm::ChannelFsm() : queue_(nullptr), channel_(0U), diff --git a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc index 4d2e5616b..3a9607b5a 100644 --- a/src/algorithms/channel/libs/channel_msg_receiver_cc.cc +++ b/src/algorithms/channel/libs/channel_msg_receiver_cc.cc @@ -17,12 +17,17 @@ #include "channel_msg_receiver_cc.h" -#include #include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if PMT_USES_BOOST_ANY #include namespace wht = boost; diff --git a/src/algorithms/conditioner/adapters/CMakeLists.txt b/src/algorithms/conditioner/adapters/CMakeLists.txt index 7c24d008e..fe0bc95f6 100644 --- a/src/algorithms/conditioner/adapters/CMakeLists.txt +++ b/src/algorithms/conditioner/adapters/CMakeLists.txt @@ -37,11 +37,22 @@ endif() target_link_libraries(conditioner_adapters PUBLIC Gnuradio::runtime - PRIVATE - Gflags::gflags - Glog::glog ) +if(GNURADIO_VERSION VERSION_LESS 3.9) + target_link_libraries(conditioner_adapters + PUBLIC + Boost::headers + ) +endif() + +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(conditioner_adapters PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(conditioner_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(conditioner_adapters PRIVATE absl::flags absl::log) +endif() + target_include_directories(conditioner_adapters PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/conditioner/adapters/array_signal_conditioner.cc b/src/algorithms/conditioner/adapters/array_signal_conditioner.cc index 02471e8a5..85256ee13 100644 --- a/src/algorithms/conditioner/adapters/array_signal_conditioner.cc +++ b/src/algorithms/conditioner/adapters/array_signal_conditioner.cc @@ -17,9 +17,13 @@ #include "array_signal_conditioner.h" #include "configuration_interface.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif // Constructor ArraySignalConditioner::ArraySignalConditioner(std::shared_ptr data_type_adapt, diff --git a/src/algorithms/conditioner/adapters/signal_conditioner.cc b/src/algorithms/conditioner/adapters/signal_conditioner.cc index 871ed0a51..0c3519ce6 100644 --- a/src/algorithms/conditioner/adapters/signal_conditioner.cc +++ b/src/algorithms/conditioner/adapters/signal_conditioner.cc @@ -16,10 +16,14 @@ */ #include "signal_conditioner.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif // Constructor SignalConditioner::SignalConditioner(std::shared_ptr data_type_adapt, @@ -59,7 +63,7 @@ void SignalConditioner::connect(gr::top_block_sptr top_block) if (in_filt_->item_size() == 0) { - throw std::invalid_argument("itemsize mismatch: Invalid input/ouput data type configuration for the InputFilter"); + throw std::invalid_argument("itemsize mismatch: Invalid input/output data type configuration for the InputFilter"); } const size_t data_type_adapter_output_size = data_type_adapt_->get_right_block()->output_signature()->sizeof_stream_item(0); @@ -69,12 +73,12 @@ void SignalConditioner::connect(gr::top_block_sptr top_block) if (data_type_adapter_output_size != input_filter_input_size) { - throw std::invalid_argument("itemsize mismatch: Invalid input/ouput data type configuration for the DataTypeAdapter/InputFilter connection"); + throw std::invalid_argument("itemsize mismatch: Invalid input/output data type configuration for the DataTypeAdapter/InputFilter connection"); } if (input_filter_output_size != resampler_input_size) { - throw std::invalid_argument("itemsize mismatch: Invalid input/ouput data type configuration for the Input Filter/Resampler connection"); + throw std::invalid_argument("itemsize mismatch: Invalid input/output data type configuration for the Input Filter/Resampler connection"); } top_block->connect(data_type_adapt_->get_right_block(), 0, in_filt_->get_left_block(), 0); diff --git a/src/algorithms/data_type_adapter/adapters/CMakeLists.txt b/src/algorithms/data_type_adapter/adapters/CMakeLists.txt index f3829b5ab..9b5935e5b 100644 --- a/src/algorithms/data_type_adapter/adapters/CMakeLists.txt +++ b/src/algorithms/data_type_adapter/adapters/CMakeLists.txt @@ -7,6 +7,7 @@ set(DATATYPE_ADAPTER_SOURCES byte_to_short.cc + cshort_to_grcomplex.cc ibyte_to_cbyte.cc ibyte_to_complex.cc ibyte_to_cshort.cc @@ -16,6 +17,7 @@ set(DATATYPE_ADAPTER_SOURCES set(DATATYPE_ADAPTER_HEADERS byte_to_short.h + cshort_to_grcomplex.h ibyte_to_cbyte.h ibyte_to_complex.h ibyte_to_cshort.h @@ -53,11 +55,16 @@ target_link_libraries(data_type_adapters Gnuradio::blocks data_type_gr_blocks PRIVATE - Gflags::gflags - Glog::glog Volk::volk ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(data_type_adapters PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(data_type_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(data_type_adapters PRIVATE absl::flags absl::log) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(data_type_adapters diff --git a/src/algorithms/data_type_adapter/adapters/byte_to_short.cc b/src/algorithms/data_type_adapter/adapters/byte_to_short.cc index 43e9d119b..d25a23f0e 100644 --- a/src/algorithms/data_type_adapter/adapters/byte_to_short.cc +++ b/src/algorithms/data_type_adapter/adapters/byte_to_short.cc @@ -16,9 +16,14 @@ #include "byte_to_short.h" #include "configuration_interface.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + ByteToShort::ByteToShort(const ConfigurationInterface* configuration, std::string role, @@ -30,7 +35,7 @@ ByteToShort::ByteToShort(const ConfigurationInterface* configuration, { const std::string default_input_item_type("byte"); const std::string default_output_item_type("short"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./data_type_adapter.dat"); DLOG(INFO) << "role " << role_; diff --git a/src/algorithms/data_type_adapter/adapters/byte_to_short.h b/src/algorithms/data_type_adapter/adapters/byte_to_short.h index cd31891e7..13fef0e79 100644 --- a/src/algorithms/data_type_adapter/adapters/byte_to_short.h +++ b/src/algorithms/data_type_adapter/adapters/byte_to_short.h @@ -27,7 +27,7 @@ * Classes for data type conversion * \{ */ /** \addtogroup Data_type_adapters data_type_adapters - * Wrap GNU Radio data tyope adapter blocks with a GNSSBlockInterface + * Wrap GNU Radio data type adapter blocks with a GNSSBlockInterface * \{ */ diff --git a/src/algorithms/data_type_adapter/adapters/cshort_to_grcomplex.cc b/src/algorithms/data_type_adapter/adapters/cshort_to_grcomplex.cc new file mode 100644 index 000000000..ad63835ce --- /dev/null +++ b/src/algorithms/data_type_adapter/adapters/cshort_to_grcomplex.cc @@ -0,0 +1,92 @@ +/*! + * \file cshort_to_grcomplex.cc + * \brief Adapts an 16-bits complex sample stream to a float complex stream + * \author Carles Fernandez Prades, 2014 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "cshort_to_grcomplex.h" +#include "configuration_interface.h" +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + + +CshortToGrComplex::CshortToGrComplex(const ConfigurationInterface* configuration, + std::string role, + unsigned int in_streams, + unsigned int out_streams) : role_(std::move(role)), + in_streams_(in_streams), + out_streams_(out_streams), + dump_(configuration->property(role_ + ".dump", false)) +{ + const std::string default_dump_filename("./data_type_adapter.dat"); + + DLOG(INFO) << "role " << role_; + + dump_filename_ = configuration->property(role_ + ".dump_filename", default_dump_filename); + cshort_to_gr_complex_ = make_cshort_to_gr_complex(); + + DLOG(INFO) << "data_type_adapter_(" << cshort_to_gr_complex_->unique_id() << ")"; + + if (dump_) + { + DLOG(INFO) << "Dumping output into file " << dump_filename_; + const size_t item_size = sizeof(gr_complex); + file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str()); + } + if (in_streams_ > 1) + { + LOG(ERROR) << "This implementation only supports one input stream"; + } + if (out_streams_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +void CshortToGrComplex::connect(gr::top_block_sptr top_block) +{ + if (dump_) + { + top_block->connect(cshort_to_gr_complex_, 0, file_sink_, 0); + } + else + { + DLOG(INFO) << "Nothing to connect internally"; + } +} + + +void CshortToGrComplex::disconnect(gr::top_block_sptr top_block) +{ + if (dump_) + { + top_block->disconnect(cshort_to_gr_complex_, 0, file_sink_, 0); + } +} + + +gr::basic_block_sptr CshortToGrComplex::get_left_block() +{ + return cshort_to_gr_complex_; +} + + +gr::basic_block_sptr CshortToGrComplex::get_right_block() +{ + return cshort_to_gr_complex_; +} diff --git a/src/algorithms/data_type_adapter/adapters/cshort_to_grcomplex.h b/src/algorithms/data_type_adapter/adapters/cshort_to_grcomplex.h new file mode 100644 index 000000000..219158dce --- /dev/null +++ b/src/algorithms/data_type_adapter/adapters/cshort_to_grcomplex.h @@ -0,0 +1,83 @@ +/*! + * \file cshort_to_grcomplex.h + * \brief Adapts an 16-bits complex sample stream to a float complex stream + * \author Carles Fernandez Prades, 2014 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_CSHORT_TO_GRCOMPLEX_H +#define GNSS_SDR_CSHORT_TO_GRCOMPLEX_H + +#include "cshort_to_gr_complex.h" +#include "gnss_block_interface.h" +#include +#include +#include + +/** \addtogroup Data_Type Data Type Adapters + * Classes for data type conversion + * \{ */ +/** \addtogroup Data_type_adapters data_type_adapters + * Wrap GNU Radio data type adapter blocks with a GNSSBlockInterface + * \{ */ + + +class ConfigurationInterface; + +/*! + * \brief Adapts an 16-bits complex sample stream to a float complex stream + * + */ +class CshortToGrComplex : public GNSSBlockInterface +{ +public: + CshortToGrComplex(const ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); + + ~CshortToGrComplex() = default; + + inline std::string role() override + { + return role_; + } + + //! Returns "Cshort_To_Gr_Complex" + inline std::string implementation() override + { + return "Cshort_To_Gr_Complex"; + } + + inline size_t item_size() override + { + return 2 * sizeof(float); + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + +private: + cshort_to_gr_complex_sptr cshort_to_gr_complex_; + gr::blocks::file_sink::sptr file_sink_; + std::string dump_filename_; + std::string role_; + unsigned int in_streams_; + unsigned int out_streams_; + bool dump_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_CSHORT_TO_GRCOMPLEX_H diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc b/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc index dc825015d..df7322761 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_cbyte.cc @@ -17,8 +17,14 @@ #include "ibyte_to_cbyte.h" #include "configuration_interface.h" -#include #include +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif IbyteToCbyte::IbyteToCbyte(const ConfigurationInterface* configuration, @@ -32,7 +38,7 @@ IbyteToCbyte::IbyteToCbyte(const ConfigurationInterface* configuration, { const std::string default_input_item_type("byte"); const std::string default_output_item_type("lv_8sc_t"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./data_type_adapter.dat"); DLOG(INFO) << "role " << role_; diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc b/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc index 13be7798c..7682f4405 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_complex.cc @@ -16,7 +16,13 @@ #include "ibyte_to_complex.h" #include "configuration_interface.h" +#include + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif IbyteToComplex::IbyteToComplex(const ConfigurationInterface* configuration, const std::string& role, @@ -29,7 +35,7 @@ IbyteToComplex::IbyteToComplex(const ConfigurationInterface* configuration, cons { const std::string default_input_item_type("byte"); const std::string default_output_item_type("gr_complex"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./data_type_adapter.dat"); DLOG(INFO) << "role " << role_; diff --git a/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc b/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc index a146ef474..5e37d724b 100644 --- a/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc +++ b/src/algorithms/data_type_adapter/adapters/ibyte_to_cshort.cc @@ -17,9 +17,14 @@ #include "ibyte_to_cshort.h" #include "configuration_interface.h" -#include #include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif IbyteToCshort::IbyteToCshort(const ConfigurationInterface* configuration, const std::string& role, @@ -32,7 +37,7 @@ IbyteToCshort::IbyteToCshort(const ConfigurationInterface* configuration, { const std::string default_input_item_type("byte"); const std::string default_output_item_type("cshort"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./data_type_adapter.dat"); DLOG(INFO) << "role " << role_; diff --git a/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc b/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc index 0e67db072..e18d61015 100644 --- a/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc +++ b/src/algorithms/data_type_adapter/adapters/ishort_to_complex.cc @@ -16,8 +16,13 @@ #include "ishort_to_complex.h" #include "configuration_interface.h" -#include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif IshortToComplex::IshortToComplex(const ConfigurationInterface* configuration, const std::string& role, @@ -30,7 +35,7 @@ IshortToComplex::IshortToComplex(const ConfigurationInterface* configuration, { const std::string default_input_item_type("short"); const std::string default_output_item_type("gr_complex"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./data_type_adapter.dat"); DLOG(INFO) << "role " << role_; diff --git a/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc b/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc index b51232869..717d7064d 100644 --- a/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc +++ b/src/algorithms/data_type_adapter/adapters/ishort_to_cshort.cc @@ -17,9 +17,14 @@ #include "ishort_to_cshort.h" #include "configuration_interface.h" -#include #include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif IshortToCshort::IshortToCshort(const ConfigurationInterface* configuration, const std::string& role, @@ -32,7 +37,7 @@ IshortToCshort::IshortToCshort(const ConfigurationInterface* configuration, { const std::string default_input_item_type("short"); const std::string default_output_item_type("cshort"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./data_type_adapter.dat"); DLOG(INFO) << "role " << role_; diff --git a/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt b/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt index 5a05385c2..79330488e 100644 --- a/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/data_type_adapter/gnuradio_blocks/CMakeLists.txt @@ -6,12 +6,14 @@ set(DATA_TYPE_GR_BLOCKS_SOURCES + cshort_to_gr_complex.cc interleaved_byte_to_complex_byte.cc interleaved_short_to_complex_short.cc interleaved_byte_to_complex_short.cc ) set(DATA_TYPE_GR_BLOCKS_HEADERS + cshort_to_gr_complex.h interleaved_byte_to_complex_byte.h interleaved_short_to_complex_short.h interleaved_byte_to_complex_short.h @@ -42,6 +44,7 @@ target_link_libraries(data_type_gr_blocks Boost::headers PRIVATE Volk::volk + Volkgnsssdr::volkgnsssdr ) target_include_directories(data_type_gr_blocks diff --git a/src/algorithms/data_type_adapter/gnuradio_blocks/cshort_to_gr_complex.cc b/src/algorithms/data_type_adapter/gnuradio_blocks/cshort_to_gr_complex.cc new file mode 100644 index 000000000..b547d943f --- /dev/null +++ b/src/algorithms/data_type_adapter/gnuradio_blocks/cshort_to_gr_complex.cc @@ -0,0 +1,50 @@ +/*! + * \file cshort_to_gr_complex.cc + * \brief Adapts a complex short (16 + 16 bits) sample stream into a + * std::complex stream (32 + 32 bits) + * \author Carles Fernandez Prades, 2014 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#include "cshort_to_gr_complex.h" +#include +#include +#include +#include // for max + + +cshort_to_gr_complex_sptr make_cshort_to_gr_complex() +{ + return cshort_to_gr_complex_sptr(new cshort_to_gr_complex()); +} + + +cshort_to_gr_complex::cshort_to_gr_complex() + : sync_block("cshort_to_gr_complex", + gr::io_signature::make(1, 1, sizeof(lv_16sc_t)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) +{ + const auto alignment_multiple = static_cast(volk_get_alignment() / sizeof(lv_16sc_t)); + set_alignment(std::max(1, alignment_multiple)); +} + + +int cshort_to_gr_complex::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const auto *in = reinterpret_cast(input_items[0]); + auto *out = reinterpret_cast(output_items[0]); + volk_gnsssdr_16ic_convert_32fc(out, in, noutput_items); + return noutput_items; +} diff --git a/src/algorithms/data_type_adapter/gnuradio_blocks/cshort_to_gr_complex.h b/src/algorithms/data_type_adapter/gnuradio_blocks/cshort_to_gr_complex.h new file mode 100644 index 000000000..6605597d3 --- /dev/null +++ b/src/algorithms/data_type_adapter/gnuradio_blocks/cshort_to_gr_complex.h @@ -0,0 +1,55 @@ +/*! + * \file cshort_to_gr_complex.h + * \brief Adapts a complex short (16 + 16 bits) sample stream into a + * std::complex stream (32 + 32 bits) + * \author Carles Fernandez Prades, 2014 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_CSHORT_TO_GR_COMPLEX_H +#define GNSS_SDR_CSHORT_TO_GR_COMPLEX_H + +#include "gnss_block_interface.h" +#include + +/** \addtogroup Data_Type + * \{ */ +/** \addtogroup data_type_gnuradio_blocks + * \{ */ + + +class cshort_to_gr_complex; + +using cshort_to_gr_complex_sptr = gnss_shared_ptr; + +cshort_to_gr_complex_sptr make_cshort_to_gr_complex(); + +/*! + * \brief This class adapts a short (16-bits) interleaved sample stream + * into a std::complex stream + */ +class cshort_to_gr_complex : public gr::sync_block +{ +public: + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +private: + friend cshort_to_gr_complex_sptr make_cshort_to_gr_complex(); + cshort_to_gr_complex(); +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_CSHORT_TO_GR_COMPLEX_H \ No newline at end of file diff --git a/src/algorithms/input_filter/adapters/CMakeLists.txt b/src/algorithms/input_filter/adapters/CMakeLists.txt index a4f052ade..6af64cff8 100644 --- a/src/algorithms/input_filter/adapters/CMakeLists.txt +++ b/src/algorithms/input_filter/adapters/CMakeLists.txt @@ -47,11 +47,16 @@ target_link_libraries(input_filter_adapters algorithms_libs input_filter_gr_blocks PRIVATE - Gflags::gflags - Glog::glog Volk::volk ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(input_filter_adapters PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(input_filter_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(input_filter_adapters PRIVATE absl::flags absl::log) +endif() + if(GNURADIO_IS_38_OR_GREATER) target_compile_definitions(input_filter_adapters PUBLIC -DGR_GREATER_38=1) endif() diff --git a/src/algorithms/input_filter/adapters/beamformer_filter.cc b/src/algorithms/input_filter/adapters/beamformer_filter.cc index 4a96bf85b..b3efdee03 100644 --- a/src/algorithms/input_filter/adapters/beamformer_filter.cc +++ b/src/algorithms/input_filter/adapters/beamformer_filter.cc @@ -17,9 +17,14 @@ #include "beamformer_filter.h" #include "beamformer.h" #include "configuration_interface.h" -#include #include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif BeamformerFilter::BeamformerFilter( const ConfigurationInterface* configuration, const std::string& role, @@ -30,7 +35,7 @@ BeamformerFilter::BeamformerFilter( dump_(configuration->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_file("./data/input_filter.dat"); + const std::string default_dump_file("./input_filter.dat"); item_type_ = configuration->property(role + ".item_type", default_item_type); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); DLOG(INFO) << "role " << role_; diff --git a/src/algorithms/input_filter/adapters/fir_filter.cc b/src/algorithms/input_filter/adapters/fir_filter.cc index ad76b5f6a..92c84645a 100644 --- a/src/algorithms/input_filter/adapters/fir_filter.cc +++ b/src/algorithms/input_filter/adapters/fir_filter.cc @@ -17,11 +17,15 @@ #include "fir_filter.h" #include "configuration_interface.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif FirFilter::FirFilter(const ConfigurationInterface* configuration, std::string role, @@ -138,7 +142,7 @@ void FirFilter::init() const std::string default_input_item_type("gr_complex"); const std::string default_output_item_type("gr_complex"); const std::string default_taps_item_type("float"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./input_filter.dat"); const std::string default_filter_type("bandpass"); const std::vector default_bands = {0.0, 0.4, 0.6, 1.0}; const std::vector default_ampl = {1.0, 1.0, 0.0, 0.0}; diff --git a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc index 1d4e2f386..ba75c6f67 100644 --- a/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc +++ b/src/algorithms/input_filter/adapters/freq_xlating_fir_filter.cc @@ -17,13 +17,17 @@ #include "freq_xlating_fir_filter.h" #include "configuration_interface.h" -#include #include #include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif FreqXlatingFirFilter::FreqXlatingFirFilter(const ConfigurationInterface* configuration, std::string role, @@ -37,7 +41,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(const ConfigurationInterface* configu const std::string default_input_item_type("gr_complex"); const std::string default_output_item_type("gr_complex"); const std::string default_taps_item_type("float"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./input_filter.dat"); const double default_intermediate_freq = 0.0; const double default_sampling_freq = 4000000.0; const int default_number_of_taps = 6; diff --git a/src/algorithms/input_filter/adapters/notch_filter.cc b/src/algorithms/input_filter/adapters/notch_filter.cc index 1ca31c5f3..b84c8833d 100644 --- a/src/algorithms/input_filter/adapters/notch_filter.cc +++ b/src/algorithms/input_filter/adapters/notch_filter.cc @@ -19,8 +19,13 @@ #include "configuration_interface.h" #include "notch_cc.h" #include -#include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif NotchFilter::NotchFilter(const ConfigurationInterface* configuration, const std::string& role, @@ -32,7 +37,7 @@ NotchFilter::NotchFilter(const ConfigurationInterface* configuration, dump_(configuration->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_file("./data/input_filter.dat"); + const std::string default_dump_file("./input_filter.dat"); const float default_pfa = 0.001; const float default_p_c_factor = 0.9; const int default_length_ = 32; diff --git a/src/algorithms/input_filter/adapters/notch_filter_lite.cc b/src/algorithms/input_filter/adapters/notch_filter_lite.cc index 8dc161688..c6b4ab8d7 100644 --- a/src/algorithms/input_filter/adapters/notch_filter_lite.cc +++ b/src/algorithms/input_filter/adapters/notch_filter_lite.cc @@ -19,9 +19,14 @@ #include "configuration_interface.h" #include "notch_lite_cc.h" #include -#include #include // for max +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif NotchFilterLite::NotchFilterLite(const ConfigurationInterface* configuration, const std::string& role, @@ -33,7 +38,7 @@ NotchFilterLite::NotchFilterLite(const ConfigurationInterface* configuration, dump_(configuration->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_file("./data/input_filter.dat"); + const std::string default_dump_file("./input_filter.dat"); const float default_p_c_factor = 0.9; const float default_pfa = 0.001; const float default_samp_freq = 4000000; diff --git a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc index b28c13d47..8732ba4f8 100644 --- a/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc +++ b/src/algorithms/input_filter/adapters/pulse_blanking_filter.cc @@ -19,12 +19,16 @@ #include "pulse_blanking_filter.h" #include "configuration_interface.h" #include -#include #include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif PulseBlankingFilter::PulseBlankingFilter(const ConfigurationInterface* configuration, std::string role, @@ -35,7 +39,7 @@ PulseBlankingFilter::PulseBlankingFilter(const ConfigurationInterface* configura out_streams_(out_streams) { const std::string default_item_type("gr_complex"); - const std::string default_dump_filename("../data/input_filter.dat"); + const std::string default_dump_filename("./input_filter.dat"); const float default_pfa_ = 0.04; const float pfa = configuration->property(role_ + ".pfa", default_pfa_); const int default_length_ = 32; diff --git a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc index 8a4982b1b..c662427bd 100644 --- a/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc +++ b/src/algorithms/input_filter/gnuradio_blocks/notch_cc.cc @@ -43,7 +43,7 @@ Notch::Notch(float pfa, pfa_(pfa), noise_pow_est_(0.0), length_(length), // Set the number of samples per segment - n_deg_fred_(2 * length), // Number of dregrees of freedom, + n_deg_fred_(2 * length), // Number of degrees of freedom, n_segments_(0), n_segments_est_(n_segments_est), // Set the number of segments for noise power estimation n_segments_reset_(n_segments_reset), // Set the period (in segments) when the noise power is estimated diff --git a/src/algorithms/libs/CMakeLists.txt b/src/algorithms/libs/CMakeLists.txt index 1e31cf4c3..3f0b050a6 100644 --- a/src/algorithms/libs/CMakeLists.txt +++ b/src/algorithms/libs/CMakeLists.txt @@ -109,10 +109,15 @@ target_link_libraries(algorithms_libs core_system_parameters Volk::volk Volkgnsssdr::volkgnsssdr - Gflags::gflags - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(algorithms_libs PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(algorithms_libs PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(algorithms_libs PRIVATE absl::flags absl::log) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(algorithms_libs PUBLIC -DGNURADIO_USES_STD_POINTERS=1 @@ -208,13 +213,14 @@ else() target_link_libraries(gnss_sdr_flags PRIVATE Boost::filesystem Boost::system) endif() -target_link_libraries(gnss_sdr_flags - PUBLIC - Gflags::gflags -) - -if(GFLAGS_GREATER_20 OR ${LOCAL_GFLAGS}) - target_compile_definitions(gnss_sdr_flags PRIVATE -DGFLAGS_GREATER_2_0=1) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(gnss_sdr_flags PUBLIC Gflags::gflags) + target_compile_definitions(gnss_sdr_flags PUBLIC -DUSE_GLOG_AND_GFLAGS=1) + if(GFLAGS_GREATER_20 OR "${LOCAL_GFLAGS}") + target_compile_definitions(gnss_sdr_flags PRIVATE -DGFLAGS_GREATER_2_0=1) + endif() +else() + target_link_libraries(gnss_sdr_flags PUBLIC absl::flags) endif() target_compile_definitions(gnss_sdr_flags diff --git a/src/algorithms/libs/gnss_sdr_flags.cc b/src/algorithms/libs/gnss_sdr_flags.cc index 4961c01aa..8cd9bab54 100644 --- a/src/algorithms/libs/gnss_sdr_flags.cc +++ b/src/algorithms/libs/gnss_sdr_flags.cc @@ -1,7 +1,7 @@ /*! * \file gnss_sdr_flags.cc * \brief Helper file for gnss-sdr commandline flags - * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.es + * \author Carles Fernandez-Prades, 2018-2024. cfernandez(at)cttc.es * * * ----------------------------------------------------------------------------- @@ -9,7 +9,7 @@ * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -19,9 +19,8 @@ #include "gnss_sdr_flags.h" #include "gnss_sdr_filesystem.h" #include -#include - +#if USE_GLOG_AND_GFLAGS DEFINE_string(c, "-", "Path to the configuration file (if set, overrides --config_file)."); DEFINE_string(config_file, std::string(GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/default.conf"), @@ -69,7 +68,7 @@ DEFINE_bool(keyboard, true, "If set to false, it disables the keyboard listener static bool ValidateC(const char* flagname, const std::string& value) { - if (fs::exists(value) or value == "-") + if (fs::exists(value) || value == "-") { // value is ok return true; } @@ -80,7 +79,7 @@ static bool ValidateC(const char* flagname, const std::string& value) static bool ValidateConfigFile(const char* flagname, const std::string& value) { - if (fs::exists(value) or value == std::string(GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/default.conf")) + if (fs::exists(value) || value == std::string(GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/default.conf")) { // value is ok return true; } @@ -91,7 +90,7 @@ static bool ValidateConfigFile(const char* flagname, const std::string& value) static bool ValidateS(const char* flagname, const std::string& value) { - if (fs::exists(value) or value == "-") + if (fs::exists(value) || value == "-") { // value is ok return true; } @@ -102,7 +101,7 @@ static bool ValidateS(const char* flagname, const std::string& value) static bool ValidateSignalSource(const char* flagname, const std::string& value) { - if (fs::exists(value) or value == "-") + if (fs::exists(value) || value == "-") { // value is ok return true; } @@ -235,3 +234,134 @@ DEFINE_validator(pll_bw_hz, &ValidatePllBw); DEFINE_validator(carrier_smoothing_factor, &ValidateCarrierSmoothingFactor); #endif + +#else +ABSL_FLAG(std::string, c, "-", "Path to the configuration file (if set, overrides --config_file)."); +ABSL_FLAG(std::string, config_file, std::string(GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/default.conf"), "Path to the configuration file."); +ABSL_FLAG(std::string, log_dir, "", "Directory for log files"); +ABSL_FLAG(std::string, s, "-", "If defined, path to the file containing the signal samples (overrides the configuration file and --signal_source)."); +ABSL_FLAG(std::string, signal_source, "-", "If defined, path to the file containing the signal samples (overrides the configuration file)."); +ABSL_FLAG(std::string, timestamp_source, "-", "If defined, path to the file containing the signal timestamp data (overrides the configuration file)."); +ABSL_FLAG(bool, rf_shutdown, true, "If set to false, AD9361 RF channels are not shut down when exiting the program. Useful to leave the AD9361 configured and running."); +ABSL_FLAG(int32_t, doppler_max, 0, "If defined, sets the maximum Doppler value in the search grid, in Hz (overrides the configuration file)."); +ABSL_FLAG(int32_t, doppler_step, 0, "If defined, sets the frequency step in the search grid, in Hz (overrides the configuration file)."); +ABSL_FLAG(int32_t, cn0_samples, 20, "Number of correlator outputs used for CN0 estimation."); +ABSL_FLAG(int32_t, cn0_min, 25, "Minimum valid CN0 (in dB-Hz)."); +ABSL_FLAG(int32_t, max_carrier_lock_fail, 5000, "Maximum number of carrier lock failures before dropping a satellite."); +ABSL_FLAG(int32_t, max_lock_fail, 50, "Maximum number of code lock failures before dropping a satellite."); +ABSL_FLAG(double, carrier_lock_th, 0.7, "Carrier lock threshold (in rad)."); +ABSL_FLAG(double, dll_bw_hz, 0.0, "If defined, bandwidth of the DLL low pass filter, in Hz (overrides the configuration file)."); +ABSL_FLAG(double, pll_bw_hz, 0.0, "If defined, bandwidth of the PLL low pass filter, in Hz (overrides the configuration file)."); +ABSL_FLAG(int32_t, carrier_smoothing_factor, DEFAULT_CARRIER_SMOOTHING_FACTOR, "Sets carrier smoothing factor M (overrides the configuration file)"); +ABSL_FLAG(std::string, RINEX_version, "-", "If defined, specifies the RINEX version (2.11 or 3.02). Overrides the configuration file."); +ABSL_FLAG(std::string, RINEX_name, "-", "If defined, specifies the RINEX files base name"); +ABSL_FLAG(bool, keyboard, true, "If set to false, it disables the keyboard listener (so the receiver cannot be stopped with q+[Enter])"); + +bool ValidateFlags() +{ + bool success = true; + + auto value_c = absl::GetFlag(FLAGS_c); + if (!(fs::exists(value_c) || value_c == "-")) + { + std::cerr << "Invalid value for flag -c. The file '" << value_c << "' does not exist.\n"; + success = false; + } + + auto value_config_file = absl::GetFlag(FLAGS_config_file); + if (!(fs::exists(value_config_file) || value_config_file == std::string(GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/default.conf"))) + { + std::cerr << "Invalid value for flag -config_file. The file '" << value_config_file << "' does not exist.\n"; + success = false; + } + + auto value_s = absl::GetFlag(FLAGS_s); + if (!(fs::exists(value_s) || value_s == "-")) + { + std::cerr << "Invalid value for flag -s. The file '" << value_s << "' does not exist.\n"; + success = false; + } + + auto value_signal_source = absl::GetFlag(FLAGS_signal_source); + if (!(fs::exists(value_signal_source) || value_signal_source == "-")) + { + std::cerr << "Invalid value for flag -signal_source. The file '" << value_signal_source << "' does not exist.\n"; + success = false; + } + + auto value_doppler_max = absl::GetFlag(FLAGS_doppler_max); + const int32_t max_doppler_value = 1000000; + if (value_doppler_max < 0 || value_doppler_max > max_doppler_value) + { + std::cerr << "Invalid value for flag -doppler_max. Allowed range is 0 < doppler_max < " << max_doppler_value << " Hz.\n"; + success = false; + } + + auto value_doppler_step = absl::GetFlag(FLAGS_doppler_step); + const int32_t max_value_doppler_step = 10000; + if (value_doppler_step < 0 || value_doppler_step > max_value_doppler_step) + { + std::cerr << "Invalid value for flag -doppler_step: " << value_doppler_step << ". Allowed range is 0 < doppler_step < " << max_value_doppler_step << " Hz.\n"; + success = false; + } + + auto value_cn0_samples = absl::GetFlag(FLAGS_cn0_samples); + const int32_t max_value_cn0_samples = 10000; + if (value_cn0_samples < 0 || value_cn0_samples > max_value_cn0_samples) + { + std::cerr << "Invalid value for flag -cn0_samples: " << value_cn0_samples << ". Allowed range is 0 < cn0_samples < " << max_value_cn0_samples << " Hz.\n"; + success = false; + } + + auto value_cn0_min = absl::GetFlag(FLAGS_cn0_min); + const int32_t max_value_cn0_min = 100; + if (value_cn0_min < 0 || value_cn0_min > max_value_cn0_min) + { + std::cerr << "Invalid value for flag -cn0_min: " << value_cn0_min << ". Allowed range is 0 < cn0_min < " << max_value_cn0_min << " Hz.\n"; + success = false; + } + + auto value_max_lock_fail = absl::GetFlag(FLAGS_max_lock_fail); + const int32_t max_value_max_lock_fail = 10000; + if (value_max_lock_fail < 0 || value_max_lock_fail > max_value_max_lock_fail) + { + std::cerr << "Invalid value for flag -max_lock_fail: " << value_max_lock_fail << ". Allowed range is 0 < max_lock_fail < " << max_value_max_lock_fail << " Hz.\n"; + success = false; + } + + auto value_carrier_lock_th = absl::GetFlag(FLAGS_carrier_lock_th); + const double max_value_carrier_lock_th = 1.508; + if (value_carrier_lock_th < 0.0 || value_carrier_lock_th > max_value_carrier_lock_th) + { + std::cerr << "Invalid value for flag -carrier_lock_th: " << value_carrier_lock_th << ". Allowed range is 0 < carrier_lock_th < " << max_value_carrier_lock_th << " Hz.\n"; + success = false; + } + + auto value_dll_bw_hz = absl::GetFlag(FLAGS_dll_bw_hz); + const double max_value_dll_bw_hz = 10000.0; + if (value_dll_bw_hz < 0.0 || value_dll_bw_hz > max_value_dll_bw_hz) + { + std::cerr << "Invalid value for flag -dll_bw_hz: " << value_dll_bw_hz << ". Allowed range is 0 < dll_bw_hz < " << max_value_dll_bw_hz << " Hz.\n"; + success = false; + } + + auto value_pll_bw_hz = absl::GetFlag(FLAGS_pll_bw_hz); + const double max_value_pll_bw_hz = 10000.0; + if (value_pll_bw_hz < 0.0 || value_pll_bw_hz > max_value_pll_bw_hz) + { + std::cerr << "Invalid value for flag -pll_bw_hz: " << value_pll_bw_hz << ". Allowed range is 0 < pll_bw_hz < " << max_value_pll_bw_hz << " Hz.\n"; + success = false; + } + + auto value_carrier_smoothing_factor = absl::GetFlag(FLAGS_carrier_smoothing_factor); + const int32_t min_value_carrier_smoothing_factor = 1; + if (value_carrier_smoothing_factor < min_value_carrier_smoothing_factor) + { + std::cerr << "Invalid value for flag -carrier_smoothing_factor: " << value_carrier_smoothing_factor << ". Allowed range is 1 <= carrier_smoothing_factor.\n"; + success = false; + } + + return success; +} + +#endif diff --git a/src/algorithms/libs/gnss_sdr_flags.h b/src/algorithms/libs/gnss_sdr_flags.h index 361195a49..4b175d071 100644 --- a/src/algorithms/libs/gnss_sdr_flags.h +++ b/src/algorithms/libs/gnss_sdr_flags.h @@ -1,7 +1,7 @@ /*! * \file gnss_sdr_flags.h * \brief Helper file for gnss-sdr commandline flags - * \author Carles Fernandez-Prades, 2018. cfernandez(at)cttc.es + * \author Carles Fernandez-Prades, 2018-2024. cfernandez(at)cttc.es * * * ----------------------------------------------------------------------------- @@ -9,7 +9,7 @@ * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -18,9 +18,20 @@ #ifndef GNSS_SDR_GNSS_SDR_FLAGS_H #define GNSS_SDR_GNSS_SDR_FLAGS_H - -#include #include +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#include +#include +#include +#include +#endif + /** \addtogroup Algorithms_Library * \{ */ @@ -28,7 +39,7 @@ * Library for command-line handling. * \{ */ - +#if USE_GLOG_AND_GFLAGS DECLARE_string(c); //!< Path to the configuration file. DECLARE_string(config_file); //!< Path to the configuration file. @@ -62,6 +73,115 @@ DECLARE_string(RINEX_version); //!< If defined, specifies the RINEX version (2. DECLARE_string(RINEX_name); //!< If defined, specifies the RINEX files base name DECLARE_bool(keyboard); //!< If set to false, disables the keyboard listener. Only for debug purposes (e.g. ASAN mode termination) +#else +ABSL_DECLARE_FLAG(std::string, c); //!< Path to the configuration file. +ABSL_DECLARE_FLAG(std::string, config_file); //!< Path to the configuration file. + +ABSL_DECLARE_FLAG(std::string, log_dir); //!< Path to the folder in which logging will be stored. + +// Declare flags for signal sources +ABSL_DECLARE_FLAG(std::string, s); //!< Path to the file containing the signal samples. +ABSL_DECLARE_FLAG(std::string, signal_source); //!< Path to the file containing the signal samples. +ABSL_DECLARE_FLAG(std::string, timestamp_source); //!< Path to the file containing the signal samples. +ABSL_DECLARE_FLAG(bool, rf_shutdown); //!< Shutdown RF when program exits. + +// Declare flags for acquisition blocks +ABSL_DECLARE_FLAG(int32_t, doppler_max); //!< If defined, maximum Doppler value in the search grid, in Hz (overrides the configuration file). +ABSL_DECLARE_FLAG(int32_t, doppler_step); //!< If defined, sets the frequency step in the search grid, in Hz, in Hz (overrides the configuration file). + +// Declare flags for tracking blocks +ABSL_DECLARE_FLAG(int32_t, cn0_samples); //!< Number of correlator outputs used for CN0 estimation. +ABSL_DECLARE_FLAG(int32_t, cn0_min); //!< Minimum valid CN0 (in dB-Hz). +ABSL_DECLARE_FLAG(int32_t, max_lock_fail); //!< Maximum number of code lock failures before dropping a satellite. +ABSL_DECLARE_FLAG(int32_t, max_carrier_lock_fail); //!< Maximum number of carrier lock failures before dropping a satellite. +ABSL_DECLARE_FLAG(double, carrier_lock_th); //!< Carrier lock threshold (in rad). +ABSL_DECLARE_FLAG(double, dll_bw_hz); //!< Bandwidth of the DLL low pass filter, in Hz (overrides the configuration file). +ABSL_DECLARE_FLAG(double, pll_bw_hz); //!< Bandwidth of the PLL low pass filter, in Hz (overrides the configuration file). + +// Declare flags for observables block +ABSL_DECLARE_FLAG(int32_t, carrier_smoothing_factor); //!< Sets carrier smoothing factor M (overrides the configuration file). +const int32_t DEFAULT_CARRIER_SMOOTHING_FACTOR = 200; + +// Declare flags for PVT +ABSL_DECLARE_FLAG(std::string, RINEX_version); //!< If defined, specifies the RINEX version (2.11 or 3.02). Overrides the configuration file. +ABSL_DECLARE_FLAG(std::string, RINEX_name); //!< If defined, specifies the RINEX files base name +ABSL_DECLARE_FLAG(bool, keyboard); //!< If set to false, disables the keyboard listener. Only for debug purposes (e.g. ASAN mode termination) + +static inline void GetTempDirectories(std::vector& list) +{ + list.clear(); + // Directories, in order of preference. If we find a dir that + // exists, we stop adding other less-preferred dirs + const char* candidates[] = { + // Non-null only during unittest/regtest + std::getenv("TEST_TMPDIR"), + + // Explicitly-supplied temp dirs + std::getenv("TMPDIR"), + std::getenv("TMP"), + + // If all else fails + "/tmp", + }; + for (auto d : candidates) + { + if (!d) continue; // Empty env var + + // Make sure we don't surprise anyone who's expecting a '/' + std::string dstr = d; + if (dstr[dstr.size() - 1] != '/') + { + dstr += "/"; + } + list.push_back(dstr); + + struct stat statbuf; + if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) + { + // We found a dir that exists - we're done. + return; + } + } +} + + +static inline void GetExistingTempDirectories(std::vector& list) +{ + GetTempDirectories(list); + auto i_dir = list.begin(); + while (i_dir != list.end()) + { + if (access(i_dir->c_str(), 0)) + { + i_dir = list.erase(i_dir); + } + else + { + ++i_dir; + } + }; +} + + +static inline std::string GetTempDir() +{ + std::vector temp_directories_list; + GetExistingTempDirectories(temp_directories_list); + + if (temp_directories_list.empty()) + { + std::cerr << "No temporary directory found\n"; + exit(EXIT_FAILURE); + } + + // Use first directory from list of existing temporary directories. + return temp_directories_list.front(); +} + +bool ValidateFlags(); + +#endif + /** \} */ /** \} */ #endif // GNSS_SDR_GNSS_SDR_FLAGS_H diff --git a/src/algorithms/libs/gsl/include/gsl/gsl-lite.hpp b/src/algorithms/libs/gsl/include/gsl/gsl-lite.hpp index 50ae0af72..e4ed24221 100644 --- a/src/algorithms/libs/gsl/include/gsl/gsl-lite.hpp +++ b/src/algorithms/libs/gsl/include/gsl/gsl-lite.hpp @@ -3,7 +3,7 @@ // For more information see https://github.com/gsl-lite/gsl-lite // // Copyright (c) 2015-2019 Martin Moene -// Copyright (c) 2019-2021 Moritz Beutel +// Copyright (c) 2019-2024 Moritz Beutel // Copyright (c) 2015-2018 Microsoft Corporation. All rights reserved. // // SPDX-License-Identifier: MIT @@ -25,7 +25,7 @@ #include // for move(), forward<>(), swap() #define gsl_lite_MAJOR 0 -#define gsl_lite_MINOR 40 +#define gsl_lite_MINOR 42 #define gsl_lite_PATCH 0 #define gsl_lite_VERSION gsl_STRINGIFY(gsl_lite_MAJOR) "." gsl_STRINGIFY(gsl_lite_MINOR) "." gsl_STRINGIFY(gsl_lite_PATCH) @@ -177,6 +177,15 @@ #endif #define gsl_FEATURE_OWNER_MACRO_() gsl_FEATURE_OWNER_MACRO +// #if defined( gsl_FEATURE_STRING_SPAN ) +// # if ! gsl_CHECK_CFG_TOGGLE_VALUE_( gsl_FEATURE_STRING_SPAN ) +// # pragma message ("invalid configuration value gsl_FEATURE_STRING_SPAN=" gsl_STRINGIFY(gsl_FEATURE_STRING_SPAN) ", must be 0 or 1") +// # endif +// #else +// # define gsl_FEATURE_STRING_SPAN (gsl_CONFIG_DEFAULTS_VERSION == 0) // default +// #endif +// #define gsl_FEATURE_STRING_SPAN_() gsl_FEATURE_STRING_SPAN + #if defined(gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD) #if !gsl_CHECK_CFG_TOGGLE_VALUE_(gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD) #pragma message("invalid configuration value gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD=" gsl_STRINGIFY(gsl_FEATURE_EXPERIMENTAL_RETURN_GUARD) ", must be 0 or 1") @@ -211,7 +220,7 @@ #if !defined(gsl_CONFIG_DEPRECATE_TO_LEVEL) #if gsl_CONFIG_DEFAULTS_VERSION >= 1 -#define gsl_CONFIG_DEPRECATE_TO_LEVEL 6 +#define gsl_CONFIG_DEPRECATE_TO_LEVEL 7 #else #define gsl_CONFIG_DEPRECATE_TO_LEVEL 0 #endif @@ -295,6 +304,15 @@ #endif #define gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION_() gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION +#if defined(gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS) +#if !gsl_CHECK_CFG_TOGGLE_VALUE_(gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS) +#pragma message("invalid configuration value gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS=" gsl_STRINGIFY(gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS) ", must be 0 or 1") +#endif +#else +#define gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS 1 // default +#endif +#define gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS_() gsl_CONFIG_VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS + #if defined(gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF) #if !gsl_CHECK_CFG_NO_VALUE_(gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF) #pragma message("invalid configuration value gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF=" gsl_STRINGIFY(gsl_CONFIG_CONTRACT_CHECKING_EXPECTS_OFF) "; macro must be defined without value") @@ -468,7 +486,7 @@ #endif #endif -// C++ language version detection (C++20 is speculative): +// C++ language version detection (C++23 is speculative): // Note: VC14.0/1900 (VS2015) lacks too much from C++14. #ifndef gsl_CPLUSPLUS @@ -489,7 +507,8 @@ #define gsl_CPP11_OR_GREATER (gsl_CPLUSPLUS >= 201103L) #define gsl_CPP14_OR_GREATER (gsl_CPLUSPLUS >= 201402L) #define gsl_CPP17_OR_GREATER (gsl_CPLUSPLUS >= 201703L) -#define gsl_CPP20_OR_GREATER (gsl_CPLUSPLUS >= 202000L) +#define gsl_CPP20_OR_GREATER (gsl_CPLUSPLUS >= 202002L) +#define gsl_CPP23_OR_GREATER (gsl_CPLUSPLUS > 202002L) // tentative // C++ language version (represent 98 as 3): @@ -511,6 +530,7 @@ // MSVC++ 14.0 _MSC_VER == 1900 gsl_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) // MSVC++ 14.1 _MSC_VER >= 1910 gsl_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) // MSVC++ 14.2 _MSC_VER >= 1920 gsl_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) +// MSVC++ 14.3 _MSC_VER >= 1930 gsl_COMPILER_MSVC_VERSION == 143 (Visual Studio 2022) #if defined(_MSC_VER) && !defined(__clang__) #define gsl_COMPILER_MSVC_VER (_MSC_VER) @@ -545,7 +565,14 @@ // AppleClang 11.0.3 __apple_build_version__ == 11030032 gsl_COMPILER_APPLECLANG_VERSION == 1103 (Xcode 11.4, 11.4.1, 11.5, 11.6) (LLVM 9.0.0) // AppleClang 12.0.0 __apple_build_version__ == 12000032 gsl_COMPILER_APPLECLANG_VERSION == 1200 (Xcode 12.0–12.4) (LLVM 10.0.0) // AppleClang 12.0.5 __apple_build_version__ == 12050022 gsl_COMPILER_APPLECLANG_VERSION == 1205 (Xcode 12.5) (LLVM 11.1.0) -// AppleClang 13.0.0 __apple_build_version__ == 13000029 gsl_COMPILER_APPLECLANG_VERSION == 1300 (Xcode 13.0) (LLVM 12.0.0) +// AppleClang 13.0.0 __apple_build_version__ == 13000029 gsl_COMPILER_APPLECLANG_VERSION == 1300 (Xcode 13.0–13.2.1) (LLVM 12.0.0) +// AppleClang 13.1.6 __apple_build_version__ == 13160021 gsl_COMPILER_APPLECLANG_VERSION == 1316 (Xcode 13.3–13.4.1) (LLVM 13.0.0) +// AppleClang 14.0.0 __apple_build_version__ == 14000029 gsl_COMPILER_APPLECLANG_VERSION == 1400 (Xcode 14.0–14.2) (LLVM 14.0.0) +// AppleClang 14.0.3 __apple_build_version__ == 14030022 gsl_COMPILER_APPLECLANG_VERSION == 1403 (Xcode 14.3) (LLVM 15.0.0) +// AppleClang 15.0.0 __apple_build_version__ == 15000040 gsl_COMPILER_APPLECLANG_VERSION == 1500 (Xcode 15.0) (LLVM 16.0.0) +// AppleClang 15.0.0 __apple_build_version__ == 15000100 gsl_COMPILER_APPLECLANG_VERSION == 1500 (Xcode 15.1–15.2) (LLVM 16.0.0) +// AppleClang 15.0.0 __apple_build_version__ == 15000309 gsl_COMPILER_APPLECLANG_VERSION == 1500 (Xcode 15.3–15.4) (LLVM 16.0.0) +// AppleClang 16.0.0 __apple_build_version__ == 16000026 gsl_COMPILER_APPLECLANG_VERSION == 1600 (Xcode 16.0) (LLVM 17.0.6) #if defined(__apple_build_version__) #define gsl_COMPILER_APPLECLANG_VERSION gsl_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) @@ -605,7 +632,7 @@ // Presence of wide character support: -#ifdef __DJGPP__ +#if defined(__DJGPP__) || (defined(_LIBCPP_VERSION) && defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)) #define gsl_HAVE_WCHAR 0 #else #define gsl_HAVE_WCHAR 1 @@ -754,6 +781,7 @@ #define gsl_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE_() gsl_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE #define gsl_HAVE_DEDUCTION_GUIDES_() gsl_HAVE_DEDUCTION_GUIDES #define gsl_HAVE_NODISCARD_() gsl_HAVE_NODISCARD +#define gsl_HAVE_MAYBE_UNUSED_() gsl_CPP17_OR_GREATER #define gsl_HAVE_CONSTEXPR_17_() gsl_HAVE_CONSTEXPR_17 // Presence of C++20 language features: @@ -762,6 +790,12 @@ #define gsl_HAVE_CONSTEXPR_20_() gsl_HAVE_CONSTEXPR_20 +// Presence of C++23 language features: + +#define gsl_HAVE_CONSTEXPR_23 gsl_CPP23_OR_GREATER + +#define gsl_HAVE_CONSTEXPR_23_() gsl_HAVE_CONSTEXPR_23 + // Presence of C++ library features: #if gsl_BETWEEN(gsl_COMPILER_ARMCC_VERSION, 1, 600) @@ -771,12 +805,14 @@ #define gsl_STDLIB_CPP14_OR_GREATER 0 #define gsl_STDLIB_CPP17_OR_GREATER 0 #define gsl_STDLIB_CPP20_OR_GREATER 0 +#define gsl_STDLIB_CPP23_OR_GREATER 0 #else #define gsl_STDLIB_CPP98_OR_GREATER gsl_CPP98_OR_GREATER #define gsl_STDLIB_CPP11_OR_GREATER gsl_CPP11_OR_GREATER #define gsl_STDLIB_CPP14_OR_GREATER gsl_CPP14_OR_GREATER #define gsl_STDLIB_CPP17_OR_GREATER gsl_CPP17_OR_GREATER #define gsl_STDLIB_CPP20_OR_GREATER gsl_CPP20_OR_GREATER +#define gsl_STDLIB_CPP23_OR_GREATER gsl_CPP23_OR_GREATER #endif #define gsl_STDLIB_CPP11_100 (gsl_STDLIB_CPP11_OR_GREATER || gsl_COMPILER_MSVC_VER >= 1600) @@ -884,6 +920,12 @@ #define gsl_constexpr20 /*constexpr*/ #endif +#if gsl_HAVE(CONSTEXPR_23) +#define gsl_constexpr23 constexpr +#else +#define gsl_constexpr23 /*constexpr*/ +#endif + #if gsl_HAVE(EXPLICIT) #define gsl_explicit explicit #else @@ -941,6 +983,19 @@ #define gsl_NORETURN #endif +#if gsl_HAVE(MAYBE_UNUSED) +#define gsl_MAYBE_UNUSED [[maybe_unused]] +#if gsl_COMPILER_GNUC_VERSION +// GCC currently ignores the [[maybe_unused]] attribute on data members and warns accordingly (cf. https://stackoverflow.com/a/65633590). +#define gsl_MAYBE_UNUSED_MEMBER +#else // ! gsl_COMPILER_GNUC_VERSION +#define gsl_MAYBE_UNUSED_MEMBER [[maybe_unused]] +#endif // gsl_COMPILER_GNUC_VERSION +#else +#define gsl_MAYBE_UNUSED +#define gsl_MAYBE_UNUSED_MEMBER +#endif + #if gsl_HAVE(DEPRECATED) && !defined(gsl_TESTING_) #define gsl_DEPRECATED [[deprecated]] #define gsl_DEPRECATED_MSG(msg) [[deprecated(msg)]] @@ -963,6 +1018,12 @@ #define gsl_STATIC_ASSERT_(cond, msg) ((void)sizeof(char[1 - 2 * !!(cond)])) #endif +#if _MSC_VER >= 1900 // Visual Studio 2015 and newer, or Clang emulating a corresponding MSVC +#define gsl_EMPTY_BASES_ __declspec(empty_bases) +#else +#define gsl_EMPTY_BASES_ +#endif + #if gsl_HAVE(TYPE_TRAITS) #define gsl_DEFINE_ENUM_BITMASK_OPERATORS_(ENUM) \ @@ -1194,14 +1255,12 @@ using ::__cxxabiv1::__cxa_get_globals; #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) -// MSVC warning suppression macros: +// Warning suppression macros: #if gsl_COMPILER_MSVC_VERSION >= 140 && !gsl_COMPILER_NVCC_VERSION #define gsl_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]] -#define gsl_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress \ - : code)) -#define gsl_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable \ - : codes)) +#define gsl_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress : code)) +#define gsl_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable : codes)) #define gsl_RESTORE_MSVC_WARNINGS() __pragma(warning(pop)) #else // TODO: define for Clang @@ -1211,25 +1270,45 @@ using ::__cxxabiv1::__cxa_get_globals; #define gsl_RESTORE_MSVC_WARNINGS() #endif -// Suppress the following MSVC GSL warnings: -// - C26432: gsl::c.21 : if you define or delete any default operation in the type '...', define or delete them all -// - C26410: gsl::r.32 : the parameter 'ptr' is a reference to const unique pointer, use const T* or const T& instead -// - C26415: gsl::r.30 : smart pointer parameter 'ptr' is used only to access contained pointer. Use T* or T& instead -// - C26418: gsl::r.36 : shared pointer parameter 'ptr' is not copied or moved. Use T* or T& instead -// - C26472: gsl::t.1 : don't use a static_cast for arithmetic conversions; -// use brace initialization, gsl::narrow_cast or gsl::narrow -// - C26439: gsl::f.6 : special function 'function' can be declared 'noexcept' -// - C26440: gsl::f.6 : function 'function' can be declared 'noexcept' -// - C26455: gsl::f.6 : default constructor may not throw. Declare it 'noexcept' -// - C26473: gsl::t.1 : don't cast between pointer types where the source type and the target type are the same -// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead -// - C26482: gsl::b.2 : only index into arrays using constant expressions -// - C26446: gdl::b.4 : prefer to use gsl::at() instead of unchecked subscript operator -// - C26490: gsl::t.1 : don't use reinterpret_cast -// - C26487: gsl::l.4 : don't return a pointer '('s result)' that may be invalid -// - C26457: es.48 : (void) should not be used to ignore return values, use 'std::ignore =' instead +// Warning suppressions: -gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 26481 26482 26446 26490 26487 26457) +#if gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" // because of `fail_fast` and `narrowing_error` +#endif // gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION + +#if gsl_COMPILER_GNUC_VERSION +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuseless-cast" // we use `static_cast<>()` in several places where it is possibly redundant depending on the configuration of the library +#endif // gsl_COMPILER_GNUC_VERSION + +// Suppress the following MSVC GSL warnings: +// - C26432: gsl::c.21 : if you define or delete any default operation in the type '...', define or delete them all +// - C26410: gsl::r.32 : the parameter 'ptr' is a reference to const unique pointer, use const T* or const T& instead +// - C26415: gsl::r.30 : smart pointer parameter 'ptr' is used only to access contained pointer. Use T* or T& instead +// - C26418: gsl::r.36 : shared pointer parameter 'ptr' is not copied or moved. Use T* or T& instead +// - C26472: gsl::t.1 : don't use a static_cast for arithmetic conversions; +// use brace initialization, gsl::narrow_cast or gsl::narrow +// - C26439: gsl::f.6 : special function 'function' can be declared 'noexcept' +// - C26440: gsl::f.6 : function 'function' can be declared 'noexcept' +// - C26455: gsl::f.6 : default constructor may not throw. Declare it 'noexcept' +// - C26473: gsl::t.1 : don't cast between pointer types where the source type and the target type are the same +// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead +// - C26482: gsl::b.2 : only index into arrays using constant expressions +// - C26446: gdl::b.4 : prefer to use gsl::at() instead of unchecked subscript operator +// - C26490: gsl::t.1 : don't use reinterpret_cast +// - C26487: gsl::l.4 : don't return a pointer '('s result)' that may be invalid +// - C26434: gsl::c.128 : function 'symbol_1' hides a non-virtual function 'symbol_2' (false positive for compiler-generated functions such as constructors) +// - C26456: gsl::c.128 : operator 'symbol_1' hides a non-virtual operator 'symbol_2' (false positive for compiler-generated operators) +// - C26457: es.48 : (void) should not be used to ignore return values, use 'std::ignore =' instead + +gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 26481 26482 26446 26490 26487 26434 26456 26457) +#if gsl_BETWEEN(gsl_COMPILER_MSVC_VERSION, 110, 140) // VS 2012 and 2013 +#pragma warning(disable : 4127) // conditional expression is constant +#endif // gsl_BETWEEN( gsl_COMPILER_MSVC_VERSION, 110, 140 ) +#if gsl_COMPILER_MSVC_VERSION == 140 // VS 2015 +#pragma warning(disable : 4577) // 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc +#endif // gsl_COMPILER_MSVC_VERSION == 140 namespace gsl { @@ -1242,6 +1321,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + // We implement `equal()` and `lexicographical_compare()` here to avoid having to pull in the header. template bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) @@ -1257,7 +1337,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) { // Implementation borrowed from https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare. - for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) + for (; first1 != last1 && first2 != last2; ++first1, static_cast(++first2)) { if (*first1 < *first2) return true; if (*first2 < *first1) return false; @@ -1271,6 +1351,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace std11 { + #if gsl_HAVE(ADD_CONST) using std::add_const; @@ -1411,6 +1492,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace std14 { + #if gsl_HAVE(UNIQUE_PTR) #if gsl_HAVE(MAKE_UNIQUE) @@ -1435,6 +1517,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + #if gsl_HAVE(VARIADIC_TEMPLATE) template @@ -1469,6 +1552,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace std17 { + template struct bool_constant : std11::integral_constant { @@ -1541,7 +1625,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD gsl_api inline gsl_constexpr auto - data(T (&arr)[N]) gsl_noexcept -> T * + data(T (&arr)[N]) gsl_noexcept -> T * { return &arr[0]; } @@ -1575,6 +1659,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace std20 { + #if gsl_CPP11_100 struct identity @@ -1660,8 +1745,16 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 } // namespace std20 + // C++23 emulation: + + namespace std23 + { + + } // namespace std23 + namespace detail { + /// for gsl_ENABLE_IF_() /*enum*/ class enabler @@ -1849,7 +1942,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 // GSL.assert: assertions // -#if gsl_HAVE(TYPE_TRAITS) +#if gsl_HAVE(TYPE_TRAITS) && gsl_CONFIG(VALIDATES_UNENFORCED_CONTRACT_EXPRESSIONS) #define gsl_ELIDE_(x) static_assert(::std::is_constructible::value, "argument of contract check must be convertible to bool") #else #define gsl_ELIDE_(x) @@ -1868,7 +1961,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if gsl_DEVICE_CODE #if defined(gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME) #if gsl_COMPILER_NVCC_VERSION >= 113 -#define gsl_ASSUME_(x) ((x) ? static_cast(0) : __builtin_unreachable()) +#define gsl_ASSUME_(x) (__builtin_assume(!!(x))) #define gsl_ASSUME_UNREACHABLE_() __builtin_unreachable() #else // unknown device compiler #error gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ASSUME: gsl-lite does not know how to generate UB optimization hints in device code for this compiler; use gsl_CONFIG_DEVICE_UNENFORCED_CONTRACTS_ELIDE instead @@ -2051,6 +2144,8 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + + #if gsl_HAVE(EXCEPTIONS) gsl_NORETURN inline void fail_fast_throw(char const *message) { @@ -2117,6 +2212,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace std11 { + #if gsl_HAVE(UNCAUGHT_EXCEPTIONS) inline unsigned char uncaught_exceptions() gsl_noexcept @@ -2155,55 +2251,148 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 { public: explicit final_action(F action) gsl_noexcept - : action_(std::move(action)), + : action_(std::move(action)) +#if gsl_CONFIG_DEFAULTS_VERSION < 1 || !gsl_CPP17_OR_GREATER + , invoke_(true) +#endif { } + // We only provide the move constructor for legacy defaults, or if we cannot rely on C++17 guaranteed copy elision. +#if gsl_CONFIG_DEFAULTS_VERSION < 1 || !gsl_CPP17_OR_GREATER final_action(final_action &&other) gsl_noexcept : action_(std::move(other.action_)), invoke_(other.invoke_) { other.invoke_ = false; } +#endif // gsl_CONFIG_DEFAULTS_VERSION < 1 || ! gsl_CPP17_OR_GREATER - gsl_SUPPRESS_MSGSL_WARNING(f .6) virtual ~final_action() gsl_noexcept + gsl_SUPPRESS_MSGSL_WARNING(f.6) +#if gsl_CONFIG_DEFAULTS_VERSION < 1 // we avoid the unnecessary virtual calls if modern defaults are selected + virtual +#endif + ~final_action() gsl_noexcept { +#if gsl_CONFIG_DEFAULTS_VERSION < 1 || !gsl_CPP17_OR_GREATER if (invoke_) - action_(); +#endif + { + action_(); + } } gsl_is_delete_access : final_action(final_action const &) gsl_is_delete; final_action &operator=(final_action const &) gsl_is_delete; final_action &operator=(final_action &&) gsl_is_delete; +#if gsl_CONFIG_DEFAULTS_VERSION < 1 protected: void dismiss() gsl_noexcept { invoke_ = false; } +#endif // gsl_CONFIG_DEFAULTS_VERSION < 1 private: F action_; - bool invoke_; + gsl_MAYBE_UNUSED_MEMBER bool invoke_; // member is defined unconditionally so as not to have ABI depend on C++ language support }; template - gsl_NODISCARD inline final_action - finally(F const &action) gsl_noexcept + gsl_NODISCARD inline final_action::type> + finally(F && action) gsl_noexcept { - return final_action(action); - } - - template - gsl_NODISCARD inline final_action - finally(F && action) gsl_noexcept - { - return final_action(std::forward(action)); + return final_action::type>(std::forward(action)); } #if gsl_FEATURE(EXPERIMENTAL_RETURN_GUARD) +#if gsl_CONFIG_DEFAULTS_VERSION >= 1 + template + class final_action_return + { + public: + explicit final_action_return(F action) gsl_noexcept + : action_(std::move(action)), + exception_count_(std11::uncaught_exceptions()) + { + } + + // We only provide the move constructor if we cannot rely on C++17 guaranteed copy elision. +#if !gsl_CPP17_OR_GREATER + final_action_return(final_action_return &&other) gsl_noexcept + : action_(std::move(other.action_)), + exception_count_(other.exception_count_) + { + other.exception_count_ = 0xFF; // abuse member as special "no-invoke" marker + } +#endif // ! gsl_CPP17_OR_GREATER + + gsl_SUPPRESS_MSGSL_WARNING(f.6) ~final_action_return() gsl_noexcept + { +#if !gsl_CPP17_OR_GREATER + if (exception_count_ != 0xFF) // abuse member as special "no-invoke" marker +#endif + { + if (std11::uncaught_exceptions() == exception_count_) + { + action_(); + } + } + } + + gsl_is_delete_access : final_action_return(final_action_return const &) gsl_is_delete; + final_action_return &operator=(final_action_return const &) gsl_is_delete; + final_action_return &operator=(final_action_return &&) gsl_is_delete; + + private: + F action_; + unsigned char exception_count_; + }; + template + class final_action_error + { + public: + explicit final_action_error(F action) gsl_noexcept + : action_(std::move(action)), + exception_count_(std11::uncaught_exceptions()) + { + } + + // We only provide the move constructor if we cannot rely on C++17 guaranteed copy elision. +#if !gsl_CPP17_OR_GREATER + final_action_error(final_action_error &&other) gsl_noexcept + : action_(std::move(other.action_)), + exception_count_(other.exception_count_) + { + other.exception_count_ = 0xFF; // abuse member as special "no-invoke" marker + } +#endif // ! gsl_CPP17_OR_GREATER + + gsl_SUPPRESS_MSGSL_WARNING(f.6) ~final_action_error() gsl_noexcept + { +#if !gsl_CPP17_OR_GREATER + if (exception_count_ != 0xFF) // abuse member as special "no-invoke" marker +#endif + { + if (std11::uncaught_exceptions() != exception_count_) + { + action_(); + } + } + } + + gsl_is_delete_access : final_action_error(final_action_error const &) gsl_is_delete; + final_action_error &operator=(final_action_error const &) gsl_is_delete; + final_action_error &operator=(final_action_error &&) gsl_is_delete; + + private: + F action_; + unsigned char exception_count_; + }; +#else // gsl_CONFIG_DEFAULTS_VERSION < 1 template class final_action_return : public final_action { @@ -2233,20 +2422,6 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 unsigned char exception_count; }; - template - gsl_NODISCARD inline final_action_return - on_return(F const &action) gsl_noexcept - { - return final_action_return(action); - } - - template - gsl_NODISCARD inline final_action_return - on_return(F && action) gsl_noexcept - { - return final_action_return(std::forward(action)); - } - template class final_action_error : public final_action { @@ -2275,19 +2450,20 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 private: unsigned char exception_count; }; +#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1 template - gsl_NODISCARD inline final_action_error - on_error(F const &action) gsl_noexcept + gsl_NODISCARD inline final_action_return::type> + on_return(F && action) gsl_noexcept { - return final_action_error(action); + return final_action_return::type>(std::forward(action)); } template - gsl_NODISCARD inline final_action_error - on_error(F && action) gsl_noexcept + gsl_NODISCARD inline final_action_error::type> + on_error(F && action) gsl_noexcept { - return final_action_error(std::forward(action)); + return final_action_error::type>(std::forward(action)); } #endif // gsl_FEATURE( EXPERIMENTAL_RETURN_GUARD ) @@ -2296,7 +2472,10 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #else // ! gsl_STDLIB_CPP11_110 - class final_action +#if gsl_DEPRECATE_TO_LEVEL(8) + gsl_DEPRECATED_MSG("final_action for pre-C++11 compilers is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 8 ) + class final_action { public: typedef void (*Action)(); @@ -2333,14 +2512,21 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 }; template - inline final_action finally(F const &f) +#if gsl_DEPRECATE_TO_LEVEL(8) + gsl_DEPRECATED_MSG("finally() for pre-C++11 compilers is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 8 ) + inline final_action + finally(F const &f) { - return final_action((f)); + return final_action(f); } #if gsl_FEATURE(EXPERIMENTAL_RETURN_GUARD) - class final_action_return : public final_action +#if gsl_DEPRECATE_TO_LEVEL(8) + gsl_DEPRECATED_MSG("final_action_return for pre-C++11 compilers is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 8 ) + class final_action_return : public final_action { public: explicit final_action_return(Action action) @@ -2362,12 +2548,19 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 }; template - inline final_action_return on_return(F const &action) +#if gsl_DEPRECATE_TO_LEVEL(8) + gsl_DEPRECATED_MSG("on_return() for pre-C++11 compilers is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 8 ) + inline final_action_return + on_return(F const &action) { return final_action_return(action); } - class final_action_error : public final_action +#if gsl_DEPRECATE_TO_LEVEL(8) + gsl_DEPRECATED_MSG("final_action_error for pre-C++11 compilers is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 8 ) + class final_action_error : public final_action { public: explicit final_action_error(Action action) @@ -2389,7 +2582,11 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 }; template - inline final_action_error on_error(F const &action) +#if gsl_DEPRECATE_TO_LEVEL(8) + gsl_DEPRECATED_MSG("on_error() for pre-C++11 compilers is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 8 ) + inline final_action_error + on_error(F const &action) { return final_action_error(action); } @@ -2402,7 +2599,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD gsl_api inline gsl_constexpr T - narrow_cast(U && u) gsl_noexcept + narrow_cast(U && u) gsl_noexcept { return static_cast(std::forward(u)); } @@ -2433,6 +2630,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + template struct is_same_signedness : public std::integral_constant::value == std::is_signed::value> { @@ -2467,14 +2665,14 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #endif template - gsl_NODISCARD -#if !gsl_CONFIG(NARROW_THROWS_ON_TRUNCATION) && !defined(gsl_CONFIG_CONTRACT_VIOLATION_THROWS) + gsl_NODISCARD gsl_constexpr14 +#if !gsl_CONFIG(NARROW_THROWS_ON_TRUNCATION) gsl_api -#endif +#endif // ! gsl_CONFIG( NARROW_THROWS_ON_TRUNCATION ) inline T narrow(U u) { -#if gsl_CONFIG(NARROW_THROWS_ON_TRUNCATION) && !gsl_HAVE(EXCEPTIONS) +#if !gsl_HAVE(EXCEPTIONS) && gsl_CONFIG(NARROW_THROWS_ON_TRUNCATION) gsl_STATIC_ASSERT_(detail::dependent_false::value, "According to the GSL specification, narrow<>() throws an exception of type narrowing_error on truncation. Therefore " "it cannot be used if exceptions are disabled. Consider using narrow_failfast<>() instead which raises a precondition " @@ -2483,20 +2681,11 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 T t = static_cast(u); - if (static_cast(t) != u) - { -#if gsl_HAVE(EXCEPTIONS) && (gsl_CONFIG(NARROW_THROWS_ON_TRUNCATION) || defined(gsl_CONFIG_CONTRACT_VIOLATION_THROWS)) - throw narrowing_error(); -#else - std::terminate(); -#endif - } - #if gsl_HAVE(TYPE_TRAITS) #if gsl_COMPILER_NVCC_VERSION || gsl_COMPILER_NVHPC_VERSION - if (!detail::have_same_sign(t, u, detail::is_same_signedness())) + if (static_cast(t) != u || !detail::have_same_sign(t, u, detail::is_same_signedness())) #else - gsl_SUPPRESS_MSVC_WARNING(4127, "conditional expression is constant") if (!detail::is_same_signedness::value && (t < T()) != (u < U())) + gsl_SUPPRESS_MSVC_WARNING(4127, "conditional expression is constant") if (static_cast(t) != u || (!detail::is_same_signedness::value && (t < T()) != (u < U()))) #endif #else // Don't assume T() works: @@ -2505,7 +2694,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 // Suppress: pointless comparison of unsigned integer with zero. #pragma diag_suppress 186 #endif - if ((t < 0) != (u < 0)) + if (static_cast(t) != u || (t < 0) != (u < 0)) #if gsl_COMPILER_NVHPC_VERSION // Restore: pointless comparison of unsigned integer with zero. #pragma diag_default 186 @@ -2513,30 +2702,32 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #endif { -#if gsl_HAVE(EXCEPTIONS) && (gsl_CONFIG(NARROW_THROWS_ON_TRUNCATION) || defined(gsl_CONFIG_CONTRACT_VIOLATION_THROWS)) +#if gsl_CONFIG(NARROW_THROWS_ON_TRUNCATION) throw narrowing_error(); -#else +#else // ! gsl_CONFIG( NARROW_THROWS_ON_TRUNCATION ) +#if gsl_DEVICE_CODE + gsl_TRAP_(); +#else // host code std::terminate(); #endif +#endif // gsl_CONFIG( NARROW_THROWS_ON_TRUNCATION ) } return t; } template - gsl_NODISCARD gsl_api inline T + gsl_NODISCARD gsl_api gsl_constexpr14 inline T narrow_failfast(U u) { T t = static_cast(u); - gsl_Expects(static_cast(t) == u); - #if gsl_HAVE(TYPE_TRAITS) #if gsl_COMPILER_NVCC_VERSION || gsl_COMPILER_NVHPC_VERSION - gsl_Expects(::gsl::detail::have_same_sign(t, u, ::gsl::detail::is_same_signedness())); + gsl_Assert(static_cast(t) == u && ::gsl::detail::have_same_sign(t, u, ::gsl::detail::is_same_signedness())); #else gsl_SUPPRESS_MSVC_WARNING(4127, "conditional expression is constant") - gsl_Expects((::gsl::detail::is_same_signedness::value || (t < T()) == (u < U()))); + gsl_Assert(static_cast(t) == u && (::gsl::detail::is_same_signedness::value || (t < T()) == (u < U()))); #endif #else // Don't assume T() works: @@ -2545,7 +2736,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 // Suppress: pointless comparison of unsigned integer with zero. #pragma diag_suppress 186 #endif - gsl_Expects((t < 0) == (u < 0)); + gsl_Assert(static_cast(t) == u && (t < 0) == (u < 0)); #if gsl_COMPILER_NVHPC_VERSION // Restore: pointless comparison of unsigned integer with zero. #pragma diag_default 186 @@ -2615,12 +2806,13 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + // helper class to figure out the pointed-to type of a pointer #if gsl_STDLIB_CPP11_OR_GREATER template struct element_type_helper { - // For types without a member element_type (this will handle raw pointers) + // For types without a member element_type (this could handle typed raw pointers but not `void*`) typedef typename std::remove_reference())>::type type; }; @@ -2637,13 +2829,13 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 { typedef typename T::element_type type; }; +#endif // gsl_STDLIB_CPP11_OR_GREATER template struct element_type_helper { typedef T type; }; -#endif // gsl_STDLIB_CPP11_OR_GREATER template struct is_not_null_or_bool_oracle : std11::false_type @@ -2659,7 +2851,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 }; - template + template struct not_null_data; #if gsl_HAVE(MOVE_FORWARD) template @@ -2672,12 +2864,16 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 { } - gsl_api gsl_constexpr14 not_null_data(not_null_data &&other) gsl_noexcept + gsl_api gsl_constexpr14 not_null_data(not_null_data &&other) + gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion : ptr_(std::move(other.ptr_)) { + gsl_Assert(ptr_ != gsl_nullptr); } - gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data &&other) gsl_noexcept + gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data &&other) + gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion { + gsl_Assert(other.ptr_ != gsl_nullptr || &other == this); ptr_ = std::move(other.ptr_); return *this; } @@ -2685,8 +2881,6 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 gsl_is_delete_access : not_null_data(not_null_data const &) gsl_is_delete; not_null_data &operator=(not_null_data const &) gsl_is_delete; }; -#if gsl_CONFIG_DEFAULTS_VERSION >= 1 -#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1 #endif // gsl_HAVE( MOVE_FORWARD ) template struct not_null_data @@ -2704,12 +2898,16 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 { } - gsl_api gsl_constexpr14 not_null_data(not_null_data &&other) gsl_noexcept + gsl_api gsl_constexpr14 not_null_data(not_null_data &&other) + gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion : ptr_(std::move(other.ptr_)) { + gsl_Assert(ptr_ != gsl_nullptr); } - gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data &&other) gsl_noexcept + gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data &&other) + gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion { + gsl_Assert(other.ptr_ != gsl_nullptr || &other == this); ptr_ = std::move(other.ptr_); return *this; } @@ -2718,16 +2916,15 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 gsl_api gsl_constexpr14 not_null_data(not_null_data const &other) : ptr_(other.ptr_) { - gsl_Expects(ptr_ != gsl_nullptr); + gsl_Assert(ptr_ != gsl_nullptr); } gsl_api gsl_constexpr14 not_null_data &operator=(not_null_data const &other) { - gsl_Expects(other.ptr_ != gsl_nullptr); + gsl_Assert(other.ptr_ != gsl_nullptr); ptr_ = other.ptr_; return *this; } }; -#if gsl_CONFIG_DEFAULTS_VERSION >= 1 template struct not_null_data { @@ -2738,7 +2935,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 { } }; -#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1 + template struct is_copyable #if gsl_HAVE(TYPE_TRAITS) @@ -2759,26 +2956,59 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template struct not_null_accessor; + template + struct not_null_deref + { + typedef typename element_type_helper::type element_type; + + gsl_NODISCARD gsl_api gsl_constexpr14 element_type & + operator*() const + { + return *not_null_accessor::get_checked(static_cast(*this)); + } + }; + template + struct not_null_deref + { + }; + + template + struct is_void : std11::false_type + { + }; + template <> + struct is_void : std11::true_type + { + }; + + template + struct is_void_ptr : is_void::type> + { + }; + } // namespace detail template - class not_null + class + gsl_EMPTY_BASES_ // not strictly needed, but will become necessary if we add more base classes + not_null : public detail::not_null_deref, T, detail::is_void_ptr::value> { private: detail::not_null_data::value> data_; // need to access `not_null::data_` - template - friend class not_null; - template friend struct detail::not_null_accessor; + typedef detail::not_null_accessor accessor; + public: typedef typename detail::element_type_helper::type element_type; #if gsl_HAVE(TYPE_TRAITS) - static_assert(std::is_assignable::type>::type &, std::nullptr_t>::value, "T cannot be assigned nullptr."); + static_assert(!std::is_reference::value, "T may not be a reference type"); + static_assert(!std::is_const::value && !std::is_volatile::value, "T may not be cv-qualified"); + static_assert(std::is_assignable::value, "T cannot be assigned nullptr"); #endif #if gsl_CONFIG(NOT_NULL_EXPLICIT_CTOR) @@ -2848,7 +3078,6 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #endif // gsl_HAVE( MOVE_FORWARD ) #endif // gsl_CONFIG( NOT_NULL_EXPLICIT_CTOR ) - public: #if gsl_HAVE(MOVE_FORWARD) // In Clang 3.x, `is_constructible>, unique_ptr>` tries to instantiate the copy constructor of `unique_ptr<>`, triggering an error. // Note that Apple Clang's `__clang_major__` etc. are different from regular Clang. @@ -2858,9 +3087,8 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 , typename std::enable_if<(std::is_constructible::value && !std::is_convertible::value), int>::type = 0> gsl_api gsl_constexpr14 explicit not_null(not_null other) - : data_(T(std::move(other.data_.ptr_))) + : data_(T(detail::not_null_accessor::get_checked(std::move(other)))) { - gsl_Expects(data_.ptr_ != gsl_nullptr); } template ::value), int>::type = 0> gsl_api gsl_constexpr14 not_null(not_null other) - : data_(T(std::move(other.data_.ptr_))) + : data_(T(detail::not_null_accessor::get_checked(std::move(other)))) { - gsl_Expects(data_.ptr_ != gsl_nullptr); } #else // a.k.a. ! ( gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) // If type_traits are not available, then we can't distinguish `is_convertible<>` and `is_constructible<>`, so we unconditionally permit implicit construction. template gsl_api gsl_constexpr14 not_null(not_null other) - : data_(T(std::move(other.data_.ptr_))) + : data_(T(detail::not_null_accessor::get_checked(std::move(other)))) { gsl_Expects(data_.ptr_ != gsl_nullptr); } template gsl_api gsl_constexpr14 not_null &operator=(not_null other) { - gsl_Expects(other.data_.ptr_ != gsl_nullptr); - data_.ptr_ = std::move(other.data_.ptr_); + data_.ptr_ = detail::not_null_accessor::get_checked(std::move(other)); return *this; } #endif // gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) #else // a.k.a. ! gsl_HAVE( MOVE_FORWARD ) template gsl_api gsl_constexpr14 not_null(not_null const &other) - : data_(T(other.data_.ptr_)) + : data_(T(detail::not_null_accessor::get_checked(other))) { - gsl_Expects(data_.ptr_ != gsl_nullptr); } template gsl_api gsl_constexpr14 not_null &operator=(not_null const &other) { - gsl_Expects(other.data_.ptr_ != gsl_nullptr); - data_.ptr_ = other.data_.ptr_; + data_.ptr_ = detail::not_null_accessor::get_checked(other); return *this; } #endif // gsl_HAVE( MOVE_FORWARD ) @@ -2908,23 +3132,20 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 gsl_NODISCARD gsl_api gsl_constexpr14 element_type * get() const { - gsl_Assert(data_.ptr_ != gsl_nullptr); - return data_.ptr_.get(); + return accessor::get_checked(*this).get(); } #else #if gsl_CONFIG(NOT_NULL_GET_BY_CONST_REF) gsl_NODISCARD gsl_api gsl_constexpr14 T const & get() const { - gsl_Assert(data_.ptr_ != gsl_nullptr); - return data_.ptr_; + return accessor::get_checked(*this); } #else gsl_NODISCARD gsl_api gsl_constexpr14 T get() const { - gsl_Assert(data_.ptr_ != gsl_nullptr); - return data_.ptr_; + return accessor::get_checked(*this); } #endif #endif @@ -2971,8 +3192,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 & #endif { - gsl_Assert(data_.ptr_ != gsl_nullptr); - return U(data_.ptr_); + return U(accessor::get_checked(*this)); } #if gsl_HAVE(FUNCTION_REF_QUALIFIER) template () const { - gsl_Assert(data_.ptr_ != gsl_nullptr); - return data_.ptr_; - } - - gsl_NODISCARD gsl_api gsl_constexpr14 element_type & - operator*() const - { - gsl_Assert(data_.ptr_ != gsl_nullptr); - return *data_.ptr_; + return accessor::get_checked(*this); } #if gsl_HAVE(MOVE_FORWARD) // Visual C++ 2013 doesn't generate default move constructors, so we declare them explicitly. gsl_api gsl_constexpr14 not_null(not_null &&other) - gsl_noexcept_not_testing // we want to be nothrow-movable despite the precondition check + gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion : data_(std::move(other.data_)) { - gsl_Expects(data_.ptr_ != gsl_nullptr); } gsl_api gsl_constexpr14 not_null &operator=(not_null &&other) - gsl_noexcept_not_testing // we want to be nothrow-movable despite the precondition check + gsl_noexcept_not_testing // we want to be nothrow-movable despite the assertion { - gsl_Expects(other.data_.ptr_ != gsl_nullptr || &other == this); data_ = std::move(other.data_); return *this; } @@ -3062,7 +3268,8 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 gsl_api gsl_constexpr20 friend void swap(not_null &lhs, not_null &rhs) gsl_noexcept_not_testing // we want to be nothrow-swappable despite the precondition check { - gsl_Expects(lhs.data_.ptr_ != gsl_nullptr && rhs.data_.ptr_ != gsl_nullptr); + accessor::check(lhs); + accessor::check(rhs); using std::swap; swap(lhs.data_.ptr_, rhs.data_.ptr_); } @@ -3090,174 +3297,6 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 not_null &operator-=(std::ptrdiff_t) gsl_is_delete; void operator[](std::ptrdiff_t) const gsl_is_delete; }; -#if gsl_CONFIG_DEFAULTS_VERSION >= 1 - template - class not_null - { - private: - detail::not_null_data data_; - - // need to access `not_null::data_` - template - friend class not_null; - - template - friend struct detail::not_null_accessor; - - public: - typedef T element_type; - - gsl_api gsl_constexpr14 -#if gsl_CONFIG(NOT_NULL_EXPLICIT_CTOR) - explicit -#endif // gsl_CONFIG( NOT_NULL_EXPLICIT_CTOR ) - not_null(T *other) - : data_(other) - { - gsl_Expects(data_.ptr_ != gsl_nullptr); - } - -#if gsl_HAVE(MOVE_FORWARD) - // In Clang 3.x, `is_constructible>, unique_ptr>` tries to instantiate the copy constructor of `unique_ptr<>`, triggering an error. - // Note that Apple Clang's `__clang_major__` etc. are different from regular Clang. -#if gsl_HAVE(TYPE_TRAITS) && gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) && !gsl_BETWEEN(gsl_COMPILER_CLANG_VERSION, 1, 400) && !gsl_BETWEEN(gsl_COMPILER_APPLECLANG_VERSION, 1, 1001) - template ::value && !std::is_convertible::value), int>::type = 0> - gsl_api gsl_constexpr14 explicit not_null(not_null other) - : data_(static_cast(std::move(other.data_.ptr_))) - { - gsl_Expects(data_.ptr_ != gsl_nullptr); - } - - template ::value), int>::type = 0> - gsl_api gsl_constexpr14 not_null(not_null other) - : data_(std::move(other.data_.ptr_)) - { - gsl_Expects(data_.ptr_ != gsl_nullptr); - } -#else // a.k.a. ! ( gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) - // If type_traits are not available, then we can't distinguish `is_convertible<>` and `is_constructible<>`, so we unconditionally permit implicit construction. - template - gsl_api gsl_constexpr14 not_null(not_null other) - : data_(std::move(other.data_.ptr_)) - { - gsl_Expects(data_.ptr_ != gsl_nullptr); - } - template - gsl_api gsl_constexpr14 not_null &operator=(not_null other) - { - gsl_Expects(other.data_.ptr_ != gsl_nullptr); - data_.ptr_ = std::move(other.data_.ptr_); - return *this; - } -#endif // gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && ! gsl_BETWEEN( gsl_COMPILER_CLANG_VERSION, 1, 400 ) && ! gsl_BETWEEN( gsl_COMPILER_APPLECLANG_VERSION, 1, 1001 ) -#else // a.k.a. ! gsl_HAVE( MOVE_FORWARD ) - template - gsl_api gsl_constexpr14 not_null(not_null const &other) - : data_(other.data_.ptr_) - { - gsl_Expects(data_.ptr_ != gsl_nullptr); - } - template - gsl_api gsl_constexpr14 not_null &operator=(not_null const &other) - { - gsl_Expects(other.data_.ptr_ != gsl_nullptr); - data_.ptr_ = other.data_.ptr_; - return *this; - } -#endif // gsl_HAVE( MOVE_FORWARD ) - -#if !gsl_CONFIG(TRANSPARENT_NOT_NULL) - gsl_NODISCARD gsl_api gsl_constexpr14 T * - get() const - { - return data_.ptr_; - } -#endif - -#if gsl_HAVE(TYPE_TRAITS) && gsl_HAVE(DEFAULT_FUNCTION_TEMPLATE_ARG) && gsl_HAVE(EXPLICIT) - // explicit conversion operator - template ::value && !std::is_convertible::value && !detail::is_not_null_or_bool_oracle::value), int>::type = 0> - gsl_NODISCARD gsl_api gsl_constexpr14 explicit - operator U() const - { - return U(data_.ptr_); - } - - // implicit conversion operator - template ::value && std::is_convertible::value && !detail::is_not_null_or_bool_oracle::value), int>::type = 0> - gsl_NODISCARD gsl_api gsl_constexpr14 - operator U() const - { - return data_.ptr_; - } -#else // a.k.a. #if !( gsl_HAVE( MOVE_FORWARD ) && gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && gsl_HAVE( EXPLICIT ) ) - template - gsl_NODISCARD gsl_api gsl_constexpr14 - operator U() const - { - return data_.ptr_; - } -#endif // gsl_HAVE( MOVE_FORWARD ) && gsl_HAVE( TYPE_TRAITS ) && gsl_HAVE( DEFAULT_FUNCTION_TEMPLATE_ARG ) && gsl_HAVE( EXPLICIT ) - - gsl_NODISCARD gsl_api gsl_constexpr14 T * - operator->() const - { - return data_.ptr_; - } - - gsl_NODISCARD gsl_api gsl_constexpr14 element_type & - operator*() const - { - return *data_.ptr_; - } - -#if gsl_HAVE(IS_DEFAULT) - gsl_constexpr14 not_null(not_null const &) = default; - gsl_constexpr14 not_null &operator=(not_null const &) = default; -#endif - - gsl_api gsl_constexpr20 friend void swap(not_null &lhs, not_null &rhs) gsl_noexcept - { - using std::swap; - swap(lhs.data_.ptr_, rhs.data_.ptr_); - } - - gsl_is_delete_access : not_null() gsl_is_delete; - // prevent compilation when initialized with a nullptr or literal 0: -#if gsl_HAVE(NULLPTR) - not_null(std::nullptr_t) gsl_is_delete; - not_null &operator=(std::nullptr_t) gsl_is_delete; -#else - not_null(int) gsl_is_delete; - not_null &operator=(int) gsl_is_delete; -#endif - - // unwanted operators...pointers only point to single objects! - not_null &operator++() gsl_is_delete; - not_null &operator--() gsl_is_delete; - not_null operator++(int) gsl_is_delete; - not_null operator--(int) gsl_is_delete; - not_null &operator+(size_t) gsl_is_delete; - not_null &operator+=(size_t) gsl_is_delete; - not_null &operator-(size_t) gsl_is_delete; - not_null &operator-=(size_t) gsl_is_delete; - not_null &operator+=(std::ptrdiff_t) gsl_is_delete; - not_null &operator-=(std::ptrdiff_t) gsl_is_delete; - void operator[](std::ptrdiff_t) const gsl_is_delete; - }; -#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1 #if gsl_HAVE(DEDUCTION_GUIDES) template not_null(U) -> not_null; @@ -3298,6 +3337,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + template struct as_nullable_helper { @@ -3316,15 +3356,53 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 { return std::move(p.data_.ptr_); } + static gsl_api T get_checked(not_null &&p) + { + gsl_Assert(p.data_.ptr_ != gsl_nullptr); + return std::move(p.data_.ptr_); + } #endif static gsl_api T const &get(not_null const &p) gsl_noexcept { return p.data_.ptr_; } + static gsl_api bool is_valid(not_null const &p) gsl_noexcept + { + return p.data_.ptr_ != gsl_nullptr; + } + static gsl_api void check(not_null const &p) + { + gsl_Assert(p.data_.ptr_ != gsl_nullptr); + } + static gsl_api T const &get_checked(not_null const &p) + { + gsl_Assert(p.data_.ptr_ != gsl_nullptr); + return p.data_.ptr_; + } + }; + template + struct not_null_accessor + { + static gsl_api T *const &get(not_null const &p) gsl_noexcept + { + return p.data_.ptr_; + } + static gsl_api bool is_valid(not_null const & /*p*/) gsl_noexcept + { + return true; + } + static gsl_api void check(not_null const & /*p*/) + { + } + static gsl_api T *const &get_checked(not_null const &p) gsl_noexcept + { + return p.data_.ptr_; + } }; namespace no_adl { + #if gsl_HAVE(MOVE_FORWARD) template gsl_NODISCARD gsl_api gsl_constexpr auto as_nullable(T &&p) @@ -3336,9 +3414,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD gsl_api gsl_constexpr14 T as_nullable(not_null &&p) { - T result = detail::not_null_accessor::get(std::move(p)); - gsl_Expects(result != gsl_nullptr); - return result; + return detail::not_null_accessor::get_checked(std::move(p)); } #else // ! gsl_HAVE( MOVE_FORWARD ) template @@ -3351,28 +3427,14 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 gsl_NODISCARD gsl_api gsl_constexpr14 T const & as_nullable(not_null const &p) { - T const &result = detail::not_null_accessor::get(p); - gsl_Expects(result != gsl_nullptr); - return result; - } - template - gsl_NODISCARD gsl_api gsl_constexpr T * - as_nullable(not_null p) gsl_noexcept - { - return detail::not_null_accessor::get(p); + return detail::not_null_accessor::get_checked(p); } template gsl_NODISCARD gsl_api gsl_constexpr bool is_valid(not_null const &p) { - return detail::not_null_accessor::get(p) != gsl_nullptr; - } - template - gsl_NODISCARD gsl_api gsl_constexpr bool - is_valid(not_null const &) - { - return true; + return detail::not_null_accessor::is_valid(p); } } // namespace no_adl @@ -3390,8 +3452,8 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 gsl_ENABLE_IF_((std::is_constructible::value))> gsl_api gsl_constexpr14 #if gsl_HAVE(MOVE_FORWARD) - not_null_ic(U &&u) - : not_null(std::forward(u)) + not_null_ic(U u) + : not_null(std::move(u)) #else // ! gsl_HAVE( MOVE_FORWARD ) not_null_ic(U const &u) : not_null(u) @@ -3434,43 +3496,51 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_(bool) operator==(not_null const &l, not_null const &r) - gsl_RETURN_DECLTYPE_(l.operator->() == r.operator->()) + gsl_RETURN_DECLTYPE_(l.operator-> () == r.operator->()) { return l.operator->() == r.operator->(); } template gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_(bool) operator==(not_null const &l, U const &r) - gsl_RETURN_DECLTYPE_(l.operator->() == r) + gsl_RETURN_DECLTYPE_(l.operator-> () == r) { return l.operator->() == r; } template gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_(bool) operator==(T const &l, not_null const &r) - gsl_RETURN_DECLTYPE_(l == r.operator->()) + gsl_RETURN_DECLTYPE_(l == r.operator-> ()) { return l == r.operator->(); } + // The C++ Core Guidelines discourage the use of pointer arithmetic, and gsl-lite consequently refrains from defining operators + // for pointer arithmetic or the subscript operator in `not_null<>`. However, comparison of `not_null<>` objects is supported; + // although the standard does not mandate a certain ordering for objects with two exceptions (objects from the same array; + // data members of the same class, as required for `offsetof()`), it does require that `operator<` establishes a total ordering + // of pointers, as implied by https://eel.is/c++draft/expr.rel#5. Among other things, this guarantees that a list of pointers + // can be sorted and searched, or that pointers can be used as a key in a relational container such as `std::map<>`. + // Therefore, we also define relational comparison operators for `not_null<>`. + template gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_(bool) operator<(not_null const &l, not_null const &r) - gsl_RETURN_DECLTYPE_(l.operator->() < r.operator->()) + gsl_RETURN_DECLTYPE_(l.operator-> () < r.operator->()) { return l.operator->() < r.operator->(); } template gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_(bool) operator<(not_null const &l, U const &r) - gsl_RETURN_DECLTYPE_(l.operator->() < r) + gsl_RETURN_DECLTYPE_(l.operator-> () < r) { return l.operator->() < r; } template gsl_NODISCARD inline gsl_api gsl_constexpr gsl_TRAILING_RETURN_TYPE_(bool) operator<(T const &l, not_null const &r) - gsl_RETURN_DECLTYPE_(l < r.operator->()) + gsl_RETURN_DECLTYPE_(l < r.operator-> ()) { return l < r.operator->(); } @@ -3779,6 +3849,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + template gsl_api gsl_constexpr14 T *endptr(T *data, gsl_CONFIG_SPAN_INDEX_TYPE size) { @@ -4286,7 +4357,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if gsl_CONFIG(ALLOWS_NONSTRICT_SPAN_COMPARISON) template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator==(span const &l, span const &r) { @@ -4294,7 +4365,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 } template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator<(span const &l, span const &r) { @@ -4304,7 +4375,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #else // a.k.a. !gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator==(span const &l, span const &r) { @@ -4312,7 +4383,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 } template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr bool operator<(span const &l, span const &r) { @@ -4363,6 +4434,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + template gsl_api gsl_constexpr14 inline OI copy_n(II first, N count, OI result) { @@ -4425,14 +4497,14 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD gsl_api inline gsl_constexpr span - make_span(T * first, T * last) + make_span(T * first, T * last) { return span(first, last); } template gsl_NODISCARD inline gsl_constexpr span - make_span(T(&arr)[N]) + make_span(T(&arr)[N]) { return span(gsl_ADDRESSOF(arr[0]), N); } @@ -4441,7 +4513,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD inline gsl_constexpr span - make_span(std::array & arr) + make_span(std::array & arr) { return span(arr); } @@ -4458,8 +4530,8 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template ()))> gsl_NODISCARD inline gsl_constexpr auto - make_span(Container & cont) - ->span::type> + make_span(Container & cont) + -> span::type> { return span::type>(cont); } @@ -4467,7 +4539,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template ()))> gsl_NODISCARD inline gsl_constexpr auto make_span(Container const &cont) - ->span::type> + -> span::type> { return span::type>(cont); } @@ -4476,7 +4548,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template inline span - make_span(std::vector & cont) + make_span(std::vector & cont) { return span(with_container, cont); } @@ -4493,7 +4565,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD inline gsl_constexpr span - make_span(with_container_t, Container & cont) gsl_noexcept + make_span(with_container_t, Container & cont) gsl_noexcept { return span(with_container, cont); } @@ -4510,7 +4582,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if !gsl_DEPRECATE_TO_LEVEL(4) template gsl_DEPRECATED inline span - make_span(Ptr & ptr) + make_span(Ptr & ptr) { return span(ptr); } @@ -4529,7 +4601,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template gsl_NODISCARD gsl_api inline gsl_constexpr span - byte_span(T & t) gsl_noexcept + byte_span(T & t) gsl_noexcept { return span(reinterpret_cast(&t), sizeof(T)); } @@ -4543,8 +4615,9 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #endif // gsl_FEATURE_TO_STD( BYTE_SPAN ) + // #if gsl_FEATURE( STRING_SPAN ) // - // basic_string_span: + // basic_string_span: // template @@ -4552,6 +4625,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 namespace detail { + template struct is_basic_string_span_oracle : std11::false_type { @@ -4609,9 +4683,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if gsl_HAVE(IS_DEFAULT) gsl_constexpr basic_string_span() gsl_noexcept = default; #else - gsl_api gsl_constexpr basic_string_span() gsl_noexcept - { - } + gsl_api gsl_constexpr basic_string_span() gsl_noexcept {} #endif #if gsl_HAVE(NULLPTR) @@ -4624,24 +4696,35 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #ifdef __CUDACC_RELAXED_CONSTEXPR__ gsl_api #endif // __CUDACC_RELAXED_CONSTEXPR__ - gsl_constexpr - basic_string_span(pointer ptr) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(pointer ptr) : span_(remove_z(ptr, (std::numeric_limits::max)())) { } - gsl_api gsl_constexpr basic_string_span(pointer ptr, index_type count) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_api gsl_constexpr basic_string_span(pointer ptr, index_type count) : span_(ptr, count) { } - gsl_api gsl_constexpr basic_string_span(pointer firstElem, pointer lastElem) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_api gsl_constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) { } template - gsl_constexpr basic_string_span(element_type (&arr)[N]) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(element_type (&arr)[N]) : span_(remove_z(gsl_ADDRESSOF(arr[0]), N)) { } @@ -4649,13 +4732,19 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if gsl_HAVE(ARRAY) template - gsl_constexpr basic_string_span(std::array::type, N> &arr) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(std::array::type, N> &arr) : span_(remove_z(arr)) { } template - gsl_constexpr basic_string_span(std::array::type, N> const &arr) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(std::array::type, N> const &arr) : span_(remove_z(arr)) { } @@ -4669,7 +4758,10 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template ::value && !detail::is_basic_string_span::value && std::is_convertible::value && std::is_convertible().data())>::value))> - gsl_constexpr basic_string_span(Container &cont) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(Container &cont) : span_((cont)) { } @@ -4679,7 +4771,10 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template ::value && !detail::is_basic_string_span::value && std::is_convertible::value && std::is_convertible().data())>::value))> - gsl_constexpr basic_string_span(Container const &cont) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(Container const &cont) : span_((cont)) { } @@ -4687,13 +4782,19 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #elif gsl_HAVE(UNCONSTRAINED_SPAN_CONTAINER_CTOR) template - gsl_constexpr basic_string_span(Container &cont) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(Container &cont) : span_(cont) { } template - gsl_constexpr basic_string_span(Container const &cont) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(Container const &cont) : span_(cont) { } @@ -4701,7 +4802,10 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #else template - gsl_api gsl_constexpr basic_string_span(span const &rhs) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_api gsl_constexpr basic_string_span(span const &rhs) : span_(rhs) { } @@ -4711,7 +4815,10 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if gsl_FEATURE_TO_STD(WITH_CONTAINER) template - gsl_constexpr basic_string_span(with_container_t, Container &cont) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span(with_container_t, Container &cont) : span_(with_container, cont) { } @@ -4731,7 +4838,10 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template ::pointer, pointer>::value))> - gsl_api gsl_constexpr basic_string_span(basic_string_span const &rhs) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_api gsl_constexpr basic_string_span(basic_string_span const &rhs) : span_(reinterpret_cast(rhs.data()), rhs.length()) // NOLINT { } @@ -4739,22 +4849,31 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if gsl_STDLIB_CPP11_120 template ::pointer, pointer>::value))> - gsl_api gsl_constexpr basic_string_span(basic_string_span &&rhs) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_api gsl_constexpr basic_string_span(basic_string_span &&rhs) : span_(reinterpret_cast(rhs.data()), rhs.length()) // NOLINT { } #endif // gsl_STDLIB_CPP11_120 template - gsl_constexpr basic_string_span( - std::basic_string::type, CharTraits, Allocator> &str) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span( + std::basic_string::type, CharTraits, Allocator> &str) : span_(gsl_ADDRESSOF(str[0]), str.length()) { } template - gsl_constexpr basic_string_span( - std::basic_string::type, CharTraits, Allocator> const &str) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_string_span<><> is deprecated; use span<> instead") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_constexpr basic_string_span( + std::basic_string::type, CharTraits, Allocator> const &str) : span_(gsl_ADDRESSOF(str[0]), str.length()) { } @@ -4943,7 +5062,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 #if gsl_CONFIG(ALLOWS_NONSTRICT_SPAN_COMPARISON) template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator==(basic_string_span const &l, U const &u) gsl_noexcept { @@ -4953,7 +5072,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 } template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator<(basic_string_span const &l, U const &u) gsl_noexcept { @@ -4966,7 +5085,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template ::value))> - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator==(U const &u, basic_string_span const &r) gsl_noexcept { @@ -4977,7 +5096,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 template ::value))> - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator<(U const &u, basic_string_span const &r) gsl_noexcept { @@ -4987,10 +5106,10 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 } #endif -#else //gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) +#else // gsl_CONFIG( ALLOWS_NONSTRICT_SPAN_COMPARISON ) template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator==(basic_string_span const &l, basic_string_span const &r) gsl_noexcept { @@ -4998,7 +5117,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 } template - gsl_SUPPRESS_MSGSL_WARNING(stl .1) + gsl_SUPPRESS_MSGSL_WARNING(stl.1) gsl_NODISCARD inline gsl_constexpr14 bool operator<(basic_string_span const &l, basic_string_span const &r) gsl_noexcept { @@ -5089,6 +5208,7 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 { return span(reinterpret_cast(spn.data()), spn.size_bytes()); // NOLINT } + // #endif // gsl_FEATURE( STRING_SPAN ) // // String types: @@ -5102,6 +5222,8 @@ gsl_DISABLE_MSVC_WARNINGS(26432 26410 26415 26418 26472 26439 26440 26455 26473 typedef const wchar_t *cwzstring; #endif + // #if gsl_FEATURE( STRING_SPAN ) + typedef basic_string_span string_span; typedef basic_string_span cstring_span; @@ -5157,6 +5279,7 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic namespace detail { + template void write_padding(Stream &os, std::streamsize n) { @@ -5222,6 +5345,7 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic } #endif // gsl_HAVE( WCHAR ) + // #endif // gsl_FEATURE( STRING_SPAN ) // // ensure_sentinel() @@ -5233,6 +5357,7 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic // namespace detail { + template gsl_constexpr14 static span ensure_sentinel(T *seq, SizeType max = (std::numeric_limits::max)()) { @@ -5265,7 +5390,7 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic template gsl_NODISCARD inline gsl_constexpr14 span - ensure_z(T(&sz)[N]) + ensure_z(T(&sz)[N]) { return ::gsl::ensure_z(gsl_ADDRESSOF(sz[0]), N); } @@ -5274,14 +5399,15 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic template gsl_NODISCARD inline gsl_constexpr14 span::type> - ensure_z(Container & cont) + ensure_z(Container & cont) { return ::gsl::ensure_z(cont.data(), cont.length()); } #endif + // #if gsl_FEATURE( STRING_SPAN ) // - // basic_zstring_span<> - A view of contiguous null-terminated characters, replace (*,len). + // basic_zstring_span<> - A view of contiguous null-terminated characters, replace (*,len). // template @@ -5297,7 +5423,10 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic typedef element_type *czstring_type; typedef basic_string_span string_span_type; - gsl_api gsl_constexpr14 basic_zstring_span(span_type s) +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_zstring_span<> is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_api gsl_constexpr14 basic_zstring_span(span_type s) : span_(s) { // expects a zero-terminated span @@ -5310,9 +5439,7 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic gsl_constexpr14 basic_zstring_span &operator=(basic_zstring_span const &) = default; gsl_constexpr14 basic_zstring_span &operator=(basic_zstring_span &&) = default; #else - gsl_api gsl_constexpr basic_zstring_span(basic_zstring_span const &other) : span_(other.span_) - { - } + gsl_api gsl_constexpr basic_zstring_span(basic_zstring_span const &other) : span_(other.span_) {} gsl_api gsl_constexpr basic_zstring_span &operator=(basic_zstring_span const &other) { span_ = other.span_; @@ -5326,15 +5453,21 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic return false; } - gsl_NODISCARD gsl_api gsl_constexpr string_span_type - as_string_span() const gsl_noexcept +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_zstring_span<> is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + gsl_NODISCARD gsl_api gsl_constexpr string_span_type + as_string_span() const gsl_noexcept { return string_span_type(span_.data(), span_.size() - 1); } - /*gsl_api*/ // currently disabled due to an apparent NVCC bug - gsl_NODISCARD gsl_constexpr string_span_type - ensure_z() const +#if gsl_DEPRECATE_TO_LEVEL(7) + gsl_DEPRECATED_MSG("basic_zstring_span<> is deprecated") +#endif // gsl_DEPRECATE_TO_LEVEL( 7 ) + /*gsl_api*/ // currently disabled due to an apparent NVCC bug + gsl_NODISCARD gsl_constexpr string_span_type + ensure_z() const { return ::gsl::ensure_z(span_.data(), span_.size()); } @@ -5360,6 +5493,7 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic typedef basic_zstring_span wzstring_span; typedef basic_zstring_span cwzstring_span; #endif + // #endif // gsl_FEATURE( STRING_SPAN ) } // namespace gsl @@ -5371,8 +5505,10 @@ inline std::basic_string< typename std::remove_const::type > to_string( basic namespace gsl { + namespace detail { + // // Helper struct for std::hash specializations // @@ -5399,11 +5535,12 @@ struct conditionally_enabled_hash namespace std { + template struct hash<::gsl::not_null> : public ::gsl::detail::conditionally_enabled_hash>::value> { public: - gsl_NODISCARD gsl_constexpr std::size_t + gsl_NODISCARD std::size_t operator()(::gsl::not_null const &v) const // hash function is not `noexcept` because `as_nullable()` has preconditions { @@ -5414,7 +5551,7 @@ template struct hash<::gsl::not_null> { public: - gsl_NODISCARD gsl_constexpr std::size_t + gsl_NODISCARD std::size_t operator()(::gsl::not_null const &v) const gsl_noexcept { return hash()(::gsl::as_nullable(v)); @@ -5425,9 +5562,14 @@ template <> struct hash<::gsl::byte> { public: - gsl_NODISCARD gsl_constexpr std::size_t operator()(::gsl::byte v) const gsl_noexcept + gsl_NODISCARD std::size_t operator()(::gsl::byte v) const gsl_noexcept { +#if gsl_CONFIG_DEFAULTS_VERSION >= 1 + return std::hash{}(::gsl::to_uchar(v)); +#else // gsl_CONFIG_DEFAULTS_VERSION < 1 + // Keep the old hashing algorithm if legacy defaults are used. return ::gsl::to_integer(v); +#endif // gsl_CONFIG_DEFAULTS_VERSION >= 1 } }; @@ -5462,15 +5604,18 @@ public: namespace gsl_lite { + namespace std11 = ::gsl::std11; namespace std14 = ::gsl::std14; namespace std17 = ::gsl::std17; namespace std20 = ::gsl::std20; +namespace std23 = ::gsl::std23; using namespace std11; -//using namespace std14; // contains only make_unique<>(), which is superseded by `gsl::make_unique<>()` +// using namespace std14; // contains only make_unique<>(), which is superseded by `gsl::make_unique<>()` using namespace std17; using namespace std20; +using namespace std23; using namespace ::gsl::detail::no_adl; @@ -5541,6 +5686,7 @@ using ::gsl::span; using ::gsl::as_writeable_bytes; #endif +// # if gsl_FEATURE( STRING_SPAN ) using ::gsl::basic_string_span; using ::gsl::cstring_span; using ::gsl::string_span; @@ -5548,6 +5694,7 @@ using ::gsl::string_span; using ::gsl::basic_zstring_span; using ::gsl::czstring_span; using ::gsl::zstring_span; +// # endif // gsl_FEATURE( STRING_SPAN ) using ::gsl::czstring; using ::gsl::zstring; @@ -5556,8 +5703,10 @@ using ::gsl::zstring; using ::gsl::cwzstring; using ::gsl::wzstring; +// # if gsl_FEATURE( STRING_SPAN ) using ::gsl::cwzstring_span; using ::gsl::wzstring_span; +// # endif // gsl_FEATURE( STRING_SPAN ) #endif // gsl_HAVE( WCHAR ) using ::gsl::ensure_z; @@ -5567,6 +5716,12 @@ using ::gsl::ensure_z; #endif // gsl_FEATURE( GSL_LITE_NAMESPACE ) gsl_RESTORE_MSVC_WARNINGS() +#if gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION +#pragma clang diagnostic pop +#endif // gsl_COMPILER_CLANG_VERSION || gsl_COMPILER_APPLECLANG_VERSION +#if gsl_COMPILER_GNUC_VERSION +#pragma GCC diagnostic pop +#endif // gsl_COMPILER_GNUC_VERSION // #undef internal macros #undef gsl_STATIC_ASSERT_ diff --git a/src/algorithms/libs/opencl/cl.hpp b/src/algorithms/libs/opencl/cl.hpp index 5b07e0091..b2c467e04 100644 --- a/src/algorithms/libs/opencl/cl.hpp +++ b/src/algorithms/libs/opencl/cl.hpp @@ -2588,7 +2588,7 @@ public: return ::clUnloadPlatformCompiler(object_); } #endif // #if defined(CL_VERSION_1_2) -}; // class Platform +}; // class Platform /** * Deprecated APIs for 1.2 @@ -4745,9 +4745,9 @@ public: //! \brief Default constructor - initializes to nullptr. #if defined(CL_VERSION_1_2) - BufferRenderGL() : ImageGL(){}; + BufferRenderGL() : ImageGL() {}; #else // #if defined(CL_VERSION_1_2) - BufferRenderGL() : Image2DGL(){}; + BufferRenderGL() : Image2DGL() {}; #endif // #if defined(CL_VERSION_1_2) /*! \brief Constructor from cl_mem - takes ownership. diff --git a/src/algorithms/libs/pass_through.cc b/src/algorithms/libs/pass_through.cc index bc54ae61a..0c2a17fa3 100644 --- a/src/algorithms/libs/pass_through.cc +++ b/src/algorithms/libs/pass_through.cc @@ -18,12 +18,17 @@ #include "pass_through.h" #include "configuration_interface.h" -#include #include #include #include // for int8_t #include // for operator<< +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Pass_Through::Pass_Through(const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/libs/rtklib/CMakeLists.txt b/src/algorithms/libs/rtklib/CMakeLists.txt index c23d55119..e308f102c 100644 --- a/src/algorithms/libs/rtklib/CMakeLists.txt +++ b/src/algorithms/libs/rtklib/CMakeLists.txt @@ -70,12 +70,17 @@ target_link_libraries(algorithms_libs_rtklib core_system_parameters algorithms_libs Armadillo::armadillo - Gflags::gflags - Glog::glog LAPACK::LAPACK BLAS::BLAS ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(algorithms_libs_rtklib PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(algorithms_libs_rtklib PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(algorithms_libs_rtklib PRIVATE absl::flags absl::log) +endif() + if(ENABLE_ARMA_NO_DEBUG) target_compile_definitions(algorithms_libs_rtklib PRIVATE -DARMA_NO_BOUND_CHECKING=1 diff --git a/src/algorithms/libs/rtklib/rtklib.h b/src/algorithms/libs/rtklib/rtklib.h index b5658641e..4d33cad0b 100644 --- a/src/algorithms/libs/rtklib/rtklib.h +++ b/src/algorithms/libs/rtklib/rtklib.h @@ -374,7 +374,7 @@ typedef struct typedef struct { /* observation data */ - int n, nmax; /* number of obervation data/allocated */ + int n, nmax; /* number of observation data/allocated */ obsd_t *data; /* observation data records */ } obs_t; @@ -664,7 +664,7 @@ typedef struct double deph[3]; /* delta orbit {radial,along,cross} (m) */ double ddeph[3]; /* dot delta orbit {radial,along,cross} (m/s) */ double dclk[3]; /* delta clock {c0,c1,c2} (m,m/s,m/s^2) */ - double hrclk; /* high-rate clock corection (m) */ + double hrclk; /* high-rate clock correction (m) */ float cbias[MAXCODE]; /* code biases (m) */ double pbias[MAXCODE]; /* phase biases (m) */ float stdpb[MAXCODE]; /* std-dev of phase biases (m) */ @@ -1159,7 +1159,7 @@ typedef struct typedef struct -{ /* tcp cilent type */ +{ /* tcp client type */ tcp_t svr; /* tcp server control */ int toinact; /* inactive timeout (ms) (0:no timeout) */ int tirecon; /* reconnect interval (ms) (0:no reconnect) */ diff --git a/src/algorithms/libs/rtklib/rtklib_ppp.cc b/src/algorithms/libs/rtklib/rtklib_ppp.cc index ebd7ddc48..2310fcc6f 100644 --- a/src/algorithms/libs/rtklib/rtklib_ppp.cc +++ b/src/algorithms/libs/rtklib/rtklib_ppp.cc @@ -1727,34 +1727,34 @@ int res_ppp(int iter __attribute__((unused)), const obsd_t *obs, int n, const do if (opt->maxinno > 0.0 && fabs(v[nv]) > opt->maxinno && sys != SYS_GLO) { #endif - trace(2, "ppp outlier rejected %s sat=%2d type=%d v=%.3f\n", - time_str(obs[i].time, 0), sat, j, v[nv]); - rtk->ssat[sat - 1].rejc[0]++; - continue; + trace(2, "ppp outlier rejected %s sat=%2d type=%d v=%.3f\n", + time_str(obs[i].time, 0), sat, j, v[nv]); + rtk->ssat[sat - 1].rejc[0]++; + continue; + } + if (j == 0) + { + rtk->ssat[sat - 1].vsat[0] = 1; + } + nv++; } - if (j == 0) - { - rtk->ssat[sat - 1].vsat[0] = 1; - } - nv++; } -} -for (i = 0; i < nv; i++) - { - for (j = 0; j < nv; j++) - { - R[i + j * nv] = i == j ? var[i] : 0.0; - } - } -trace(5, "x=\n"); -tracemat(5, x, 1, nx, 8, 3); -trace(5, "v=\n"); -tracemat(5, v, 1, nv, 8, 3); -trace(5, "H=\n"); -tracemat(5, H, nx, nv, 8, 3); -trace(5, "R=\n"); -tracemat(5, R, nv, nv, 8, 5); -return nv; + for (i = 0; i < nv; i++) + { + for (j = 0; j < nv; j++) + { + R[i + j * nv] = i == j ? var[i] : 0.0; + } + } + trace(5, "x=\n"); + tracemat(5, x, 1, nx, 8, 3); + trace(5, "v=\n"); + tracemat(5, v, 1, nv, 8, 3); + trace(5, "H=\n"); + tracemat(5, H, nx, nv, 8, 3); + trace(5, "R=\n"); + tracemat(5, R, nv, nv, 8, 5); + return nv; } diff --git a/src/algorithms/libs/rtklib/rtklib_rtcm3.cc b/src/algorithms/libs/rtklib/rtklib_rtcm3.cc index afed31c1f..c7f7e3632 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtcm3.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtcm3.cc @@ -3825,7 +3825,7 @@ int decode_msm7(rtcm_t *rtcm, int sys) i += 10; } for (j = 0; j < ncell; j++) - { /* half-cycle amiguity */ + { /* half-cycle ambiguity */ half[j] = getbitu(rtcm->buff, i, 1); i += 1; } diff --git a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc index f216e1344..1ef558bc5 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc @@ -30,7 +30,6 @@ *----------------------------------------------------------------------------*/ #include "rtklib_rtkcmn.h" -#include #include #include #include @@ -43,6 +42,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + const double GPST0[] = {1980, 1, 6, 0, 0, 0}; /* gps time reference */ const double GST0[] = {1999, 8, 22, 0, 0, 0}; /* galileo system time reference */ const double BDT0[] = {2006, 1, 1, 0, 0, 0}; /* beidou time reference */ @@ -1034,7 +1039,7 @@ double *zeros(int n, int m) { return nullptr; } - if (!(p = static_cast(calloc(sizeof(double), n * m)))) + if (!(p = static_cast(calloc(n * m, sizeof(double))))) { fatalerr("matrix memory allocation error: n=%d,m=%d\n", n, m); } @@ -1111,7 +1116,7 @@ void cross3(const double *a, const double *b, double *c) /* normalize 3d vector --------------------------------------------------------- * normalize 3d vector * args : double *a I vector a (3 x 1) - * double *b O normlized vector (3 x 1) || b || = 1 + * double *b O normalized vector (3 x 1) || b || = 1 * return : status (1:ok,0:error) *-----------------------------------------------------------------------------*/ int normv3(const double *a, double *b) @@ -1228,7 +1233,7 @@ int solve(const char *tr, const double *A, const double *Y, int n, * double *y I (weighted) measurements (m x 1) * int n,m I number of parameters and measurements (n <= m) * double *x O estmated parameters (n x 1) - * double *Q O esimated parameters covariance matrix (n x n) + * double *Q O estimated parameters covariance matrix (n x n) * return : status (0:ok,0>:error) * notes : for weighted least square, replace A and y by A*w and w*y (w=W^(1/2)) * matirix stored by column-major order (fortran convention) @@ -1772,9 +1777,7 @@ gtime_t timeget() { gtime_t time; double ep[6] = {}; - struct timeval tv - { - }; + struct timeval tv{}; struct tm *tt; if (!gettimeofday(&tv, nullptr) && (tt = gmtime(&tv.tv_sec))) @@ -1904,7 +1907,7 @@ int read_leaps_usno(FILE *fp) * return : status (1:ok,0:error) * notes : The leap second table should be as follows or leapsec.dat provided * by USNO. - * (1) The records in the table file cosist of the following fields: + * (1) The records in the table file consist of the following fields: * year month day hour min sec UTC-GPST(s) * (2) The date and time indicate the start UTC time for the UTC-GPST * (3) The date and time should be descending order. @@ -4585,7 +4588,7 @@ double ionppp(const double *pos, const double *azel, double re, double tropmodel(gtime_t time __attribute__((unused)), const double *pos, const double *azel, double humi) { - const double temp0 = 15.0; /* temparature at sea level */ + const double temp0 = 15.0; /* temperature at sea level */ double hgt; double pres; double temp; diff --git a/src/algorithms/libs/rtklib/rtklib_rtkcmn.h b/src/algorithms/libs/rtklib/rtklib_rtkcmn.h index d606d4d4e..14caedd99 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkcmn.h +++ b/src/algorithms/libs/rtklib/rtklib_rtkcmn.h @@ -31,14 +31,14 @@ * References : * [1] IS-GPS-200M, Navstar GPS Space Segment/Navigation User Interfaces, * May, 2021 - * [2] RTCA/DO-229C, Minimum operational performanc standards for global + * [2] RTCA/DO-229C, Minimum operational performance standards for global * positioning system/wide area augmentation system airborne equipment, * RTCA inc, November 28, 2001 * [3] M.Rothacher, R.Schmid, ANTEX: The Antenna Exchange Format Version 1.4, * 15 September, 2010 * [4] A.Gelb ed., Applied Optimal Estimation, The M.I.T Press, 1974 * [5] A.E.Niell, Global mapping functions for the atmosphere delay at radio - * wavelengths, Jounal of geophysical research, 1996 + * wavelengths, Journal of geophysical research, 1996 * [6] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format * Version 3.00, November 28, 2007 * [7] J.Kouba, A Guide to using International GNSS Service (IGS) products, diff --git a/src/algorithms/libs/rtklib/rtklib_rtkpos.cc b/src/algorithms/libs/rtklib/rtklib_rtkpos.cc index 8c31aec6b..136e9d0f8 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkpos.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtkpos.cc @@ -58,7 +58,7 @@ static gtime_t time_stat = {0, 0}; /* rtk status file time */ * args : char *file I rtk status file * int level I rtk status level (0: off) * return : status (1:ok,0:error) - * notes : file can constain time keywords (%Y,%y,%m...) defined in reppath(). + * notes : file can contain time keywords (%Y,%y,%m...) defined in reppath(). * The time to replace keywords is based on UTC of CPU time. * output : solution status file record format * diff --git a/src/algorithms/libs/rtklib/rtklib_sbas.cc b/src/algorithms/libs/rtklib/rtklib_sbas.cc index deebafd7a..313ba06d4 100644 --- a/src/algorithms/libs/rtklib/rtklib_sbas.cc +++ b/src/algorithms/libs/rtklib/rtklib_sbas.cc @@ -29,7 +29,7 @@ * * * References : - * [1] RTCA/DO-229C, Minimum operational performanc standards for global + * [1] RTCA/DO-229C, Minimum operational performance standards for global * positioning system/wide area augmentation system airborne equipment, * RTCA inc, November 28, 2001 * [2] IS-QZSS v.1.1, Quasi-Zenith Satellite System Navigation Service diff --git a/src/algorithms/libs/rtklib/rtklib_sbas.h b/src/algorithms/libs/rtklib/rtklib_sbas.h index 7d108cca6..ae9ff1232 100644 --- a/src/algorithms/libs/rtklib/rtklib_sbas.h +++ b/src/algorithms/libs/rtklib/rtklib_sbas.h @@ -29,7 +29,7 @@ * * * References : - * [1] RTCA/DO-229C, Minimum operational performanc standards for global + * [1] RTCA/DO-229C, Minimum operational performance standards for global * positioning system/wide area augmentation system airborne equipment, * RTCA inc, November 28, 2001 * [2] IS-QZSS v.1.1, Quasi-Zenith Satellite System Navigation Service diff --git a/src/algorithms/libs/rtklib/rtklib_solution.cc b/src/algorithms/libs/rtklib/rtklib_solution.cc index 17ad78ead..609456d4b 100644 --- a/src/algorithms/libs/rtklib/rtklib_solution.cc +++ b/src/algorithms/libs/rtklib/rtklib_solution.cc @@ -2383,7 +2383,7 @@ void outprcopt(FILE *fp, const prcopt_t *opt) /* output solution header ------------------------------------------------------ - * output solution heade to file + * output solution header to file * args : FILE *fp I output file pointer * solopt_t *opt I solution options * return : none diff --git a/src/algorithms/libs/rtklib/rtklib_stream.cc b/src/algorithms/libs/rtklib/rtklib_stream.cc index 3cb647ad6..d4ee0324b 100644 --- a/src/algorithms/libs/rtklib/rtklib_stream.cc +++ b/src/algorithms/libs/rtklib/rtklib_stream.cc @@ -87,9 +87,7 @@ serial_t *openserial(const char *path, int mode, char *msg) const speed_t bs[] = { B300, B600, B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400}; - struct termios ios - { - }; + struct termios ios{}; int rw = 0; tracet(3, "openserial: path=%s mode=%d\n", path, mode); @@ -301,7 +299,7 @@ int openfile_(file_t *file, gtime_t time, char *msg) { file->tick_f = 0; } - /* adust time to read playback file */ + /* adjust time to read playback file */ timeset(file->time); } else @@ -1104,9 +1102,7 @@ void updatetcpsvr(tcpsvr_t *tcpsvr, char *msg) /* accept client connection --------------------------------------------------*/ int accsock(tcpsvr_t *tcpsvr, char *msg) { - struct sockaddr_in addr - { - }; + struct sockaddr_in addr{}; socket_t sock; socklen_t len = sizeof(addr); int i; diff --git a/src/algorithms/libs/rtklib/rtklib_tides.cc b/src/algorithms/libs/rtklib/rtklib_tides.cc index 4c2f1d6a2..5adedf45c 100644 --- a/src/algorithms/libs/rtklib/rtklib_tides.cc +++ b/src/algorithms/libs/rtklib/rtklib_tides.cc @@ -281,12 +281,12 @@ void tide_pole(gtime_t tut, const double *pos, const double *erpv, * 8: elimate permanent deformation * double *erp I earth rotation parameters (NULL: not used) * double *odisp I ocean loading parameters (NULL: not used) - * odisp[0+i*6]: consituent i amplitude radial(m) - * odisp[1+i*6]: consituent i amplitude west (m) - * odisp[2+i*6]: consituent i amplitude south (m) - * odisp[3+i*6]: consituent i phase radial (deg) - * odisp[4+i*6]: consituent i phase west (deg) - * odisp[5+i*6]: consituent i phase south (deg) + * odisp[0+i*6]: constituent i amplitude radial(m) + * odisp[1+i*6]: constituent i amplitude west (m) + * odisp[2+i*6]: constituent i amplitude south (m) + * odisp[3+i*6]: constituent i phase radial (deg) + * odisp[4+i*6]: constituent i phase west (deg) + * odisp[5+i*6]: constituent i phase south (deg) * (i=0:M2,1:S2,2:N2,3:K2,4:K1,5:O1,6:P1,7:Q1, * 8:Mf,9:Mm,10:Ssa) * double *dr O displacement by earth tides (ecef) (m) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/.gitignore b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/.gitignore index a3bcb1ddf..e0043b895 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/.gitignore +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/.gitignore @@ -3,16 +3,16 @@ *~ *.pyc *.pyo -html/ -build/ -cmake_build/ -cmake-build-*/ -out/ +*.swp +/*build*/ +/archives/ +/.DS_Store +/gen/volk_gnsssdr_arch_defs.py +/html/ +/out/ .project .cproject .vagrant/ .vscode/ .vs/ -*.swp -/.DS_Store -/gen/volk_gnsssdr_arch_defs.py + diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index bca6d3d23..b2b83fe95 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -8,7 +8,7 @@ ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.8.12...3.28) +cmake_minimum_required(VERSION 2.8.12...4.0) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Choose build type: None Debug Release RelWithDebInfo MinSizeRel") project(volk_gnsssdr) enable_language(CXX) @@ -206,8 +206,9 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.") set(VERSION_INFO_MAJOR_VERSION 0) set(VERSION_INFO_MINOR_VERSION 0) -set(VERSION_INFO_MAINT_VERSION 19) +set(VERSION_INFO_MAINT_VERSION 20) include(VolkGnsssdrVersion) # setup version info +include(VolkGnsssdrFindPaths) # set VOLK_GNSSSDR_LIB_PATHS and VOLK_GNSSSDR_INCLUDE_PATHS @@ -394,23 +395,12 @@ endif() ######################################################################## # Detect /lib versus /lib64 ######################################################################## -if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64) - set(LIB_SUFFIX 64) -endif() +include(GNUInstallDirs) ######################################################################## # Setup the package config file ######################################################################## -# set variables found in the pc.in file -if(NOT LIB_SUFFIX) - set(LIB_SUFFIX "") -endif() -set(prefix ${CMAKE_INSTALL_PREFIX}) -set(exec_prefix "\${prefix}") -set(libdir "\${exec_prefix}/lib${LIB_SUFFIX}") -set(includedir "\${prefix}/include") - configure_file( ${PROJECT_SOURCE_DIR}/tmpl/volk_gnsssdr.pc.in ${PROJECT_BINARY_DIR}/volk_gnsssdr.pc @@ -419,7 +409,7 @@ configure_file( install( FILES ${PROJECT_BINARY_DIR}/volk_gnsssdr.pc - DESTINATION lib${LIB_SUFFIX}/pkgconfig + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT "volk_gnsssdr_devel" ) @@ -427,7 +417,7 @@ install( # Install all headers in the include directories ######################################################################## set(VOLK_RUNTIME_DIR bin) -set(VOLK_LIBRARY_DIR lib${LIB_SUFFIX}) +set(VOLK_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}) set(VOLK_INCLUDE_DIR include) install( @@ -524,7 +514,7 @@ configure_file( ######################################################################## if(NOT CMAKE_MODULES_DIR) - set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) + set(CMAKE_MODULES_DIR ${CMAKE_INSTALL_LIBDIR}/cmake) endif() install( diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md index 2bbf9ebd8..393f9b71f 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md @@ -67,7 +67,7 @@ and will make use of it if already installed, thus avoiding to install it twice. First, make sure that the required dependencies are installed in your machine: ``` -$ sudo apt-get install build-essential python3-mako cmake git ca-certificates \ +$ sudo apt install build-essential python3-mako cmake git ca-certificates \ libboost-dev libboost-filesystem-dev libboost-system-dev ``` diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt index e4bfcf4d7..e821363c6 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/CMakeLists.txt @@ -77,6 +77,9 @@ if(UNIX) ) endif() +include(XcodeRemoveWarningDuplicates) +xcode_remove_warning_duplicates(volk_gnsssdr_profile) + if(ENABLE_STRIP) if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) set_target_properties(volk_gnsssdr_profile @@ -106,6 +109,8 @@ if(UNIX) ) endif() +xcode_remove_warning_duplicates(volk_gnsssdr-config-info) + if(ENABLE_STRIP) if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) set_target_properties(volk_gnsssdr-config-info diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_option_helpers.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_option_helpers.cc index f88da8bd7..9d6f16a7f 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_option_helpers.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_option_helpers.cc @@ -111,8 +111,8 @@ void option_list::parse(int argc, char** argv) for (int arg_number = 0; arg_number < argc; ++arg_number) { for (std::vector::iterator this_option = d_internal_list.begin(); - this_option != d_internal_list.end(); - this_option++) + this_option != d_internal_list.end(); + this_option++) { int int_val = INT_MIN; if (this_option->longform == std::string(argv[arg_number]) || @@ -254,8 +254,8 @@ void option_list::help() std::cout << d_program_name << std::endl; std::cout << " -h [ --help ] \t\tdisplay this help message" << std::endl; for (std::vector::iterator this_option = d_internal_list.begin(); - this_option != d_internal_list.end(); - this_option++) + this_option != d_internal_list.end(); + this_option++) { std::string help_line(" "); if (this_option->shortform == "-") diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_profile.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_profile.cc index 2c52adf65..8710f2966 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_profile.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/apps/volk_gnsssdr_profile.cc @@ -236,7 +236,7 @@ void read_results(std::vector *results, std::string kernel_result.config_name = std::string(single_kernel_result[0]); kernel_result.best_arch_u = std::string(single_kernel_result[1]); kernel_result.best_arch_a = std::string(single_kernel_result[2]); - results->push_back(kernel_result); + results->push_back(std::move(kernel_result)); } } } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Checks/check-rvv-intrinsics.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Checks/check-rvv-intrinsics.c new file mode 100644 index 000000000..ba98fc574 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Checks/check-rvv-intrinsics.c @@ -0,0 +1,13 @@ +/* + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * SPDX-FileCopyrightText: 2025 C. Fernandez-Prades cfernandez(at)cttc.es + * SPDX-License-Identifier: BSD-3-Clause + */ + +#if (__riscv_v_intrinsic >= 1000000 || __clang_major__ >= 18 || __GNUC__ >= 14) +int main() { return 0; } +#else +#error "rvv intrinsics aren't supported" +#endif diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/DetectMacOSPackaging.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/DetectMacOSPackaging.cmake new file mode 100644 index 000000000..5be83478e --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/DetectMacOSPackaging.cmake @@ -0,0 +1,26 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2025 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +set(MACOS_PACKAGES_PREFIX "") +# Detect if MacPorts is installed on this system; if so, return base path and version +execute_process(COMMAND which port RESULT_VARIABLE DETECT_MACPORTS OUTPUT_VARIABLE MACPORTS_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) +if(${DETECT_MACPORTS} EQUAL 0) + # "/opt/local/bin/port", so we get the parent directory + get_filename_component(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY) + # "/opt/local/bin", so we get the parent directory + get_filename_component(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY) + execute_process(COMMAND port version RESULT_VARIABLE DETECT_MACPORTS_VERSION OUTPUT_VARIABLE MACPORTS_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" MACPORTS_VERSION "${MACPORTS_VERSION}") + set(MACOS_PACKAGES_PREFIX ${MACPORTS_PREFIX}) +endif() + +# Detect if Homebrew is installed on this system; if so, return base path and version +execute_process(COMMAND brew --prefix RESULT_VARIABLE DETECT_HOMEBREW OUTPUT_VARIABLE HOMEBREW_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) +if(${DETECT_HOMEBREW} EQUAL 0) + execute_process(COMMAND brew --version RESULT_VARIABLE DETECT_HOMEBREW_VERSION OUTPUT_VARIABLE HOMEBREW_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" HOMEBREW_VERSION "${HOMEBREW_VERSION}") + set(MACOS_PACKAGES_PREFIX ${HOMEBREW_PREFIX}) +endif() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake index 6f25e91d2..0cf9c286d 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake @@ -1,54 +1,25 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2021-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause set(FPHSA_NAME_MISMATCHED ON) +if(NOT VOLK_GNSSSDR_LIB_PATHS) + include(VolkGnsssdrFindPaths) +endif() + find_library(CPUFEATURES_LIBRARIES NAMES cpu_features - PATHS /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/powerpc-linux-gnuspe - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/lib/i386-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/x86_64-kfreebsd-gnu - /usr/lib/i386-kfreebsd-gnu - /usr/lib/m68k-linux-gnu - /usr/lib/sh4-linux-gnu - /usr/lib/sparc64-linux-gnu - /usr/lib/x86_64-linux-gnux32 - /usr/lib/alpha-linux-gnu - /usr/lib/riscv64-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + PATHS $ENV{CPUFEATURES_DIR}/lib + ${VOLK_GNSSSDR_LIB_PATHS} ) find_path(CPUFEATURES_INCLUDE_DIR cpu_features_macros.h PATHS $ENV{CPUFEATURES_DIR}/include $ENV{CPUFEATURES_DIR} - /usr/include - /usr/local/include - ~/Library/Frameworks - /Library/Frameworks - /sw/include # Fink - /opt/local/include # MacPorts - /opt/csw/include # Blastwave + ${VOLK_GNSSSDR_INCLUDE_PATHS} PATH_SUFFIXES cpu_features ) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake index facb29f51..22e7f943b 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindORC.cmake @@ -1,13 +1,18 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# Copyright (C) 2015-2020 (see AUTHORS file for a list of contributors) +# Copyright (C) 2015-2025 (see AUTHORS file for a list of contributors) # SPDX-License-Identifier: BSD-3-Clause set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE) set(FPHSA_NAME_MISMATCHED ON) include(FindPkgConfig) + +if(NOT VOLK_GNSSSDR_LIB_PATHS) + include(VolkGnsssdrFindPaths) +endif() + pkg_check_modules(PC_ORC "orc-0.4 > 0.4.22") if(NOT ORC_ROOT) @@ -36,16 +41,14 @@ find_program(ORCC_EXECUTABLE orcc HINTS ${ORC_ROOT_USER_PROVIDED}/bin PATHS /usr/bin /usr/local/bin - /opt/local/bin + ${CMAKE_SYSTEM_PREFIX_PATH}/bin ) find_path(ORC_INCLUDE_DIR NAMES orc/orc.h HINTS ${PC_ORC_INCLUDEDIR} PATHS ${ORC_ROOT_USER_PROVIDED}/include - /usr/include - /usr/local/include - /opt/local/include + ${VOLK_GNSSSDR_INCLUDE_PATHS} PATH_SUFFIXES orc-0.4 ) @@ -54,80 +57,23 @@ find_path(ORC_LIBRARY_DIR HINTS ${PC_ORC_LIBDIR} PATHS ${ORC_ROOT_USER_PROVIDED}/lib ${ORC_ROOT_USER_PROVIDED}/lib64 - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${VOLK_GNSSSDR_LIB_PATHS} ) find_library(ORC_LIB orc-0.4 HINTS ${PC_ORC_LIBRARY_DIRS} PATHS ${ORC_ROOT_USER_PROVIDED}/lib ${ORC_ROOT_USER_PROVIDED}/lib64 - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${VOLK_GNSSSDR_LIB_PATHS} ) find_library(ORC_LIBRARY_STATIC ${CMAKE_STATIC_LIBRARY_PREFIX}orc-0.4${CMAKE_STATIC_LIBRARY_SUFFIX} HINTS ${PC_ORC_LIBRARY_DIRS} PATHS ${ORC_ROOT}/lib ${ORC_ROOT}/lib64 - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 ${ORC_ROOT_USER_PROVIDED}/lib ${ORC_ROOT_USER_PROVIDED}/lib64 - /usr/lib - /usr/lib64 - /usr/lib/x86_64-linux-gnu - /usr/lib/i386-linux-gnu - /usr/lib/arm-linux-gnueabihf - /usr/lib/arm-linux-gnueabi - /usr/lib/aarch64-linux-gnu - /usr/lib/mipsel-linux-gnu - /usr/lib/mips-linux-gnu - /usr/lib/mips64el-linux-gnuabi64 - /usr/lib/powerpc-linux-gnu - /usr/lib/powerpc64-linux-gnu - /usr/lib/powerpc64le-linux-gnu - /usr/lib/hppa-linux-gnu - /usr/lib/s390x-linux-gnu - /usr/local/lib - /usr/local/lib64 - /opt/local/lib + ${VOLK_GNSSSDR_LIB_PATHS} ) if(PC_ORC_VERSION) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrFindPaths.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrFindPaths.cmake new file mode 100644 index 000000000..6ce8d50f1 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkGnsssdrFindPaths.cmake @@ -0,0 +1,80 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2011-2025 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(VOLK_GNSSSDR_LIB_PATHS) + return() +endif() + +if(NOT CMAKE_INSTALL_LIBDIR) + include(GNUInstallDirs) +endif() + +set(VOLK_GNSSSDR_LIB_PATHS + /usr/lib + /usr/lib64 + /usr/lib/aarch64-linux-gnu + /usr/lib/alpha-linux-gnu + /usr/lib/arm-linux-gnueabi + /usr/lib/arm-linux-gnueabihf + /usr/lib/hppa-linux-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/i386-gnu + /usr/lib/i386-kfreebsd-gnu + /usr/lib/i386-linux-gnu + /usr/lib/loongarch64-linux-gnu + /usr/lib/m68k-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/mipsel-linux-gnu + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc-linux-gnuspe + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/riscv64-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/sh4-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/x86_64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/local/lib + /usr/local/lib64 + /usr/local/lib/i386 + ${CMAKE_INSTALL_FULL_LIBDIR} + ${CMAKE_SYSTEM_PREFIX_PATH}/${CMAKE_INSTALL_LIBDIR} + ${CMAKE_INSTALL_PREFIX}/lib + ${CMAKE_INSTALL_PREFIX}/lib64 +) + +set(VOLK_GNSSSDR_INCLUDE_PATHS + /usr/include + /usr/local/include + ${CMAKE_INSTALL_FULL_INCLUDEDIR} + ${CMAKE_SYSTEM_PREFIX_PATH}/include + ${CMAKE_INSTALL_PREFIX}/include +) + +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + if(NOT MACOS_PACKAGES_PREFIX) + include(DetectMacOSPackaging) + endif() + set(VOLK_GNSSSDR_LIB_PATHS + ${VOLK_GNSSSDR_LIB_PATHS} + ${MACOS_PACKAGES_PREFIX}/${CMAKE_INSTALL_LIBDIR} + ${MACOS_PACKAGES_PREFIX}/lib + ${MACOS_PACKAGES_PREFIX}/lib64 + ) + set(VOLK_GNSSSDR_INCLUDE_PATHS ${VOLK_GNSSSDR_INCLUDE_PATHS} + ${MACOS_PACKAGES_PREFIX}/include + ~/Library/Frameworks + /Library/Frameworks + /sw/include # Fink + /opt/csw/include # Blastwave + ) +endif() + +list(REMOVE_DUPLICATES VOLK_GNSSSDR_LIB_PATHS) +list(REMOVE_DUPLICATES VOLK_GNSSSDR_INCLUDE_PATHS) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/XcodeRemoveWarningDuplicates.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/XcodeRemoveWarningDuplicates.cmake new file mode 100644 index 000000000..f4e150fcc --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/XcodeRemoveWarningDuplicates.cmake @@ -0,0 +1,23 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2011-2024 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(DEFINED __INCLUDED_XCODE_REMOVE_WARNING_DUPLICATES_CMAKE) + return() +endif() +set(__INCLUDED_XCODE_REMOVE_WARNING_DUPLICATES_CMAKE TRUE) + +function(xcode_remove_warning_duplicates target) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0.0") + # A bug in Xcode 15 adds duplicate flags to the linker. In addition, the + # `-warn_duplicate_libraries` is now enabled by default which may result + # in several 'duplicate libraries warning'. + # - https://gitlab.kitware.com/cmake/cmake/-/issues/25297 and + # - https://indiestack.com/2023/10/xcode-15-duplicate-library-linker-warnings/ + target_link_options(${target} PUBLIC "LINKER:-no_warn_duplicate_libraries") + endif() + endif() +endfunction() \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage index b1fbc390d..f077f66b8 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage @@ -2,7 +2,7 @@ .\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-FileCopyrightText: Carles Fernandez-Prades .\" Contact carles.fernandez@cttc.es to correct errors or typos. -.TH volk_gnsssdr\-config\-info 1 "23 Jan 2024" "0.0.19" "volk_gnsssdr\-config\-info man page" +.TH volk_gnsssdr\-config\-info 1 "1 Apr 2025" "0.0.20" "volk_gnsssdr\-config\-info man page" .SH NAME \fBvolk_gnsssdr\-config\-info\fR \- Prints configuration information of libvolk_gnsssdr functions. .SH SYNOPSIS diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage index 36febf4e3..933a464b3 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage @@ -2,7 +2,7 @@ .\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-FileCopyrightText: Carles Fernandez-Prades .\" Contact carles.fernandez@cttc.es to correct errors or typos. -.TH volk_gnsssdr_profile 1 "23 Jan 2024" "0.0.19" "volk_gnsssdr_profile man page" +.TH volk_gnsssdr_profile 1 "1 Apr 2025" "0.0.20" "volk_gnsssdr_profile man page" .SH NAME \fBvolk_gnsssdr_profile\fR \- Profiler application for libvolk_gnsssdr functions. .SH SYNOPSIS diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Toolchains/rv64gcv-linux-gnu.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Toolchains/rv64gcv-linux-gnu.cmake new file mode 100644 index 000000000..54be4cc5d --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Toolchains/rv64gcv-linux-gnu.cmake @@ -0,0 +1,32 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# Copyright (C) 2011-2025 (see AUTHORS file for a list of contributors) +# SPDX-License-Identifier: BSD-3-Clause + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) + +set(CMAKE_C_COMPILER $ENV{CC}) +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_CXX_COMPILER $ENV{CXX}) + +set(CMAKE_C_FLAGS "$ENV{CFLAGS} -march=rv64gcv" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "" FORCE) +set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -g" CACHE STRING "" FORCE) + +set(CMAKE_OBJCOPY + ${RISCV64_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}objcopy + CACHE INTERNAL "objcopy tool") +set(CMAKE_SIZE_UTIL + ${RISCV64_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}size + CACHE INTERNAL "size tool") + +set(CMAKE_FIND_ROOT_PATH ${BINUTILS_PATH}) + +set(QEMU_VLEN $ENV{VLEN}) +if(NOT QEMU_VLEN) + set(QEMU_VLEN "128") +endif() + +set(CMAKE_CROSSCOMPILING_EMULATOR "qemu-riscv64-static -L /usr/riscv64-linux-gnu/ -cpu rv64,zba=true,zbb=true,v=on,vlen=${QEMU_VLEN},rvv_ta_all_1s=on,rvv_ma_all_1s=on") diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/msvc/sys/time.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/msvc/sys/time.h index 07eb3f849..63b1bd429 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/msvc/sys/time.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/msvc/sys/time.h @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Carles Fernandez-Prades #ifndef _MSC_VER // [ #error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] +#else #ifndef _MSC_SYS_TIME_H #define _MSC_SYS_TIME_H @@ -72,3 +72,6 @@ static inline int gettimeofday(struct timeval *tv, struct timezone *tz) return 0; } + +#endif // _MSC_SYS_TIME_H +#endif // _MSC_VER \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt index 7e7f7b90b..fb4a99a78 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt @@ -3,12 +3,6 @@ cmake_minimum_required(VERSION 3.13) -# option() honors normal variables. -# see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html -if(POLICY CMP0077) - cmake_policy(SET CMP0077 NEW) -endif() - project(CpuFeatures VERSION 0.9.0 LANGUAGES C) set(CMAKE_C_STANDARD 99) @@ -54,7 +48,7 @@ option(BUILD_SHARED_LIBS "Build library as shared." OFF) # Force PIC on unix when building shared libs # see: https://en.wikipedia.org/wiki/Position-independent_code if(BUILD_SHARED_LIBS AND UNIX) - option(CMAKE_POSITION_INDEPENDENT_CODE "Build with Position Independant Code." ON) + option(CMAKE_POSITION_INDEPENDENT_CODE "Build with Position Independent Code." ON) endif() include(CheckIncludeFile) @@ -151,7 +145,7 @@ if(UNIX) add_library(unix_based_hardware_detection OBJECT ${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h ${PROJECT_SOURCE_DIR}/src/hwcaps_linux_or_android.c - ${PROJECT_SOURCE_DIR}/src/hwcaps_freebsd.c + ${PROJECT_SOURCE_DIR}/src/hwcaps_freebsd_or_openbsd.c ${PROJECT_SOURCE_DIR}/src/hwcaps.c ) setup_include_and_definitions(unix_based_hardware_detection) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h index 42b4e55b1..020c3d09f 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h @@ -4,7 +4,6 @@ #ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ -#include //////////////////////////////////////////////////////////////////////////////// // Architectures //////////////////////////////////////////////////////////////////////////////// @@ -85,6 +84,10 @@ #define CPU_FEATURES_OS_FREEBSD #endif +#if defined(__OpenBSD__) +#define CPU_FEATURES_OS_OPENBSD +#endif + #if defined(__ANDROID__) #define CPU_FEATURES_OS_ANDROID #endif @@ -227,11 +230,13 @@ #endif // defined(CPU_FEATURES_ARCH_X86) #if defined(CPU_FEATURES_ARCH_ANY_ARM) -#if defined(__ARM_NEON__) +// Note: MSVC targeting ARM does not define `__ARM_NEON` but Windows on ARM +// requires it. In that case we force NEON detection. +#if defined(__ARM_NEON) || defined(CPU_FEATURES_COMPILER_MSC) #define CPU_FEATURES_COMPILED_ANY_ARM_NEON 1 #else #define CPU_FEATURES_COMPILED_ANY_ARM_NEON 0 -#endif // defined(__ARM_NEON__) +#endif // defined(__ARM_NEON) || defined(CPU_FEATURES_COMPILER_MSC) #endif // defined(CPU_FEATURES_ARCH_ANY_ARM) #if defined(CPU_FEATURES_ARCH_MIPS) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h index 618f17def..41108b6ec 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h @@ -180,6 +180,33 @@ typedef struct int smebi32i32 : 1; // 1-bit binary to 32-bit integer outer product. int smeb16b16 : 1; // SME2.1 BFloat16 instructions. int smef16f16 : 1; // FP16 to FP16 outer product. + int mops : 1; // Standardized memory operations. + int hbc : 1; // Hinted conditional branches. + int sveb16b16 : 1; // Non-widening BFloat16 to BFloat16 arithmetic for SVE2 + // and SME2. + int lrcpc3 : 1; // Load-Acquire RCpc instructions version 3. + int lse128 : 1; // 128-bit Atomics. + int fpmr : 1; // Floating-point Mode Register. + int lut : 1; // Lookup table instructions with 2-bit and 4-bit indices. + int faminmax : 1; // Maximum and minimum absolute value instructions. + int f8cvt : 1; // FP scaling instructions and FP8 convert instructions. + int f8fma : 1; // FP8 to single-precision and half-precision + // multiply-accumulate instructions. + int f8dp4 : 1; // FP8 to single-precision 4-way dot product FDOT (4-way) + // instructions. + int f8dp2 : 1; // FP8 to half-precision 2-way dot product FDOT (2-way) + // instructions. + int f8e4m3 : 1; // Arm FP8 E4M3 format. + int f8e5m2 : 1; // Arm FP8 E5M2 format. + int smelutv2 : 1; // SME2 lookup table LUTI4 and MOVT instructions. + int smef8f16 : 1; // SME2 F8F16 instructions. + int smef8f32 : 1; // SME2 F8F32 instructions. + int smesf8fma : 1; // SVE2 FP8 to single-precision and half-precision + // multiply-accumulate instructions. + int smesf8dp4 : 1; // SVE2 FP8 to single-precision 4-way dot product FDOT + // (4-way) instructions. + int smesf8dp2 : 1; // SVE2 FP8 to half-precision 2-way dot product FDOT + // (2-way) instructions. // Make sure to update Aarch64FeaturesEnum below if you add a field here. } Aarch64Features; @@ -276,6 +303,26 @@ typedef enum AARCH64_SME_BI32I32, AARCH64_SME_B16B16, AARCH64_SME_F16F16, + AARCH64_MOPS, + AARCH64_HBC, + AARCH64_SVE_B16B16, + AARCH64_LRCPC3, + AARCH64_LSE128, + AARCH64_FPMR, + AARCH64_LUT, + AARCH64_FAMINMAX, + AARCH64_F8CVT, + AARCH64_F8FMA, + AARCH64_F8DP4, + AARCH64_F8DP2, + AARCH64_F8E4M3, + AARCH64_F8E5M2, + AARCH64_SME_LUTV2, + AARCH64_SME_F8F16, + AARCH64_SME_F8F32, + AARCH64_SME_SF8FMA, + AARCH64_SME_SF8DP4, + AARCH64_SME_SF8DP2, AARCH64_LAST_, } Aarch64FeaturesEnum; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h index 455192aa8..a41224290 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h @@ -93,7 +93,7 @@ typedef enum PPC_HAS_MMU, /* Memory management unit */ PPC_HAS_4xxMAC, PPC_UNIFIED_CACHE, /* Unified instruction and data cache */ - PPC_HAS_SPE, /* Signal processing extention unit */ + PPC_HAS_SPE, /* Signal processing extension unit */ PPC_HAS_EFP_SINGLE, /* SPE single precision fpu */ PPC_HAS_EFP_DOUBLE, /* SPE double precision fpu */ PPC_NO_TB, /* No timebase */ @@ -110,7 +110,7 @@ typedef enum PPC_POWER6_EXT, PPC_ARCH_2_06, /* ISA 2.06 - POWER7 */ PPC_HAS_VSX, /* Vector-scalar extension */ - PPC_PSERIES_PERFMON_COMPAT, /* Set of backwards compatibile performance + PPC_PSERIES_PERFMON_COMPAT, /* Set of backwards compatible performance monitoring events */ PPC_TRUE_LE, PPC_PPC_LE, diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h index 8bc36d143..4c2687ebb 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h @@ -116,7 +116,7 @@ typedef struct // Calls cpuid and returns an initialized X86info. X86Info GetX86Info(void); -// Returns cache hierarchy informations. +// Returns cache hierarchy information. // Can call cpuid multiple times. CacheInfo GetX86CacheInfo(void); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h index a787aa966..3f500f606 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h @@ -92,6 +92,26 @@ CPU_FEATURES_START_CPP_NAMESPACE #define AARCH64_HWCAP2_SME_BI32I32 (1UL << 40) #define AARCH64_HWCAP2_SME_B16B16 (1UL << 41) #define AARCH64_HWCAP2_SME_F16F16 (1UL << 42) +#define AARCH64_HWCAP2_MOPS (1UL << 43) +#define AARCH64_HWCAP2_HBC (1UL << 44) +#define AARCH64_HWCAP2_SVE_B16B16 (1UL << 45) +#define AARCH64_HWCAP2_LRCPC3 (1UL << 46) +#define AARCH64_HWCAP2_LSE128 (1UL << 47) +#define AARCH64_HWCAP2_FPMR (1UL << 48) +#define AARCH64_HWCAP2_LUT (1UL << 49) +#define AARCH64_HWCAP2_FAMINMAX (1UL << 50) +#define AARCH64_HWCAP2_F8CVT (1UL << 51) +#define AARCH64_HWCAP2_F8FMA (1UL << 52) +#define AARCH64_HWCAP2_F8DP4 (1UL << 53) +#define AARCH64_HWCAP2_F8DP2 (1UL << 54) +#define AARCH64_HWCAP2_F8E4M3 (1UL << 55) +#define AARCH64_HWCAP2_F8E5M2 (1UL << 56) +#define AARCH64_HWCAP2_SME_LUTV2 (1UL << 57) +#define AARCH64_HWCAP2_SME_F8F16 (1UL << 58) +#define AARCH64_HWCAP2_SME_F8F32 (1UL << 59) +#define AARCH64_HWCAP2_SME_SF8FMA (1UL << 60) +#define AARCH64_HWCAP2_SME_SF8DP4 (1UL << 61) +#define AARCH64_HWCAP2_SME_SF8DP2 (1UL << 62) // http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h #define ARM_HWCAP_SWP (1UL << 0) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/ndk_compat/cpu-features.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/ndk_compat/cpu-features.h index 791b05ffd..a2415cb65 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/ndk_compat/cpu-features.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/ndk_compat/cpu-features.h @@ -165,7 +165,7 @@ extern uint64_t android_getCpuFeatures(void); * This flag implies -mfpu=neon-vfpv4. * * -mcpu=iwmmxt - * Allows the use of iWMMXt instrinsics with GCC. + * Allows the use of iWMMXt intrinsics with GCC. * * IMPORTANT NOTE: These flags should only be tested when * android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, i.e. this is a diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps_freebsd.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps_freebsd_or_openbsd.c similarity index 85% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps_freebsd.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps_freebsd_or_openbsd.c index 34c29e7ae..8756c4c30 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps_freebsd.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps_freebsd_or_openbsd.c @@ -3,7 +3,7 @@ #include "cpu_features_macros.h" -#ifdef CPU_FEATURES_OS_FREEBSD +#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) #include "internal/hwcaps.h" @@ -38,8 +38,8 @@ const char *CpuFeatures_GetPlatformPointer(void) { return NULL; } const char *CpuFeatures_GetBasePlatformPointer(void) { return NULL; } #else -#error "FreeBSD needs support for elf_aux_info" +#error "FreeBSD / OpenBSD needs support for elf_aux_info" #endif // HAVE_STRONG_ELF_AUX_INFO #endif // CPU_FEATURES_TEST -#endif // CPU_FEATURES_OS_FREEBSD \ No newline at end of file +#endif // CPU_FEATURES_OS_FREEBSD || CPU_FEATURES_OS_OPENBSD \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64__base_implementation.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64__base_implementation.inl index 36fd9a65c..d0057ee10 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64__base_implementation.inl +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64__base_implementation.inl @@ -100,7 +100,31 @@ AARCH64_HWCAP2_SME_BI32I32) \ LINE(AARCH64_SME_B16B16, smeb16b16, "smeb16b16", 0, \ AARCH64_HWCAP2_SME_B16B16) \ - LINE(AARCH64_SME_F16F16, smef16f16, "smef16f16", 0, AARCH64_HWCAP2_SME_F16F16) + LINE(AARCH64_SME_F16F16, smef16f16, "smef16f16", 0, \ + AARCH64_HWCAP2_SME_F16F16) \ + LINE(AARCH64_MOPS, mops, "mops", 0, AARCH64_HWCAP2_MOPS) \ + LINE(AARCH64_HBC, hbc, "hbc", 0, AARCH64_HWCAP2_HBC) \ + LINE(AARCH64_SVE_B16B16, sveb16b16, "sveb16b16", 0, \ + AARCH64_HWCAP2_SVE_B16B16) \ + LINE(AARCH64_LRCPC3, lrcpc3, "lrcpc3", 0, AARCH64_HWCAP2_LRCPC3) \ + LINE(AARCH64_LSE128, lse128, "lse128", 0, AARCH64_HWCAP2_LSE128) \ + LINE(AARCH64_FPMR, fpmr, "fpmr", 0, AARCH64_HWCAP2_FPMR) \ + LINE(AARCH64_LUT, lut, "lut", 0, AARCH64_HWCAP2_LUT) \ + LINE(AARCH64_FAMINMAX, faminmax, "faminmax", 0, AARCH64_HWCAP2_FAMINMAX) \ + LINE(AARCH64_F8CVT, f8cvt, "f8cvt", 0, AARCH64_HWCAP2_F8CVT) \ + LINE(AARCH64_F8FMA, f8fma, "f8fma", 0, AARCH64_HWCAP2_F8FMA) \ + LINE(AARCH64_F8DP4, f8dp4, "f8dp4", 0, AARCH64_HWCAP2_F8DP4) \ + LINE(AARCH64_F8DP2, f8dp2, "f8dp2", 0, AARCH64_HWCAP2_F8DP2) \ + LINE(AARCH64_F8E4M3, f8e4m3, "f8e4m3", 0, AARCH64_HWCAP2_F8E4M3) \ + LINE(AARCH64_F8E5M2, f8e5m2, "f8e5m2", 0, AARCH64_HWCAP2_F8E5M2) \ + LINE(AARCH64_SME_LUTV2, smelutv2, "smelutv1", 0, AARCH64_HWCAP2_SME_LUTV2) \ + LINE(AARCH64_SME_F8F16, smef8f16, "smef8f16", 0, AARCH64_HWCAP2_SME_F8F16) \ + LINE(AARCH64_SME_F8F32, smef8f32, "smef8f32", 0, AARCH64_HWCAP2_SME_F8F32) \ + LINE(AARCH64_SME_SF8FMA, smesf8fma, "smesf8fma", 0, \ + AARCH64_HWCAP2_SME_SF8FMA) \ + LINE(AARCH64_SME_SF8DP4, smesf8dp4, "smesf8dp4", 0, \ + AARCH64_HWCAP2_SME_SF8DP4) \ + LINE(AARCH64_SME_SF8DP2, smesf8dp2, "smesf8dp2", 0, AARCH64_HWCAP2_SME_SF8DP2) #define INTROSPECTION_PREFIX Aarch64 #define INTROSPECTION_ENUM_PREFIX AARCH64 #include "define_introspection_and_hwcaps.inl" \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_cpuid.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_cpuid.c index 5ae3a1df7..92386cdcd 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_cpuid.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_cpuid.c @@ -2,10 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 #include "cpu_features_macros.h" +#include #ifdef CPU_FEATURES_ARCH_AARCH64 -#if (defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) || \ - defined(CPU_FEATURES_OS_ANDROID)) +#if (defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) || \ + defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)) #if (defined(CPU_FEATURES_COMPILER_GCC) || defined(CPU_FEATURES_COMPILER_CLANG)) #include "internal/cpuid_aarch64.h" @@ -16,9 +17,7 @@ uint64_t GetMidrEl1(void) { uint64_t midr_el1; - // clang-format off __asm("mrs %0, MIDR_EL1" : "=r"(midr_el1)); - // clang-format on return midr_el1; } #endif // CPU_FEATURES_MOCK_CPUID_AARCH64 @@ -27,6 +26,6 @@ uint64_t GetMidrEl1(void) #error "Unsupported compiler, aarch64 cpuid requires either GCC or Clang." #endif // (defined(CPU_FEATURES_COMPILER_GCC) || // defined(CPU_FEATURES_COMPILER_CLANG)) -#endif // (defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) - // || defined(CPU_FEATURES_OS_ANDROID)) +#endif // (defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) + // || defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)) #endif // CPU_FEATURES_ARCH_AARCH64 \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_freebsd.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_freebsd_or_openbsd.c similarity index 86% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_freebsd.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_freebsd_or_openbsd.c index 7360da790..3a63c35fc 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_freebsd.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_freebsd_or_openbsd.c @@ -4,7 +4,7 @@ #include "cpu_features_macros.h" #ifdef CPU_FEATURES_ARCH_AARCH64 -#ifdef CPU_FEATURES_OS_FREEBSD +#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) #include "cpuinfo_aarch64.h" #include "internal/cpuid_aarch64.h" @@ -35,5 +35,5 @@ Aarch64Info GetAarch64Info(void) return info; } -#endif // CPU_FEATURES_OS_FREEBSD -#endif // CPU_FEATURES_ARCH_AARCH64 +#endif // CPU_FEATURES_OS_FREEBSD || CPU_FEATURES_OS_OPENBSD +#endif // CPU_FEATURES_ARCH_AARCH64 \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c index 9ac6a6107..3db3d27b2 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c @@ -129,7 +129,7 @@ PPCInfo GetPPCInfo(void) { /* * On Power feature flags aren't currently in cpuinfo so we only look at - * the auxilary vector. + * the auxiliary vector. */ PPCInfo info = kEmptyPPCInfo; const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/string_view.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/string_view.c index 3e8b8b8a5..e56055d1f 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/string_view.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/string_view.c @@ -119,7 +119,7 @@ static int ParsePositiveNumberWithBase(const StringView view, int base) int result = 0; StringView remainder = view; for (; remainder.size; - remainder = CpuFeatures_StringView_PopFront(remainder, 1)) + remainder = CpuFeatures_StringView_PopFront(remainder, 1)) { const int value = HexValue(CpuFeatures_StringView_Front(remainder)); if (value < 0 || value >= base) return -1; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c index fdbb1ba51..a559b4d78 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c @@ -148,7 +148,11 @@ static Node* CreatePrintfString(const char* format, ...) const int written = vsnprintf(ptr, gBumpAllocator.size, format, arglist); va_end(arglist); if (written < 0 || written >= (int)gBumpAllocator.size) internal_error(); - return CreateConstantString((char*)BA_Bump(written)); + // `vsnprintf` does not set `\0` when no characters are to be written. + if (written == 0) *ptr = '\0'; + // `vsnprintf` returns the number of printed characters excluding `\0`. + const int null_terminated_written = written + 1; + return CreateConstantString((char*)BA_Bump(null_terminated_written)); } // Adds a string node. diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt index 71ae6527c..01a67a026 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt @@ -28,7 +28,7 @@ target_link_libraries(stack_line_reader_for_test string_view filesystem_for_test add_library(all_libraries ../src/hwcaps.c ../src/hwcaps_linux_or_android.c - ../src/hwcaps_freebsd.c + ../src/hwcaps_freebsd_or_openbsd.c ../src/stack_line_reader.c) target_link_libraries(all_libraries hwcaps_for_testing stack_line_reader string_view) @@ -84,7 +84,7 @@ if(PROCESSOR_IS_AARCH64) ../src/impl_aarch64_linux_or_android.c ../src/impl_aarch64_windows.c ../src/impl_aarch64_macos_or_iphone.c - ../src/impl_aarch64_freebsd.c + ../src/impl_aarch64_freebsd_or_openbsd.c ) if(APPLE) target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_SYSCTL_AARCH64) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc index d6ac50110..c3f0dfc71 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc @@ -9,15 +9,15 @@ #if defined(CPU_FEATURES_OS_WINDOWS) #include "internal/windows_utils.h" #endif // CPU_FEATURES_OS_WINDOWS -#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) +#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) || defined(CPU_FEATURES_OS_LINUX) #include "internal/cpuid_aarch64.h" -#endif // defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) +#endif // defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) || defined(CPU_FEATURES_OS_LINUX) namespace cpu_features { class FakeCpuAarch64 { -#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) +#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) || defined(CPU_FEATURES_OS_LINUX) public: uint64_t GetMidrEl1() const { return _midr_el1; } @@ -87,11 +87,8 @@ static FakeCpuAarch64& cpu() } // Define OS dependent mock functions -#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) -extern "C" uint64_t GetMidrEl1(void) -{ - return cpu().GetMidrEl1(); -} +#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) || defined(CPU_FEATURES_OS_LINUX) +extern "C" uint64_t GetMidrEl1(void) { return cpu().GetMidrEl1(); } #elif defined(CPU_FEATURES_OS_MACOS) extern "C" bool GetDarwinSysCtlByName(const char* name) { @@ -137,7 +134,7 @@ TEST_F(CpuidAarch64Test, Aarch64FeaturesEnum) const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_); EXPECT_STREQ(last_name, "unknown_feature"); for (int i = static_cast(AARCH64_FP); - i != static_cast(AARCH64_LAST_); ++i) + i != static_cast(AARCH64_LAST_); ++i) { const auto feature = static_cast(i); const char* name = GetAarch64FeaturesEnumName(feature); @@ -148,7 +145,7 @@ TEST_F(CpuidAarch64Test, Aarch64FeaturesEnum) } // AT_HWCAP tests -#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD) +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) TEST_F(CpuidAarch64Test, FromHardwareCap) { ResetHwcaps(); @@ -218,7 +215,7 @@ TEST_F(CpuidAarch64Test, FromHardwareCap2) EXPECT_FALSE(info.features.dgh); EXPECT_FALSE(info.features.rng); } -#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD) +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) // OS dependent tests #if defined(CPU_FEATURES_OS_LINUX) @@ -324,6 +321,26 @@ CPU revision : 3)"); EXPECT_FALSE(info.features.smebi32i32); EXPECT_FALSE(info.features.smeb16b16); EXPECT_FALSE(info.features.smef16f16); + EXPECT_FALSE(info.features.mops); + EXPECT_FALSE(info.features.hbc); + EXPECT_FALSE(info.features.sveb16b16); + EXPECT_FALSE(info.features.lrcpc3); + EXPECT_FALSE(info.features.lse128); + EXPECT_FALSE(info.features.fpmr); + EXPECT_FALSE(info.features.lut); + EXPECT_FALSE(info.features.faminmax); + EXPECT_FALSE(info.features.f8cvt); + EXPECT_FALSE(info.features.f8fma); + EXPECT_FALSE(info.features.f8dp4); + EXPECT_FALSE(info.features.f8dp2); + EXPECT_FALSE(info.features.f8e4m3); + EXPECT_FALSE(info.features.f8e5m2); + EXPECT_FALSE(info.features.smelutv2); + EXPECT_FALSE(info.features.smef8f16); + EXPECT_FALSE(info.features.smef8f32); + EXPECT_FALSE(info.features.smesf8fma); + EXPECT_FALSE(info.features.smesf8dp4); + EXPECT_FALSE(info.features.smesf8dp2); } #elif defined(CPU_FEATURES_OS_MACOS) TEST_F(CpuidAarch64Test, FromDarwinSysctlFromName) @@ -411,7 +428,7 @@ TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4) EXPECT_FALSE(info.features.jscvt); EXPECT_FALSE(info.features.lrcpc); } -#elif defined(CPU_FEATURES_OS_FREEBSD) +#elif defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_OPENBSD) TEST_F(CpuidAarch64Test, MrsMidrEl1_RPI4) { ResetHwcaps(); @@ -445,4 +462,4 @@ TEST_F(CpuidAarch64Test, MrsMidrEl1_RPI4) } #endif // CPU_FEATURES_OS_FREEBSD } // namespace -} // namespace cpu_features +} // namespace cpu_features \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_mips_test.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_mips_test.cc index bcad73616..8808e0e8b 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_mips_test.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_mips_test.cc @@ -116,7 +116,7 @@ TEST(CpuinfoMipsTest, Goldfish) auto& fs = GetEmptyFilesystem(); fs.CreateFile("/proc/cpuinfo", R"(system type : MIPS-Goldfish Hardware : goldfish -Revison : 1 +Revision : 1 processor : 0 cpu model : MIPS 24Kc V0.0 FPU V0.0 BogoMIPS : 1042.02 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml index 35d33f174..b05e1057b 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs.xml @@ -175,4 +175,51 @@ 64 + + + + + tmpl/ currently assumes that every arch.name starting with "rv" requires + RVV intrinsics + + + There is currently no mechanism in RISC-V to append extensions, + so each arch needs to specify all of them, and the order needs in the + machine definition needs to be from the fewest to the most extensions. + Fortunately, this maps quite well to the profiles concept. + + + + -march=rv64gcv + -march=rv64gcv + + + + + -march=rv64gcv + -march=rv64gcv + + It's unclear how performance portable segmented load/stores are, so the + default rvv implementations avoid using them. + This is a pseudo arch for separate segmented load/store implementations, + and is expected to never be used standalone without "rvv". + + + + + google/cpu_features currently doesn't support these extensions and profiles. + + + + + diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs_old.xml b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs_old.xml index 13dcea3d4..f7f23f059 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs_old.xml +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/archs_old.xml @@ -293,4 +293,23 @@ 64 + + + + + -march=rv64gcv + -march=rv64gcv + + + + -march=rv64gcv + -march=rv64gcv + + It's unclear how performance portable segmented load/stores are, so the + default rvv implementations avoid using them. + This is a pseudo arch for separate segmented load/store implementations, + and is expected to never be used standalone without "rvv". + + + diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml index 1c2917313..ee6bd3ea5 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/gen/machines.xml @@ -31,6 +31,22 @@ generic 32|64| mmx| sse sse2 sse3 ssse3 orc| + +generic riscv64 orc| + + + +generic riscv64 rvv rvvseg orc| + + + + + + generic 32|64| mmx| sse sse2 sse3 sse4_a popcount orc| diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_index_max_32u.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_index_max_32u.h index 8d2ae5c1f..6f8b57b3e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_index_max_32u.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_index_max_32u.h @@ -534,4 +534,48 @@ static inline void volk_gnsssdr_32f_index_max_32u_neon(uint32_t* target, const f #endif /* LV_HAVE_NEON */ +#ifdef LV_HAVE_RVV +#include + +static inline void volk_gnsssdr_32f_index_max_32u_rvv(uint32_t* target, const float* src0, uint32_t num_points) +{ + if (num_points == 0) + { + return; + } + float max_val = src0[0]; + uint32_t max_idx = 0; + size_t vl; + + // Process in chunks + for (size_t i = 0; i < num_points; i += vl) + { + // Set vector length for this iteration + vl = __riscv_vsetvl_e32m1(num_points - i); + + // Load vector of values + vfloat32m1_t v_vals = __riscv_vle32_v_f32m1(&src0[i], vl); + + // Process each element in the vector + for (size_t j = 0; j < vl; j++) + { + float val = __riscv_vfmv_f_s_f32m1_f32(v_vals); + if (val > max_val) + { + max_val = val; + max_idx = i + j; + } + // Shift to next element by reloading + if (j + 1 < vl) + { + v_vals = __riscv_vle32_v_f32m1(&src0[i + j + 1], vl - j - 1); + } + } + } + + target[0] = max_idx; +} + +#endif /* LV_HAVE_RVV */ + #endif /* INCLUDED_volk_gnsssdr_32f_index_max_32u_H */ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt index 2562bd90c..7e8d6642f 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt @@ -4,6 +4,7 @@ # SPDX-FileCopyrightText: 2010-2021 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause +include(XcodeRemoveWarningDuplicates) ######################################################################## # header file detection @@ -102,12 +103,27 @@ execute_process( OUTPUT_VARIABLE arch_flag_lines OUTPUT_STRIP_TRAILING_WHITESPACE ) +try_compile( + HAVE_RVV_INTRINSICS + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/cmake/Checks/check-rvv-intrinsics.c +) +if(HAVE_RVV_INTRINSICS) + message(STATUS "Checking RVV intrinsics - found") +else() + message(STATUS "Checking RVV intrinsics - not found") +endif() + macro(check_arch arch_name) set(flags ${ARGN}) set(have_${arch_name} TRUE) + string(SUBSTRING "${arch_name}" 0 2 arch_prefix) foreach(flag ${flags}) if(MSVC AND (${flag} STREQUAL "/arch:SSE2" OR ${flag} STREQUAL "/arch:SSE")) # SSE/SSE2 is supported in MSVC since VS 2005 but flag not available when compiling 64-bit so do not check + elseif("${arch_prefix}" STREQUAL "rv" AND NOT HAVE_RVV_INTRINSICS) + message(STATUS "Skipping ${arch_name} due to missing RVV intrinsics support") + set(have_${arch_name} FALSE) else() include(CheckCXXCompilerFlag) set(have_flag have${flag}) @@ -256,24 +272,43 @@ endif() ######################################################################## if(NOT CROSSCOMPILE_MULTILIB AND CPU_IS_x86) include(CheckTypeSize) - check_type_size("void*[8]" SIZEOF_CPU BUILTIN_TYPES_ONLY) - if(${SIZEOF_CPU} EQUAL 64) - overrule_arch(32 "CPU width is 64 bits") - endif() - if(${SIZEOF_CPU} EQUAL 32) - overrule_arch(64 "CPU width is 32 bits") + if(CMAKE_VERSION VERSION_LESS 3.10) + check_type_size("void*[8]" SIZEOF_CPU BUILTIN_TYPES_ONLY) + if(${SIZEOF_CPU} EQUAL 64) + overrule_arch(32 "CPU width is 64 bits") + endif() + if(${SIZEOF_CPU} EQUAL 32) + overrule_arch(64 "CPU width is 32 bits") + endif() + else() + cmake_host_system_information(RESULT ASSUME_64BIT_HOST QUERY IS_64BIT) + if(ASSUME_64BIT_HOST) + overrule_arch(32 "CPU width is 64 bits") + else() + overrule_arch(64 "CPU width is 32 bits") + endif() endif() # MSVC 64 bit does not have MMX, overrule it if(MSVC) - if(${SIZEOF_CPU} EQUAL 64) - overrule_arch(mmx "No MMX for Win64") + if(CMAKE_VERSION VERSION_LESS 3.10) + if(${SIZEOF_CPU} EQUAL 64) + overrule_arch(mmx "No MMX for Win64") + endif() + else() + if(ASSUME_64BIT_HOST) + overrule_arch(mmx "No MMX for Win64") + endif() endif() force_arch(sse "Built-in for MSVC > 2013") force_arch(sse2 "Built-in for MSVC > 2013") endif() endif() +if(NOT ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^riscv64$") + overrule_arch(riscv64 "machine is not riscv64") +endif() + ######################################################################## # done overrules! print the result ######################################################################## @@ -595,6 +630,9 @@ if(NOT (ENABLE_STATIC_LIBS AND (CMAKE_GENERATOR STREQUAL Xcode))) else() target_link_libraries(volk_gnsssdr PUBLIC ${volk_gnsssdr_libraries}) endif() + + xcode_remove_warning_duplicates(volk_gnsssdr) + target_include_directories(volk_gnsssdr PUBLIC $ PUBLIC $ @@ -632,8 +670,8 @@ if(NOT (ENABLE_STATIC_LIBS AND (CMAKE_GENERATOR STREQUAL Xcode))) # Install locations install(TARGETS volk_gnsssdr EXPORT VOLK_GNSSSDR-export - LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT "volk_gnsssdr_runtime" # .so file - ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "volk_gnsssdr_devel" # .lib file + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT "volk_gnsssdr_runtime" # .so file + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT "volk_gnsssdr_devel" # .lib file RUNTIME DESTINATION bin COMPONENT "volk_gnsssdr_runtime" # .dll file ) endif() @@ -676,9 +714,11 @@ if(ENABLE_STATIC_LIBS) ) set_target_properties(volk_gnsssdr_static PROPERTIES OUTPUT_NAME volk_gnsssdr) + xcode_remove_warning_duplicates(volk_gnsssdr_static) + install(TARGETS volk_gnsssdr_static EXPORT VOLK_GNSSSDR-export - ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "volk_gnsssdr_devel" + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT "volk_gnsssdr_devel" ) endif() @@ -702,6 +742,9 @@ if(ENABLE_TESTING) TARGET_DEPS volk_gnsssdr ) endif() + + xcode_remove_warning_duplicates(volk_gnsssdr_test_all) + foreach(kernel ${h_files}) get_filename_component(kernel ${kernel} NAME) string(REPLACE ".h" "" kernel ${kernel}) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc index 9c961cee0..278b63348 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc @@ -237,7 +237,7 @@ std::vector split_signature(const std::string &protokernel_signatur } } // Get the last one to the end of the string - signature_tokens.push_back(token); + signature_tokens.push_back(std::move(token)); return signature_tokens; } @@ -527,8 +527,8 @@ bool run_volk_gnsssdr_tests(volk_gnsssdr_func_desc_t desc, std::vector *results, std::string puppet_master_name) { - return run_volk_gnsssdr_tests(desc, manual_func, name, test_params.tol(), test_params.scalar(), - test_params.vlen(), test_params.iter(), results, puppet_master_name, + return run_volk_gnsssdr_tests(desc, manual_func, std::move(name), test_params.tol(), test_params.scalar(), + test_params.vlen(), test_params.iter(), results, std::move(puppet_master_name), test_params.benchmark_mode()); } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h index 1bfd1c991..766f24c0e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.h @@ -70,7 +70,7 @@ private: public: // ctor volk_gnsssdr_test_params_t(float tol, lv_32fc_t scalar, unsigned int vlen, unsigned int iter, - bool benchmark_mode, std::string kernel_regex) : _tol(tol), _scalar(scalar), _vlen(vlen), _iter(iter), _benchmark_mode(benchmark_mode), _kernel_regex(std::move(kernel_regex)){}; + bool benchmark_mode, std::string kernel_regex) : _tol(tol), _scalar(scalar), _vlen(vlen), _iter(iter), _benchmark_mode(benchmark_mode), _kernel_regex(std::move(kernel_regex)) {}; // setters void set_tol(float tol) { _tol = tol; }; void set_scalar(lv_32fc_t scalar) { _scalar = scalar; }; @@ -104,10 +104,10 @@ public: volk_gnsssdr_test_params_t test_parameters() { return _test_parameters; }; // normal ctor volk_gnsssdr_test_case_t(volk_gnsssdr_func_desc_t desc, void (*kernel_ptr)(), std::string name, - volk_gnsssdr_test_params_t test_parameters) : _desc(desc), _kernel_ptr(kernel_ptr), _name(std::move(name)), _test_parameters(std::move(test_parameters)), _puppet_master_name("NULL"){}; + volk_gnsssdr_test_params_t test_parameters) : _desc(desc), _kernel_ptr(kernel_ptr), _name(std::move(name)), _test_parameters(std::move(test_parameters)), _puppet_master_name("NULL") {}; // ctor for puppets volk_gnsssdr_test_case_t(volk_gnsssdr_func_desc_t desc, void (*kernel_ptr)(), std::string name, - std::string puppet_master_name, volk_gnsssdr_test_params_t test_parameters) : _desc(desc), _kernel_ptr(kernel_ptr), _name(std::move(name)), _test_parameters(std::move(test_parameters)), _puppet_master_name(std::move(puppet_master_name)){}; + std::string puppet_master_name, volk_gnsssdr_test_params_t test_parameters) : _desc(desc), _kernel_ptr(kernel_ptr), _name(std::move(name)), _test_parameters(std::move(test_parameters)), _puppet_master_name(std::move(puppet_master_name)) {}; }; /************************************************ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_malloc.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_malloc.c index 4712f8561..83f5c505a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_malloc.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/volk_gnsssdr_malloc.c @@ -40,7 +40,7 @@ void *volk_gnsssdr_malloc(size_t size, size_t alignment) return NULL; } // Tweak size to satisfy ASAN (the GCC address sanitizer). - // Calling 'volk_gnsssdr_malloc' might therefor result in the allocation of more memory than + // Calling 'volk_gnsssdr_malloc' might therefore result in the allocation of more memory than // requested for correct alignment. Any allocation size change here will in general not // impact the end result since initial size alignment is required either way. if (size % alignment) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr.pc.in b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr.pc.in index 743b1c024..c525b0343 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr.pc.in +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr.pc.in @@ -1,9 +1,9 @@ # SPDX-FileCopyrightText: 2014 Carles Fernandez-Prades # SPDX-License-Identifier: GPL-3.0-or-later -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ LV_CXXFLAGS=@LV_CXXFLAGS@ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c index c089e8625..856364923 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c @@ -61,7 +61,7 @@ static int i_can_has_${arch.name} (void) { #if defined(CPU_FEATURES_ARCH_S390X) if (GetS390XInfo().features.${check} == 0){ return 0; } #endif - %elif "riscv" in arch.name: + %elif "riscv" in arch.name or arch.name[:2] == "rv": #if defined(CPU_FEATURES_ARCH_RISCV) if (GetRiscvInfo().features.${check} == 0){ return 0; } #endif diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.old.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.old.c index ab3de6694..58f506c7e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.old.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.old.c @@ -36,9 +36,7 @@ struct VOLK_CPU volk_gnsssdr_cpu; static inline unsigned long long _xgetbv(unsigned int index) { unsigned int eax, edx; - __VOLK_ASM __VOLK_VOLATILE("xgetbv" - : "=a"(eax), "=d"(edx) - : "c"(index)); + __VOLK_ASM __VOLK_VOLATILE("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); return ((unsigned long long)edx << 32) | eax; } #define __xgetbv() _xgetbv(0) diff --git a/src/algorithms/observables/adapters/CMakeLists.txt b/src/algorithms/observables/adapters/CMakeLists.txt index a4097a4dd..8417c1532 100644 --- a/src/algorithms/observables/adapters/CMakeLists.txt +++ b/src/algorithms/observables/adapters/CMakeLists.txt @@ -29,9 +29,15 @@ target_link_libraries(obs_adapters core_system_parameters PRIVATE gnss_sdr_flags - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(obs_adapters PRIVATE Glog::glog) + target_compile_definitions(obs_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(obs_adapters PRIVATE absl::flags absl::log) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(obs_adapters diff --git a/src/algorithms/observables/adapters/hybrid_observables.cc b/src/algorithms/observables/adapters/hybrid_observables.cc index fbb6ba2a3..ae28766ea 100644 --- a/src/algorithms/observables/adapters/hybrid_observables.cc +++ b/src/algorithms/observables/adapters/hybrid_observables.cc @@ -19,8 +19,14 @@ #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include "obs_conf.h" -#include #include // for operator<< +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif HybridObservables::HybridObservables(const ConfigurationInterface* configuration, const std::string& role, @@ -45,7 +51,11 @@ HybridObservables::HybridObservables(const ConfigurationInterface* configuration conf.always_output_gs = configuration->property("PVT.an_output_enabled", conf.always_output_gs) || configuration->property(role + ".always_output_gs", conf.always_output_gs); conf.enable_E6 = configuration->property("PVT.use_e6_for_pvt", conf.enable_E6); +#if USE_GLOG_AND_GFLAGS if (FLAGS_carrier_smoothing_factor == DEFAULT_CARRIER_SMOOTHING_FACTOR) +#else + if (absl::GetFlag(FLAGS_carrier_smoothing_factor) == DEFAULT_CARRIER_SMOOTHING_FACTOR) +#endif { conf.smoothing_factor = configuration->property(role + ".smoothing_factor", conf.smoothing_factor); } diff --git a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt index 225518612..a8964f90c 100644 --- a/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/observables/gnuradio_blocks/CMakeLists.txt @@ -31,12 +31,17 @@ target_link_libraries(obs_gr_blocks PRIVATE algorithms_libs core_system_parameters - Gflags::gflags - Glog::glog Matio::matio Gnuradio::pmt ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(obs_gr_blocks PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(obs_gr_blocks PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(obs_gr_blocks PRIVATE absl::flags absl::log) +endif() + target_include_directories(obs_gr_blocks PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc index a9bc19407..340c29fda 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc @@ -23,7 +23,6 @@ #include "gnss_sdr_filesystem.h" #include "gnss_sdr_make_unique.h" #include "gnss_synchro.h" -#include #include #include #include @@ -36,6 +35,12 @@ #include // for numeric_limits #include // for move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if PMT_USES_BOOST_ANY #include namespace wht = boost; @@ -607,7 +612,7 @@ void hybrid_observables_gs::set_tag_timestamp_in_sdr_timeframe(const std::vector // to an absolute GPS TOW samplestamp associated with the current set of pseudoranges if (!d_TimeChannelTagTimestamps.empty()) { - double fs = 0; + double fs = 0.0; std::vector::const_iterator it; for (it = data.begin(); it != data.end(); it++) { @@ -617,21 +622,24 @@ void hybrid_observables_gs::set_tag_timestamp_in_sdr_timeframe(const std::vector break; } } - + if (fs < 1.0) + { + return; + } double delta_rxtime_to_tag; GnssTime current_tag; do { current_tag = d_TimeChannelTagTimestamps.front(); delta_rxtime_to_tag = (static_cast(rx_clock) / fs) - current_tag.rx_time; // delta time relative to receiver's start time - if (delta_rxtime_to_tag >= 0) + if (delta_rxtime_to_tag >= 0.0) { d_TimeChannelTagTimestamps.pop(); } } - while (delta_rxtime_to_tag >= 0.1 and !d_TimeChannelTagTimestamps.empty()); + while (delta_rxtime_to_tag >= 0.1 && !d_TimeChannelTagTimestamps.empty()); - if (delta_rxtime_to_tag >= 0 and delta_rxtime_to_tag <= 0.1) + if (delta_rxtime_to_tag >= 0.0 && delta_rxtime_to_tag <= 0.1) { // std::cout << "[Time ch][" << delta_rxtime_to_tag // << "] OBS RX TimeTag Week: " << current_tag.week diff --git a/src/algorithms/observables/libs/obs_conf.cc b/src/algorithms/observables/libs/obs_conf.cc index 9c11be794..f89ae1be7 100644 --- a/src/algorithms/observables/libs/obs_conf.cc +++ b/src/algorithms/observables/libs/obs_conf.cc @@ -18,6 +18,12 @@ #include "obs_conf.h" #include "gnss_sdr_flags.h" +#if USE_GLOG_AND_GFLAGS Obs_Conf::Obs_Conf() : smoothing_factor(FLAGS_carrier_smoothing_factor) { } +#else +Obs_Conf::Obs_Conf() : smoothing_factor(absl::GetFlag(FLAGS_carrier_smoothing_factor)) +{ +} +#endif \ No newline at end of file diff --git a/src/algorithms/resampler/adapters/CMakeLists.txt b/src/algorithms/resampler/adapters/CMakeLists.txt index ac4eca082..0cda783f8 100644 --- a/src/algorithms/resampler/adapters/CMakeLists.txt +++ b/src/algorithms/resampler/adapters/CMakeLists.txt @@ -38,11 +38,16 @@ target_link_libraries(resampler_adapters PUBLIC resampler_gr_blocks PRIVATE - Gflags::gflags - Glog::glog Volk::volk ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(resampler_adapters PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(resampler_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(resampler_adapters PRIVATE absl::flags absl::log) +endif() + target_include_directories(resampler_adapters PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/resampler/adapters/direct_resampler_conditioner.cc b/src/algorithms/resampler/adapters/direct_resampler_conditioner.cc index bffa67680..444f1ed19 100644 --- a/src/algorithms/resampler/adapters/direct_resampler_conditioner.cc +++ b/src/algorithms/resampler/adapters/direct_resampler_conditioner.cc @@ -20,13 +20,18 @@ #include "direct_resampler_conditioner_cb.h" #include "direct_resampler_conditioner_cc.h" #include "direct_resampler_conditioner_cs.h" -#include #include #include // for lv_8sc_t #include #include #include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif DirectResamplerConditioner::DirectResamplerConditioner( const ConfigurationInterface* configuration, @@ -39,7 +44,7 @@ DirectResamplerConditioner::DirectResamplerConditioner( dump_(configuration->property(role + ".dump", false)) { const std::string default_item_type("short"); - const std::string default_dump_file("./data/signal_conditioner.dat"); + const std::string default_dump_file("./resampler.dat"); const double fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000.0); const double fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); item_type_ = configuration->property(role + ".item_type", default_item_type); diff --git a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc index 7ee86662f..09dafa8b6 100644 --- a/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc +++ b/src/algorithms/resampler/adapters/mmse_resampler_conditioner.cc @@ -17,12 +17,18 @@ #include "mmse_resampler_conditioner.h" #include "configuration_interface.h" -#include #include #include #include +#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + MmseResamplerConditioner::MmseResamplerConditioner( const ConfigurationInterface* configuration, const std::string& role, @@ -34,7 +40,7 @@ MmseResamplerConditioner::MmseResamplerConditioner( dump_(configuration->property(role + ".dump", false)) { const std::string default_item_type("gr_complex"); - const std::string default_dump_file("./data/signal_conditioner.dat"); + const std::string default_dump_file("./resampler.dat"); const double fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", 2048000.0); const double fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); item_type_ = configuration->property(role + ".item_type", default_item_type); diff --git a/src/algorithms/resampler/gnuradio_blocks/direct_resampler_conditioner_cc.h b/src/algorithms/resampler/gnuradio_blocks/direct_resampler_conditioner_cc.h index 0eb081643..69069fefa 100644 --- a/src/algorithms/resampler/gnuradio_blocks/direct_resampler_conditioner_cc.h +++ b/src/algorithms/resampler/gnuradio_blocks/direct_resampler_conditioner_cc.h @@ -8,7 +8,7 @@ * This block takes in a signal stream and performs direct resampling. * The theory behind this block can be found in Chapter 7.5 of the following * book: - * R. Lyons, Undestanding Digital Signal Processing, 3rd ed., Pearson Education, + * R. Lyons, Understanding Digital Signal Processing, 3rd ed., Pearson Education, * 2010. * * ----------------------------------------------------------------------------- diff --git a/src/algorithms/signal_generator/adapters/CMakeLists.txt b/src/algorithms/signal_generator/adapters/CMakeLists.txt index c430af3c2..b7f8c1537 100644 --- a/src/algorithms/signal_generator/adapters/CMakeLists.txt +++ b/src/algorithms/signal_generator/adapters/CMakeLists.txt @@ -27,11 +27,16 @@ target_link_libraries(signal_generator_adapters Gnuradio::pmt signal_generator_gr_blocks PRIVATE - Gflags::gflags - Glog::glog core_system_parameters ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(signal_generator_adapters PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(signal_generator_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(signal_generator_adapters PRIVATE absl::flags absl::log) +endif() + target_include_directories(signal_generator_adapters PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/signal_generator/adapters/signal_generator.cc b/src/algorithms/signal_generator/adapters/signal_generator.cc index 841cbfe3f..c5d745689 100644 --- a/src/algorithms/signal_generator/adapters/signal_generator.cc +++ b/src/algorithms/signal_generator/adapters/signal_generator.cc @@ -25,10 +25,14 @@ #include "Galileo_E5b.h" #include "Galileo_E6.h" #include "configuration_interface.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif SignalGenerator::SignalGenerator(const ConfigurationInterface* configuration, const std::string& role, unsigned int in_stream, diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index afbf36296..48e18e5f3 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -25,6 +25,14 @@ if(ENABLE_PLUTOSDR) set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad936x_custom_signal_source.h) endif() +if(ENABLE_AD936X_SDR AND NOT ENABLE_PLUTOSDR) + ############################################## + # CUSTOM AD936X IIO SOURCE + ############################################## + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ad936x_custom_signal_source.cc) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad936x_custom_signal_source.h) +endif() + if(ENABLE_FMCOMMS2) ############################################### # FMCOMMS2 based SDR Hardware @@ -37,8 +45,26 @@ if(ENABLE_AD9361) ############################################### # AD9361 DIRECT TO FPGA Hardware ############################################### - list(APPEND OPT_DRIVER_SOURCES ad9361_fpga_signal_source.cc) - list(APPEND OPT_DRIVER_HEADERS ad9361_fpga_signal_source.h) + list(APPEND OPT_DRIVER_SOURCES adrv9361_z7035_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS adrv9361_z7035_signal_source_fpga.h) + list(APPEND OPT_DRIVER_SOURCES fmcomms5_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS fmcomms5_signal_source_fpga.h) +endif() + +if(ENABLE_MAX2771) + ############################################### + # MAX2771 EVKIT DIRECT TO FPGA Hardware + ############################################### + list(APPEND OPT_DRIVER_SOURCES max2771_evkit_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS max2771_evkit_signal_source_fpga.h) +endif() + +if(ENABLE_DMA_PROXY) + ############################################### + # FPGA DMA source + ############################################### + list(APPEND OPT_DRIVER_SOURCES dma_signal_source_fpga.cc) + list(APPEND OPT_DRIVER_HEADERS dma_signal_source_fpga.h) endif() if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND) @@ -85,6 +111,11 @@ if(ENABLE_ZMQ) list(APPEND OPT_DRIVER_HEADERS zmq_signal_source.h) endif() +if(ENABLE_ION) + list(APPEND OPT_DRIVER_SOURCES ion_gsms_signal_source.cc) + list(APPEND OPT_DRIVER_HEADERS ion_gsms_signal_source.h) +endif() + set(SIGNAL_SOURCE_ADAPTER_SOURCES signal_source_base.cc file_source_base.cc @@ -151,7 +182,7 @@ target_include_directories(signal_source_adapters ${GNSSSDR_SOURCE_DIR}/src/core/interfaces ) -if(ENABLE_FPGA OR ENABLE_AD9361) +if(ENABLE_FPGA OR ENABLE_AD9361 OR ENABLE_ION) target_link_libraries(signal_source_adapters PUBLIC signal_source_libs @@ -169,10 +200,16 @@ target_link_libraries(signal_source_adapters algorithms_libs gnss_sdr_flags core_system_parameters - Glog::glog Volk::volk ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(signal_source_adapters PRIVATE Glog::glog) + target_compile_definitions(signal_source_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(signal_source_adapters PRIVATE absl::flags absl::log) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(signal_source_adapters PUBLIC -DGNURADIO_USES_STD_POINTERS=1 @@ -215,14 +252,14 @@ if(ENABLE_LIMESDR AND GRLIMESDR_FOUND) ) endif() -if(ENABLE_AD9361 AND LIBIIO_FOUND) +if(LIBIIO_FOUND) target_link_libraries(signal_source_adapters PRIVATE Iio::iio ) endif() -if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR) +if(ENABLE_AD9361 OR ENABLE_FMCOMMS2 OR ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR) if(LIBAD9361_VERSION) if(LIBAD9361_VERSION VERSION_GREATER 0.1) target_compile_definitions(signal_source_adapters diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc deleted file mode 100644 index 488c80ead..000000000 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ /dev/null @@ -1,867 +0,0 @@ -/*! - * \file ad9361_fpga_signal_source.cc - * \brief signal source for Analog Devices front-end AD9361 connected directly - * to FPGA accelerators. - * This source implements only the AD9361 control. It is NOT compatible with - * conventional SDR acquisition and tracking blocks. - * Please use the fmcomms2 source if conventional SDR acquisition and tracking - * is selected in the configuration file. - * \authors
      - *
    • Javier Arribas, jarribas(at)cttc.es - *
    • Marc Majoral, mmajoral(at)cttc.es - *
    - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * ----------------------------------------------------------------------------- - */ - -#include "ad9361_fpga_signal_source.h" -#include "GPS_L1_CA.h" -#include "GPS_L5.h" -#include "ad9361_manager.h" -#include "command_event.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" -#include "gnss_sdr_string_literals.h" -#include "uio_fpga.h" -#include -#include -#include // for std::max -#include // for std::chrono -#include // for std::floor -#include // for std::exception -#include // for open, O_WRONLY -#include // for std::ifstream -#include // for std::setprecision -#include // for std::cout -#include // for write -#include // fr std::vector - - -using namespace std::string_literals; - -Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *configuration, - const std::string &role, unsigned int in_stream, unsigned int out_stream, - Concurrent_Queue *queue __attribute__((unused))) - : SignalSourceBase(configuration, role, "Ad9361_Fpga_Signal_Source"s), - queue_(queue), - gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)), - gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), - rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), - filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), - filename0_(configuration->property(role + ".filename", empty_string)), - rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), - rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), - scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), - phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), - tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), - freq0_(configuration->property(role + ".freq", 0)), - freq1_(configuration->property(role + ".freq1", static_cast(GPS_L5_FREQ_HZ))), - sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), - bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), - samples_to_skip_(0), - samples_(configuration->property(role + ".samples", static_cast(0))), - freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), - freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), - tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), - Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), - Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), - num_input_files_(1), - dma_buff_offset_pos_(0), - in_stream_(in_stream), - out_stream_(out_stream), - switch_position_(configuration->property(role + ".switch_position", 0)), - item_size_(sizeof(int8_t)), - enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)), - filter_auto_(configuration->property(role + ".filter_auto", false)), - quadrature_(configuration->property(role + ".quadrature", true)), - rf_dc_(configuration->property(role + ".rf_dc", true)), - bb_dc_(configuration->property(role + ".bb_dc", true)), - rx1_enable_(configuration->property(role + ".rx1_enable", true)), - rx2_enable_(configuration->property(role + ".rx2_enable", true)), - enable_DMA_(false), - enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), - enable_ovf_check_buffer_monitor_active_(false), - dump_(configuration->property(role + ".dump", false)), - rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)), - repeat_(configuration->property(role + ".repeat", false)) -{ - const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.0); - const size_t header_size = configuration->property(role + ".header_size", 0); - - const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || - (configuration->property("Channels_1B.count", 0) > 0)); - const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || - (configuration->property("Channels_L5.count", 0) > 0) || - (configuration->property("Channels_5X.count", 0) > 0)); - - const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1; - if (freq0_ == 0) - { - // use ".freq0" - freq0_ = configuration->property(role + ".freq0", static_cast(GPS_L1_FREQ_HZ)); - } - - if (filter_auto_) - { - filter_source_ = configuration->property(role + ".filter_source", std::string("Auto")); - } - else - { - filter_source_ = configuration->property(role + ".filter_source", std::string("Off")); - } - - // override value with commandline flag, if present - if (FLAGS_signal_source != "-") - { - filename0_ = FLAGS_signal_source; - } - if (FLAGS_s != "-") - { - filename0_ = FLAGS_s; - } - - if (filename0_.empty()) - { - num_input_files_ = 2; - filename0_ = configuration->property(role + ".filename0", empty_string); - filename1_ = configuration->property(role + ".filename1", empty_string); - } - // if only one input file is specified in the configuration file then: - // if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels - // otherwise the DMA transfers the samples to the L2/L5 frequency band channels - // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. - if (filename1_.empty()) - { - if (enable_rx1_band) - { - dma_buff_offset_pos_ = 2; - } - } - else - { - dma_buff_offset_pos_ = 2; - } - - if (seconds_to_skip > 0) - { - samples_to_skip_ = static_cast(seconds_to_skip * sample_rate_) * 2; - } - if (header_size > 0) - { - samples_to_skip_ += header_size; - } - - std::string device_io_name; // Switch UIO device file - // find the uio device file corresponding to the switch. - if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << switch_device_name << '\n'; - return; - } - - if (switch_position_ != 0 && switch_position_ != 2) - { - std::cout << "SignalSource.switch_position configuration parameter must be either 0: read from file(s) via DMA, or 2: read from AD9361\n"; - std::cout << "SignalSource.switch_position configuration parameter set to its default value switch_position=0 - read from file(s)\n"; - switch_position_ = 0; - } - - switch_fpga = std::make_shared(device_io_name); - switch_fpga->set_switch_position(switch_position_); - - if (switch_position_ == 0) // Inject file(s) via DMA - { - enable_DMA_ = true; - - if (samples_ == 0) // read all file - { - /*! - * BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File. - * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the - * valve block - */ - std::ifstream file(filename0_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - std::ifstream::pos_type size; - - if (file.is_open()) - { - size = file.tellg(); - DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); - } - else - { - std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n'; - return; - } - std::streamsize ss = std::cout.precision(); - std::cout << std::setprecision(16); - std::cout << "Processing file " << filename0_ << ", which contains " << static_cast(size) << " [bytes]\n"; - std::cout.precision(ss); - - if (size > 0) - { - const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; - const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; - samples_ = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms - } - - if (!filename1_.empty()) - { - std::ifstream file(filename1_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - std::ifstream::pos_type size; - - if (file.is_open()) - { - size = file.tellg(); - DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); - } - else - { - std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n'; - return; - } - std::streamsize ss = std::cout.precision(); - std::cout << std::setprecision(16); - std::cout << "Processing file " << filename1_ << ", which contains " << static_cast(size) << " [bytes]\n"; - std::cout.precision(ss); - - int64_t samples_rx2 = 0; - if (size > 0) - { - const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; - const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; - samples_rx2 = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms - } - samples_ = std::min(samples_, samples_rx2); - } - } - - CHECK(samples_ > 0) << "File does not contain enough samples to process."; - double signal_duration_s = (static_cast(samples_) * (1 / static_cast(sample_rate_))) / 2.0; - - DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; - std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; - - if (filename1_.empty()) - { - DLOG(INFO) << "File source filename " << filename0_; - } - else - { - DLOG(INFO) << "File source filename rx1 " << filename0_; - DLOG(INFO) << "File source filename rx2 " << filename1_; - } - DLOG(INFO) << "Samples " << samples_; - DLOG(INFO) << "Sampling frequency " << sample_rate_; - DLOG(INFO) << "Item type " << std::string("ibyte"); - DLOG(INFO) << "Item size " << item_size_; - DLOG(INFO) << "Repeat " << repeat_; - } - if (switch_position_ == 2) // Real-time via AD9361 - { - std::cout << "Sample rate: " << sample_rate_ << " Sps\n"; - - enable_ovf_check_buffer_monitor_active_ = false; // check buffer overflow and buffer monitor disabled by default - - // some basic checks - if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2")) - { - std::cout << "Configuration parameter rf_port_select should take one of these values:\n"; - std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2\n"; - std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << '\n'; - rf_port_select_ = default_rf_port_select; - LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=" << default_rf_port_select; - } - - if ((gain_mode_rx1_ != "manual") && (gain_mode_rx1_ != "slow_attack") && (gain_mode_rx1_ != "fast_attack") && (gain_mode_rx1_ != "hybrid")) - { - std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:\n"; - std::cout << " manual, slow_attack, fast_attack, hybrid\n"; - std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << '\n'; - gain_mode_rx1_ = default_gain_mode; - LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; - } - - if ((gain_mode_rx2_ != "manual") && (gain_mode_rx2_ != "slow_attack") && (gain_mode_rx2_ != "fast_attack") && (gain_mode_rx2_ != "hybrid")) - { - std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:\n"; - std::cout << " manual, slow_attack, fast_attack, hybrid\n"; - std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << '\n'; - gain_mode_rx2_ = default_gain_mode; - LOG(WARNING) << "Invalid configuration value for gain_mode_rx2 parameter. Set to gain_mode_rx2=" << default_gain_mode; - } - - if (gain_mode_rx1_ == "manual") - { - if (rf_gain_rx1_ > 73.0 || rf_gain_rx1_ < -1.0) - { - std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB\n"; - std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << '\n'; - rf_gain_rx1_ = default_manual_gain_rx1; - LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=" << default_manual_gain_rx1; - } - } - - if (gain_mode_rx2_ == "manual") - { - if (rf_gain_rx2_ > 73.0 || rf_gain_rx2_ < -1.0) - { - std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB\n"; - std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << '\n'; - rf_gain_rx2_ = default_manual_gain_rx2; - LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=" << default_manual_gain_rx2; - } - } - - if ((filter_source_ != "Off") && (filter_source_ != "Auto") && (filter_source_ != "File") && (filter_source_ != "Design")) - { - std::cout << "Configuration parameter filter_source should take one of these values:\n"; - std::cout << " Off: Disable filter\n"; - std::cout << " Auto: Use auto-generated filters\n"; - std::cout << " File: User-provided filter in filter_filename parameter\n"; - std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters\n"; - std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value filter_source=Off\n"; - filter_source_ = std::string("Off"); - LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; - } - - if (bandwidth_ < 200000 || bandwidth_ > 56000000) - { - std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz\n"; - std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << '\n'; - bandwidth_ = default_bandwidth; - LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; - } - - std::cout << "LO frequency : " << freq0_ << " Hz\n"; - try - { - config_ad9361_rx_local(bandwidth_, - sample_rate_, - freq0_, - freq1_, - rf_port_select_, - rx1_enable_, - rx2_enable_, - gain_mode_rx1_, - gain_mode_rx2_, - rf_gain_rx1_, - rf_gain_rx2_, - quadrature_, - rf_dc_, - bb_dc_, - filter_source_, - filter_filename_, - Fpass_, - Fstop_); - } - catch (const std::runtime_error &e) - { - std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; - return; - } - // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION - if (enable_dds_lo_ == true) - { - if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_dds_tx_hz_) * 1.1)) || (tx_bandwidth_ < 200000) || (tx_bandwidth_ > 1000000)) - { - std::cout << "Configuration parameter tx_bandwidth value should be between " << std::max(static_cast(freq_dds_tx_hz_) * 1.1, 200000.0) << " and 1000000 Hz\n"; - std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value tx_bandwidth=500000\n"; - tx_bandwidth_ = 500000; - LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; - } - if (tx_attenuation_db_ > 0.0 || tx_attenuation_db_ < -89.75) - { - std::cout << "Configuration parameter tx_attenuation_db should take values between 0.0 and -89.95 in 0.25 dB steps\n"; - std::cout << "Error: provided value tx_attenuation_db=" << tx_attenuation_db_ << " is not among valid values\n"; - std::cout << " This parameter has been set to its default value tx_attenuation_db=" << default_tx_attenuation_db << '\n'; - tx_attenuation_db_ = default_tx_attenuation_db; - LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; - } - try - { - config_ad9361_lo_local(tx_bandwidth_, - sample_rate_, - freq_rf_tx_hz_, - tx_attenuation_db_, - freq_dds_tx_hz_, - scale_dds_dbfs_, - phase_dds_deg_); - } - catch (const std::runtime_error &e) - { - std::cerr << "Exception cached when configuring the TX carrier: " << e.what() << '\n'; - return; - } - } - - // when the receiver is working in real-time mode via AD9361 perform buffer overflow checking, - // and if dump is enabled perform buffer monitoring - enable_ovf_check_buffer_monitor_active_ = true; - - std::string device_io_name_buffer_monitor; - - std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); - - // find the uio device file corresponding to the buffer monitor - if (find_uio_dev_file_name(device_io_name_buffer_monitor, buffer_monitor_device_name, 0) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << buffer_monitor_device_name << '\n'; - return; - } - - buffer_monitor_fpga = std::make_shared(device_io_name_buffer_monitor, num_freq_bands, dump_, dump_filename); - thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); - } - - // dynamic bits selection - if (enable_dynamic_bit_selection_) - { - dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); - thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); - } - - if (in_stream_ > 0) - { - LOG(ERROR) << "A signal source does not have an input stream"; - } - if (out_stream_ > 1) - { - LOG(ERROR) << "This implementation only supports one output stream"; - } -} - - -Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource() -{ - /* cleanup and exit */ - if (switch_position_ == 0) // read samples from a file via DMA - { - std::unique_lock lock(dma_mutex); - enable_DMA_ = false; // disable the DMA - lock.unlock(); - if (thread_file_to_dma.joinable()) - { - thread_file_to_dma.join(); - } - } - - if (switch_position_ == 2) // Real-time via AD9361 - { - if (rf_shutdown_) - { - std::cout << "* AD9361 Disabling RX streaming channels\n"; - if (!disable_ad9361_rx_local()) - { - LOG(WARNING) << "Problem shutting down the AD9361 RX channels"; - } - if (enable_dds_lo_) - { - try - { - ad9361_disable_lo_local(); - } - catch (const std::exception &e) - { - LOG(WARNING) << "Problem shutting down the AD9361 TX stream: " << e.what(); - } - } - } - - // disable buffer overflow checking and buffer monitoring - std::unique_lock lock(buffer_monitor_mutex); - enable_ovf_check_buffer_monitor_active_ = false; - lock.unlock(); - - if (thread_buffer_monitor.joinable()) - { - thread_buffer_monitor.join(); - } - } - - std::unique_lock lock(dynamic_bit_selection_mutex); - bool bit_selection_enabled = enable_dynamic_bit_selection_; - lock.unlock(); - - if (bit_selection_enabled == true) - { - std::unique_lock lock(dynamic_bit_selection_mutex); - enable_dynamic_bit_selection_ = false; - lock.unlock(); - - if (thread_dynamic_bit_selection.joinable()) - { - thread_dynamic_bit_selection.join(); - } - } -} - - -void Ad9361FpgaSignalSource::start() -{ - thread_file_to_dma = std::thread([&] { run_DMA_process(filename0_, filename1_, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); }); -} - - -void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, const std::string &filename1_, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue *queue) -{ - std::ifstream infile1; - infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); - - - // FPGA DMA control - dma_fpga = std::make_shared(); - - // open the files - try - { - infile1.open(filename0_, std::ios::binary); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception opening file " << filename0_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - - std::ifstream infile2; - if (!filename1_.empty()) - { - infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); - try - { - infile2.open(filename1_, std::ios::binary); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception opening file " << filename1_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - } - - // skip the initial samples if needed - uint64_t bytes_to_skeep = samples_to_skip * item_size; - try - { - infile1.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - - if (!filename1_.empty()) - { - try - { - infile2.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - } - - // rx signal vectors - std::vector input_samples(sample_block_size * 2); // complex samples - // pointer to DMA buffer - int8_t *dma_buffer; - int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1 - bool run_DMA = true; - - // Open DMA device - if (dma_fpga->DMA_open()) - { - std::cerr << "Cannot open loop device\n"; - // stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); - return; - } - dma_buffer = dma_fpga->get_buffer_address(); - - // if only one frequency band is used then clear the samples corresponding to the unused frequency band - uint32_t dma_index = 0; - if (num_input_files_ == 1) - { - // if only one file is enabled then clear the samples corresponding to the frequency band that is not used. - for (int index0 = 0; index0 < (nread_elements); index0 += 2) - { - dma_buffer[dma_index + (2 - dma_buff_offset_pos)] = 0; - dma_buffer[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0; - dma_index += 4; - } - } - - uint64_t nbytes_remaining = samples * item_size; - uint32_t read_buffer_size = sample_block_size * 2; // complex samples - - // run the DMA - while (run_DMA) - { - dma_index = 0; - if (nbytes_remaining < read_buffer_size) - { - read_buffer_size = nbytes_remaining; - } - nbytes_remaining = nbytes_remaining - read_buffer_size; - - // read filename 0 - try - { - infile1.read(reinterpret_cast(input_samples.data()), read_buffer_size); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception reading file " << filename0_ << '\n'; - break; - } - if (infile1) - { - nread_elements = read_buffer_size; - } - else - { - // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN - nread_elements = infile1.gcount(); - } - - for (int index0 = 0; index0 < (nread_elements); index0 += 2) - { - // dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands - dma_buffer[dma_index + dma_buff_offset_pos] = input_samples[index0]; - dma_buffer[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1]; - dma_index += 4; - } - - // read filename 1 (if enabled) - if (num_input_files_ > 1) - { - dma_index = 0; - try - { - infile2.read(reinterpret_cast(input_samples.data()), read_buffer_size); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception reading file " << filename1_ << '\n'; - break; - } - if (infile2) - { - nread_elements = read_buffer_size; - } - else - { - // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN - nread_elements = infile2.gcount(); - } - - for (int index0 = 0; index0 < (nread_elements); index0 += 2) - { - // filename2 is never the L1 band - dma_buffer[dma_index] = input_samples[index0]; - dma_buffer[dma_index + 1] = input_samples[index0 + 1]; - dma_index += 4; - } - } - - if (nread_elements > 0) - { - if (dma_fpga->DMA_write(nread_elements * 2)) - { - std::cerr << "Error: DMA could not send all the required samples\n"; - break; - } - // Throttle the DMA - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - - if (nbytes_remaining == 0) - { - if (repeat) - { - // read the file again - nbytes_remaining = samples * item_size; - read_buffer_size = sample_block_size * 2; - try - { - infile1.seekg(0); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0_ << '\n'; - break; - } - - // skip the initial samples if needed - uint64_t bytes_to_skeep = samples_to_skip * item_size; - try - { - infile1.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; - break; - } - - if (!filename1_.empty()) - { - try - { - infile2.seekg(0); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1_ << '\n'; - break; - } - - try - { - infile2.ignore(bytes_to_skeep); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; - break; - } - } - } - else - { - // the input file is completely processed. Stop the receiver. - run_DMA = false; - } - } - std::unique_lock lock(dma_mutex); - if (enable_DMA_ == false) - { - run_DMA = false; - } - lock.unlock(); - } - - if (dma_fpga->DMA_close()) - { - std::cerr << "Error closing loop device " << '\n'; - } - try - { - infile1.close(); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception closing file " << filename0_ << '\n'; - } - - if (num_input_files_ > 1) - { - try - { - infile2.close(); - } - catch (const std::ifstream::failure &e) - { - std::cerr << "Exception closing file " << filename1_ << '\n'; - } - } - - // Stop the receiver - queue->push(pmt::make_any(command_event_make(200, 0))); -} - - -void Ad9361FpgaSignalSource::run_dynamic_bit_selection_process() -{ - bool dynamic_bit_selection_active = true; - - while (dynamic_bit_selection_active) - { - // setting the bit selection to the top bits - dynamic_bit_selection_fpga->bit_selection(); - std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); - std::unique_lock lock(dynamic_bit_selection_mutex); - if (enable_dynamic_bit_selection_ == false) - { - dynamic_bit_selection_active = false; - } - lock.unlock(); - } -} - - -void Ad9361FpgaSignalSource::run_buffer_monitor_process() -{ - bool enable_ovf_check_buffer_monitor_active = true; - - std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); - - while (enable_ovf_check_buffer_monitor_active) - { - buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); - std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); - std::unique_lock lock(buffer_monitor_mutex); - if (enable_ovf_check_buffer_monitor_active_ == false) - { - enable_ovf_check_buffer_monitor_active = false; - } - lock.unlock(); - } -} - - -void Ad9361FpgaSignalSource::connect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - DLOG(INFO) << "AD9361 FPGA source nothing to connect"; -} - - -void Ad9361FpgaSignalSource::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; -} - - -gr::basic_block_sptr Ad9361FpgaSignalSource::get_left_block() -{ - LOG(WARNING) << "Trying to get signal source left block."; - return {}; -} - - -gr::basic_block_sptr Ad9361FpgaSignalSource::get_right_block() -{ - return {}; -} diff --git a/src/algorithms/signal_source/adapters/ad936x_custom_signal_source.cc b/src/algorithms/signal_source/adapters/ad936x_custom_signal_source.cc index 796126e03..b824a250d 100644 --- a/src/algorithms/signal_source/adapters/ad936x_custom_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad936x_custom_signal_source.cc @@ -21,10 +21,15 @@ #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" #include -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface* configuration, @@ -71,8 +76,11 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface* item_size_ = sizeof(gr_complex); // 1. Make the driver instance bool customsamplesize = false; - if (ssize_ != 12 or spattern_ == true) customsamplesize = true; // custom FPGA DMA firmware - if (ssize_ == 12) // default original FPGA DMA firmware + if (ssize_ != 12 || spattern_ == true) + { + customsamplesize = true; // custom FPGA DMA firmware + } + if (ssize_ == 12) // default original FPGA DMA firmware { ssize_ = 16; // set to 16 bits and do not try to change sample size } @@ -148,8 +156,14 @@ Ad936xCustomSignalSource::Ad936xCustomSignalSource(const ConfigurationInterface* for (int n = 0; n < n_channels; n++) { - if (n == 0) inverted_spectrum_vec.push_back(inverted_spectrum_ch0_); - if (n == 1) inverted_spectrum_vec.push_back(inverted_spectrum_ch1_); + if (n == 0) + { + inverted_spectrum_vec.push_back(inverted_spectrum_ch0_); + } + if (n == 1) + { + inverted_spectrum_vec.push_back(inverted_spectrum_ch1_); + } } for (int n = 0; n < n_channels; n++) diff --git a/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.cc new file mode 100644 index 000000000..897dd7777 --- /dev/null +++ b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.cc @@ -0,0 +1,399 @@ +/*! + * \file adrv9361_z7035_signal_source_fpga.cc + * \brief Signal source for the Analog Devices ADRV9361-Z7035 evaluation board + * directly connected to the FPGA accelerators. + * This source implements only the AD9361 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * Please use the fmcomms2 source if conventional SDR acquisition and tracking + * is selected in the configuration file. + * \authors
      + *
    • Javier Arribas, jarribas(at)cttc.es + *
    • Marc Majoral, mmajoral(at)cttc.es + *
    + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "adrv9361_z7035_signal_source_fpga.h" +#include "GPS_L1_CA.h" +#include "GPS_L5.h" +#include "ad9361_manager.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::max +#include // for std::chrono +#include // for std::floor +#include // for std::exception +#include // for std::cout + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +Adrv9361z7035SignalSourceFPGA::Adrv9361z7035SignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "ADRV9361_Z7035_Signal_Source_FPGA"s), + gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)), + gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), + rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), + filter_source_(configuration->property(role + ".filter_source", std::string("Off"))), + filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), + rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), + rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), + scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), + phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), + tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), + freq0_(configuration->property(role + ".freq", GPS_L5_FREQ_HZ)), + sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), + bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), + freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), + freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), + tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), + Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), + Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), + in_stream_(in_stream), + out_stream_(out_stream), + item_size_(sizeof(int8_t)), + enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)), + quadrature_(configuration->property(role + ".quadrature", true)), + rf_dc_(configuration->property(role + ".rf_dc", true)), + bb_dc_(configuration->property(role + ".bb_dc", true)), + rx1_enable_(configuration->property(role + ".rx1_enable", true)), + rx2_enable_(configuration->property(role + ".rx2_enable", true)), + enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), + enable_ovf_check_buffer_monitor_active_(true), + dump_(configuration->property(role + ".dump", false)), +#if USE_GLOG_AND_GFLAGS + rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)) +#else + rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))) +#endif +{ + const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || + (configuration->property("Channels_1B.count", 0) > 0)); + const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || + (configuration->property("Channels_L5.count", 0) > 0) || + (configuration->property("Channels_5X.count", 0) > 0)); + + const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1; + if (freq0_ == 0) + { + // use ".freq0" + freq0_ = configuration->property(role + ".freq0", static_cast(GPS_L1_FREQ_HZ)); + } + + switch_fpga = std::make_shared(); + switch_fpga->set_switch_position(switch_to_real_time_mode); + + std::cout << "Sample rate: " << sample_rate_ << " Sps\n"; + + // some basic checks + if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2")) + { + std::cout << "Configuration parameter rf_port_select should take one of these values:\n"; + std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2\n"; + std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << '\n'; + rf_port_select_ = default_rf_port_select; + LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=" << default_rf_port_select; + } + + if ((gain_mode_rx1_ != "manual") && (gain_mode_rx1_ != "slow_attack") && (gain_mode_rx1_ != "fast_attack") && (gain_mode_rx1_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << '\n'; + gain_mode_rx1_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; + } + + if ((gain_mode_rx2_ != "manual") && (gain_mode_rx2_ != "slow_attack") && (gain_mode_rx2_ != "fast_attack") && (gain_mode_rx2_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << '\n'; + gain_mode_rx2_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx2 parameter. Set to gain_mode_rx2=" << default_gain_mode; + } + + if (gain_mode_rx1_ == "manual") + { + if (rf_gain_rx1_ > 73.0 || rf_gain_rx1_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << '\n'; + rf_gain_rx1_ = default_manual_gain_rx1; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=" << default_manual_gain_rx1; + } + } + + if (gain_mode_rx2_ == "manual") + { + if (rf_gain_rx2_ > 73.0 || rf_gain_rx2_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << '\n'; + rf_gain_rx2_ = default_manual_gain_rx2; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=" << default_manual_gain_rx2; + } + } + + if ((filter_source_ != "Off") && (filter_source_ != "Auto") && (filter_source_ != "File") && (filter_source_ != "Design")) + { + std::cout << "Configuration parameter filter_source should take one of these values:\n"; + std::cout << " Off: Disable filter\n"; + std::cout << " Auto: Use auto-generated filters\n"; + std::cout << " File: User-provided filter in filter_filename parameter\n"; + std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters\n"; + std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value filter_source=Off\n"; + filter_source_ = std::string("Off"); + LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; + } + + if (bandwidth_ < 200000 || bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz\n"; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << '\n'; + bandwidth_ = default_bandwidth; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; + } + + std::cout << "LO frequency : " << freq0_ << " Hz\n"; + + uint64_t freq1 = 0; // The local oscillator frequency of the ADRV9361-B is not used when using the ADRV9361-Z7035 board. + + try + { + config_ad9361_rx_local(bandwidth_, + sample_rate_, + freq0_, + freq1, + rf_port_select_, + rx1_enable_, + rx2_enable_, + gain_mode_rx1_, + gain_mode_rx2_, + rf_gain_rx1_, + rf_gain_rx2_, + quadrature_, + rf_dc_, + bb_dc_, + filter_source_, + filter_filename_, + Fpass_, + Fstop_); + } + catch (const std::runtime_error &e) + { + std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; + return; + } + // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION + if (enable_dds_lo_ == true) + { + if (tx_bandwidth_ < static_cast(std::floor(static_cast(freq_dds_tx_hz_) * 1.1)) || (tx_bandwidth_ < 200000) || (tx_bandwidth_ > 1000000)) + { + std::cout << "Configuration parameter tx_bandwidth value should be between " << std::max(static_cast(freq_dds_tx_hz_) * 1.1, 200000.0) << " and 1000000 Hz\n"; + std::cout << "Error: provided value tx_bandwidth=" << tx_bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value tx_bandwidth=500000\n"; + tx_bandwidth_ = 500000; + LOG(WARNING) << "Invalid configuration value for tx_bandwidth parameter. Set to tx_bandwidth=500000"; + } + if (tx_attenuation_db_ > 0.0 || tx_attenuation_db_ < -89.75) + { + std::cout << "Configuration parameter tx_attenuation_db should take values between 0.0 and -89.95 in 0.25 dB steps\n"; + std::cout << "Error: provided value tx_attenuation_db=" << tx_attenuation_db_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value tx_attenuation_db=" << default_tx_attenuation_db << '\n'; + tx_attenuation_db_ = default_tx_attenuation_db; + LOG(WARNING) << "Invalid configuration value for tx_attenuation_db parameter. Set to tx_attenuation_db=" << default_tx_attenuation_db; + } + try + { + config_ad9361_lo_local(tx_bandwidth_, + sample_rate_, + freq_rf_tx_hz_, + tx_attenuation_db_, + freq_dds_tx_hz_, + scale_dds_dbfs_, + phase_dds_deg_); + } + catch (const std::runtime_error &e) + { + std::cerr << "Exception cached when configuring the TX carrier: " << e.what() << '\n'; + return; + } + } + + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + + buffer_monitor_fpga = std::make_shared(num_freq_bands, dump_, dump_filename); + thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); + + // dynamic bits selection + if (enable_dynamic_bit_selection_) + { + dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); + thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); + } + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +Adrv9361z7035SignalSourceFPGA::~Adrv9361z7035SignalSourceFPGA() +{ + // cleanup and exit + if (rf_shutdown_) + { + std::cout << "* AD9361 Disabling RX streaming channels\n"; + try + { + if (!disable_ad9361_rx_local()) + { + LOG(WARNING) << "Problem shutting down the AD9361 RX channels"; + } + } + catch (const std::exception &e) + { + LOG(WARNING) << "Problem shutting down the AD9361 RX channels: " << e.what(); + std::cerr << "Problem shutting down the AD9361 RX channels: " << e.what() << '\n'; + } + + if (enable_dds_lo_) + { + try + { + ad9361_disable_lo_local(); + } + catch (const std::exception &e) + { + LOG(WARNING) << "Problem shutting down the AD9361 TX stream: " << e.what(); + } + } + } + + // disable buffer overflow checking and buffer monitoring + { + std::lock_guard lock_buffer_monitor(buffer_monitor_mutex); + enable_ovf_check_buffer_monitor_active_ = false; + } + + if (thread_buffer_monitor.joinable()) + { + thread_buffer_monitor.join(); + } + bool bit_selection_enabled = false; + { + std::lock_guard lock_dyn_bit_sel(dynamic_bit_selection_mutex); + bit_selection_enabled = enable_dynamic_bit_selection_; + } + + if (bit_selection_enabled == true) + { + { + std::lock_guard lock(dynamic_bit_selection_mutex); + enable_dynamic_bit_selection_ = false; + } + + if (thread_dynamic_bit_selection.joinable()) + { + thread_dynamic_bit_selection.join(); + } + } +} + + +void Adrv9361z7035SignalSourceFPGA::run_dynamic_bit_selection_process() +{ + bool dynamic_bit_selection_active = true; + + while (dynamic_bit_selection_active) + { + // setting the bit selection to the top bits + dynamic_bit_selection_fpga->bit_selection(); + std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); + std::lock_guard lock(dynamic_bit_selection_mutex); + if (enable_dynamic_bit_selection_ == false) + { + dynamic_bit_selection_active = false; + } + } +} + + +void Adrv9361z7035SignalSourceFPGA::run_buffer_monitor_process() +{ + bool enable_ovf_check_buffer_monitor_active = true; + + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); + + while (enable_ovf_check_buffer_monitor_active) + { + buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); + std::lock_guard lock(buffer_monitor_mutex); + if (enable_ovf_check_buffer_monitor_active_ == false) + { + enable_ovf_check_buffer_monitor_active = false; + } + } +} + + +void Adrv9361z7035SignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void Adrv9361z7035SignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr Adrv9361z7035SignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr Adrv9361z7035SignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.h similarity index 65% rename from src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h rename to src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.h index bedd25ad5..286cde2d5 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/adrv9361_z7035_signal_source_fpga.h @@ -1,7 +1,7 @@ /*! - * \file ad9361_fpga_signal_source.h - * \brief signal source for Analog Devices front-end AD9361 connected directly - * to FPGA accelerators. + * \file adrv9361_z7035_signal_source_fpga.h + * \brief Signal source for the Analog Devices ADRV9361-Z7035 evaluation board + * directly connected to the FPGA accelerators. * This source implements only the AD9361 control. It is NOT compatible with * conventional SDR acquisition and tracking blocks. * Please use the fmcomms2 source if conventional SDR acquisition and tracking @@ -12,18 +12,17 @@ * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ -#ifndef GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H -#define GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H +#ifndef GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H #include "concurrent_queue.h" #include "fpga_buffer_monitor.h" -#include "fpga_dma-proxy.h" #include "fpga_dynamic_bit_selection.h" #include "fpga_switch.h" #include "gnss_block_interface.h" @@ -44,16 +43,14 @@ class ConfigurationInterface; -class Ad9361FpgaSignalSource : public SignalSourceBase +class Adrv9361z7035SignalSourceFPGA : public SignalSourceBase { public: - Ad9361FpgaSignalSource(const ConfigurationInterface *configuration, + Adrv9361z7035SignalSourceFPGA(const ConfigurationInterface *configuration, const std::string &role, unsigned int in_stream, unsigned int out_stream, Concurrent_Queue *queue); - ~Ad9361FpgaSignalSource(); - - void start() override; + ~Adrv9361z7035SignalSourceFPGA(); inline size_t item_size() override { @@ -66,13 +63,9 @@ public: gr::basic_block_sptr get_right_block() override; private: - const std::string switch_device_name = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name - const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name - const std::string buffer_monitor_device_name = std::string("buffer_monitor"); // buffer monitor device name const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); const std::string default_rf_port_select = std::string("A_BALANCED"); const std::string default_gain_mode = std::string("slow_attack"); - const std::string empty_string; const double default_tx_attenuation_db = -10.0; const double default_manual_gain_rx1 = 64.0; const double default_manual_gain_rx2 = 64.0; @@ -84,35 +77,20 @@ private: const uint32_t buffer_monitor_period_ms = 1000; // buffer overflow and buffer monitoring initial delay const uint32_t buffer_monitoring_initial_delay_ms = 2000; - // sample block size when running in post-processing mode - const int sample_block_size = 16384; - - void run_DMA_process(const std::string &filename0, - const std::string &filename1, - uint64_t &samples_to_skip, - size_t &item_size, - int64_t &samples, - bool &repeat, - uint32_t &dma_buff_offset_pos, - Concurrent_Queue *queue); + const int32_t switch_to_real_time_mode = 2; void run_dynamic_bit_selection_process(); void run_buffer_monitor_process(); - std::thread thread_file_to_dma; + mutable std::mutex dynamic_bit_selection_mutex; + mutable std::mutex buffer_monitor_mutex; + std::thread thread_dynamic_bit_selection; std::thread thread_buffer_monitor; std::shared_ptr switch_fpga; std::shared_ptr dynamic_bit_selection_fpga; std::shared_ptr buffer_monitor_fpga; - std::shared_ptr dma_fpga; - - std::mutex dma_mutex; - std::mutex dynamic_bit_selection_mutex; - std::mutex buffer_monitor_mutex; - - Concurrent_Queue *queue_; std::string gain_mode_rx1_; std::string gain_mode_rx2_; @@ -120,8 +98,6 @@ private: std::string filter_file_; std::string filter_source_; std::string filter_filename_; - std::string filename0_; - std::string filename1_; double rf_gain_rx1_; double rf_gain_rx2_; @@ -130,41 +106,32 @@ private: double tx_attenuation_db_; uint64_t freq0_; // frequency of local oscillator for ADRV9361-A 0 - uint64_t freq1_; // frequency of local oscillator for ADRV9361-B (if present) uint64_t sample_rate_; uint64_t bandwidth_; - uint64_t samples_to_skip_; - int64_t samples_; uint64_t freq_dds_tx_hz_; uint64_t freq_rf_tx_hz_; uint64_t tx_bandwidth_; float Fpass_; float Fstop_; - uint32_t num_input_files_; - uint32_t dma_buff_offset_pos_; uint32_t in_stream_; uint32_t out_stream_; - int32_t switch_position_; size_t item_size_; bool enable_dds_lo_; - bool filter_auto_; bool quadrature_; bool rf_dc_; bool bb_dc_; bool rx1_enable_; bool rx2_enable_; - bool enable_DMA_; bool enable_dynamic_bit_selection_; bool enable_ovf_check_buffer_monitor_active_; bool dump_; bool rf_shutdown_; - bool repeat_; }; /** \} */ /** \} */ -#endif // GNSS_SDR_AD9361_FPGA_SIGNAL_SOURCE_H +#endif // GNSS_SDR_ADRV9361_Z7035_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc b/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc index 85299cc27..705ef2bb9 100644 --- a/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc @@ -18,9 +18,14 @@ #include "custom_udp_signal_source.h" #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" -#include #include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/dma_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.cc new file mode 100644 index 000000000..6d4f91b03 --- /dev/null +++ b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.cc @@ -0,0 +1,581 @@ +/*! + * \file dma_signal_source_fpga.cc + * \brief signal source for a DMA connected directly to FPGA accelerators. + * This source implements only the DMA control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * \author Marc Majoral, mmajoral(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "dma_signal_source_fpga.h" +#include "command_event.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::min +#include // for std::chrono +#include // for open, O_WRONLY +#include // for std::ifstream +#include // for std::setprecision +#include // for std::cout +#include // fr std::vector + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +DMASignalSourceFPGA::DMASignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "DMA_Signal_Source_FPGA"s), + queue_(queue), + filename0_(configuration->property(role + ".filename", empty_string)), + sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), + samples_to_skip_(0), + samples_(configuration->property(role + ".samples", static_cast(0))), + num_input_files_(1), + dma_buff_offset_pos_(0), + in_stream_(in_stream), + out_stream_(out_stream), + item_size_(sizeof(int8_t)), + enable_DMA_(false), + enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), + repeat_(configuration->property(role + ".repeat", false)) +{ + const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.0); + const size_t header_size = configuration->property(role + ".header_size", 0); + + const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || + (configuration->property("Channels_1B.count", 0) > 0)); + const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || + (configuration->property("Channels_L5.count", 0) > 0) || + (configuration->property("Channels_5X.count", 0) > 0)); + +#if USE_GLOG_AND_GFLAGS + // override value with commandline flag, if present + if (FLAGS_signal_source != "-") + { + filename0_ = FLAGS_signal_source; + } + if (FLAGS_s != "-") + { + filename0_ = FLAGS_s; + } +#else + if (absl::GetFlag(FLAGS_signal_source) != "-") + { + filename0_ = absl::GetFlag(FLAGS_signal_source); + } + if (absl::GetFlag(FLAGS_s) != "-") + { + filename0_ = absl::GetFlag(FLAGS_s); + } +#endif + if (filename0_.empty()) + { + num_input_files_ = 2; + filename0_ = configuration->property(role + ".filename0", empty_string); + filename1_ = configuration->property(role + ".filename1", empty_string); + } + // if only one input file is specified in the configuration file then: + // if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels + // otherwise the DMA transfers the samples to the L2/L5 frequency band channels + // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. + if (filename1_.empty()) + { + if (enable_rx1_band) + { + dma_buff_offset_pos_ = 2; + } + } + else + { + dma_buff_offset_pos_ = 2; + } + + if (seconds_to_skip > 0) + { + samples_to_skip_ = static_cast(seconds_to_skip * sample_rate_) * 2; + } + if (header_size > 0) + { + samples_to_skip_ += header_size; + } + + switch_fpga = std::make_shared(); + switch_fpga->set_switch_position(switch_to_DMA); + + enable_DMA_ = true; + + if (samples_ == 0) // read all file + { + std::ifstream file(filename0_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + std::ifstream::pos_type size; + + if (file.is_open()) + { + size = file.tellg(); + DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); + } + else + { + std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n'; + return; + } + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(16); + std::cout << "Processing file " << filename0_ << ", which contains " << static_cast(size) << " [bytes]\n"; + std::cout.precision(ss); + + if (size > 0) + { + const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; + const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; + samples_ = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms + } + + if (!filename1_.empty()) + { + std::ifstream file(filename1_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + std::ifstream::pos_type size; + + if (file.is_open()) + { + size = file.tellg(); + DLOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); + } + else + { + std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n'; + return; + } + std::streamsize ss = std::cout.precision(); + std::cout << std::setprecision(16); + std::cout << "Processing file " << filename1_ << ", which contains " << static_cast(size) << " [bytes]\n"; + std::cout.precision(ss); + + int64_t samples_rx2 = 0; + if (size > 0) + { + const uint64_t bytes_to_skip = samples_to_skip_ * item_size_; + const uint64_t bytes_to_process = static_cast(size) - bytes_to_skip; + samples_rx2 = floor(static_cast(bytes_to_process) / static_cast(item_size_) - ceil(0.002 * static_cast(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms + } + samples_ = std::min(samples_, samples_rx2); + } + } + + CHECK(samples_ > 0) << "File does not contain enough samples to process."; + double signal_duration_s = (static_cast(samples_) * (1 / static_cast(sample_rate_))) / 2.0; + + DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; + std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; + + if (filename1_.empty()) + { + DLOG(INFO) << "File source filename " << filename0_; + } + else + { + DLOG(INFO) << "File source filename rx1 " << filename0_; + DLOG(INFO) << "File source filename rx2 " << filename1_; + } + DLOG(INFO) << "Samples " << samples_; + DLOG(INFO) << "Sampling frequency " << sample_rate_; + DLOG(INFO) << "Item type " << std::string("ibyte"); + DLOG(INFO) << "Item size " << item_size_; + DLOG(INFO) << "Repeat " << repeat_; + // } + + // dynamic bits selection + if (enable_dynamic_bit_selection_) + { + dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); + thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); + } + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +DMASignalSourceFPGA::~DMASignalSourceFPGA() +{ + std::unique_lock lock_DMA(dma_mutex); + enable_DMA_ = false; // disable the DMA + lock_DMA.unlock(); + if (thread_file_to_dma.joinable()) + { + thread_file_to_dma.join(); + } + + std::unique_lock lock_dyn_bit_sel(dynamic_bit_selection_mutex); + bool bit_selection_enabled = enable_dynamic_bit_selection_; + lock_dyn_bit_sel.unlock(); + + if (bit_selection_enabled == true) + { + std::unique_lock lock(dynamic_bit_selection_mutex); + enable_dynamic_bit_selection_ = false; + lock.unlock(); + + if (thread_dynamic_bit_selection.joinable()) + { + thread_dynamic_bit_selection.join(); + } + } +} + + +void DMASignalSourceFPGA::start() +{ + thread_file_to_dma = std::thread([&] { run_DMA_process(filename0_, filename1_, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); }); +} + + +void DMASignalSourceFPGA::run_DMA_process(const std::string &filename0_, const std::string &filename1_, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue *queue) +{ + std::ifstream infile1; + infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + + // FPGA DMA control + dma_fpga = std::make_shared(); + + // open the files + try + { + infile1.open(filename0_, std::ios::binary); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception opening file " << filename0_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + + std::ifstream infile2; + if (!filename1_.empty()) + { + infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try + { + infile2.open(filename1_, std::ios::binary); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception opening file " << filename1_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + } + + // skip the initial samples if needed + uint64_t bytes_to_skeep = samples_to_skip * item_size; + try + { + infile1.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + + if (!filename1_.empty()) + { + try + { + infile2.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + } + + // rx signal vectors + std::vector input_samples(sample_block_size * 2); // complex samples + // pointer to DMA buffer + int8_t *dma_buffer; + int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1 + bool run_DMA = true; + + // Open DMA device + if (dma_fpga->DMA_open()) + { + std::cerr << "Cannot open loop device\n"; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + dma_buffer = dma_fpga->get_buffer_address(); + + // if only one frequency band is used then clear the samples corresponding to the unused frequency band + uint32_t dma_index = 0; + if (num_input_files_ == 1) + { + // if only one file is enabled then clear the samples corresponding to the frequency band that is not used. + for (int index0 = 0; index0 < (nread_elements); index0 += 2) + { + dma_buffer[dma_index + (2 - dma_buff_offset_pos)] = 0; + dma_buffer[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0; + dma_index += 4; + } + } + + uint64_t nbytes_remaining = samples * item_size; + uint32_t read_buffer_size = sample_block_size * 2; // complex samples + + // run the DMA + while (run_DMA) + { + dma_index = 0; + if (nbytes_remaining < read_buffer_size) + { + read_buffer_size = nbytes_remaining; + } + nbytes_remaining = nbytes_remaining - read_buffer_size; + + // read filename 0 + try + { + infile1.read(reinterpret_cast(input_samples.data()), read_buffer_size); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception reading file " << filename0_ << '\n'; + break; + } + if (infile1) + { + nread_elements = read_buffer_size; + } + else + { + // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN + nread_elements = infile1.gcount(); + } + + for (int index0 = 0; index0 < (nread_elements); index0 += 2) + { + // dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands + dma_buffer[dma_index + dma_buff_offset_pos] = input_samples[index0]; + dma_buffer[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1]; + dma_index += 4; + } + + // read filename 1 (if enabled) + if (num_input_files_ > 1) + { + dma_index = 0; + try + { + infile2.read(reinterpret_cast(input_samples.data()), read_buffer_size); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception reading file " << filename1_ << '\n'; + break; + } + if (infile2) + { + nread_elements = read_buffer_size; + } + else + { + // FLAG AS ERROR !! IT SHOULD NEVER HAPPEN + nread_elements = infile2.gcount(); + } + + for (int index0 = 0; index0 < (nread_elements); index0 += 2) + { + // filename2 is never the L1 band + dma_buffer[dma_index] = input_samples[index0]; + dma_buffer[dma_index + 1] = input_samples[index0 + 1]; + dma_index += 4; + } + } + + if (nread_elements > 0) + { + if (dma_fpga->DMA_write(nread_elements * 2)) + { + std::cerr << "Error: DMA could not send all the required samples\n"; + break; + } + // Throttle the DMA + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + if (nbytes_remaining == 0) + { + if (repeat) + { + // read the file again + nbytes_remaining = samples * item_size; + read_buffer_size = sample_block_size * 2; + try + { + infile1.seekg(0); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0_ << '\n'; + break; + } + + // skip the initial samples if needed + uint64_t bytes_to_skeep = samples_to_skip * item_size; + try + { + infile1.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename0_ << '\n'; + break; + } + + if (!filename1_.empty()) + { + try + { + infile2.seekg(0); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1_ << '\n'; + break; + } + + try + { + infile2.ignore(bytes_to_skeep); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception skipping initial samples file " << filename1_ << '\n'; + break; + } + } + } + else + { + // the input file is completely processed. Stop the receiver. + run_DMA = false; + } + } + std::unique_lock lock_DMA(dma_mutex); + if (enable_DMA_ == false) + { + run_DMA = false; + } + lock_DMA.unlock(); + } + + if (dma_fpga->DMA_close()) + { + std::cerr << "Error closing loop device " << '\n'; + } + try + { + infile1.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception closing file " << filename0_ << '\n'; + } + + if (num_input_files_ > 1) + { + try + { + infile2.close(); + } + catch (const std::ifstream::failure &e) + { + std::cerr << "Exception closing file " << filename1_ << '\n'; + } + } + + // Stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); +} + + +void DMASignalSourceFPGA::run_dynamic_bit_selection_process() +{ + bool dynamic_bit_selection_active = true; + + while (dynamic_bit_selection_active) + { + // setting the bit selection to the top bits + dynamic_bit_selection_fpga->bit_selection(); + std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); + std::unique_lock lock_dyn_bit_sel(dynamic_bit_selection_mutex); + if (enable_dynamic_bit_selection_ == false) + { + dynamic_bit_selection_active = false; + } + lock_dyn_bit_sel.unlock(); + } +} + + +void DMASignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void DMASignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr DMASignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr DMASignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/dma_signal_source_fpga.h b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.h new file mode 100644 index 000000000..efbad3b23 --- /dev/null +++ b/src/algorithms/signal_source/adapters/dma_signal_source_fpga.h @@ -0,0 +1,118 @@ +/*! + * \file dma_signal_source_fpga.h + * \brief signal source for a DMA connected directly to FPGA accelerators. + * This source implements only the DMA control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * \author Marc Majoral, mmajoral(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_DMA_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_DMA_SIGNAL_SOURCE_FPGA_H + +#include "concurrent_queue.h" +#include "fpga_dma-proxy.h" +#include "fpga_dynamic_bit_selection.h" +#include "fpga_switch.h" +#include "gnss_block_interface.h" +#include "signal_source_base.h" +#include +#include +#include +#include +#include +#include + + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + + +class ConfigurationInterface; + +class DMASignalSourceFPGA : public SignalSourceBase +{ +public: + DMASignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, + unsigned int out_stream, Concurrent_Queue *queue); + + ~DMASignalSourceFPGA(); + + void start() override; + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + +private: + const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name + const std::string empty_string; + const uint64_t default_bandwidth = 12500000; + // perform dynamic bit selection every 500 ms by default + const uint32_t Gain_control_period_ms = 500; + // sample block size when running in post-processing mode + const int sample_block_size = 16384; + const int32_t switch_to_DMA = 0; + + void run_DMA_process(const std::string &filename0, + const std::string &filename1, + uint64_t &samples_to_skip, + size_t &item_size, + int64_t &samples, + bool &repeat, + uint32_t &dma_buff_offset_pos, + Concurrent_Queue *queue); + + void run_dynamic_bit_selection_process(); + + std::thread thread_file_to_dma; + std::thread thread_dynamic_bit_selection; + + std::shared_ptr switch_fpga; + std::shared_ptr dynamic_bit_selection_fpga; + std::shared_ptr dma_fpga; + + std::mutex dma_mutex; + std::mutex dynamic_bit_selection_mutex; + + Concurrent_Queue *queue_; + + std::string filename0_; + std::string filename1_; + + uint64_t sample_rate_; + uint64_t samples_to_skip_; + int64_t samples_; + uint32_t num_input_files_; + uint32_t dma_buff_offset_pos_; + uint32_t in_stream_; + uint32_t out_stream_; + size_t item_size_; + + bool enable_DMA_; + bool enable_dynamic_bit_selection_; + bool repeat_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_DMA_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/adapters/fifo_signal_source.cc b/src/algorithms/signal_source/adapters/fifo_signal_source.cc index 7ffac8e5b..12981b3ad 100644 --- a/src/algorithms/signal_source/adapters/fifo_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fifo_signal_source.cc @@ -19,10 +19,14 @@ #include "configuration_interface.h" #include "fifo_reader.h" #include "gnss_sdr_string_literals.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif using namespace std::string_literals; @@ -30,8 +34,8 @@ FifoSignalSource::FifoSignalSource(ConfigurationInterface const* configuration, std::string const& role, unsigned int in_streams, unsigned int out_streams, [[maybe_unused]] Concurrent_Queue* queue) : SignalSourceBase(configuration, role, "Fifo_Signal_Source"s), - item_size_(sizeof(gr_complex)), // currenty output item size is always gr_complex - fifo_reader_(FifoReader::make(configuration->property(role + ".filename", "../data/example_capture.dat"s), + item_size_(sizeof(gr_complex)), // currently output item size is always gr_complex + fifo_reader_(FifoReader::make(configuration->property(role + ".filename", "./example_capture.dat"s), configuration->property(role + ".sample_type", "ishort"s))), dump_(configuration->property(role + ".dump", false)), dump_filename_(configuration->property(role + ".dump_filename", "./data/signal_source.dat"s)) diff --git a/src/algorithms/signal_source/adapters/file_signal_source.cc b/src/algorithms/signal_source/adapters/file_signal_source.cc index d1267949e..c4fbd25a2 100644 --- a/src/algorithms/signal_source/adapters/file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/file_signal_source.cc @@ -18,7 +18,12 @@ #include "file_signal_source.h" #include "gnss_sdr_string_literals.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/file_source_base.cc b/src/algorithms/signal_source/adapters/file_source_base.cc index 6efa7cdbc..aabef306b 100644 --- a/src/algorithms/signal_source/adapters/file_source_base.cc +++ b/src/algorithms/signal_source/adapters/file_source_base.cc @@ -29,12 +29,16 @@ #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" -#include #include // for std::max #include // for ceil, floor #include // for std::cout, std:cerr #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif using namespace std::string_literals; @@ -44,8 +48,8 @@ FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std: : SignalSourceBase(configuration, role, std::move(impl)), queue_(queue), role_(role), - filename_(configuration->property(role_ + ".filename"s, "../data/example_capture.dat"s)), - dump_filename_(configuration->property(role_ + ".dump_filename"s, "../data/my_capture.dat"s)), + filename_(configuration->property(role_ + ".filename"s, "./example_capture.dat"s)), + dump_filename_(configuration->property(role_ + ".dump_filename"s, "./my_capture.dat"s)), item_type_(configuration->property(role_ + ".item_type"s, std::move(default_item_type))), item_size_(0), header_size_(configuration->property(role_ + ".header_size"s, uint64_t(0))), @@ -93,7 +97,8 @@ FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std: } } - // override value with commandline flag, if present +// override value with commandline flag, if present +#if USE_GLOG_AND_GFLAGS if (FLAGS_signal_source != "-") { filename_ = FLAGS_signal_source; @@ -102,6 +107,16 @@ FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std: { filename_ = FLAGS_s; } +#else + if (absl::GetFlag(FLAGS_signal_source) != "-") + { + filename_ = absl::GetFlag(FLAGS_signal_source); + } + if (absl::GetFlag(FLAGS_s) != "-") + { + filename_ = absl::GetFlag(FLAGS_s); + } +#endif if (sampling_frequency_ == 0) { std::cerr << "Warning: parameter " << role_ << ".sampling_frequency is not set, this could lead to wrong results.\n" diff --git a/src/algorithms/signal_source/adapters/file_timestamp_signal_source.cc b/src/algorithms/signal_source/adapters/file_timestamp_signal_source.cc index 8a7c2958f..0286c6ea3 100644 --- a/src/algorithms/signal_source/adapters/file_timestamp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/file_timestamp_signal_source.cc @@ -18,9 +18,14 @@ #include "file_timestamp_signal_source.h" #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; FileTimestampSignalSource::FileTimestampSignalSource(const ConfigurationInterface* configuration, @@ -29,7 +34,7 @@ FileTimestampSignalSource::FileTimestampSignalSource(const ConfigurationInterfac unsigned int out_streams, Concurrent_Queue* queue) : FileSourceBase(configuration, role, "File_Timestamp_Signal_Source"s, queue, "byte"s), - timestamp_file_(configuration->property(role + ".timestamp_filename"s, "../data/example_capture_timestamp.dat"s)), + timestamp_file_(configuration->property(role + ".timestamp_filename"s, "./example_capture_timestamp.dat"s)), timestamp_clock_offset_ms_(configuration->property(role + ".timestamp_clock_offset_ms"s, 0.0)) { if (in_streams > 0) @@ -41,11 +46,18 @@ FileTimestampSignalSource::FileTimestampSignalSource(const ConfigurationInterfac LOG(ERROR) << "This implementation only supports one output stream"; } - // override value with commandline flag, if present + // override value with commandline flag, if present +#if USE_GLOG_AND_GFLAGS if (FLAGS_timestamp_source != "-") { timestamp_file_ = FLAGS_timestamp_source; } +#else + if (absl::GetFlag(FLAGS_timestamp_source) != "-") + { + timestamp_file_ = absl::GetFlag(FLAGS_timestamp_source); + } +#endif } diff --git a/src/algorithms/signal_source/adapters/flexiband_signal_source.cc b/src/algorithms/signal_source/adapters/flexiband_signal_source.cc index 03065374e..1848b3da5 100644 --- a/src/algorithms/signal_source/adapters/flexiband_signal_source.cc +++ b/src/algorithms/signal_source/adapters/flexiband_signal_source.cc @@ -19,11 +19,16 @@ #include "flexiband_signal_source.h" #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; @@ -34,7 +39,7 @@ FlexibandSignalSource::FlexibandSignalSource(const ConfigurationInterface* confi Concurrent_Queue* queue __attribute__((unused))) : SignalSourceBase(configuration, role, "Flexiband_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream) { - const std::string default_item_type("byte"); + const std::string default_item_type("gr_complex"); item_type_ = configuration->property(role + ".item_type", default_item_type); const std::string default_firmware_file("flexiband_I-1b.bit"); diff --git a/src/algorithms/signal_source/adapters/flexiband_signal_source.h b/src/algorithms/signal_source/adapters/flexiband_signal_source.h index 7366d7ce9..47160a32a 100644 --- a/src/algorithms/signal_source/adapters/flexiband_signal_source.h +++ b/src/algorithms/signal_source/adapters/flexiband_signal_source.h @@ -66,10 +66,10 @@ public: gr::basic_block_sptr get_right_block(int RF_channel) override; private: - boost::shared_ptr flexiband_source_; + gnss_shared_ptr flexiband_source_; - std::vector> char_to_float; - std::vector> float_to_complex_; + std::vector> char_to_float; + std::vector> float_to_complex_; std::vector null_sinks_; std::string item_type_; diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc index c68ce03aa..e2a516a36 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.cc @@ -24,12 +24,17 @@ #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" -#include #include // for max #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configuration, @@ -70,7 +75,11 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu rf_dc_(configuration->property(role + ".rf_dc", true)), bb_dc_(configuration->property(role + ".bb_dc", true)), filter_auto_(configuration->property(role + ".filter_auto", false)), +#if USE_GLOG_AND_GFLAGS rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)), +#else + rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))), +#endif dump_(configuration->property(role + ".dump", false)) { if (filter_auto_) diff --git a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h index 4bfc78cda..fa0ae8fad 100644 --- a/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h +++ b/src/algorithms/signal_source/adapters/fmcomms2_signal_source.h @@ -93,7 +93,7 @@ private: double rf_gain_rx1_; double rf_gain_rx2_; - uint64_t freq_; // frequency of local oscilator + uint64_t freq_; // frequency of local oscillator uint64_t sample_rate_; uint64_t bandwidth_; uint64_t buffer_size_; // reception buffer diff --git a/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.cc new file mode 100644 index 000000000..f52c67425 --- /dev/null +++ b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.cc @@ -0,0 +1,344 @@ +/*! + * \file fmcomms5_signal_source_fpga.cc + * \brief Signal source for the Analog Devices FMCOMMS5 directly connected + * to the FPGA accelerators. + * This source implements only the AD9361 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * Please use the fmcomms2 source if conventional SDR acquisition and tracking + * is selected in the configuration file. + * \authors
      + *
    • Javier Arribas, jarribas(at)cttc.es + *
    • Marc Majoral, mmajoral(at)cttc.es + *
    + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "fmcomms5_signal_source_fpga.h" +#include "GPS_L1_CA.h" +#include "GPS_L5.h" +#include "ad9361_manager.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::max +#include // for std::chrono +#include // for std::floor +#include // for std::exception +#include // for std::cout + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +Fmcomms5SignalSourceFPGA::Fmcomms5SignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "FMCOMMS5_Signal_Source_FPGA"s), + gain_mode_rx1_(configuration->property(role + ".gain_mode_rx1", default_gain_mode)), + gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), + rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), + filter_source_(configuration->property(role + ".filter_source", std::string("Off"))), + filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), + rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), + rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), + freq0_(configuration->property(role + ".freq0", static_cast(GPS_L1_FREQ_HZ))), + freq1_(configuration->property(role + ".freq1", static_cast(GPS_L5_FREQ_HZ))), + sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), + bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), + Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), + Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), + in_stream_(in_stream), + out_stream_(out_stream), + item_size_(sizeof(int8_t)), + quadrature_(configuration->property(role + ".quadrature", true)), + rf_dc_(configuration->property(role + ".rf_dc", true)), + bb_dc_(configuration->property(role + ".bb_dc", true)), + rx1_enable_(configuration->property(role + ".rx1_enable", true)), + rx2_enable_(configuration->property(role + ".rx2_enable", true)), + enable_dynamic_bit_selection_(configuration->property(role + ".enable_dynamic_bit_selection", true)), + enable_ovf_check_buffer_monitor_active_(true), + dump_(configuration->property(role + ".dump", false)), +#if USE_GLOG_AND_GFLAGS + rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)) +#else + rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))) +#endif +{ + const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || + (configuration->property("Channels_1B.count", 0) > 0)); + const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || + (configuration->property("Channels_L5.count", 0) > 0) || + (configuration->property("Channels_5X.count", 0) > 0)); + + const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1; + + switch_fpga = std::make_shared(); + switch_fpga->set_switch_position(switch_to_real_time_mode); + + std::cout << "Sample rate: " << sample_rate_ << " Sps\n"; + + // some basic checks + if ((rf_port_select_ != "A_BALANCED") && (rf_port_select_ != "B_BALANCED") && (rf_port_select_ != "A_N") && (rf_port_select_ != "B_N") && (rf_port_select_ != "B_P") && (rf_port_select_ != "C_N") && (rf_port_select_ != "C_P") && (rf_port_select_ != "TX_MONITOR1") && (rf_port_select_ != "TX_MONITOR2") && (rf_port_select_ != "TX_MONITOR1_2")) + { + std::cout << "Configuration parameter rf_port_select should take one of these values:\n"; + std::cout << " A_BALANCED, B_BALANCED, A_N, B_N, B_P, C_N, C_P, TX_MONITOR1, TX_MONITOR2, TX_MONITOR1_2\n"; + std::cout << "Error: provided value rf_port_select=" << rf_port_select_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_port_select=" << default_rf_port_select << '\n'; + rf_port_select_ = default_rf_port_select; + LOG(WARNING) << "Invalid configuration value for rf_port_select parameter. Set to rf_port_select=" << default_rf_port_select; + } + + if ((gain_mode_rx1_ != "manual") && (gain_mode_rx1_ != "slow_attack") && (gain_mode_rx1_ != "fast_attack") && (gain_mode_rx1_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx1 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx1=" << gain_mode_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx1=" << default_gain_mode << '\n'; + gain_mode_rx1_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx1 parameter. Set to gain_mode_rx1=" << default_gain_mode; + } + + if ((gain_mode_rx2_ != "manual") && (gain_mode_rx2_ != "slow_attack") && (gain_mode_rx2_ != "fast_attack") && (gain_mode_rx2_ != "hybrid")) + { + std::cout << "Configuration parameter gain_mode_rx2 should take one of these values:\n"; + std::cout << " manual, slow_attack, fast_attack, hybrid\n"; + std::cout << "Error: provided value gain_mode_rx2=" << gain_mode_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value gain_mode_rx2=" << default_gain_mode << '\n'; + gain_mode_rx2_ = default_gain_mode; + LOG(WARNING) << "Invalid configuration value for gain_mode_rx2 parameter. Set to gain_mode_rx2=" << default_gain_mode; + } + + if (gain_mode_rx1_ == "manual") + { + if (rf_gain_rx1_ > 73.0 || rf_gain_rx1_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx1 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx1=" << rf_gain_rx1_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx1=" << default_manual_gain_rx1 << '\n'; + rf_gain_rx1_ = default_manual_gain_rx1; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx1 parameter. Set to rf_gain_rx1=" << default_manual_gain_rx1; + } + } + + if (gain_mode_rx2_ == "manual") + { + if (rf_gain_rx2_ > 73.0 || rf_gain_rx2_ < -1.0) + { + std::cout << "Configuration parameter rf_gain_rx2 should take values between -1.0 and 73 dB\n"; + std::cout << "Error: provided value rf_gain_rx2=" << rf_gain_rx2_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value rf_gain_rx2=" << default_manual_gain_rx2 << '\n'; + rf_gain_rx2_ = default_manual_gain_rx2; + LOG(WARNING) << "Invalid configuration value for rf_gain_rx2 parameter. Set to rf_gain_rx2=" << default_manual_gain_rx2; + } + } + + if ((filter_source_ != "Off") && (filter_source_ != "Auto") && (filter_source_ != "File") && (filter_source_ != "Design")) + { + std::cout << "Configuration parameter filter_source should take one of these values:\n"; + std::cout << " Off: Disable filter\n"; + std::cout << " Auto: Use auto-generated filters\n"; + std::cout << " File: User-provided filter in filter_filename parameter\n"; + std::cout << " Design: Create filter from Fpass, Fstop, sampling_frequency and bandwidth parameters\n"; + std::cout << "Error: provided value filter_source=" << filter_source_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value filter_source=Off\n"; + filter_source_ = std::string("Off"); + LOG(WARNING) << "Invalid configuration value for filter_source parameter. Set to filter_source=Off"; + } + + if (bandwidth_ < 200000 || bandwidth_ > 56000000) + { + std::cout << "Configuration parameter bandwidth should take values between 200000 and 56000000 Hz\n"; + std::cout << "Error: provided value bandwidth=" << bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value bandwidth=" << default_bandwidth << '\n'; + bandwidth_ = default_bandwidth; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth=" << default_bandwidth; + } + + if (enable_rx1_band) + { + std::cout << "LO 0 frequency : " << freq0_ << " Hz\n"; + } + if (enable_rx2_band) + { + std::cout << "LO 1 frequency : " << freq1_ << " Hz\n"; + } + try + { + config_ad9361_rx_local(bandwidth_, + sample_rate_, + freq0_, + freq1_, + rf_port_select_, + rx1_enable_, + rx2_enable_, + gain_mode_rx1_, + gain_mode_rx2_, + rf_gain_rx1_, + rf_gain_rx2_, + quadrature_, + rf_dc_, + bb_dc_, + filter_source_, + filter_filename_, + Fpass_, + Fstop_); + } + catch (const std::runtime_error &e) + { + std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; + return; + } + + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + + buffer_monitor_fpga = std::make_shared(num_freq_bands, dump_, dump_filename); + thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); + + // dynamic bits selection + if (enable_dynamic_bit_selection_) + { + dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); + thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); + } + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +Fmcomms5SignalSourceFPGA::~Fmcomms5SignalSourceFPGA() +{ + // cleanup and exit + if (rf_shutdown_) + { + std::cout << "* Disabling RX streaming channels\n"; + try + { + if (!disable_ad9361_rx_local()) + { + LOG(WARNING) << "Problem shutting down the AD9361 RX channels"; + } + } + catch (const std::exception &e) + { + std::cerr << "Problem shutting down the AD9361 RX channels: " << e.what() << '\n'; + } + } + + // disable buffer overflow checking and buffer monitoring + { + std::lock_guard lock_buffer_monitor(buffer_monitor_mutex); + enable_ovf_check_buffer_monitor_active_ = false; + } + + if (thread_buffer_monitor.joinable()) + { + thread_buffer_monitor.join(); + } + bool bit_selection_enabled = false; + { + std::lock_guard lock_dyn_bit_sel(dynamic_bit_selection_mutex); + bit_selection_enabled = enable_dynamic_bit_selection_; + } + + if (bit_selection_enabled == true) + { + { + std::lock_guard lock(dynamic_bit_selection_mutex); + enable_dynamic_bit_selection_ = false; + } + + if (thread_dynamic_bit_selection.joinable()) + { + thread_dynamic_bit_selection.join(); + } + } +} + + +void Fmcomms5SignalSourceFPGA::run_dynamic_bit_selection_process() +{ + bool dynamic_bit_selection_active = true; + + while (dynamic_bit_selection_active) + { + // setting the bit selection to the top bits + dynamic_bit_selection_fpga->bit_selection(); + std::this_thread::sleep_for(std::chrono::milliseconds(Gain_control_period_ms)); + std::lock_guard lock(dynamic_bit_selection_mutex); + if (enable_dynamic_bit_selection_ == false) + { + dynamic_bit_selection_active = false; + } + } +} + + +void Fmcomms5SignalSourceFPGA::run_buffer_monitor_process() +{ + bool enable_ovf_check_buffer_monitor_active = true; + + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); + + while (enable_ovf_check_buffer_monitor_active) + { + buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); + std::lock_guard lock(buffer_monitor_mutex); + if (enable_ovf_check_buffer_monitor_active_ == false) + { + enable_ovf_check_buffer_monitor_active = false; + } + } +} + + +void Fmcomms5SignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void Fmcomms5SignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr Fmcomms5SignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr Fmcomms5SignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.h b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.h new file mode 100644 index 000000000..fbb10bf67 --- /dev/null +++ b/src/algorithms/signal_source/adapters/fmcomms5_signal_source_fpga.h @@ -0,0 +1,130 @@ +/*! + * \file fmcomms5_signal_source_fpga.h + * \brief Signal source for the Analog Devices FMCOMMS5 directly connected + * to the FPGA accelerators. + * This source implements only the AD9361 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * Please use the fmcomms2 source if conventional SDR acquisition and tracking + * is selected in the configuration file. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H + +#include "concurrent_queue.h" +#include "fpga_buffer_monitor.h" +#include "fpga_dynamic_bit_selection.h" +#include "fpga_switch.h" +#include "gnss_block_interface.h" +#include "signal_source_base.h" +#include +#include +#include +#include +#include +#include + + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + + +class ConfigurationInterface; + +class Fmcomms5SignalSourceFPGA : public SignalSourceBase +{ +public: + Fmcomms5SignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, + unsigned int out_stream, Concurrent_Queue *queue); + + ~Fmcomms5SignalSourceFPGA(); + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + +private: + const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); + const std::string default_rf_port_select = std::string("A_BALANCED"); + const std::string default_gain_mode = std::string("slow_attack"); + const double default_manual_gain_rx1 = 64.0; + const double default_manual_gain_rx2 = 64.0; + const uint64_t default_bandwidth = 12500000; + + // perform dynamic bit selection every 500 ms by default + const uint32_t Gain_control_period_ms = 500; + // check buffer overflow and perform buffer monitoring every 1s by default + const uint32_t buffer_monitor_period_ms = 1000; + // buffer overflow and buffer monitoring initial delay + const uint32_t buffer_monitoring_initial_delay_ms = 2000; + const int32_t switch_to_real_time_mode = 2; + + void run_dynamic_bit_selection_process(); + void run_buffer_monitor_process(); + + mutable std::mutex dynamic_bit_selection_mutex; + mutable std::mutex buffer_monitor_mutex; + + std::thread thread_dynamic_bit_selection; + std::thread thread_buffer_monitor; + + std::shared_ptr switch_fpga; + std::shared_ptr dynamic_bit_selection_fpga; + std::shared_ptr buffer_monitor_fpga; + + std::string gain_mode_rx1_; + std::string gain_mode_rx2_; + std::string rf_port_select_; + std::string filter_file_; + std::string filter_source_; + std::string filter_filename_; + + double rf_gain_rx1_; + double rf_gain_rx2_; + + uint64_t freq0_; // frequency of local oscillator for ADRV9361-A + uint64_t freq1_; // frequency of local oscillator for ADRV9361-B + uint64_t sample_rate_; + uint64_t bandwidth_; + + float Fpass_; + float Fstop_; + uint32_t in_stream_; + uint32_t out_stream_; + + size_t item_size_; + + bool quadrature_; + bool rf_dc_; + bool bb_dc_; + bool rx1_enable_; + bool rx2_enable_; + bool enable_dynamic_bit_selection_; + bool enable_ovf_check_buffer_monitor_active_; + bool dump_; + bool rf_shutdown_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_FMCOMMS5_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.cc b/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.cc index 7052f0a4c..2de8b994b 100644 --- a/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.cc @@ -19,7 +19,12 @@ #include "configuration_interface.h" #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif using namespace std::string_literals; @@ -58,11 +63,18 @@ FourBitCpxFileSignalSource::FourBitCpxFileSignalSource( LOG(ERROR) << "This implementation only supports one output stream"; } - // override value with commandline flag, if present + // override value with commandline flag, if present +#if USE_GLOG_AND_GFLAGS if (FLAGS_timestamp_source != "-") { timestamp_file_ = FLAGS_timestamp_source; } +#else + if (absl::GetFlag(FLAGS_timestamp_source) != "-") + { + timestamp_file_ = absl::GetFlag(FLAGS_timestamp_source); + } +#endif } diff --git a/src/algorithms/signal_source/adapters/gen_signal_source.cc b/src/algorithms/signal_source/adapters/gen_signal_source.cc index a87f77b12..388131815 100644 --- a/src/algorithms/signal_source/adapters/gen_signal_source.cc +++ b/src/algorithms/signal_source/adapters/gen_signal_source.cc @@ -18,12 +18,16 @@ #include "gen_signal_source.h" #include -#include #include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif // Constructor GenSignalSource::GenSignalSource(std::shared_ptr signal_generator, diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc new file mode 100644 index 000000000..c92c35433 --- /dev/null +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -0,0 +1,239 @@ +/*! + * \file ion_gsms_signal_source.h + * \brief GNSS-SDR Signal Source that reads sample streams following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "ion_gsms_signal_source.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include "gnss_sdr_valve.h" +#include +#include +#include +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +using namespace std::string_literals; + +namespace +{ +std::vector parse_comma_list(const std::string& str) +{ + std::vector list{}; + std::size_t prev_comma_at{0}; + + while (prev_comma_at < str.size()) + { + std::size_t comma_at = str.find_first_of(',', prev_comma_at); + if (comma_at == std::string::npos) + { + comma_at = str.size(); + } + list.emplace_back(str.substr(prev_comma_at, (comma_at - prev_comma_at))); + prev_comma_at = comma_at + 1; + } + + return list; +} +} // anonymous namespace + + +IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams, + Concurrent_Queue* queue) + : SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s), + stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), + metadata_filepath_(configuration->property(role + ".metadata_filename"s, "./example_capture_metadata.sdrx"s)), + in_streams_(in_streams), + out_streams_(out_streams) +{ + if (in_streams_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_streams_ <= 0) + { + LOG(ERROR) << "A signal source does not have an output stream"; + } + + // Parse XML metadata file + load_metadata(); + + // Make source vector + sources_ = make_stream_sources(stream_ids_); + + for (const auto& source : sources_) + { + for (std::size_t i = 0; i < source->output_stream_count(); ++i) + { + copy_blocks_.emplace_back(gr::blocks::copy::make(source->output_stream_item_size(i))); + valves_.emplace_back(gnss_sdr_make_valve(source->output_stream_item_size(i), source->output_stream_total_sample_count(i), queue)); + } + } +} + + +void IONGSMSSignalSource::load_metadata() +{ + metadata_ = std::make_shared(); + try + { + GnssMetadata::XmlProcessor xml_proc; + if (!xml_proc.Load(metadata_filepath_.c_str(), false, *metadata_)) + { + LOG(WARNING) << "Could not load XML metadata file " << metadata_filepath_; + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } + } + catch (GnssMetadata::ApiException& e) + { + LOG(WARNING) << "API Exception while loading XML metadata file: " << std::to_string(e.Error()); + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << std::to_string(e.Error()) << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } + catch (std::exception& e) + { + LOG(WARNING) << "Exception while loading XML metadata file: " << e.what(); + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << e.what() << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } +} + + +std::vector IONGSMSSignalSource::make_stream_sources(const std::vector& stream_ids) const +{ + std::vector sources{}; + for (const auto& file : metadata_->Files()) + { + for (const auto& lane : metadata_->Lanes()) + { + if (lane.Id() == file.Lane().Id()) + { + for (const auto& block : lane.Blocks()) + { + bool block_done = false; + for (const auto& chunk : block.Chunks()) + { + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + bool found = false; + for (const auto& stream_id : stream_ids) + { + if (stream_id == stream.Id()) + { + found = true; + break; + } + } + if (found) + { + auto source = gnss_make_shared( + metadata_filepath_, + file, + block, + stream_ids); + + sources.push_back(source); + + // This file source will take care of any other matching streams in this block + // We can skip the rest of this block + block_done = true; + break; + } + } + + if (block_done) + { + break; + } + } + if (block_done) + { + break; + } + } + } + break; + } + } + } + + return sources; +} + + +void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) +{ + std::size_t cumulative_index = 0; + for (const auto& source : sources_) + { + for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) + { + top_block->connect(source, i, copy_blocks_[cumulative_index], 0); + top_block->connect(copy_blocks_[cumulative_index], 0, valves_[cumulative_index], 0); + } + } +} + + +void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block) +{ + std::size_t cumulative_index = 0; + for (const auto& source : sources_) + { + for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) + { + top_block->disconnect(source, i, copy_blocks_[cumulative_index], 0); + top_block->disconnect(copy_blocks_[cumulative_index], 0, valves_[cumulative_index], 0); + } + } +} + + +gr::basic_block_sptr IONGSMSSignalSource::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + // return gr_basic_block_sptr(); + return IONGSMSFileSource::sptr(); +} + + +gr::basic_block_sptr IONGSMSSignalSource::get_right_block() +{ + return get_right_block(0); +} + + +gr::basic_block_sptr IONGSMSSignalSource::get_right_block(int RF_channel) +{ + if (RF_channel < 0 || RF_channel >= static_cast(copy_blocks_.size())) + { + LOG(WARNING) << "'RF_channel' out of bounds while trying to get signal source right block."; + return valves_[0]; + } + return valves_[RF_channel]; +} diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h new file mode 100644 index 000000000..bcdedbc3d --- /dev/null +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -0,0 +1,85 @@ +/*! + * \file ion_gsms_signal_source.h + * \brief GNSS-SDR Signal Source that reads sample streams following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_ION_GSMS_SIGNAL_SOURCE_H +#define GNSS_SDR_ION_GSMS_SIGNAL_SOURCE_H + +#include "configuration_interface.h" +#include "file_source_base.h" +#include "gnss_sdr_timestamp.h" +#include "ion_gsms.h" +#include +#include +#include +#include +#include + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + +/*! + * \brief Class that reads signals samples from a file + * and adapts it to a SignalSourceInterface + */ +class IONGSMSSignalSource : public SignalSourceBase +{ +public: + IONGSMSSignalSource(const ConfigurationInterface* configuration, const std::string& role, + unsigned int in_streams, unsigned int out_streams, + Concurrent_Queue* queue); + + ~IONGSMSSignalSource() override = default; + +protected: + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + gr::basic_block_sptr get_right_block(int RF_channel) override; + + inline size_t item_size() override + { + return (*sources_.begin())->output_stream_item_size(0); + } + +private: + std::vector make_stream_sources(const std::vector& stream_ids) const; + + void load_metadata(); + + std::vector stream_ids_; + std::vector sources_; + std::vector> copy_blocks_; + std::vector> valves_; + + std::string metadata_filepath_; + std::shared_ptr metadata_; + + gnss_shared_ptr timestamp_block_; + std::string timestamp_file_; + + uint32_t in_streams_; + uint32_t out_streams_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_ION_GSMS_SIGNAL_SOURCE_H diff --git a/src/algorithms/signal_source/adapters/labsat_signal_source.cc b/src/algorithms/signal_source/adapters/labsat_signal_source.cc index 30760ce97..75bd7dc54 100644 --- a/src/algorithms/signal_source/adapters/labsat_signal_source.cc +++ b/src/algorithms/signal_source/adapters/labsat_signal_source.cc @@ -18,9 +18,15 @@ #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" #include "labsat23_source.h" -#include #include #include +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/limesdr_signal_source.cc b/src/algorithms/signal_source/adapters/limesdr_signal_source.cc index a8168bd82..28f3a3a68 100644 --- a/src/algorithms/signal_source/adapters/limesdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/limesdr_signal_source.cc @@ -20,10 +20,15 @@ #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" #include -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; LimesdrSignalSource::LimesdrSignalSource(const ConfigurationInterface* configuration, diff --git a/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.cc b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.cc new file mode 100644 index 000000000..80b310034 --- /dev/null +++ b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.cc @@ -0,0 +1,464 @@ +/*! + * \file max2771_evkit_signal_source_fpga.cc + * \brief Signal source for the MAX2771EVKIT evaluation board connected directly + * to FPGA accelerators. + * This source implements only the MAX2771 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "max2771_evkit_signal_source_fpga.h" +#include "GPS_L1_CA.h" +#include "GPS_L2C.h" +#include "GPS_L5.h" +#include "configuration_interface.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include // for std::max +#include // for std::chrono +#include // for std::floor +#include // for std::exception +#include // for std::cout +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + +using namespace std::string_literals; + +MAX2771EVKITSignalSourceFPGA::MAX2771EVKITSignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, unsigned int out_stream, + Concurrent_Queue *queue __attribute__((unused))) + : SignalSourceBase(configuration, role, "MAX2771_EVKIT_Signal_Source_FPGA"s), + freq_(configuration->property(role + ".freq", static_cast(GPS_L1_FREQ_HZ))), + sample_rate_(configuration->property(role + ".sampling_frequency", default_sampling_rate)), + in_stream_(in_stream), + out_stream_(out_stream), + bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), + filter_order_(configuration->property(role + ".filter_order", default_filter_order)), + gain_in_(configuration->property(role + ".PGA_gain", default_PGA_gain_value)), + item_size_(sizeof(int8_t)), + chipen_(true), + if_filter_gain_(configuration->property(role + ".enable_IF_filter_gain", true)), + LNA_active_(configuration->property(role + ".LNA_active", false)), + enable_agc_(configuration->property(role + ".enable_AGC", true)), + enable_ovf_check_buffer_monitor_active_(true), + dump_(configuration->property(role + ".dump", false)), +#if USE_GLOG_AND_GFLAGS + rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)) +#else + rf_shutdown_(configuration->property(role + ".rf_shutdown", absl::GetFlag(FLAGS_rf_shutdown))) +#endif +{ + // some basic checks + if (freq_ != GPS_L1_FREQ_HZ and freq_ != GPS_L2_FREQ_HZ and freq_ != GPS_L5_FREQ_HZ) + { + std::cout << "Configuration parameter freq should take values " << GPS_L1_FREQ_HZ << ", " << GPS_L2_FREQ_HZ << ", or " << GPS_L5_FREQ_HZ << "\n"; + std::cout << "Error: provided value freq = " << freq_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value freq = " << GPS_L1_FREQ_HZ << '\n'; + LOG(WARNING) << "Invalid configuration value for freq parameter. Set to freq = " << GPS_L1_FREQ_HZ; + freq_ = GPS_L1_FREQ_HZ; + } + if (sample_rate_ != 4092000 and sample_rate_ != 8184000 and sample_rate_ != 16368000 and sample_rate_ != 32736000) + { + std::cout << "Configuration parameter sampling_frequency should take values 4092000, 8184000, 16368000, or 32736000\n"; + std::cout << "Error: provided value sampling_frequency = " << sample_rate_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value sampling_frequency = " << default_sampling_rate << '\n'; + LOG(WARNING) << "Invalid configuration value for sampling_frequency parameter. Set to sampling_frequency = " << default_sampling_rate; + sample_rate_ = default_sampling_rate; + } + if (bandwidth_ != 2500000 and bandwidth_ != 4200000 and bandwidth_ != 8700000 and bandwidth_ != 16400000 and bandwidth_ != 23400000 and bandwidth_ != 36000000) + { + std::cout << "Configuration parameter bandwidth can only take the following values: 2500000, 4200000, 8700000, 16400000, 23400000, and 36000000 Hz\n"; + std::cout << "Error: provided value bandwidth = " << bandwidth_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value bandwidth = " << default_bandwidth << '\n'; + LOG(WARNING) << "Invalid configuration value for bandwidth parameter. Set to bandwidth = " << default_bandwidth; + bandwidth_ = default_bandwidth; + } + if (filter_order_ != 3 and filter_order_ != 5) + { + std::cout << "Configuration parameter filter_order should take values 3 or 5\n"; + std::cout << "Error: provided value filter_order = " << filter_order_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value filter_order = " << default_filter_order << '\n'; + LOG(WARNING) << "Invalid configuration value for filter_order parameter. Set to filter_order = " << default_filter_order; + filter_order_ = default_filter_order; + } + if (gain_in_ > max_PGA_gain_value) + { + std::cout << "Configuration parameter PGA_gain should be up to " << max_PGA_gain_value << "\n"; + std::cout << "Error: provided value PGA_gain = " << gain_in_ << " is not among valid values\n"; + std::cout << " This parameter has been set to its default value PGA_gain = " << default_PGA_gain_value << '\n'; + LOG(WARNING) << "Invalid configuration value for PGA_gain parameter. Set to PGA_gain = " << default_PGA_gain_value; + gain_in_ = default_PGA_gain_value; + } + + std::vector register_values = setup_regs(); + + spidev_fpga = std::make_shared(); + + if (spidev_fpga->SPI_open()) + { + std::cerr << "Cannot open SPI device\n"; + // stop the receiver + queue->push(pmt::make_any(command_event_make(200, 0))); + return; + } + + if (configure(register_values)) + { + std::cerr << "Error configuring the MAX2771 device " << '\n'; + } + + if (spidev_fpga->SPI_close()) + { + std::cerr << "Error closing SPI device " << '\n'; + } + + std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); + + buffer_monitor_fpga = std::make_shared(NUM_FREQ_BANDS, dump_, dump_filename); + thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); + + if (in_stream_ > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_stream_ > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +std::vector MAX2771EVKITSignalSourceFPGA::setup_regs(void) +{ + auto register_values = std::vector(MAX2771_NUM_REGS); + uint32_t LNA_mode = (LNA_active_) ? 0x0 : 0x2; + uint32_t Filter_Bandwidth; + + switch (bandwidth_) + { + case 2500000: + Filter_Bandwidth = 0x0; + break; + case 4200000: + Filter_Bandwidth = 0x2; + break; + case 8700000: + Filter_Bandwidth = 0x1; + break; + case 16400000: + Filter_Bandwidth = 0x7; + break; + case 23400000: + Filter_Bandwidth = 0x3; + break; + case 36000000: + Filter_Bandwidth = 0x4; + break; + default: + Filter_Bandwidth = 0x0; // default bandwidth + } + + uint32_t chipen_select = (chipen_) ? 0x1 : 0x0; + uint32_t Filter_order_sel = (filter_order_ == 5) ? 0x0 : 0x1; + uint32_t IF_filter_gain_sel = (if_filter_gain_) ? 0x1 : 0x0; + + register_values[0] = // configuration 1 register + (chipen_select << 31) + + (IDLE << 30) + + (0x8 << 26) + // reserved + (0x8 << 22) + // reserved + (0x2 << 20) + // reserved + (0x1 << 18) + // reserved + (MIXPOLE << 17) + + (LNA_mode << 15) + + (MIXERMODE << 13) + + (FCEN << 6) + + (Filter_Bandwidth << 3) + + (Filter_order_sel << 2) + + (FCENX << 1) + + IF_filter_gain_sel; + + uint32_t AGC_mode = (enable_agc_) ? 0x0 : 0x2; + + register_values[1] = // configuration 2 register + (0x0 << 31) + // reserved + (0x1 << 29) + // reserved + (ANAIMON << 28) + + (IQEN << 27) + + (GAINREF << 15) + + (SPI_SDIO_CONFIG << 13) + + (AGC_mode << 11) + + (FORMAT << 9) + + (BITS << 6) + + (DRVCFG << 4) + + (0x1 << 3) + // reserved + (0x0 << 2) + // reserved + DIEID; + + register_values[2] = // configuration 3 register + (0x0 << 28) + // reserved + (gain_in_ << 22) + + (0x1 << 21) + // reserved + (HILOADEN << 20) + + (0x1 << 19) + // reserved + (0x1 << 18) + // reserved + (0x1 << 17) + // reserved + (0x1 << 16) + // reserved + (FHIPEN << 15) + + (0x0 << 14) + // reserved + (PGAIEN << 13) + + (PGAQEN << 12) + + (STRMEN << 11) + + (STRMSTART << 10) + + (STRMSTOP << 9) + + (0x7 << 6) + // reserved + (STRMBITS << 4) + + (STAMPEN << 3) + + (TIMESYNCEN << 2) + + (DATASYNCEN << 1) + + STRMRST; + + uint32_t clock_out_div_ratio; + + switch (sample_rate_) + { + case 4092000: + clock_out_div_ratio = 0x1; // XTAL frequency /4 + break; + case 8184000: + clock_out_div_ratio = 0x2; // XTAL frequency /2 + break; + case 16368000: + clock_out_div_ratio = 0x3; // XTAL frequency + break; + case 32736000: + clock_out_div_ratio = 0x0; // XTAL Frequency x2 + break; + default: + clock_out_div_ratio = 0x1; // default XTAL frequency + } + + register_values[3] = // PLL configuration register + (clock_out_div_ratio << 29) + + (LOBAND << 28) + + (0x1 << 27) + // reserved + (0x0 << 26) + // reserved + (0x0 << 25) + // reserved + (REFOUTEN << 24) + + (0x1 << 23) + // reserved + (0x0 << 21) + // reserved + (IXTAL << 19) + + (0x10 << 14) + // reserved + (0x0 << 13) + // reserved + (0x0 << 10) + // reserved + (ICP << 9) + + (0x0 << 8) + // reserved + (0x0 << 7) + // reserved + (0x0 << 4) + // reserved + (INT_PLL << 3) + + (PWRSAV << 2) + + (0x0 << 1) + // reserved + 0x0; // reserved + + uint32_t freq_sel; + switch (freq_) + { + case static_cast(GPS_L1_FREQ_HZ): + freq_sel = 0x604; + break; + case static_cast(GPS_L2_FREQ_HZ): + freq_sel = 0x4B0; + break; + case static_cast(GPS_L5_FREQ_HZ): + freq_sel = 0x47E; + break; + default: + freq_sel = 0x604; + } + + register_values[4] = // PLL integer division register + (0x0 << 28) + // reserved + (freq_sel << 13) + + (RDIV << 3) + + 0x0; // reserved + + register_values[5] = // PLL fractional division register + (0x0 << 28) + // reserved + (FDIV << 8) + + (0x7 << 4) + // reserved + (0x0 << 3) + // reserved + (0x0 << 2) + // reserved + (0x0 << 1) + // reserved + 0x0; // reserved + + register_values[6] = // DSP interface register + (0x0 << 28) + // reserved + 0x8000000; // reserved + + register_values[7] = // clock configuration 1 register + (0x0 << 29) + // reserved + (EXTADCCLK << 28) + + (REFCLK_L_CNT << 16) + + (REFCLK_M_CNT << 4) + + (FCLKIN << 3) + + (ADCCLK << 2) + + (0x1 << 1) + // reserved + MODE; + + register_values[8] = TEST_MODE_1_REG_VAL; // test mode 1 register + + register_values[9] = TEST_MODE_2_REG_VAL; // test mode 2 register + + register_values[10] = // clock configuration 2 register + (0x0 << 29) + // reserved + (0x0 << 28) + // reserved + (ADCCLK_L_CNT << 16) + + (ADCCLK_M_CNT << 4) + + (PRE_FRACDIV_SEL << 3) + + (CLKOUT_SEL << 2) + + 0x0; // reserved + + return register_values; +} + + +bool MAX2771EVKITSignalSourceFPGA::configure(std::vector register_values) +{ + // write the registers + std::cerr << "Configuring MAX2771 registers" << std::endl; + uint32_t status = 0; + for (uint32_t k = 0; k < register_values.size(); k++) + { + status = spidev_fpga->write_reg32(k, register_values[k]); + if (status) + { + std::cerr << "Error writing the MAX2771 registers" << std::endl; + break; + } + } + + // Read the registers and verify that the values are correctly written + std::vector reg_read = std::vector(register_values.size()); + + for (uint8_t n = 0; n < register_values.size(); ++n) + { + status = spidev_fpga->read_reg32(n, ®_read[n]); + if (status) + { + std::cerr << "Error reading the MAX2771 registers" << std::endl; + return status; + } + else + { + if (reg_read[n] != register_values[n]) + { + std::cerr << "Error: Failed to verify the MAX2771 registers " << std::endl; + return -1; + } + } + } + + return 0; +} + + +MAX2771EVKITSignalSourceFPGA::~MAX2771EVKITSignalSourceFPGA() +{ + // cleanup and exit + if (rf_shutdown_) + { + chipen_ = false; + std::cout << "* MAX2771 Disabling RX streaming channels\n"; + std::vector register_values = setup_regs(); + + if (spidev_fpga->SPI_open()) + { + std::cerr << "Cannot open SPI device\n"; + return; + } + + if (configure(register_values)) + { + std::cerr << "Error disabling the MAX2771 device " << '\n'; + } + + if (spidev_fpga->SPI_close()) + { + std::cerr << "Error closing SPI device " << '\n'; + } + } + + // disable buffer overflow checking and buffer monitoring + { + std::lock_guard lock_buffer_monitor(buffer_monitor_mutex); + enable_ovf_check_buffer_monitor_active_ = false; + } + + if (thread_buffer_monitor.joinable()) + { + thread_buffer_monitor.join(); + } +} + + +void MAX2771EVKITSignalSourceFPGA::run_buffer_monitor_process() +{ + bool enable_ovf_check_buffer_monitor_active = true; + + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitoring_initial_delay_ms)); + + while (enable_ovf_check_buffer_monitor_active) + { + buffer_monitor_fpga->check_buffer_overflow_and_monitor_buffer_status(); + std::this_thread::sleep_for(std::chrono::milliseconds(buffer_monitor_period_ms)); + std::lock_guard lock(buffer_monitor_mutex); + if (enable_ovf_check_buffer_monitor_active_ == false) + { + enable_ovf_check_buffer_monitor_active = false; + } + } +} + + +void MAX2771EVKITSignalSourceFPGA::connect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to connect"; +} + + +void MAX2771EVKITSignalSourceFPGA::disconnect(gr::top_block_sptr top_block) +{ + if (top_block) + { /* top_block is not null */ + }; + DLOG(INFO) << "AD9361 FPGA source nothing to disconnect"; +} + + +gr::basic_block_sptr MAX2771EVKITSignalSourceFPGA::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + return {}; +} + + +gr::basic_block_sptr MAX2771EVKITSignalSourceFPGA::get_right_block() +{ + return {}; +} diff --git a/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.h b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.h new file mode 100644 index 000000000..5ba036ca3 --- /dev/null +++ b/src/algorithms/signal_source/adapters/max2771_evkit_signal_source_fpga.h @@ -0,0 +1,162 @@ +/*! + * \file max2771_evkit_signal_source_fpga.h + * \brief Signal source for the MAX2771EVKIT evaluation board connected directly + * to FPGA accelerators. + * This source implements only the MAX2771 control. It is NOT compatible with + * conventional SDR acquisition and tracking blocks. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_MAX2771_EVKIT_SIGNAL_SOURCE_FPGA_H +#define GNSS_SDR_MAX2771_EVKIT_SIGNAL_SOURCE_FPGA_H + +#include "command_event.h" +#include "concurrent_queue.h" +#include "fpga_buffer_monitor.h" +#include "fpga_spidev.h" +#include "gnss_block_interface.h" +#include "signal_source_base.h" +#include // for pmt::pmt_t +#include // for fixed-width integer types +#include // for smart pointers +#include // for mutex +#include // for strings +#include // for threads +#include // for std::vector + + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + + +class ConfigurationInterface; + +class MAX2771EVKITSignalSourceFPGA : public SignalSourceBase +{ +public: + MAX2771EVKITSignalSourceFPGA(const ConfigurationInterface *configuration, + const std::string &role, unsigned int in_stream, + unsigned int out_stream, Concurrent_Queue *queue); + + ~MAX2771EVKITSignalSourceFPGA(); + + std::vector setup_regs(void); + + inline size_t item_size() override + { + return item_size_; + } + + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; + +private: + const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); + const uint64_t default_bandwidth = 2500000; + const uint32_t default_filter_order = 5; + const uint64_t default_sampling_rate = 4092000; + const uint32_t default_PGA_gain_value = 0x3A; // default PGA gain when AGC is off + // max PGA gain value + const uint32_t max_PGA_gain_value = 0x3F; + // check buffer overflow and perform buffer monitoring every 1s by default + const uint32_t buffer_monitor_period_ms = 1000; + // buffer overflow and buffer monitoring initial delay + const uint32_t buffer_monitoring_initial_delay_ms = 2000; + // MAX2771 number of configuration registers + const uint32_t MAX2771_NUM_REGS = 11; + // MAX2771 configuration register fields + const uint32_t NUM_FREQ_BANDS = 1; + const uint32_t IDLE = 0x0; // Idle mode disabled + const uint32_t MIXPOLE = 0x0; // set the passive filter pole at mixer output at 13 MHz. + const uint32_t MIXERMODE = 0x0; // L1 band enabled + const uint32_t FCEN = 0x58; // Center frequency not used when in low-pass filter mode. Set to default value. + const uint32_t FCENX = 0x0; // POlyphase filter selection set to Lowpass filter + const uint32_t ANAIMON = 0x0; // analog monitor disabled + const uint32_t IQEN = 0x1; // I and Q channels enable + const uint32_t GAINREF = 0xAA; // AGC Gain ref + const uint32_t SPI_SDIO_CONFIG = 0x0; // SPI SDIO config when tri-stated: nothing applied + const uint32_t FORMAT = 0x1; // sign and magnitude + const uint32_t BITS = 0x2; // number of bits in the ADC = 2 + const uint32_t DRVCFG = 0x0; // output driver configuration = CMOS Logic + const uint32_t DIEID = 0x0; // identifies version of IC + const uint32_t HILOADEN = 0x0; // disable output driver for high loads + const uint32_t FHIPEN = 0x1; // enable highpass coupling between filter and PGA. + const uint32_t PGAIEN = 0x1; // I-Channel PGA Enable + const uint32_t PGAQEN = 0x1; // Q-Channel PGA Enable + const uint32_t STRMEN = 0x0; // disable DSP interface for serial streaming of data + const uint32_t STRMSTART = 0x0; // the rising edge of this bit enables data streaming to the output, clock, data, sync and frame sync outputs. + const uint32_t STRMSTOP = 0x0; // the rising edge of this bit disables data streaming to the output, clock, data sync and frame sync outputs. + const uint32_t STRMBITS = 0x1; // number of bits to be streamed: I MSB, I LSB + const uint32_t STAMPEN = 0x1; // enable frame number insertion + const uint32_t TIMESYNCEN = 0x1; // enable the output of the time sync pulses at all times when streaming is enabled. + const uint32_t DATASYNCEN = 0x0; // disable the sync pulses at the DATASYNC output + const uint32_t STRMRST = 0x0; // counter reset not active + const uint32_t LOBAND = 0x0; // L1 band + const uint32_t REFOUTEN = 0x1; // Output clock buffer enable + const uint32_t IXTAL = 0x1; // XTAL osscillator/buffer set to normal current + const uint32_t ICP = 0x0; // charge pump current selection set to 0.5 mA + const uint32_t INT_PLL = 0x1; // PLL mode set to integer-N PLL + const uint32_t PWRSAV = 0x0; // PLL power save mode disabled + const uint32_t RDIV = 0x10; // Set the PLL reference division ratio such that the L1 band is tuned to 1575.42 Mhz + const uint32_t FDIV = 0x80000; // PLL fractional division ratio not used. Set to default value + const uint32_t EXTADCCLK = 0x0; // use internally generated clock + const uint32_t REFCLK_L_CNT = 0x100; // set the L counter of the reference clock configuration to its default value + const uint32_t REFCLK_M_CNT = 0x61B; // set the M counter of the reference clock configuration to its default value + const uint32_t FCLKIN = 0x0; // fractional clock divider set to default value + const uint32_t ADCCLK = 0x0; // ADC clock selection set to reference clock divider/multiplier + const uint32_t MODE = 0x0; // DSP interface mode selection + const uint32_t ADCCLK_L_CNT = 0x100; // set the L counter of the ADC clock configuration to its default value + const uint32_t ADCCLK_M_CNT = 0x61B; // set the M counter of the ADC clock configuration to its default value + const uint32_t PRE_FRACDIV_SEL = 0x0; // bypass fractional clock divider + const uint32_t CLKOUT_SEL = 0x1; // CLKOUT selection set to ADC clock + // MAX2771 configuration register registers + const uint32_t TEST_MODE_1_REG_VAL = 0x01E0F401; // reserved + const uint32_t TEST_MODE_2_REG_VAL = 0x00000002; + + bool configure(std::vector register_values); + void run_buffer_monitor_process(); + + mutable std::mutex buffer_monitor_mutex; + + std::thread thread_buffer_monitor; + + std::shared_ptr buffer_monitor_fpga; + std::shared_ptr spidev_fpga; + + uint64_t freq_; // frequency of local oscillator + uint64_t sample_rate_; + + uint32_t in_stream_; + uint32_t out_stream_; + uint32_t bandwidth_; // 2500000, 4200000, 8700000, 16400000, 23400000, 36000000 + uint32_t filter_order_; // 3, 5 + uint32_t gain_in_; // 0 to 0x3F + + size_t item_size_; // 1 + + bool chipen_; // chip enable + bool if_filter_gain_; // true, false + bool LNA_active_; // true, false + bool enable_agc_; // true, false + bool enable_ovf_check_buffer_monitor_active_; + bool dump_; + bool rf_shutdown_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_MAX2771_EVKIT_SIGNAL_SOURCE_FPGA_H diff --git a/src/algorithms/signal_source/adapters/multichannel_file_signal_source.cc b/src/algorithms/signal_source/adapters/multichannel_file_signal_source.cc index fd7973d90..84271beea 100644 --- a/src/algorithms/signal_source/adapters/multichannel_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/multichannel_file_signal_source.cc @@ -20,13 +20,18 @@ #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" -#include #include #include #include #include // for std::cerr #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/nsr_file_signal_source.cc b/src/algorithms/signal_source/adapters/nsr_file_signal_source.cc index c86c11e76..1945f5f85 100644 --- a/src/algorithms/signal_source/adapters/nsr_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/nsr_file_signal_source.cc @@ -18,7 +18,12 @@ #include "nsr_file_signal_source.h" #include "gnss_sdr_string_literals.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc b/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc index f7ab32057..9071bf22c 100644 --- a/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc @@ -21,10 +21,15 @@ #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" #include -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; @@ -81,6 +86,23 @@ OsmosdrSignalSource::OsmosdrSignalSource(const ConfigurationInterface* configura std::cout << "PLL Frequency tune error: " << osmosdr_source_->get_center_freq() - freq_ << " [Hz]...\n"; LOG(INFO) << "PLL Frequency tune error: " << osmosdr_source_->get_center_freq() - freq_ << " [Hz]...\n"; + // Set IQ balance and DC offset modes + // iq balance correction mode: 0 = Off, 1 = Manual, 2 = Automatic + // dc offset correction mode: 0 = Off, 1 = Manual, 2 = Automatic + int iq_balance_mode = configuration->property(role + ".iq_balance_mode", 2); + if (iq_balance_mode < 0 || iq_balance_mode > 2) + { + iq_balance_mode = 2; + } + int dc_offset_mode = configuration->property(role + ".dc_offset_mode", 2); + if (dc_offset_mode < 0 || dc_offset_mode > 2) + { + dc_offset_mode = 2; + } + + osmosdr_source_->set_iq_balance_mode(iq_balance_mode); + osmosdr_source_->set_dc_offset_mode(dc_offset_mode); + // 4. set rx gain if (this->AGC_enabled_ == true) { @@ -123,10 +145,9 @@ OsmosdrSignalSource::OsmosdrSignalSource(const ConfigurationInterface* configura if (if_bw_ > 0.0) { osmosdr_source_->set_bandwidth(if_bw_, 0); + // Get actual bandwidth + std::cout << "Actual Bandwidth: " << osmosdr_source_->get_bandwidth(0) << " [Hz]...\n"; } - - // Get actual bandwidth - std::cout << "Actual Bandwidth: " << osmosdr_source_->get_bandwidth(0) << " [Hz]...\n"; } else { diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc index fd69989f7..f4b782400 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.cc @@ -20,9 +20,13 @@ #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h index 96e6702ae..573ded861 100644 --- a/src/algorithms/signal_source/adapters/plutosdr_signal_source.h +++ b/src/algorithms/signal_source/adapters/plutosdr_signal_source.h @@ -87,7 +87,7 @@ private: std::string item_type_; double rf_gain_; int64_t samples_; - uint64_t freq_; // frequency of local oscilator + uint64_t freq_; // frequency of local oscillator uint64_t sample_rate_; uint64_t bandwidth_; uint64_t buffer_size_; // reception buffer diff --git a/src/algorithms/signal_source/adapters/raw_array_signal_source.cc b/src/algorithms/signal_source/adapters/raw_array_signal_source.cc index b282aad24..18d563235 100644 --- a/src/algorithms/signal_source/adapters/raw_array_signal_source.cc +++ b/src/algorithms/signal_source/adapters/raw_array_signal_source.cc @@ -18,11 +18,15 @@ #include "concurrent_queue.h" #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc b/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc index 86da2608d..2e5849eb5 100644 --- a/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc @@ -22,11 +22,16 @@ #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" #include -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; RtlTcpSignalSource::RtlTcpSignalSource(const ConfigurationInterface* configuration, diff --git a/src/algorithms/signal_source/adapters/spir_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_file_signal_source.cc index 23d74e93b..63b89e54d 100644 --- a/src/algorithms/signal_source/adapters/spir_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_file_signal_source.cc @@ -17,8 +17,13 @@ #include "spir_file_signal_source.h" #include "gnss_sdr_string_literals.h" -#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index dead525be..1b29d773e 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -19,13 +19,19 @@ #include "spir_gss6450_file_signal_source.h" #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" -#include #include #include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#include +#endif + using namespace std::string_literals; SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(const ConfigurationInterface* configuration, @@ -48,8 +54,8 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(const ConfigurationInte enable_throttle_control_(configuration->property(role + ".enable_throttle_control", false)), endian_swap_(configuration->property(role + ".endian", false)) { - const std::string default_filename("../data/my_capture.dat"); - const std::string default_dump_filename("../data/my_capture_dump.dat"); + const std::string default_filename("./my_capture.dat"); + const std::string default_dump_filename("./my_capture_dump.dat"); filename_ = configuration->property(role + ".filename", default_filename); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); diff --git a/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc b/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc index 1350bded2..3c85bf02d 100644 --- a/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc @@ -17,7 +17,12 @@ #include "two_bit_cpx_file_signal_source.h" #include "gnss_sdr_string_literals.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/two_bit_packed_file_signal_source.cc b/src/algorithms/signal_source/adapters/two_bit_packed_file_signal_source.cc index 57e6e7768..81f55cf81 100644 --- a/src/algorithms/signal_source/adapters/two_bit_packed_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/two_bit_packed_file_signal_source.cc @@ -19,9 +19,14 @@ #include "two_bit_packed_file_signal_source.h" #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; TwoBitPackedFileSignalSource::TwoBitPackedFileSignalSource( diff --git a/src/algorithms/signal_source/adapters/uhd_signal_source.cc b/src/algorithms/signal_source/adapters/uhd_signal_source.cc index efaae370b..7e9010aa5 100644 --- a/src/algorithms/signal_source/adapters/uhd_signal_source.cc +++ b/src/algorithms/signal_source/adapters/uhd_signal_source.cc @@ -21,13 +21,18 @@ #include "gnss_sdr_filesystem.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" -#include #include #include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; diff --git a/src/algorithms/signal_source/adapters/zmq_signal_source.cc b/src/algorithms/signal_source/adapters/zmq_signal_source.cc index bc8616ccd..924262617 100644 --- a/src/algorithms/signal_source/adapters/zmq_signal_source.cc +++ b/src/algorithms/signal_source/adapters/zmq_signal_source.cc @@ -17,7 +17,12 @@ #include "zmq_signal_source.h" #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif using namespace std::string_literals; diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 0a89dffd6..b5f993fb1 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -10,17 +10,16 @@ if(ENABLE_RAW_UDP AND PCAP_FOUND) list(APPEND OPT_DRIVER_HEADERS gr_complex_ip_packet_source.h) endif() -if(ENABLE_AD936X_SDR) - set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gr_complex_ip_packet_source.cc) - set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} gr_complex_ip_packet_source.h) -endif() - - -if(ENABLE_PLUTOSDR) +if(ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ad936x_iio_source.cc) set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad936x_iio_source.h) endif() +if(ENABLE_ION) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ion_gsms.cc) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ion_gsms.h) +endif() + set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES fifo_reader.cc unpack_byte_2bit_samples.cc @@ -75,10 +74,15 @@ target_link_libraries(signal_source_gr_blocks PRIVATE algorithms_libs core_libs - Gflags::gflags - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(signal_source_gr_blocks PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(signal_source_gr_blocks PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(signal_source_gr_blocks PRIVATE absl::flags absl::log) +endif() + target_include_directories(signal_source_gr_blocks PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/receiver @@ -128,6 +132,14 @@ if(USE_BOOST_BIND_PLACEHOLDERS) ) endif() +# Fix for Boost Asio > 1.86. address::from_string was deprecated in Boost 1.71 +if(Boost_VERSION_STRING VERSION_LESS 1.71.0) + target_compile_definitions(signal_source_gr_blocks + PRIVATE + -DBOOST_ASIO_USE_FROM_STRING=1 + ) +endif() + if(USE_GENERIC_LAMBDAS) set(has_generic_lambdas HAS_GENERIC_LAMBDA=1) set(no_has_generic_lambdas HAS_GENERIC_LAMBDA=0) diff --git a/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.cc b/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.cc index 0cf885fe2..c87006bd5 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.cc @@ -1,6 +1,7 @@ /*! * \file ad936x_iio_source.cc - * \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the AD936x AD front-end family with special FPGA custom functionalities. + * \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the + * AD936x AD front-end family with special FPGA custom functionalities. * \author Javier Arribas, jarribas(at)cttc.es * * ----------------------------------------------------------------------------- @@ -33,23 +34,23 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr( - std::string pluto_uri_, - std::string board_type_, - long long bandwidth_, - long long sample_rate_, - long long freq_, - std::string rf_port_select_, - std::string rf_filter, - std::string gain_mode_rx0_, - std::string gain_mode_rx1_, + const std::string& pluto_uri_, + const std::string& board_type_, + int64_t bandwidth_, + int64_t sample_rate_, + int64_t freq_, + const std::string& rf_port_select_, + const std::string& rf_filter, + const std::string& gain_mode_rx0_, + const std::string& gain_mode_rx1_, double rf_gain_rx0_, double rf_gain_rx1_, bool enable_ch0, bool enable_ch1, - long long freq_2ch, + int64_t freq_2ch, bool ppsmode_, bool customsamplesize_, - std::string fe_ip_, + const std::string& fe_ip_, int fe_ctlport_, int ssize_, int bshift_, @@ -85,9 +86,10 @@ ad936x_iio_source_sptr ad936x_iio_make_source_sptr( tx_lo_channel_)); } -void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector *files_out) + +void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples* samples_in, int nchannels, std::vector* files_out) { - int32_t current_byte = 0; + uint32_t current_byte = 0; int16_t ch = 0; // std::cout << "nbytes: " << samples_in->n_bytes << " nsamples: " << samples_in->n_samples << " nch: " << nchannels << "\n"; while (current_byte < samples_in->n_bytes) @@ -101,24 +103,25 @@ void ad936x_iio_source::ad9361_channel_demux_and_record(ad936x_iio_samples *samp } } + ad936x_iio_source::ad936x_iio_source( - std::string pluto_uri_, - std::string board_type_, - long long bandwidth_, - long long sample_rate_, - long long freq_, - std::string rf_port_select_, - std::string rf_filter, - std::string gain_mode_rx0_, - std::string gain_mode_rx1_, + const std::string& pluto_uri_, + const std::string& board_type_, + int64_t bandwidth_, + int64_t sample_rate_, + int64_t freq_, + const std::string& rf_port_select_, + const std::string& rf_filter, + const std::string& gain_mode_rx0_, + const std::string& gain_mode_rx1_, double rf_gain_rx0_, double rf_gain_rx1_, bool enable_ch0, bool enable_ch1, - long long freq_2ch, + int64_t freq_2ch, bool ppsmode_, bool customsamplesize_, - std::string fe_ip_, + const std::string& fe_ip_, int fe_ctlport_, int ssize_, int bshift_, @@ -171,54 +174,81 @@ ad936x_iio_source::ad936x_iio_source( case 16: { std::cout << "FPGA sample size set to 16 bits per sample.\n"; - if (pps_rx->send_cmd("ssize=16\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("ssize=16\n") == false) + { + std::cout << "cmd send error!\n"; + } break; } case 8: { std::cout << "FPGA sample size set to 8 bits per sample.\n"; - if (pps_rx->send_cmd("ssize=8\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("ssize=8\n") == false) + { + std::cout << "cmd send error!\n"; + } break; } case 4: { std::cout << "FPGA sample size set to 4 bits per sample.\n"; - if (pps_rx->send_cmd("ssize=4\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("ssize=4\n") == false) + { + std::cout << "cmd send error!\n"; + } break; } case 2: { std::cout << "FPGA sample size set to 2 bits per sample.\n"; - if (pps_rx->send_cmd("ssize=2\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("ssize=2\n") == false) + { + std::cout << "cmd send error!\n"; + } break; } default: { std::cout << "WARNING: Unsupported ssize. FPGA sample size set to 16 bits per sample.\n"; - if (pps_rx->send_cmd("ssize=16") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("ssize=16") == false) + { + std::cout << "cmd send error!\n"; + } } } if (bshift_ >= 0 and bshift_ <= 14) { std::cout << "FPGA sample bits shift left set to " + std::to_string(bshift_) + " positions.\n"; - if (pps_rx->send_cmd("bshift=" + std::to_string(bshift_) + "\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("bshift=" + std::to_string(bshift_) + "\n") == false) + { + std::cout << "cmd send error!\n"; + } } else { std::cout << "WARNING: Unsupported bshift. FPGA sample bits shift left set to 0.\n"; - if (pps_rx->send_cmd("bshift=0\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("bshift=0\n") == false) + { + std::cout << "cmd send error!\n"; + } } if (spattern_ == true) { std::cout << "FPGA debug sample pattern is active!.\n"; - if (pps_rx->send_cmd("spattern=1\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("spattern=1\n") == false) + { + std::cout << "cmd send error!\n"; + } } else { std::cout << "FPGA debug sample pattern disabled.\n"; - if (pps_rx->send_cmd("spattern=0\n") == false) std::cout << "cmd send error!\n"; + if (pps_rx->send_cmd("spattern=0\n") == false) + { + std::cout << "cmd send error!\n"; + } } } else @@ -238,7 +268,7 @@ ad936x_iio_source::ad936x_iio_source( exit(1); } } - catch (std::exception const &ex) + catch (std::exception const& ex) { std::cerr << "STD exception: " << ex.what() << std::endl; exit(1); @@ -267,6 +297,7 @@ ad936x_iio_source::ad936x_iio_source( // } } + ad936x_iio_source::~ad936x_iio_source() { // Terminate PPS thread @@ -284,6 +315,7 @@ bool ad936x_iio_source::start() return ad936x_custom->start_sample_rx(false); } + bool ad936x_iio_source::stop() { std::cout << "stopping ad936x_iio_source...\n"; @@ -291,17 +323,17 @@ bool ad936x_iio_source::stop() return true; } + int ad936x_iio_source::general_work(int noutput_items, - __attribute__((unused)) gr_vector_int &ninput_items, - __attribute__((unused)) gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + __attribute__((unused)) gr_vector_int& ninput_items, + __attribute__((unused)) gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) { std::shared_ptr current_buffer; - ad936x_iio_samples *current_samples; + ad936x_iio_samples* current_samples; ad936x_custom->pop_sample_buffer(current_buffer); current_samples = current_buffer.get(); - // I and Q samples are interleaved in buffer: IQIQIQ... int32_t n_interleaved_iq_samples_per_channel = current_samples->n_bytes / (ad936x_custom->n_channels * 2); if (noutput_items < n_interleaved_iq_samples_per_channel) @@ -312,7 +344,7 @@ int ad936x_iio_source::general_work(int noutput_items, else { // ad9361_channel_demux_and_record(current_samples, ad936x_custom->n_channels, &samplesfile); - auto **out = reinterpret_cast(&output_items[0]); + auto** out = reinterpret_cast(&output_items[0]); uint32_t current_byte = 0; uint32_t current_byte_in_gr = 0; int16_t ch = 0; diff --git a/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.h b/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.h index 411906a3e..8f5a34c7c 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.h +++ b/src/algorithms/signal_source/gnuradio_blocks/ad936x_iio_source.h @@ -1,6 +1,7 @@ /*! * \file ad936x_iio_source.h - * \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the AD936x AD front-end family with special FPGA custom functionalities. + * \brief A direct IIO custom front-end gnss-sdr signal gnuradio block for the + * AD936x AD front-end family with special FPGA custom functionalities. * \author Javier Arribas, jarribas(at)cttc.es * * ----------------------------------------------------------------------------- @@ -44,23 +45,23 @@ class ad936x_iio_source; using ad936x_iio_source_sptr = gnss_shared_ptr; ad936x_iio_source_sptr ad936x_iio_make_source_sptr( - std::string pluto_uri_, - std::string board_type_, - long long bandwidth_, - long long sample_rate_, - long long freq_, - std::string rf_port_select_, - std::string rf_filter, - std::string gain_mode_rx0_, - std::string gain_mode_rx1_, + const std::string &pluto_uri_, + const std::string &board_type_, + int64_t bandwidth_, + int64_t sample_rate_, + int64_t freq_, + const std::string &rf_port_select_, + const std::string &rf_filter, + const std::string &gain_mode_rx0_, + const std::string &gain_mode_rx1_, double rf_gain_rx0_, double rf_gain_rx1_, bool enable_ch0, bool enable_ch1, - long long freq_2ch, + int64_t freq_2ch, bool ppsmode_, bool customsamplesize_, - std::string fe_ip_, + const std::string &fe_ip_, int fe_ctlport_, int ssize_, int bshift_, @@ -90,23 +91,23 @@ public: private: friend ad936x_iio_source_sptr ad936x_iio_make_source_sptr( - std::string pluto_uri_, - std::string board_type_, - long long bandwidth_, - long long sample_rate_, - long long freq_, - std::string rf_port_select_, - std::string rf_filter, - std::string gain_mode_rx0_, - std::string gain_mode_rx1_, + const std::string &pluto_uri_, + const std::string &board_type_, + int64_t bandwidth_, + int64_t sample_rate_, + int64_t freq_, + const std::string &rf_port_select_, + const std::string &rf_filter, + const std::string &gain_mode_rx0_, + const std::string &gain_mode_rx1_, double rf_gain_rx0_, double rf_gain_rx1_, bool enable_ch0, bool enable_ch1, - long long freq_2ch, + int64_t freq_2ch, bool ppsmode_, bool customsamplesize_, - std::string fe_ip_, + const std::string &fe_ip_, int fe_ctlport_, int ssize_, int bshift_, @@ -116,23 +117,23 @@ private: int tx_lo_channel_); ad936x_iio_source( - std::string pluto_uri_, - std::string board_type_, - long long bandwidth_, - long long sample_rate_, - long long freq_, - std::string rf_port_select_, - std::string rf_filter, - std::string gain_mode_rx0_, - std::string gain_mode_rx1_, + const std::string &pluto_uri_, + const std::string &board_type_, + int64_t bandwidth_, + int64_t sample_rate_, + int64_t freq_, + const std::string &rf_port_select_, + const std::string &rf_filter, + const std::string &gain_mode_rx0_, + const std::string &gain_mode_rx1_, double rf_gain_rx0_, double rf_gain_rx1_, bool enable_ch0, bool enable_ch1, - long long freq_2ch, + int64_t freq_2ch, bool ppsmode_, bool customsamplesize_, - std::string fe_ip_, + const std::string &fe_ip_, int fe_ctlport_, int ssize_, int bshift_, @@ -141,7 +142,6 @@ private: bool high_side_lo_, int tx_lo_channel_); - void ad9361_channel_demux_to_buffer(ad936x_iio_samples *samples_in, int nchannels, gr_vector_void_star &output_items); void ad9361_channel_demux_and_record(ad936x_iio_samples *samples_in, int nchannels, std::vector *files_out); diff --git a/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc b/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc index 583fe6810..2617cc9fd 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc @@ -16,7 +16,12 @@ */ #include "fifo_reader.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif // initial construction; pass to private constructor FifoReader::sptr FifoReader::make(const std::string &file_name, const std::string &sample_type) diff --git a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h index a7d37b5a0..711632f21 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h +++ b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h @@ -84,9 +84,7 @@ private: boost::thread *d_pcap_thread; // boost::mutex d_mutex; - struct sockaddr_in si_me - { - }; + struct sockaddr_in si_me{}; std::string d_src_device; std::string d_origin_address; pcap_t *descr; // ethernet pcap device descriptor diff --git a/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc new file mode 100644 index 000000000..22a25868c --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc @@ -0,0 +1,202 @@ +/*! + * \file ion_gsms.cc + * \brief GNU Radio block that reads a Block from a file following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "ion_gsms.h" +#include "gnuradio/block.h" +#include +#include +#include +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +IONGSMSFileSource::IONGSMSFileSource( + const fs::path& metadata_filepath, + const GnssMetadata::File& file, + const GnssMetadata::Block& block, + const std::vector& stream_ids) + : gr::sync_block( + "ion_gsms_file_source", + gr::io_signature::make(0, 0, 0), + make_output_signature(block, stream_ids)), + file_stream_(metadata_filepath.parent_path() / file.Url().Value(), std::ios::in | std::ios::binary), + io_buffer_offset_(0), + maximum_item_rate_(0), + chunk_cycle_length_(0) +{ + fs::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); + std::size_t block_offset = file.Offset(); + + if (!file_stream_.is_open()) + { + LOG(WARNING) << "ION_GSMS_Signal_Source - Unable to open the samples file: " << (data_filepath).c_str(); + std::cerr << "ION_GSMS_Signal_Source - Unable to open the samples file: " << (data_filepath).c_str() << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } + + // Skip offset and block header + file_stream_.seekg(file.Offset() + block_offset + block.SizeHeader()); + + std::size_t output_stream_offset = 0; + for (const auto& chunk : block.Chunks()) + { + chunk_data_.emplace_back(std::make_shared(chunk, stream_ids, output_stream_offset)); + chunk_cycle_length_ += chunk.CountWords() * chunk.SizeWord(); + const std::size_t out_count = chunk_data_.back()->output_stream_count(); + output_stream_offset += out_count; + for (std::size_t i = 0; i < out_count; ++i) + { + output_stream_item_sizes_.push_back(chunk_data_.back()->output_stream_item_size(i)); + output_stream_item_rates_.push_back(chunk_data_.back()->output_stream_item_rate(i)); + maximum_item_rate_ = std::max(chunk_data_.back()->output_stream_item_rate(i), maximum_item_rate_); + } + } + output_stream_count_ = output_stream_offset; + + output_stream_total_sample_counts_.resize(output_stream_count_); + + std::size_t cycle_count = block.Cycles(); + if (cycle_count == 0) + { + // Read the whole file + const std::size_t file_size = fs::file_size(data_filepath); + cycle_count = std::floor((file_size - block_offset - block.SizeHeader()) / chunk_cycle_length_); + } + + for (std::size_t i = 0; i < output_stream_count_; ++i) + { + output_stream_total_sample_counts_[i] = cycle_count * output_stream_item_rates_[i]; + } +} + + +std::size_t IONGSMSFileSource::output_stream_count() const +{ + return output_stream_count_; +} + + +std::size_t IONGSMSFileSource::output_stream_item_size(std::size_t stream_index) const +{ + return output_stream_item_sizes_[stream_index]; +} + + +std::size_t IONGSMSFileSource::output_stream_total_sample_count(std::size_t stream_index) const +{ + return output_stream_total_sample_counts_[stream_index]; +} + + +gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids) +{ + int nstreams = 0; + std::vector item_sizes{}; + + for (const auto& chunk : block.Chunks()) + { + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + bool found = false; + for (const auto& stream_id : stream_ids) + { + if (stream_id == stream.Id()) + { + found = true; + break; + } + } + if (found) + { + ++nstreams; + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) + { + // Samples have 'Complex' format + sample_bitsize /= 2; + } + item_sizes.push_back(bits_to_item_size(sample_bitsize)); + } + } + } + } + + return gr::io_signature::makev( + nstreams, + nstreams, + item_sizes); +} + + +int IONGSMSFileSource::work( + int noutput_items, + gr_vector_const_void_star& input_items __attribute__((unused)), + gr_vector_void_star& output_items) +{ + // Compute the maximum number of samples that will be copied across all output buffer. + // If there are more than one output buffer (multichannel set up), the one with the most samples will be used as the maximum. + // + // Complex samples produce 2 items each (I and Q). In order to account for them, we subtract 1 from `noutput_items` and + // then floor the division. During testing, not doing this caused `max_sample_output` to oscillate between two values, thus + // resizing the `io_buffer_` on each call to `work()`. + const std::size_t max_sample_output = std::floor((noutput_items - 1.0) / maximum_item_rate_); + + // Resize the IO buffer to fit exactly the maximum amount of samples that will be outputted. + io_buffer_.resize(max_sample_output * chunk_cycle_length_); + + // We will be walking the IO buffer with this variable. + io_buffer_offset_ = 0; + + // Read samples from file into IO buffer + const std::size_t bytes_to_read = io_buffer_.size(); + file_stream_.read(io_buffer_.data(), bytes_to_read); + + // Reset `items_produced_` vector. This vector will accumulate the amount of items produced for each output stream. + items_produced_.clear(); + items_produced_.resize(output_items.size()); + + // Walk the IO buffer one chunk cycle at a time. See ION documentation for a definition of chunk and chunk cycle. + while (io_buffer_offset_ < bytes_to_read) + { + // Iterate chunks within a chunk cycle + for (auto& chunk : chunk_data_) + { + // Copy chunk into a separate buffer where the samples will be shifted from. + const std::size_t bytes_copied = chunk->read_from_buffer(reinterpret_cast(io_buffer_.data()), io_buffer_offset_); + + // Advance IO buffer offset + io_buffer_offset_ += bytes_copied; + + // Shift samples into output buffers following the appropriate unpacking strategy for this chunk. + chunk->write_to_output(output_items, items_produced_); + } + } + + // Call `produce(int, int)` with the appropriate item count for each output stream. + for (std::size_t i = 0; i < items_produced_.size(); ++i) + { + produce(i, items_produced_[i]); + } + + return WORK_CALLED_PRODUCE; +} diff --git a/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h new file mode 100644 index 000000000..4a6baa7e9 --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h @@ -0,0 +1,74 @@ +/*! + * \file ion_gsms.h + * \brief GNU Radio block that reads a Block from a file following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_ION_GSMS_H +#define GNSS_SDR_ION_GSMS_H + +#include "gnss_block_interface.h" +#include "gnss_sdr_filesystem.h" +#include "ion_gsms_chunk_data.h" +#include +#include +#include +#include +#include +#include +#include + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_gnuradio_blocks + * \{ */ + +class IONGSMSFileSource : public gr::sync_block +{ +public: + using sptr = gnss_shared_ptr; + + IONGSMSFileSource( + const fs::path& metadata_filepath, + const GnssMetadata::File& file, + const GnssMetadata::Block& block, + const std::vector& stream_ids); + + int work( + int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) override; + + std::size_t output_stream_count() const; + std::size_t output_stream_item_size(std::size_t stream_index) const; + std::size_t output_stream_total_sample_count(std::size_t stream_index) const; + +private: + static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids); + + std::ifstream file_stream_; + std::vector io_buffer_; + std::size_t io_buffer_offset_; + std::vector items_produced_; + std::size_t output_stream_count_; + std::vector output_stream_item_sizes_; + std::vector output_stream_item_rates_; + std::vector output_stream_total_sample_counts_; + std::size_t maximum_item_rate_; + std::vector> chunk_data_; + std::size_t chunk_cycle_length_; +}; + +/** \} */ +/** \} */ +#endif // GNSS_SDR_ION_GSMS_H diff --git a/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.cc b/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.cc index 1b490b4f3..7bb984596 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.cc @@ -20,9 +20,13 @@ #include "rtl_tcp_commands.h" #include #include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif namespace ip = boost::asio::ip; @@ -64,9 +68,11 @@ rtl_tcp_signal_source_c::rtl_tcp_signal_source_c(const std::string &address, { lookup_[i] = (static_cast(i & 0xff) - 127.4F) * (1.0F / 128.0F); } - - // 2. Set socket options +#if BOOST_ASIO_USE_FROM_STRING ip::address addr = ip::address::from_string(address, ec); +#else + ip::address addr = ip::make_address(address, ec); +#endif if (ec) { std::cout << address << " is not an IP address\n"; @@ -74,20 +80,22 @@ rtl_tcp_signal_source_c::rtl_tcp_signal_source_c(const std::string &address, return; } ip::tcp::endpoint ep(addr, port); - socket_.open(ep.protocol(), ec); + + // 2. Set socket options + socket_.open(ep.protocol(), ec); // NOLINT(bugprone-unused-return-value) if (ec) { std::cout << "Failed to open socket.\n"; LOG(ERROR) << "Failed to open socket."; } - socket_.set_option(boost::asio::socket_base::reuse_address(true), ec); + socket_.set_option(boost::asio::socket_base::reuse_address(true), ec); // NOLINT(bugprone-unused-return-value) if (ec) { std::cout << "Failed to set reuse address option: " << ec << '\n'; LOG(WARNING) << "Failed to set reuse address option"; } - socket_.set_option(boost::asio::socket_base::linger(true, 0), ec); + socket_.set_option(boost::asio::socket_base::linger(true, 0), ec); // NOLINT(bugprone-unused-return-value) if (ec) { std::cout << "Failed to set linger option: " << ec << '\n'; @@ -95,8 +103,7 @@ rtl_tcp_signal_source_c::rtl_tcp_signal_source_c(const std::string &address, } // 3. Connect socket - - socket_.connect(ep, ec); + socket_.connect(ep, ec); // NOLINT(bugprone-unused-return-value) if (ec) { std::cout << "Failed to connect to " << addr << ":" << port @@ -109,7 +116,7 @@ rtl_tcp_signal_source_c::rtl_tcp_signal_source_c(const std::string &address, LOG(INFO) << "Connected to " << addr << ":" << port; // 4. Set nodelay - socket_.set_option(ip::tcp::no_delay(true), ec); + socket_.set_option(ip::tcp::no_delay(true), ec); // NOLINT(bugprone-unused-return-value) if (ec) { std::cout << "Failed to set no delay option.\n"; @@ -312,7 +319,7 @@ void rtl_tcp_signal_source_c::handle_read(const boost::system::error_code &ec, unread_++; } } - // let woker know that more data is available + // let worker know that more data is available not_empty_.notify_one(); // Read some more #if USE_BOOST_BIND_PLACEHOLDERS diff --git a/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h b/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h index 9babb7b15..145ef861f 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h +++ b/src/algorithms/signal_source/gnuradio_blocks/rtl_tcp_signal_source_c.h @@ -6,7 +6,7 @@ * The implementation of this block is a combination of various helpful * sources. The data format and command structure is taken from the * original Osmocom rtl_tcp_source_f (https://git.osmocom.org/gr-osmosdr). - * The aynchronous reading code comes from the examples provides + * The asynchronous reading code comes from the examples provides * by Boost.Asio and the bounded buffer producer-consumer solution is * taken from the Boost.CircularBuffer examples (https://www.boost.org/). * diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index a5d582116..0df4f3303 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -7,33 +7,49 @@ set(OPT_SIGNAL_SOURCE_LIB_SOURCES "") set(OPT_SIGNAL_SOURCE_LIB_HEADERS "") + if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad9361_manager.h) endif() -if(ENABLE_FPGA OR ENABLE_AD9361) +if(ENABLE_MAX2771) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_spidev.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_spidev.h) +endif() + +if(ENABLE_FPGA) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_switch.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_switch.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dynamic_bit_selection.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) +endif() + +if(ENABLE_DMA_PROXY) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma-proxy.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma-proxy.h) endif() - -if(ENABLE_PLUTOSDR) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_samples.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_samples.h) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_custom.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_custom.h) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} pps_samplestamp.h) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ppstcprx.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ppstcprx.h) +if((ENABLE_FPGA AND ENABLE_AD9361) OR ENABLE_MAX2771) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) endif() +if(ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad936x_iio_samples.h) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_custom.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad936x_iio_custom.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} pps_samplestamp.h) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ppstcprx.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ppstcprx.h) +endif() + +if(ENABLE_ION) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_chunk_data.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_stream_encodings.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_unpacking_ctx.h) +endif() set(SIGNAL_SOURCE_LIB_SOURCES rtl_tcp_commands.cc @@ -74,11 +90,16 @@ target_link_libraries(signal_source_libs Boost::headers Gnuradio::runtime PRIVATE - Gflags::gflags - Glog::glog core_libs ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(signal_source_libs PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(signal_source_libs PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(signal_source_libs PRIVATE absl::flags absl::log) +endif() + target_include_directories(signal_source_libs PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/receiver @@ -92,7 +113,7 @@ if(GNURADIO_USES_STD_POINTERS) ) endif() -if(ENABLE_FMCOMMS2 OR ENABLE_AD9361 OR ENABLE_PLUTOSDR) +if(ENABLE_FMCOMMS2 OR ENABLE_AD9361 OR ENABLE_PLUTOSDR OR ENABLE_AD936X_SDR) target_link_libraries(signal_source_libs PUBLIC Iio::iio @@ -115,6 +136,10 @@ if(ENABLE_FPGA OR ENABLE_AD9361) ) endif() +if(ENABLE_ION) + target_link_libraries(signal_source_libs PUBLIC ION::ion algorithms_libs) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(signal_source_libs diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index 7e7e3fa74..025f97627 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -16,7 +16,6 @@ * ----------------------------------------------------------------------------- */ #include "ad9361_manager.h" -#include #include #include #include // for ifstream @@ -25,6 +24,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + /* check return value of attr_write function */ void errchk(int v, const char *what) { @@ -344,7 +349,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, #ifndef LIBAD9361_VERSION_GREATER_THAN_01 if (filter_source_ == "Design") { - std::cout << "Option filter_source=Design is not available in this version. Set to filter_source=Off\n"; + std::cout << "Option filter_source=Design is not available in this version of libad9361. Set to filter_source=Off\n"; filter_source_ = std::string("Off"); } if (Fpass_ != 0.0 or Fstop_ != 0.0) @@ -631,7 +636,7 @@ bool config_ad9361_rx_remote(const std::string &remote_host, { return false; } - if (setup_filter(std::move(filter_source_), bandwidth_, sample_rate_, freq_, rf_port_select_, ad9361_phy, rx_chan0, chn, 0, std::move(filter_filename_), Fpass_, Fstop_) == -1) + if (setup_filter(filter_source_, bandwidth_, sample_rate_, freq_, rf_port_select_, ad9361_phy, rx_chan0, chn, 0, std::move(filter_filename_), Fpass_, Fstop_) == -1) { return false; } diff --git a/src/algorithms/signal_source/libs/ad936x_iio_custom.cc b/src/algorithms/signal_source/libs/ad936x_iio_custom.cc index ce25e7897..c41d74b9a 100644 --- a/src/algorithms/signal_source/libs/ad936x_iio_custom.cc +++ b/src/algorithms/signal_source/libs/ad936x_iio_custom.cc @@ -1,6 +1,7 @@ /*! * \file ad936x_iio_custom.cc - * \brief A direct IIO custom front-end driver for the AD936x AD front-end family with special FPGA custom functionalities. + * \brief A direct IIO custom front-end driver for the AD936x AD front-end + * family with special FPGA custom functionalities. * \author Javier Arribas, jarribas(at)cttc.es * ----------------------------------------------------------------------------- * @@ -13,9 +14,9 @@ * ----------------------------------------------------------------------------- */ #include "ad936x_iio_custom.h" +#include "display.h" #include #include -#include #include #include #include @@ -24,28 +25,42 @@ #include #include -ad936x_iio_custom::ad936x_iio_custom(int debug_level_, int log_level_) +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +ad936x_iio_custom::ad936x_iio_custom( + int debug_level_, + int log_level_) : n_channels(0), + ctx(nullptr), + phy(nullptr), + stream_dev(nullptr), + dds_dev(nullptr), + receive_samples(false), + fpga_overflow(false), + sample_rate_sps(0), + debug_level(debug_level_), + log_level(log_level_), + PPS_mode(false) { - receive_samples = false; - fpga_overflow = false; - sample_rate_sps = 0; - ctx = NULL; - phy = NULL; - dds_dev = NULL; - stream_dev = NULL; - debug_level = debug_level_; - log_level = log_level_; - PPS_mode = false; - n_channels = 0; } + ad936x_iio_custom::~ad936x_iio_custom() { // disable TX - if (phy != NULL) PlutoTxEnable(false); + if (phy != nullptr) + { + PlutoTxEnable(false); + } // Close device - if (ctx != NULL) iio_context_destroy(ctx); + if (ctx != nullptr) + { + iio_context_destroy(ctx); + } } @@ -54,12 +69,14 @@ void ad936x_iio_custom::set_gnsstime_queue(std::shared_ptr> queue) { Pps_queue = std::move(queue); } -bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::string board_type) + +bool ad936x_iio_custom::initialize_device(const std::string &pluto_device_uri, const std::string &board_type) { // Find devices if (pluto_device_uri == "local") @@ -114,25 +131,24 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str ctx = iio_create_context_from_uri(pluto_device_uri.c_str()); } - if (ctx == NULL) + if (ctx == nullptr) { std::cout << "Unable to create context from uri: " << pluto_device_uri << std::endl; return false; } - phy = iio_context_find_device(ctx, "ad9361-phy"); - if (phy == NULL) + if (phy == nullptr) { std::cout << "Unable to find ad9361-phy device from uri: " << pluto_device_uri << std::endl; return false; } - if (board_type.compare("fmcomms5") == 0) + if (board_type == "fmcomms5") { stream_dev = iio_context_find_device(ctx, "cf-ad9361-A"); // first ad9361 in FMCOMMS5 - if (stream_dev == NULL) + if (stream_dev == nullptr) { std::cout << "Unable to find cf-ad9361-A device from uri: " << pluto_device_uri << std::endl; return false; @@ -141,13 +157,13 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str else { stream_dev = iio_context_find_device(ctx, "cf-ad9361-lpc"); // regular AD9361 stream device in single AD9361 boards - if (stream_dev == NULL) + if (stream_dev == nullptr) { std::cout << "Unable to find cf-ad9361-lpc device from uri: " << pluto_device_uri << std::endl; return false; }; dds_dev = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); // DDS core for LO oscillator (external transverter operation) - if (stream_dev == NULL) + if (stream_dev == nullptr) { std::cout << "Warning: Unable to find cf-ad9361-dds-core-lpc device from uri: " << pluto_device_uri << std::endl; }; @@ -160,23 +176,22 @@ bool ad936x_iio_custom::initialize_device(std::string pluto_device_uri, std::str void ad936x_iio_custom::configure_params(struct iio_device *phy, const std::vector ¶ms) { - for (std::vector::const_iterator it = params.begin(); - it != params.end(); ++it) + for (const auto ¶m : params) { - struct iio_channel *chn = NULL; - const char *attr = NULL; + struct iio_channel *chn = nullptr; + const char *attr = nullptr; size_t pos; int ret; - pos = it->find('='); + pos = param.find('='); if (pos == std::string::npos) { - std::cerr << "Malformed line: " << *it << std::endl; + std::cerr << "Malformed line: " << param << std::endl; continue; } - std::string key = it->substr(0, pos); - std::string val = it->substr(pos + 1, std::string::npos); + std::string key = param.substr(0, pos); + std::string val = param.substr(pos + 1, std::string::npos); ret = iio_device_identify_filename(phy, key.c_str(), &chn, &attr); @@ -188,13 +203,19 @@ void ad936x_iio_custom::configure_params(struct iio_device *phy, } if (chn) - ret = iio_channel_attr_write(chn, - attr, val.c_str()); + { + ret = iio_channel_attr_write(chn, + attr, val.c_str()); + } else if (iio_device_find_attr(phy, attr)) - ret = iio_device_attr_write(phy, attr, val.c_str()); + { + ret = iio_device_attr_write(phy, attr, val.c_str()); + } else - ret = iio_device_debug_attr_write(phy, - attr, val.c_str()); + { + ret = iio_device_debug_attr_write(phy, + attr, val.c_str()); + } if (ret < 0) { std::cerr << "Unable to write attribute " << key @@ -208,9 +229,9 @@ void ad936x_iio_custom::set_params_rx(struct iio_device *phy_device, unsigned long long frequency, unsigned long samplerate, unsigned long bandwidth, bool quadrature, bool rfdc, bool bbdc, - std::string gain1, double gain1_value, - std::string gain2, double gain2_value, - std::string port_select) + const std::string &gain1, double gain1_value, + const std::string &gain2, double gain2_value, + const std::string &port_select) { std::vector params; @@ -281,7 +302,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_, std::to_string(phase_dds_deg_ * 1000.0)); params_dds.push_back("out_altvoltage0_TX1_I_F1_scale=" + std::to_string(scale_dds_)); - params_dds.push_back("out_altvoltage0_TX1_I_F1_raw=1"); + params_dds.emplace_back("out_altvoltage0_TX1_I_F1_raw=1"); // DDS TX CH1 Q (tone #1) params_dds.push_back("out_altvoltage2_TX1_Q_F1_frequency=" + std::to_string(freq_dds_tx_hz_)); @@ -289,7 +310,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_, std::to_string(phase_dds_deg_ * 1000.0 + 270000.0)); params_dds.push_back("out_altvoltage2_TX1_Q_F1_scale=" + std::to_string(scale_dds_)); - params_dds.push_back("out_altvoltage2_TX1_Q_F1_raw=1"); + params_dds.emplace_back("out_altvoltage2_TX1_Q_F1_raw=1"); configure_params(dds_dev, params_dds); } @@ -310,7 +331,7 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_, std::to_string(phase_dds_deg_ * 1000.0)); params_dds.push_back("out_altvoltage4_TX2_I_F1_scale=" + std::to_string(scale_dds_)); - params_dds.push_back("out_altvoltage4_TX2_I_F1_raw=1"); + params_dds.emplace_back("out_altvoltage4_TX2_I_F1_raw=1"); // DDS TX CH2 Q (tone #1) params_dds.push_back("out_altvoltage6_TX2_Q_F1_frequency=" + std::to_string(freq_dds_tx_hz_)); @@ -318,19 +339,18 @@ bool ad936x_iio_custom::config_ad9361_dds(uint64_t freq_rf_tx_hz_, std::to_string(phase_dds_deg_ * 1000.0 + 270000.0)); params_dds.push_back("out_altvoltage6_TX2_Q_F1_scale=" + std::to_string(scale_dds_)); - params_dds.push_back("out_altvoltage6_TX2_Q_F1_raw=1"); + params_dds.emplace_back("out_altvoltage6_TX2_Q_F1_raw=1"); configure_params(dds_dev, params_dds); } - return true; } bool ad936x_iio_custom::check_device() { - if (stream_dev != NULL) + if (stream_dev != nullptr) { return true; } @@ -340,10 +360,11 @@ bool ad936x_iio_custom::check_device() } } + bool ad936x_iio_custom::get_iio_param(iio_device *dev, const std::string ¶m, std::string &value) { - struct iio_channel *chn = 0; - const char *attr = 0; + struct iio_channel *chn = nullptr; + const char *attr = nullptr; char valuestr[256]; int ret; ssize_t nchars; @@ -381,6 +402,7 @@ bool ad936x_iio_custom::get_iio_param(iio_device *dev, const std::string ¶m, } } + bool ad936x_iio_custom::read_die_temp(double &temp_c) { std::string temp_mC_str; @@ -389,9 +411,12 @@ bool ad936x_iio_custom::read_die_temp(double &temp_c) { try { - uint32_t temp_mC = boost::lexical_cast(temp_mC_str); + auto temp_mC = boost::lexical_cast(temp_mC_str); temp_c = static_cast(temp_mC) / 1000.0; - if (temp_c > 120) temp_c = -1; + if (temp_c > 120) + { + temp_c = -1; + } return true; } catch (const boost::bad_lexical_cast &e) @@ -405,13 +430,15 @@ bool ad936x_iio_custom::read_die_temp(double &temp_c) return false; } } + + bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, long long sample_rate_, long long freq_, - std::string rf_port_select_, - std::string rf_filter, - std::string gain_mode_rx0_, - std::string gain_mode_rx1_, + const std::string &rf_port_select_, + const std::string &rf_filter, + const std::string &gain_mode_rx0_, + const std::string &gain_mode_rx1_, double rf_gain_rx0_, double rf_gain_rx1_, bool enable_ch0, @@ -420,18 +447,20 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, double lo_attenuation_db_, bool high_side_lo_, int tx_lo_channel_) - { - if (check_device() == false) return false; + if (check_device() == false) + { + return false; + } bool no_errors = true; std::cout << "Configuring phy device parameters...\n"; int ret; - if (rf_filter.compare("Disabled") == 0) + if (rf_filter == "Disabled") { std::cout << "LNA Filter switch is disabled.\n"; } - else if (rf_filter.compare("Auto") == 0) + else if (rf_filter == "Auto") { std::cout << "Selecting LNA RF filter based on the selected RF frequency... \n"; if (freq_ == 1575420000) @@ -488,9 +517,9 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, params.push_back("out_voltage_rf_bandwidth=" + std::to_string(bandwidth_)); - params.push_back("in_voltage_quadrature_tracking_en=1"); - params.push_back("in_voltage_rf_dc_offset_tracking_en=1"); - params.push_back("in_voltage_bb_dc_offset_tracking_en=1"); + params.emplace_back("in_voltage_quadrature_tracking_en=1"); + params.emplace_back("in_voltage_rf_dc_offset_tracking_en=1"); + params.emplace_back("in_voltage_bb_dc_offset_tracking_en=1"); configure_params(phy, params); @@ -605,14 +634,12 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, std::cerr << "Warning: rf_port_select write returned: " << ret << "\n"; no_errors = false; } - // ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_); // if (ret < 0) // { // std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n"; // no_errors = false; // } - long long set_rf_bw; ret = iio_channel_attr_read_longlong(phy_ch, "rf_bandwidth", &set_rf_bw); if (ret < 0) @@ -625,7 +652,6 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, std::cerr << "Info: rf_bandwidth read returned: " << set_rf_bw << " Hz \n"; } - if (setRXGain(0, gain_mode_rx0_, rf_gain_rx0_) == false) { std::cerr << "Info: setRXGain read returned false \n"; @@ -657,14 +683,12 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, std::cerr << "Warning: rf_port_select write returned: " << ret << "\n"; no_errors = false; } - // ret = iio_channel_attr_write_longlong(phy_ch, "rf_bandwidth", bandwidth_); // if (ret < 0) // { // std::cerr << "Warning: rf_bandwidth write returned: " << ret << "\n"; // no_errors = false; // } - long long set_rf_bw; ret = iio_channel_attr_read_longlong(phy_ch, "rf_bandwidth", &set_rf_bw); if (ret < 0) @@ -697,9 +721,13 @@ bool ad936x_iio_custom::init_config_ad9361_rx(long long bandwidth_, return no_errors; } + bool ad936x_iio_custom::set_rx_frequency(long long freq_hz) { - if (check_device() == false) return false; + if (check_device() == false) + { + return false; + } // Configure RX LO channel (NOTICE that altvoltage0 is the RX LO oscillator!, altvoltage1 is the TX oscillator) struct iio_channel *lo_ch; @@ -722,7 +750,10 @@ bool ad936x_iio_custom::set_rx_frequency(long long freq_hz) bool ad936x_iio_custom::get_rx_frequency(long long &freq_hz) { - if (check_device() == false) return false; + if (check_device() == false) + { + return false; + } // Configure RX LO channel (NOTICE that altvoltage0 is the RX LO oscillator!, altvoltage1 is the TX oscillator) struct iio_channel *lo_ch; @@ -742,9 +773,13 @@ bool ad936x_iio_custom::get_rx_frequency(long long &freq_hz) return true; } -bool ad936x_iio_custom::setRXGain(int ch_num, std::string gain_mode, double gain_dB) + +bool ad936x_iio_custom::setRXGain(int ch_num, const std::string &gain_mode, double gain_dB) { - if (check_device() == false) return false; + if (check_device() == false) + { + return false; + } std::vector params; if (ch_num == 0) { @@ -774,9 +809,13 @@ bool ad936x_iio_custom::setRXGain(int ch_num, std::string gain_mode, double gain } } + double ad936x_iio_custom::get_rx_gain(int ch_num) { - if (check_device() == false) return -1; + if (check_device() == false) + { + return -1; + } double gain_dB; // gain in dB int ret = 0; if (ch_num == 0) @@ -807,11 +846,15 @@ double ad936x_iio_custom::get_rx_gain(int ch_num) bool ad936x_iio_custom::calibrate([[maybe_unused]] int ch, [[maybe_unused]] double bw_hz) { - if (check_device() == false) return false; + if (check_device() == false) + { + return false; + } // todo return true; } + void ad936x_iio_custom::monitor_thread_fn() { uint32_t val; @@ -844,24 +887,27 @@ void ad936x_iio_custom::monitor_thread_fn() // } else { if (val & 4) { - std::cout << "WARNING: IIO status register reported overflow!\n"; - LOG(INFO) << "WARNING: IIO status register reported overflow!"; + std::cout + << TEXT_BOLD_RED + << "WARNING: IIO status register reported overflow!\n"; + LOG(WARNING) << "WARNING: IIO status register reported overflow!"; } - /* Clear bits */ if (val) { ret = iio_device_reg_write(stream_dev, 0x80000088, val); if (ret) - fprintf(stderr, "Failed to clearn DMA status register: %s\n", - strerror(-ret)); + { + fprintf(stderr, "Failed to clearn DMA status register: %s\n", + strerror(-ret)); + } } sleep(1); } - return; } + void ad936x_iio_custom::stop_record() { receive_samples = false; @@ -910,6 +956,7 @@ void ad936x_iio_custom::PlutoTxEnable(bool txon) } } + void ad936x_iio_custom::setPlutoGpo(int p) { char pins[11]; @@ -928,7 +975,7 @@ void ad936x_iio_custom::setPlutoGpo(int p) } -bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) +bool ad936x_iio_custom::select_rf_filter(const std::string &rf_filter) { // adi,gpo-manual-mode-enable Enables GPO manual mode, this will conflict with automatic ENSM slave and eLNA mode // adi,gpo-manual-mode-enable-mask Enable bit mask, setting or clearing bits will change the level of the corresponding output. Bit0 → GPO, Bit1 → GPO1, Bit2 → GPO2, Bit3 → GP03 @@ -948,8 +995,10 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) // 1 Enable // X Enable Mask if Identifier=0xF - - if (check_device() == false) return false; + if (check_device() == false) + { + return false; + } // int plutoGpo = 0; int ret; ret = iio_device_debug_attr_write(phy, "adi,gpo-manual-mode-enable", "1"); @@ -960,7 +1009,7 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) return false; } - if (rf_filter.compare("E1") == 0) + if (rf_filter == "E1") { // set gpio0 to switch L1 filter // setPlutoGpo(plutoGpo); @@ -971,7 +1020,7 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) return false; } } - else if (rf_filter.compare("E5E6") == 0) + else if (rf_filter == "E5E6") { // set gpio0 to switch L5/L6 filter (GPO0) // plutoGpo = plutoGpo | 0x10; @@ -983,7 +1032,7 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) return false; } } - if (rf_filter.compare("none") == 0) + if (rf_filter == "none") { std::cout << "RF external filter not selected\n"; } @@ -1001,6 +1050,8 @@ bool ad936x_iio_custom::select_rf_filter(std::string rf_filter) return true; } + + void ad936x_iio_custom::get_PPS_timestamp() { GnssTime tow; @@ -1037,7 +1088,6 @@ void ad936x_iio_custom::get_PPS_timestamp() // record pps rise samplestamp associated to the absolute sample counter // PPS rising edge must be associated with the corresponding uBlox time message (tx once a second) - if (GnssTime_queue->timed_wait_and_pop(tow, 2000) == false) { if (receive_samples == true) @@ -1068,6 +1118,8 @@ void ad936x_iio_custom::get_PPS_timestamp() } } } + + bool ad936x_iio_custom::start_sample_rx(bool ppsmode) { // using queues of smart pointers to preallocated buffers @@ -1093,18 +1145,18 @@ bool ad936x_iio_custom::start_sample_rx(bool ppsmode) switch (n_channels) { case 1: - channels.push_back("voltage0"); // Channel 0 I - channels.push_back("voltage1"); // Channel 0 Q + channels.emplace_back("voltage0"); // Channel 0 I + channels.emplace_back("voltage1"); // Channel 0 Q break; case 2: - channels.push_back("voltage0"); // Channel 0 I - channels.push_back("voltage1"); // Channel 0 Q - channels.push_back("voltage2"); // Channel 1 I - channels.push_back("voltage3"); // Channel 1 Q + channels.emplace_back("voltage0"); // Channel 0 I + channels.emplace_back("voltage1"); // Channel 0 Q + channels.emplace_back("voltage2"); // Channel 1 I + channels.emplace_back("voltage3"); // Channel 1 Q break; default: - channels.push_back("voltage0"); // Channel 0 I - channels.push_back("voltage1"); // Channel 0 Q + channels.emplace_back("voltage0"); // Channel 0 I + channels.emplace_back("voltage1"); // Channel 0 Q } receive_samples = true; @@ -1113,9 +1165,7 @@ bool ad936x_iio_custom::start_sample_rx(bool ppsmode) // start sample overflow detector overflow_monitor_thread = std::thread(&ad936x_iio_custom::monitor_thread_fn, this); - // start PPS and GNSS Time capture thread - if (ppsmode == true) { capture_time_thread = std::thread(&ad936x_iio_custom::get_PPS_timestamp, this); @@ -1123,19 +1173,25 @@ bool ad936x_iio_custom::start_sample_rx(bool ppsmode) return true; } + void ad936x_iio_custom::pop_sample_buffer(std::shared_ptr ¤t_buffer) { used_buffers.wait_and_pop(current_buffer); } + void ad936x_iio_custom::push_sample_buffer(std::shared_ptr ¤t_buffer) { free_buffers.push(current_buffer); } + void ad936x_iio_custom::capture(const std::vector &channels) { - if (check_device() == false) return; + if (check_device() == false) + { + return; + } struct iio_buffer *rxbuf; @@ -1163,16 +1219,14 @@ void ad936x_iio_custom::capture(const std::vector &channels) } else { - for (std::vector::const_iterator it = - channels.begin(); - it != channels.end(); ++it) + for (const auto &channel : channels) { struct iio_channel *chn = iio_device_find_channel(stream_dev, - it->c_str(), false); + channel.c_str(), false); if (!chn) { - std::cerr << "Channel " << it->c_str() << " not found\n"; + std::cerr << "Channel " << channel.c_str() << " not found\n"; return; } else @@ -1231,7 +1285,10 @@ void ad936x_iio_custom::capture(const std::vector &channels) items_in_buffer = static_cast(ret) / bytes_to_interleaved_iq_samples; - if (items_in_buffer == 0) return; + if (items_in_buffer == 0) + { + return; + } current_samples->n_channels = n_channels; current_samples->n_interleaved_iq_samples = items_in_buffer; diff --git a/src/algorithms/signal_source/libs/ad936x_iio_custom.h b/src/algorithms/signal_source/libs/ad936x_iio_custom.h index 83a61282a..0c6199968 100644 --- a/src/algorithms/signal_source/libs/ad936x_iio_custom.h +++ b/src/algorithms/signal_source/libs/ad936x_iio_custom.h @@ -1,6 +1,7 @@ /*! * \file ad936x_iio_custom.h - * \brief A direct IIO custom front-end driver for the AD936x AD front-end family with special FPGA custom functionalities. + * \brief A direct IIO custom front-end driver for the AD936x AD front-end + * family with special FPGA custom functionalities. * \author Javier Arribas, jarribas(at)cttc.es * ----------------------------------------------------------------------------- * @@ -14,41 +15,41 @@ */ -#ifndef SRC_LIBS_ad936x_iio_custom_H_ -#define SRC_LIBS_ad936x_iio_custom_H_ +#ifndef GNSS_SDR_AD936X_IIO_CUSTOM_H +#define GNSS_SDR_AD936X_IIO_CUSTOM_H +#include "ad936x_iio_samples.h" #include "concurrent_queue.h" #include "gnss_time.h" #include "pps_samplestamp.h" #include +#include +#include // multichip sync and high level functions #include #include - -#ifdef __APPLE__ -#include -#else -#include -#endif - -#include "ad936x_iio_samples.h" -#include // multichip sync and high level functions #include #include +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ + + class ad936x_iio_custom { public: ad936x_iio_custom(int debug_level_, int log_level_); virtual ~ad936x_iio_custom(); - bool initialize_device(std::string pluto_device_uri, std::string board_type); + bool initialize_device(const std::string &pluto_device_uri, const std::string &board_type); bool init_config_ad9361_rx(long long bandwidth_, long long sample_rate_, long long freq_, - std::string rf_port_select_, - std::string rf_filter, - std::string gain_mode_rx0_, - std::string gain_mode_rx1_, + const std::string &rf_port_select_, + const std::string &rf_filter, + const std::string &gain_mode_rx0_, + const std::string &gain_mode_rx1_, double rf_gain_rx0_, double rf_gain_rx1_, bool enable_ch0, @@ -61,7 +62,7 @@ public: bool calibrate(int ch, double bw_hz); double get_rx_gain(int ch_num); - bool setRXGain(int ch_num, std::string gain_mode, double gain_dB); + bool setRXGain(int ch_num, const std::string &gain_mode, double gain_dB); bool set_antenna_port(int ch, int antenna_idx); double get_frequency(int ch); @@ -93,9 +94,9 @@ private: unsigned long long frequency, unsigned long samplerate, unsigned long bandwidth, bool quadrature, bool rfdc, bool bbdc, - std::string gain1, double gain1_value, - std::string gain2, double gain2_value, - std::string port_select); + const std::string &gain1, double gain1_value, + const std::string &gain2, double gain2_value, + const std::string &port_select); bool config_ad9361_dds(uint64_t freq_rf_tx_hz_, double tx_attenuation_db_, @@ -107,7 +108,7 @@ private: void get_PPS_timestamp(); void capture(const std::vector &channels); - bool select_rf_filter(std::string rf_filter); + bool select_rf_filter(const std::string &rf_filter); void monitor_thread_fn(); @@ -120,15 +121,6 @@ private: struct iio_device *stream_dev; struct iio_device *dds_dev; - // stream - - uint64_t sample_rate_sps; - - - int debug_level; - int log_level; - bool PPS_mode; - std::mutex mtx; std::condition_variable cv; @@ -142,6 +134,14 @@ private: std::thread capture_samples_thread; std::thread overflow_monitor_thread; std::thread capture_time_thread; + + // stream + uint64_t sample_rate_sps; + int debug_level; + int log_level; + bool PPS_mode; }; -#endif /* SRC_LIBS_ad936x_iio_custom_H_ */ +/** \} */ +/** \} */ +#endif // GNSS_SDR_AD936X_IIO_CUSTOM_H diff --git a/src/algorithms/signal_source/libs/ad936x_iio_samples.cc b/src/algorithms/signal_source/libs/ad936x_iio_samples.cc deleted file mode 100644 index b9b7b505a..000000000 --- a/src/algorithms/signal_source/libs/ad936x_iio_samples.cc +++ /dev/null @@ -1,25 +0,0 @@ -/*! - * \file ad936x_iio_samples.cc - * \brief A class that holds a custom sample buffer for Analog Devices AD936x family front-ends. - * \author Javier Arribas, jarribas(at)cttc.es - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * ----------------------------------------------------------------------------- - */ - -#include "ad936x_iio_samples.h" - -ad936x_iio_samples::ad936x_iio_samples() -{ - n_bytes = 0; - n_interleaved_iq_samples = 0; - step_bytes = 0; - n_channels = 0; -} diff --git a/src/algorithms/signal_source/libs/ad936x_iio_samples.h b/src/algorithms/signal_source/libs/ad936x_iio_samples.h index 63d30545b..5ff43d065 100644 --- a/src/algorithms/signal_source/libs/ad936x_iio_samples.h +++ b/src/algorithms/signal_source/libs/ad936x_iio_samples.h @@ -15,26 +15,32 @@ */ -#ifndef SRC_LIBS_ad936x_iio_samples_H_ -#define SRC_LIBS_ad936x_iio_samples_H_ +#ifndef GNSS_SDR_AD936X_IIO_SAMPLES_H +#define GNSS_SDR_AD936X_IIO_SAMPLES_H #define IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES 32768 * 4 - #define IIO_INPUTRAMFIFOSIZE 256 +#include #include -#include #include +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ + class ad936x_iio_samples { public: - ad936x_iio_samples(); - uint32_t n_bytes; - uint32_t n_interleaved_iq_samples; - uint16_t n_channels; - uint16_t step_bytes; + ad936x_iio_samples() = default; + uint32_t n_bytes{0}; + uint32_t n_interleaved_iq_samples{0}; + uint16_t n_channels{0}; + uint16_t step_bytes{0}; char buffer[IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES * 4 * 4]; // max 16 bits samples per buffer (4 channels, 2-bytes per I + 2-bytes per Q) }; +/** \} */ +/** \} */ #endif diff --git a/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc b/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc index 449579441..1f56afbf4 100644 --- a/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc +++ b/src/algorithms/signal_source/libs/fpga_buffer_monitor.cc @@ -25,7 +25,7 @@ #include "fpga_buffer_monitor.h" #include "gnss_sdr_create_directory.h" #include "gnss_sdr_filesystem.h" -#include +#include "uio_fpga.h" #include // for time, localtime #include // for open, O_RDWR, O_SYNC #include // for string, ofstream @@ -34,8 +34,14 @@ #include // for close #include // for move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif -Fpga_buffer_monitor::Fpga_buffer_monitor(const std::string &device_name, + +Fpga_buffer_monitor::Fpga_buffer_monitor( uint32_t num_freq_bands, bool dump, std::string dump_filename) @@ -45,10 +51,19 @@ Fpga_buffer_monitor::Fpga_buffer_monitor(const std::string &device_name, d_max_buff_occ_freq_band_1(0), d_dump(dump) { - // open device descriptor - if ((d_device_descriptor = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + std::string device_io_name; + + // find the uio device file corresponding to the buffer monitor + if (find_uio_dev_file_name(device_io_name, BUFFER_MONITOR_DEVICE_NAME, 0) < 0) { - LOG(WARNING) << "Cannot open deviceio" << device_name; + std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << BUFFER_MONITOR_DEVICE_NAME << '\n'; + return; + } + + // open device descriptor + if ((d_device_descriptor = open(device_io_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_io_name; } // device memory map diff --git a/src/algorithms/signal_source/libs/fpga_buffer_monitor.h b/src/algorithms/signal_source/libs/fpga_buffer_monitor.h index 00b413e30..7231c5ae3 100644 --- a/src/algorithms/signal_source/libs/fpga_buffer_monitor.h +++ b/src/algorithms/signal_source/libs/fpga_buffer_monitor.h @@ -45,10 +45,13 @@ public: /*! * \brief Constructor */ - explicit Fpga_buffer_monitor(const std::string& device_name, - uint32_t num_freq_bands, + explicit Fpga_buffer_monitor(uint32_t num_freq_bands, bool dump, std::string dump_filename); + // explicit Fpga_buffer_monitor(const std::string& device_name, + // uint32_t num_freq_bands, + // bool dump, + // std::string dump_filename); /*! * \brief Destructor @@ -61,6 +64,7 @@ public: void check_buffer_overflow_and_monitor_buffer_status(); private: + const std::string BUFFER_MONITOR_DEVICE_NAME = std::string("buffer_monitor"); // buffer monitor device name static const size_t FPGA_PAGE_SIZE = 0x1000; static const uint32_t test_register_writeval = 0x55AA; static const uint32_t num_sapmples_per_buffer_element = 2; diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc index 8cec947ef..3fd9b7c85 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc @@ -19,130 +19,135 @@ * ----------------------------------------------------------------------------- */ -#include "fpga_dynamic_bit_selection.h" -#include "uio_fpga.h" -#include -#include // for open, O_RDWR, O_SYNC -#include // for cout -#include // for mmap -#include // for close - -Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(bool enable_rx1_band, bool enable_rx2_band) - : d_map_base_freq_band_1(nullptr), - d_map_base_freq_band_2(nullptr), - d_dev_descr_freq_band_1(0), - d_dev_descr_freq_band_2(0), - d_shift_out_bits_freq_band_1(0), - d_shift_out_bits_freq_band_2(0), - d_enable_rx1_band(enable_rx1_band), - d_enable_rx2_band(enable_rx2_band) -{ - if (d_enable_rx1_band) - { - open_device(&d_map_base_freq_band_1, d_dev_descr_freq_band_1, 0); - - // init bit selection corresponding to frequency band 1 - d_shift_out_bits_freq_band_1 = shift_out_bits_default; - d_map_base_freq_band_1[0] = d_shift_out_bits_freq_band_1; - } - if (d_enable_rx2_band) - { - open_device(&d_map_base_freq_band_2, d_dev_descr_freq_band_2, 1); - - // init bit selection corresponding to frequency band 2 - d_shift_out_bits_freq_band_2 = shift_out_bits_default; - d_map_base_freq_band_2[0] = d_shift_out_bits_freq_band_2; - } - DLOG(INFO) << "Dynamic bit selection FPGA class created"; -} - - -Fpga_dynamic_bit_selection::~Fpga_dynamic_bit_selection() -{ - if (d_enable_rx1_band) - { - close_device(d_map_base_freq_band_1, d_dev_descr_freq_band_1); - } - if (d_enable_rx2_band) - { - close_device(d_map_base_freq_band_2, d_dev_descr_freq_band_2); - } -} - - -void Fpga_dynamic_bit_selection::bit_selection() -{ - if (d_enable_rx1_band) - { - bit_selection_per_rf_band(d_map_base_freq_band_1, d_shift_out_bits_freq_band_1); - } - - if (d_enable_rx2_band) - { - bit_selection_per_rf_band(d_map_base_freq_band_2, d_shift_out_bits_freq_band_2); - } -} - - -void Fpga_dynamic_bit_selection::open_device(volatile unsigned **d_map_base, int &d_dev_descr, int freq_band) -{ - // find the uio device file corresponding to the dynamic bit selector 0 module. - std::string device_name; - if (find_uio_dev_file_name(device_name, dyn_bit_sel_device_name, freq_band) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; - std::cout << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; - return; - } - // dynamic bits selection corresponding to frequency band 1 - if ((d_dev_descr = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) - { - LOG(WARNING) << "Cannot open deviceio" << device_name; - std::cout << "Cannot open deviceio" << device_name << std::endl; - } - *d_map_base = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, d_dev_descr, 0)); - - if (*d_map_base == reinterpret_cast(-1)) - { - LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 1 into tracking memory"; - std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n"; - } -} - - -void Fpga_dynamic_bit_selection::bit_selection_per_rf_band(volatile unsigned *d_map_base, uint32_t shift_out_bits) -{ - // estimated signal power - uint32_t rx_signal_power = d_map_base[1]; - - // dynamic bit selection - if (rx_signal_power > Power_Threshold_High) - { - if (shift_out_bits < shift_out_bit_max) - { - shift_out_bits = shift_out_bits + 1; - } - } - else if (rx_signal_power < Power_Threshold_Low) - { - if (shift_out_bits > shift_out_bits_min) - { - shift_out_bits = shift_out_bits - 1; - } - } - - // update bit selection corresopnding to frequency band 1 - d_map_base[0] = shift_out_bits; -} - - -void Fpga_dynamic_bit_selection::close_device(volatile unsigned *d_map_base, int &d_dev_descr) -{ - auto *aux = const_cast(d_map_base); - if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) - { - std::cout << "Failed to unmap memory uio\n"; - } - close(d_dev_descr); -} + #include "fpga_dynamic_bit_selection.h" + #include "uio_fpga.h" + #include // for open, O_RDWR, O_SYNC + #include // for cout + #include // for mmap + #include // for close + + #if USE_GLOG_AND_GFLAGS + #include + #else + #include + #endif + + Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(bool enable_rx1_band, bool enable_rx2_band) + : d_map_base_freq_band_1(nullptr), + d_map_base_freq_band_2(nullptr), + d_dev_descr_freq_band_1(0), + d_dev_descr_freq_band_2(0), + d_shift_out_bits_freq_band_1(0), + d_shift_out_bits_freq_band_2(0), + d_enable_rx1_band(enable_rx1_band), + d_enable_rx2_band(enable_rx2_band) + { + if (d_enable_rx1_band) + { + open_device(&d_map_base_freq_band_1, d_dev_descr_freq_band_1, 0); + + // init bit selection corresponding to frequency band 1 + d_shift_out_bits_freq_band_1 = shift_out_bits_default; + d_map_base_freq_band_1[0] = d_shift_out_bits_freq_band_1; + } + if (d_enable_rx2_band) + { + open_device(&d_map_base_freq_band_2, d_dev_descr_freq_band_2, 1); + + // init bit selection corresponding to frequency band 2 + d_shift_out_bits_freq_band_2 = shift_out_bits_default; + d_map_base_freq_band_2[0] = d_shift_out_bits_freq_band_2; + } + DLOG(INFO) << "Dynamic bit selection FPGA class created"; + } + + + Fpga_dynamic_bit_selection::~Fpga_dynamic_bit_selection() + { + if (d_enable_rx1_band) + { + close_device(d_map_base_freq_band_1, d_dev_descr_freq_band_1); + } + if (d_enable_rx2_band) + { + close_device(d_map_base_freq_band_2, d_dev_descr_freq_band_2); + } + } + + + void Fpga_dynamic_bit_selection::bit_selection() + { + if (d_enable_rx1_band) + { + bit_selection_per_rf_band(d_map_base_freq_band_1, d_shift_out_bits_freq_band_1); + } + + if (d_enable_rx2_band) + { + bit_selection_per_rf_band(d_map_base_freq_band_2, d_shift_out_bits_freq_band_2); + } + } + + + void Fpga_dynamic_bit_selection::open_device(volatile unsigned **d_map_base, int &d_dev_descr, int freq_band) + { + // find the uio device file corresponding to the dynamic bit selector 0 module. + std::string device_name; + if (find_uio_dev_file_name(device_name, dyn_bit_sel_device_name, freq_band) < 0) + { + std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; + return; + } + // dynamic bits selection corresponding to frequency band 1 + if ((d_dev_descr = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_name; + std::cout << "Cannot open deviceio" << device_name << std::endl; + } + *d_map_base = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, d_dev_descr, 0)); + + if (*d_map_base == reinterpret_cast(-1)) + { + LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 1 into tracking memory"; + std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n"; + } + } + + + void Fpga_dynamic_bit_selection::bit_selection_per_rf_band(volatile unsigned *d_map_base, uint32_t shift_out_bits) + { + // estimated signal power + uint32_t rx_signal_power = d_map_base[1]; + + // dynamic bit selection + if (rx_signal_power > Power_Threshold_High) + { + if (shift_out_bits < shift_out_bit_max) + { + shift_out_bits = shift_out_bits + 1; + } + } + else if (rx_signal_power < Power_Threshold_Low) + { + if (shift_out_bits > shift_out_bits_min) + { + shift_out_bits = shift_out_bits - 1; + } + } + + // update bit selection corresponding to frequency band 1 + d_map_base[0] = shift_out_bits; + } + + + void Fpga_dynamic_bit_selection::close_device(volatile unsigned *d_map_base, int &d_dev_descr) + { + auto *aux = const_cast(d_map_base); + if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) + { + std::cout << "Failed to unmap memory uio\n"; + } + close(d_dev_descr); + } \ No newline at end of file diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h index 3f4b73a5a..53729b265 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h @@ -56,7 +56,6 @@ public: void bit_selection(void); private: - const std::string switch_device_name = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name static const size_t FPGA_PAGE_SIZE = 0x1000; static const uint32_t Num_bits_ADC = 12; // Number of bits in the ADC diff --git a/src/algorithms/signal_source/libs/fpga_spidev.cc b/src/algorithms/signal_source/libs/fpga_spidev.cc new file mode 100644 index 000000000..f90cf4ac9 --- /dev/null +++ b/src/algorithms/signal_source/libs/fpga_spidev.cc @@ -0,0 +1,131 @@ +/*! + * \file fpga_spidev.cc + * \brief FPGA SPI control. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "fpga_spidev.h" +#include // for memset() +#include // for open(), O_RDWR +#include // for std::cerr +#include // spidev driver +#include // for ioctl() +#include // for close() + + +int Fpga_spidev::SPI_open() +{ + if ((d_fd = open(SPI_DEVICE_NAME.c_str(), O_RDWR)) < 0) + { + std::cerr << "Failed to open the " << SPI_DEVICE_NAME << " device file \n"; + return -1; + } + + int ret; + int32_t mode = 0; + + ret = ioctl(d_fd, SPI_IOC_WR_MODE32, &mode); + if (ret == -1) + { + std::cerr << "can't set spi mode\n"; + return -1; + } + + ret = ioctl(d_fd, SPI_IOC_RD_MODE32, &mode); // le digo al spi "algo" + if (ret == -1) + { + std::cerr << "can't set spi mode\n"; + return -1; + } + + return 0; +} + +int Fpga_spidev::write_reg32(char addr, uint32_t data) +{ + uint8_t data_buffer[2]; + uint8_t recv_buffer[4]; + int res = 0; + struct spi_ioc_transfer xfer[2]; + memset(xfer, 0, sizeof(xfer)); + xfer[0].bits_per_word = 8; + xfer[0].speed_hz = SPI_SPEED; + xfer[1].bits_per_word = 8; + xfer[1].speed_hz = SPI_SPEED; + + memset(&recv_buffer, 0, sizeof(recv_buffer)); + memset(&data_buffer, 0, sizeof(data_buffer)); + + data_buffer[1] = addr << 4 | 0 << 3; + xfer[0].tx_buf = (unsigned long)data_buffer; + xfer[0].len = 2; + + // Would use memcpy but 'data' is in little endian + ((char*)recv_buffer)[0] = ((char*)&data)[3]; + ((char*)recv_buffer)[1] = ((char*)&data)[2]; + ((char*)recv_buffer)[2] = ((char*)&data)[1]; + ((char*)recv_buffer)[3] = ((char*)&data)[0]; + + xfer[1].tx_buf = (unsigned long)recv_buffer; + xfer[1].len = 4; + res = ioctl(d_fd, SPI_IOC_MESSAGE(2), xfer); + if (res < 0) + { + std::cout << "Error sending SPI message\n"; + return res; + } + return 0; +} + +int Fpga_spidev::read_reg32(uint8_t addr, uint32_t* copy_to) +{ + uint8_t data_buffer[2]; + uint8_t recv_buffer[4]; + int res; + struct spi_ioc_transfer xfer[2]; + memset(xfer, 0, sizeof(xfer)); + xfer[0].bits_per_word = 8; + xfer[0].speed_hz = SPI_SPEED; + xfer[1].bits_per_word = 8; + xfer[1].speed_hz = SPI_SPEED; + + memset(&recv_buffer, 0, sizeof(recv_buffer)); + memset(&data_buffer, 0, sizeof(data_buffer)); + + data_buffer[1] = addr << 4 | 1 << 3; + xfer[0].tx_buf = (unsigned long)data_buffer; + xfer[0].len = 2; + + xfer[1].rx_buf = (unsigned long)recv_buffer; + xfer[1].len = 4; + res = ioctl(d_fd, SPI_IOC_MESSAGE(2), xfer); + if (res < 0) + { + std::cout << "Error sending SPI message\n"; + return res; + } + + // the register data is received in the reverse order + uint32_t tmp_result = 0; + for (uint32_t k = 0; k < 4; ++k) + { + tmp_result = tmp_result + ((recv_buffer[3 - k]) << 8 * k); + } + *copy_to = tmp_result; + + return 0; +} + +int Fpga_spidev::SPI_close() const +{ + return close(d_fd); +} diff --git a/src/algorithms/signal_source/libs/fpga_spidev.h b/src/algorithms/signal_source/libs/fpga_spidev.h new file mode 100644 index 000000000..ccef015d2 --- /dev/null +++ b/src/algorithms/signal_source/libs/fpga_spidev.h @@ -0,0 +1,62 @@ +/*! + * \file fpga_spidev.h + * \brief FPGA SPI control. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_FPGA_SPIDEV_H +#define GNSS_SDR_FPGA_SPIDEV_H + +#include +#include + +class Fpga_spidev +{ +public: + /*! + * \brief Default constructor. + */ + Fpga_spidev() = default; + + /*! + * \brief Default destructor. + */ + ~Fpga_spidev() = default; + + /*! + * \brief write a register through the SPI. + */ + int write_reg32(char addr, uint32_t data); + + /*! + * \brief read a register through the SPI. + */ + int read_reg32(uint8_t addr, uint32_t* copy_to); + /*! + * \brief Open the SPI device driver. + */ + int SPI_open(void); + + /*! + * \brief Close the SPI device driver + */ + int SPI_close(void) const; + +private: + static const uint32_t SPI_SPEED = 250000; + const std::string SPI_DEVICE_NAME = std::string("/dev/spidev2.0"); // Switch UIO device name + + int d_fd; +}; + + +#endif // GNSS_SDR_FPGA_SPIDEV_H diff --git a/src/algorithms/signal_source/libs/fpga_switch.cc b/src/algorithms/signal_source/libs/fpga_switch.cc index b56f63bf5..2730bdf36 100644 --- a/src/algorithms/signal_source/libs/fpga_switch.cc +++ b/src/algorithms/signal_source/libs/fpga_switch.cc @@ -21,17 +21,31 @@ */ #include "fpga_switch.h" -#include +#include "uio_fpga.h" #include // for open, O_RDWR, O_SYNC #include // for cout #include // for mmap #include // for close -Fpga_Switch::Fpga_Switch(const std::string &device_name) +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +Fpga_Switch::Fpga_Switch(void) { - if ((d_device_descriptor = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + std::string device_io_name; // Switch UIO device file + // find the uio device file corresponding to the switch. + if (find_uio_dev_file_name(device_io_name, SWITCH_DEVICE_NAME, 0) < 0) { - LOG(WARNING) << "Cannot open deviceio" << device_name; + std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << SWITCH_DEVICE_NAME << '\n'; + return; + } + + if ((d_device_descriptor = open(device_io_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_io_name; } d_map_base = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0)); diff --git a/src/algorithms/signal_source/libs/fpga_switch.h b/src/algorithms/signal_source/libs/fpga_switch.h index b4a73cb4f..8a46c214d 100644 --- a/src/algorithms/signal_source/libs/fpga_switch.h +++ b/src/algorithms/signal_source/libs/fpga_switch.h @@ -42,8 +42,7 @@ public: /*! * \brief Constructor */ - explicit Fpga_Switch(const std::string& device_name); - + Fpga_Switch(void); /*! * \brief Destructor */ @@ -55,6 +54,7 @@ public: void set_switch_position(int32_t switch_position); private: + const std::string SWITCH_DEVICE_NAME = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name static const size_t FPGA_PAGE_SIZE = 0x1000; static const uint32_t TEST_REGISTER_TRACK_WRITEVAL = 0x55AA; static const uint32_t MAX_LENGTH_DEVICEIO_NAME = 50; diff --git a/src/algorithms/signal_source/libs/gnss_sdr_valve.cc b/src/algorithms/signal_source/libs/gnss_sdr_valve.cc index 6054af6dd..a62917745 100644 --- a/src/algorithms/signal_source/libs/gnss_sdr_valve.cc +++ b/src/algorithms/signal_source/libs/gnss_sdr_valve.cc @@ -19,11 +19,16 @@ #include "gnss_sdr_valve.h" #include "command_event.h" -#include // for LOG #include // for io_signature #include // for min #include // for memcpy +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + Gnss_Sdr_Valve::Gnss_Sdr_Valve(size_t sizeof_stream_item, uint64_t nitems, Concurrent_Queue* queue, diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc new file mode 100644 index 000000000..66ffa1e62 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -0,0 +1,271 @@ +/*! + * \file ion_gsms_chunk_data.cc + * \brief Holds logic for reading and decoding samples from a chunk + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "ion_gsms_chunk_data.h" +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + + +IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset) + : chunk_(chunk), + sizeword_(chunk_.SizeWord()), + countwords_(chunk_.CountWords()) +{ + // Instantiate the Allocator functor + Allocator allocator(countwords_, buffer_); + // Call with_word_type with the Allocator functor + with_word_type(sizeword_, allocator); + + const std::size_t total_bitsize = sizeword_ * countwords_ * 8; + std::size_t used_bitsize = 0; + std::size_t output_streams = 0; + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + used_bitsize += stream.Packedbits(); + + bool found = false; + for (const auto& stream_id : stream_ids) + { + if (stream_id == stream.Id()) + { + found = true; + break; + } + } + if (found) + { + streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()), output_streams + output_stream_offset); + ++output_streams; + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_rate = stream.RateFactor(); + if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) + { + // Samples have 'Complex' format + sample_bitsize /= 2; + sample_rate *= 2; + } + output_stream_item_size_.push_back(bits_to_item_size(sample_bitsize)); + output_stream_item_rate_.push_back(sample_rate); + } + else + { + streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()), -1); + } + } + } + + output_stream_count_ = output_streams; + padding_bitsize_ = total_bitsize - used_bitsize; +} + + +IONGSMSChunkData::~IONGSMSChunkData() +{ + Deleter deleter(static_cast(buffer_)); + with_word_type(sizeword_, deleter); +} + + +std::size_t IONGSMSChunkData::read_from_buffer(uint8_t* buffer, std::size_t offset) +{ + memset(buffer_, 0, sizeword_ * countwords_); + memcpy(buffer_, &buffer[offset], sizeword_ * countwords_); + return sizeword_ * countwords_; +} + + +void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, std::vector& output_items) +{ + switch (sizeword_) + { + case 1: + unpack_words(outputs, output_items); + break; + case 2: + unpack_words(outputs, output_items); + break; + case 4: + unpack_words(outputs, output_items); + break; + case 8: + unpack_words(outputs, output_items); + break; + default: + LOG(ERROR) << "Unknown word size (" << std::to_string(sizeword_) << "), unpacking nothing."; + break; + } +} + + +std::size_t IONGSMSChunkData::output_stream_count() const +{ + return output_stream_count_; +} + + +std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index) const +{ + return output_stream_item_size_[stream_index]; +} + + +std::size_t IONGSMSChunkData::output_stream_item_rate(std::size_t stream_index) const +{ + return output_stream_item_rate_[stream_index]; +} + + +template +void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, std::vector& output_items) +{ + WT* data = static_cast(buffer_); + // TODO - Swap endianness if needed + + IONGSMSChunkUnpackingCtx ctx{ + chunk_.Shift(), + data, + countwords_, + }; + + // Head padding + if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head) + { + ctx.shift_padding(padding_bitsize_); + } + + // Samples + for (const auto& [lump, stream, encoding, output_index] : streams_) + { + if (output_index == -1) + { + // skip stream + ctx.shift_padding(stream.Packedbits()); + } + else + { + output_items[output_index] += write_stream_samples(ctx, lump, stream, encoding, &outputs[output_index]); + } + } +} + + +template +std::size_t IONGSMSChunkData::write_stream_samples( + IONGSMSChunkUnpackingCtx& ctx, + const GnssMetadata::Lump& lump, + const GnssMetadata::IonStream& stream, + const GnssMetadata::StreamEncoding stream_encoding, + void** out) +{ + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_count = stream.RateFactor(); + + if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) + { + // Samples have 'Complex' format + sample_bitsize /= 2; + sample_count *= 2; + } + + if (sample_bitsize <= 8) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); + } + else if (sample_bitsize <= 16) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); + } + else if (sample_bitsize <= 32) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); + } + else if (sample_bitsize <= 64) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); + } + + return sample_count; +} + + +template +void IONGSMSChunkData::write_n_samples( + IONGSMSChunkUnpackingCtx& ctx, + GnssMetadata::Lump::LumpShift lump_shift, + uint8_t sample_bitsize, + std::size_t sample_count, + GnssMetadata::StreamEncoding stream_encoding, + OT** out) +{ + if (lump_shift == GnssMetadata::Lump::shiftRight) + { + auto* sample = static_cast(*out); + sample += sample_count; + for (std::size_t i = 0; i < sample_count; ++i) + { + *sample = 0; + ctx.shift_sample(sample_bitsize, sample); + decode_sample(sample_bitsize, sample, stream_encoding); + --sample; + } + } + else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined) + { + auto* sample = static_cast(*out); + for (std::size_t i = 0; i < sample_count; ++i) + { + *sample = 0; + ctx.shift_sample(sample_bitsize, sample); + decode_sample(sample_bitsize, sample, stream_encoding); + ++sample; + } + } + + (*out) += sample_count; +} + + +// Static utilities +template +void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, Sample* sample, const GnssMetadata::StreamEncoding encoding) +{ + // using SampleType = std::remove_pointer_t; + switch (sample_bitsize) + { + case 2: + *sample = GnssMetadata::two_bit_look_up[encoding][*sample]; + break; + case 3: + *sample = GnssMetadata::three_bit_look_up[encoding][*sample]; + break; + case 4: + *sample = GnssMetadata::four_bit_look_up[encoding][*sample]; + break; + case 5: + *sample = GnssMetadata::five_bit_look_up[encoding][*sample]; + break; + default: + // TODO - Is this an error that can happen? + // for now we'll just do nothing, if the sample is this wide it may need no decoding + break; + } +} diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h new file mode 100644 index 000000000..5170af848 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -0,0 +1,188 @@ +/*! + * \file ion_gsms_chunk_data.h + * \brief Holds logic for reading and decoding samples from a chunk + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_ION_GSMS_CHUNK_DATA_H +#define GNSS_SDR_ION_GSMS_CHUNK_DATA_H + +#include "ion_gsms_chunk_unpacking_ctx.h" +#include "ion_gsms_stream_encodings.h" +#include +#include +#include +#include +#include +#include +#include + + +inline std::size_t bits_to_item_size(std::size_t bit_count) +{ + if (bit_count <= 8) + { + return 1; + } + if (bit_count <= 16) + { + return 2; + } + if (bit_count <= 32) + { + return 4; + } + if (bit_count <= 64) + { + return 8; + } + + // You are asking too much of this humble processor + std::cerr << "Item size too large (" << std::to_string(bit_count) << "), returning nonsense.\n"; + return 1; +} + + +// Define a functor that has a templated operator() +struct Allocator +{ + size_t countwords_; + void*& buffer_; // Using void* to hold any type of pointer + + Allocator(size_t countwords, void*& buffer) + : countwords_(countwords), buffer_(buffer) {} + + template + void operator()() const + { + buffer_ = new WordType[countwords_]; + } +}; + + +// Define a functor to delete the allocated memory +struct Deleter +{ + void* buffer_; + + explicit Deleter(void* buffer) + : buffer_(buffer) {} + + template + void operator()() const + { + delete[] static_cast(buffer_); + } +}; + + +template +void with_word_type(uint8_t word_size, Callback callback) +{ + switch (word_size) + { + case 1: + callback.template operator()(); + break; + case 2: + callback.template operator()(); + break; + case 4: + callback.template operator()(); + break; + case 8: + callback.template operator()(); + break; + default: + std::cerr << "Unknown word size (" << std::to_string(word_size) << "), returning nonsense.\n"; + break; + } +} + +class IONGSMSChunkData +{ +public: + IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset); + + ~IONGSMSChunkData(); + + IONGSMSChunkData(const IONGSMSChunkData& rhl) = delete; + IONGSMSChunkData& operator=(const IONGSMSChunkData& rhl) = delete; + + IONGSMSChunkData(IONGSMSChunkData&& rhl) = delete; + IONGSMSChunkData& operator=(IONGSMSChunkData&& rhl) = delete; + + std::size_t read_from_buffer(uint8_t* buffer, std::size_t offset); + + void write_to_output(gr_vector_void_star& outputs, std::vector& output_items); + + std::size_t output_stream_count() const; + std::size_t output_stream_item_size(std::size_t stream_index) const; + std::size_t output_stream_item_rate(std::size_t stream_index) const; + +private: + template + void unpack_words(gr_vector_void_star& outputs, std::vector& output_items); + + template + std::size_t write_stream_samples( + IONGSMSChunkUnpackingCtx& ctx, + const GnssMetadata::Lump& lump, + const GnssMetadata::IonStream& stream, + GnssMetadata::StreamEncoding stream_encoding, + void** out); + + template + void write_n_samples( + IONGSMSChunkUnpackingCtx& ctx, + GnssMetadata::Lump::LumpShift lump_shift, + uint8_t sample_bitsize, + std::size_t sample_count, + GnssMetadata::StreamEncoding stream_encoding, + OT** out); + + template + static void decode_sample(uint8_t sample_bitsize, Sample* sample, GnssMetadata::StreamEncoding encoding); + + const GnssMetadata::Chunk& chunk_; + uint8_t sizeword_; + uint8_t countwords_; + uint8_t padding_bitsize_; + std::size_t output_stream_count_; + std::vector output_stream_item_size_; + std::vector output_stream_item_rate_; + + struct stream_metadata_t + { + const GnssMetadata::Lump& lump; + const GnssMetadata::IonStream& stream; + GnssMetadata::StreamEncoding stream_encoding; + int output_index = -1; + + stream_metadata_t( + const GnssMetadata::Lump& lump_, + const GnssMetadata::IonStream& stream_, + GnssMetadata::StreamEncoding stream_encoding_, + int output_index_ = -1) : lump(lump_), + stream(stream_), + stream_encoding(stream_encoding_), + output_index(output_index_) + { + } + }; + std::vector streams_; + + void* buffer_; +}; + +#endif // GNSS_SDR_ION_GSMS_CHUNK_DATA_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h new file mode 100644 index 000000000..6799f1080 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h @@ -0,0 +1,184 @@ +/*! + * \file ion_gsms_chunk_unpacking_ctx.h + * \brief Holds state and provides utilities for unpacking samples from a chunk + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * This is a template class, and thus, its member functions must be defined in the header file. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H +#define GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H + +#include +#include +#include + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ + +template +struct IONGSMSChunkUnpackingCtx +{ + static constexpr uint8_t word_bitsize_ = sizeof(WT) * 8; + + const GnssMetadata::Chunk::WordShift word_shift_direction_; + WT* iterator_ = nullptr; // Not owned by this class, MUST NOT destroy + WT current_word_{}; + uint8_t bitshift_ = 0; + + IONGSMSChunkUnpackingCtx( + const GnssMetadata::Chunk::WordShift word_shift, + WT* data_buffer, + uint8_t data_buffer_word_count) : word_shift_direction_(word_shift) + { + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + iterator_ = data_buffer; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + iterator_ = &data_buffer[data_buffer_word_count]; + } + if (iterator_) + { + advance_word(); // Initializes current_word_ + } + } + + void advance_word() + { + WT word = *iterator_; + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + ++iterator_; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + --iterator_; + } + + current_word_ = word; + } + + void shift_current_word(uint8_t n) + { + if ((n % word_bitsize_) == 0) + { + for (uint8_t i = 0; i < (n / word_bitsize_); ++i) + { + advance_word(); + } + return; + } + + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + current_word_ <<= n; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + current_word_ >>= n; + } + + bitshift_ += n; + if (bitshift_ >= word_bitsize_) + { + advance_word(); + bitshift_ -= word_bitsize_; + } + } + + void shift_padding(uint8_t n_bits) + { + if (n_bits == 0) + { + return; + } + + if ((n_bits + (bitshift_ % word_bitsize_)) >= word_bitsize_) + { + const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_); + + shift_current_word(bits_shifted); + shift_padding(n_bits - bits_shifted); + } + else + { + shift_current_word(n_bits); + } + } + + template + void shift_sample(uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) + { + if (sample_bitsize % word_bitsize_ == 0) + { + const uint8_t words_per_sample = sample_bitsize / word_bitsize_; + for (uint8_t i = 0; i < words_per_sample; ++i) + { + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + *output |= (current_word_ << ((words_per_sample - 1 - i) * word_bitsize_)); + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + *output |= (current_word_ << (i * word_bitsize_)); + // TODO - reverse bit order of sample? maybe? + } + advance_word(); + } + } + else if ((sample_bitsize + (bitshift_ % word_bitsize_)) > word_bitsize_) + { + const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_); + + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize_ - bits_shifted)) - 1); + *output |= ((current_word_ & mask) >> output_bit_offset); + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (bits_shifted)) - 1); + *output |= (current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + } + + shift_current_word(bits_shifted); + shift_sample(sample_bitsize - bits_shifted, output, bits_shifted); + } + else + { + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize_ - sample_bitsize)) - 1); + OT sample = (current_word_ & mask) >> (word_bitsize_ - sample_bitsize); + *output |= (sample) >> output_bit_offset; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (sample_bitsize)) - 1); + *output |= (current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + } + + shift_current_word(sample_bitsize); + } + } +}; + +/** \} */ +/** \} */ +#endif // GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h new file mode 100644 index 000000000..5b39e6497 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h @@ -0,0 +1,170 @@ +/*! + * \file ion_gsms_stream_encodings.h + * \brief Implements look up tables for all encodings in the standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * These tables are taken from the stardard's official document. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H +#define GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H + +#include + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ + +namespace GnssMetadata +{ + +using StreamEncoding = unsigned char; + +namespace StreamEncodings +{ + +constexpr unsigned char SIGN = 0; +constexpr unsigned char OB = 1; +constexpr unsigned char SM = 2; +constexpr unsigned char MS = 3; +constexpr unsigned char TC = 4; +constexpr unsigned char OG = 5; +constexpr unsigned char OBA = 6; +constexpr unsigned char SMA = 7; +constexpr unsigned char MSA = 8; +constexpr unsigned char TCA = 9; +constexpr unsigned char OGA = 10; +constexpr unsigned char FP = 11; + +} // namespace StreamEncodings + +inline StreamEncoding encoding_from_string(const std::string& str) +{ + if (str == "SIGN") + { + return StreamEncodings::SIGN; + } + if (str == "OB") + { + return StreamEncodings::OB; + } + if (str == "SM") + { + return StreamEncodings::SM; + } + if (str == "MS") + { + return StreamEncodings::MS; + } + if (str == "TC") + { + return StreamEncodings::TC; + } + if (str == "OG") + { + return StreamEncodings::OG; + } + if (str == "OBA") + { + return StreamEncodings::OBA; + } + if (str == "SMA") + { + return StreamEncodings::SMA; + } + if (str == "MSA") + { + return StreamEncodings::MSA; + } + if (str == "TCA") + { + return StreamEncodings::TCA; + } + if (str == "OGA") + { + return StreamEncodings::OGA; + } + if (str == "FP") + { + return StreamEncodings::FP; + } + return 0; +} + +template +inline T two_bit_look_up[11][4]{ + {}, // [0] + {-2, -1, 0, 1}, // [1 /*OB*/] + {0, 1, 0, -1}, // [2 /*SM*/] + {0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, -2, -1}, // [4 /*TC*/] + {-2, -1, 1, 0}, // [5 /*OG*/] + {-3, -1, 1, 3}, // [6 /*OBA*/] + {1, 3, -1, -3}, // [7 /*SMA*/] + {1, -1, 3, -3}, // [8 /*MSA*/] + {1, 3, -3, -1}, // [9 /*TCA*/] + {-3, -1, 3, 1}, // [10 /*OGA*/] +}; + +template +inline T three_bit_look_up[11][8]{ + {}, // [0] + {-4, -3, -2, -1, 0, 1, 2, 3}, // [1 /*OB*/] + {0, 1, 2, 3, 0, -1, -2, -3}, // [2 /*SM*/] + {0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, 2, 3, -4, -3, -2, -1}, // [4 /*TC*/] + {-4, -3, -1, -2, 3, 2, 0, 1}, // [5 /*OG*/] + {-7, -5, -3, -1, 1, 3, 5, 7}, // [6 /*OBA*/] + {1, 3, 5, 7, -1, -3, -5, -7}, // [7 /*SMA*/] + {1, -1, 3, -3, 5, -5, 7, -7}, // [8 /*MSA*/] + {1, 3, 5, 7, -7, -5, -3, -1}, // [9 /*TCA*/] + {-7, -5, -1, -3, 7, 5, 1, 3}, // [10 /*OGA*/] +}; + +template +inline T four_bit_look_up[11][16]{ + {}, // [0] + {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // [1 /*OB*/] + {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, // [2 /*SM*/] + {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, // [4 /*TC*/] + {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, // [5 /*OG*/] + {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, // [6 /*OBA*/] + {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, // [7 /*SMA*/] + {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, // [8 /*MSA*/] + {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, // [9 /*TCA*/] + {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, // [10 /*OGA*/] +}; + +template +inline T five_bit_look_up[11][32]{ + {}, // [0] + {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, // [1 /*OB*/] + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, // [2 /*SM*/] + {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, // [4 /*TC*/] + {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, // [5 /*OG*/] + {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, // [6 /*OBA*/] + {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, // [7 /*SMA*/] + {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, // [8 /*MSA*/] + {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, // [9 /*TCA*/] + {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, // [10 /*OGA*/] +}; + +} // namespace GnssMetadata + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H diff --git a/src/algorithms/signal_source/libs/pps_samplestamp.h b/src/algorithms/signal_source/libs/pps_samplestamp.h index df4b40929..facb0e284 100644 --- a/src/algorithms/signal_source/libs/pps_samplestamp.h +++ b/src/algorithms/signal_source/libs/pps_samplestamp.h @@ -21,7 +21,7 @@ class PpsSamplestamp { public: - uint64_t samplestamp = 0; // PPS rising edge samples counter from the beginning of rx stream opperation. Notice that it is reseted to zero if sample buffer overflow is detected on the FPGA side + uint64_t samplestamp = 0; // PPS rising edge samples counter from the beginning of rx stream operation. Notice that it is reset to zero if sample buffer overflow is detected on the FPGA side uint32_t overflow_reg = 0; // >0 indicates overflow situation in the FPGA RX buffer }; diff --git a/src/algorithms/signal_source/libs/ppstcprx.cc b/src/algorithms/signal_source/libs/ppstcprx.cc index c23261aff..94dda2052 100644 --- a/src/algorithms/signal_source/libs/ppstcprx.cc +++ b/src/algorithms/signal_source/libs/ppstcprx.cc @@ -20,19 +20,6 @@ #include #include -pps_tcp_rx::pps_tcp_rx() -{ - // TODO Auto-generated constructor stub - is_connected = false; - clientSd = -1; -} - - -pps_tcp_rx::~pps_tcp_rx() -{ - // TODO Auto-generated destructor stub -} - void pps_tcp_rx::set_pps_samplestamp_queue(std::shared_ptr> queue) { @@ -40,7 +27,7 @@ void pps_tcp_rx::set_pps_samplestamp_queue(std::shared_ptr> Pps_queue; - int clientSd; + int clientSd{-1}; public: - volatile bool is_connected; - pps_tcp_rx(); - virtual ~pps_tcp_rx(); + volatile bool is_connected{false}; + pps_tcp_rx() = default; + virtual ~pps_tcp_rx() = default; - void receive_pps(std::string ip_address, int port); - bool send_cmd(std::string cmd); + void receive_pps(const std::string& ip_address, int port); + bool send_cmd(std::string cmd) const; void set_pps_samplestamp_queue(std::shared_ptr> queue); }; diff --git a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt index 9c0ae28ee..a804a1a86 100644 --- a/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/adapters/CMakeLists.txt @@ -59,11 +59,16 @@ target_link_libraries(telemetry_decoder_adapters telemetry_decoder_gr_blocks telemetry_decoder_libs PRIVATE - Gflags::gflags - Glog::glog Gnuradio::runtime ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(telemetry_decoder_adapters PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(telemetry_decoder_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(telemetry_decoder_adapters PRIVATE absl::flags absl::log) +endif() + target_include_directories(telemetry_decoder_adapters PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc index 433ad8643..8f7229954 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc @@ -18,7 +18,12 @@ #include "beidou_b1i_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif BeidouB1iTelemetryDecoder::BeidouB1iTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc index 6b35a9c07..502479613 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc @@ -17,7 +17,12 @@ #include "beidou_b3i_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif BeidouB3iTelemetryDecoder::BeidouB3iTelemetryDecoder( const ConfigurationInterface *configuration, diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc index cadc48503..e6c302437 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc @@ -19,7 +19,12 @@ #include "galileo_e1b_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GalileoE1BTelemetryDecoder::GalileoE1BTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc index 73bf36b88..cf0c3828c 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5a_telemetry_decoder.cc @@ -22,7 +22,12 @@ #include "galileo_e5a_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GalileoE5aTelemetryDecoder::GalileoE5aTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc index 94181a94c..d6c66b20c 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e5b_telemetry_decoder.cc @@ -20,7 +20,12 @@ #include "galileo_e5b_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GalileoE5bTelemetryDecoder::GalileoE5bTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc index 4f4517ef7..5fd6342ea 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e6_telemetry_decoder.cc @@ -19,7 +19,12 @@ #include "galileo_e6_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GalileoE6TelemetryDecoder::GalileoE6TelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc index 037f20454..c6de2b98f 100644 --- a/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l1_ca_telemetry_decoder.cc @@ -19,7 +19,12 @@ #include "glonass_l1_ca_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GlonassL1CaTelemetryDecoder::GlonassL1CaTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc index cfa172edd..77dfb5528 100644 --- a/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/glonass_l2_ca_telemetry_decoder.cc @@ -18,7 +18,12 @@ #include "glonass_l2_ca_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GlonassL2CaTelemetryDecoder::GlonassL2CaTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc index 9ee5f3db1..7f9a243bd 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.cc @@ -18,7 +18,12 @@ #include "gps_l1_ca_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h index b10bed4d4..571c17be1 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/gps_l1_ca_telemetry_decoder.h @@ -32,7 +32,7 @@ * Classes for the decoding of GNSS Navigation messages. * \{ */ /** \addtogroup Telemetry_Decoder_adapters telemetry_decoder_adapters - * Wrap GNU Radio blocs for the decoding of GNSS Navigation messages with a + * Wrap GNU Radio blocks for the decoding of GNSS Navigation messages with a * TelemetryDecoderInterface * \{ */ diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc index f662627d7..6db0843bb 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l2c_telemetry_decoder.cc @@ -18,7 +18,12 @@ #include "gps_l2c_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GpsL2CTelemetryDecoder::GpsL2CTelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc index a302c479f..e5dadfa90 100644 --- a/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/gps_l5_telemetry_decoder.cc @@ -18,7 +18,12 @@ #include "gps_l5_telemetry_decoder.h" #include "configuration_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GpsL5TelemetryDecoder::GpsL5TelemetryDecoder( diff --git a/src/algorithms/telemetry_decoder/adapters/sbas_l1_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/sbas_l1_telemetry_decoder.cc index 82b639f70..4fdd9a18d 100644 --- a/src/algorithms/telemetry_decoder/adapters/sbas_l1_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/sbas_l1_telemetry_decoder.cc @@ -18,8 +18,13 @@ #include "sbas_l1_telemetry_decoder.h" #include "configuration_interface.h" -#include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif SbasL1TelemetryDecoder::SbasL1TelemetryDecoder( const ConfigurationInterface* configuration, diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt index c71184aa8..7c9ff7b83 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt @@ -58,11 +58,16 @@ target_link_libraries(telemetry_decoder_gr_blocks Gnuradio::runtime Boost::headers PRIVATE - Gflags::gflags - Glog::glog Gnuradio::pmt ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(telemetry_decoder_gr_blocks PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(telemetry_decoder_gr_blocks PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(telemetry_decoder_gr_blocks PRIVATE absl::flags absl::log) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(telemetry_decoder_gr_blocks PUBLIC -DGNURADIO_USES_STD_POINTERS=1 diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc index 0edbfee36..c7ecd7da4 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_gs.cc @@ -26,7 +26,6 @@ #include "gnss_sdr_make_unique.h" // for std::make_unique in C++11 #include "gnss_synchro.h" #include "tlm_utils.h" -#include #include #include // for make_any #include // for mp @@ -38,6 +37,12 @@ #include // for shared_ptr, make_shared #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #define CRC_ERROR_LIMIT 8 diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc index a1fd40555..d27afa592 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc @@ -25,7 +25,6 @@ #include "gnss_sdr_make_unique.h" // for std::make_unique in C++11 #include "gnss_synchro.h" #include "tlm_utils.h" -#include #include #include // for make_any #include // for mp @@ -37,6 +36,12 @@ #include // for shared_ptr, make_shared #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #define CRC_ERROR_LIMIT 8 beidou_b3i_telemetry_decoder_gs_sptr diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index 690715725..53687a2e1 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -34,7 +34,6 @@ #include "tlm_crc_stats.h" // for Tlm_CRC_Stats #include "tlm_utils.h" // for save_tlm_matfile, tlm_remove_file #include "viterbi_decoder.h" // for Viterbi_Decoder -#include // for LOG, DLOG #include // for gr::io_signature::make #include // for pmt::mp #include // for std::array @@ -46,9 +45,16 @@ #include // for std::numeric_limits #include // for std::map #include // for std::out_of_range +#include // for std::tuple #include // for typeid #include // for std::pair +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -106,6 +112,7 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs( d_enable_reed_solomon_inav(false), d_valid_timetag(false), d_E6_TOW_set(false), + d_there_are_e1_channels(conf.there_are_e1_channels), d_there_are_e6_channels(conf.there_are_e6_channels), d_use_ced(conf.use_ced) { @@ -116,12 +123,19 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs( // Control messages to tracking block this->message_port_register_out(pmt::mp("telemetry_to_trk")); + if (d_there_are_e1_channels) + { + // register OSM out + this->message_port_register_out(pmt::mp("OSNMA_from_TLM")); + } + if (d_there_are_e6_channels) { // register Gal E6 messages HAS out this->message_port_register_out(pmt::mp("E6_HAS_from_TLM")); // register TOW from map out this->message_port_register_out(pmt::mp("TOW_from_TLM")); + // register TOW to TLM input this->message_port_register_in(pmt::mp("TOW_to_TLM")); // handler for input port @@ -356,7 +370,6 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in // 1. De-interleave std::vector page_part_symbols_soft_value(frame_length); deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_soft_value.data()); - // 2. Viterbi decoder // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) for (int32_t i = 0; i < frame_length; i++) @@ -426,7 +439,29 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in } // 4. Push the new navigation data to the queues - if (d_inav_nav.have_new_ephemeris() == true) + // extract OSNMA bits, reset container. + if (d_inav_nav.get_osnma_adkd_0_12_nav_bits().size() == 549) + { + DLOG(INFO) << "Galileo OSNMA: new ADKD=0/12 navData from " << d_satellite << " at TOW_sf=" << d_inav_nav.get_TOW5() - 25; + const auto tmp_obj_osnma = std::make_shared>( // < PRNd , navDataBits, TOW_Sosf> + d_satellite.get_PRN(), + d_inav_nav.get_osnma_adkd_0_12_nav_bits(), + d_inav_nav.get_TOW5() - 25); + this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj_osnma)); + d_inav_nav.reset_osnma_nav_bits_adkd0_12(); + } + if (d_inav_nav.get_osnma_adkd_4_nav_bits().size() == 141) + { + DLOG(INFO) << "Galileo OSNMA: new ADKD=4 navData from " << d_satellite << " at TOW_sf=" << d_inav_nav.get_TOW6() - 5; + const auto tmp_obj = std::make_shared>( // < PRNd , navDataBits, TOW_Sosf> // TODO conversion from W6 to W_Start_of_subframe + d_satellite.get_PRN(), + d_inav_nav.get_osnma_adkd_4_nav_bits(), + d_inav_nav.get_TOW6() - 5); + this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj)); + d_inav_nav.reset_osnma_nav_bits_adkd4(); + } + + if (d_inav_nav.have_new_ephemeris() == true) // C: tells if W1-->W4 available from same block (and W5!) { // get object for this SV (mandatory) const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_ephemeris()); @@ -477,7 +512,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in } } - if (d_inav_nav.have_new_iono_and_GST() == true) + if (d_inav_nav.have_new_iono_and_GST() == true) // C: W5 { // get object for this SV (mandatory) const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_iono()); @@ -508,7 +543,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in } } - if (d_inav_nav.have_new_utc_model() == true) + if (d_inav_nav.have_new_utc_model() == true) // C: tells if W6 is available { // get object for this SV (mandatory) const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_utc_model()); @@ -543,7 +578,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in DLOG(INFO) << "delta_t=" << d_delta_t << "[s]"; } - if (d_inav_nav.have_new_almanac() == true) + if (d_inav_nav.have_new_almanac() == true) // flag_almanac_4 tells if W10 available. { const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_almanac()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); @@ -575,6 +610,12 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in DLOG(INFO) << "d_TOW_at_current_symbol_ms=" << d_TOW_at_current_symbol_ms; DLOG(INFO) << "d_nav.WN_0=" << d_inav_nav.get_Galileo_week(); } + auto newOSNMA = d_inav_nav.have_new_nma(); + if (d_band == '1' && newOSNMA) + { + const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_osnma_msg()); + this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj)); + } } @@ -737,7 +778,7 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(uint64_t time_stamp, float * std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel " << d_channel << " from satellite " << d_satellite << " with CN0=" - << std::setprecision(2) << cn0 << " dB-Hz" << std::setprecision(default_precision) + << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << TEXT_RESET << std::endl; } } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h index 9cf5c81e0..a6391a2e0 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h @@ -152,6 +152,7 @@ private: bool d_enable_reed_solomon_inav; bool d_valid_timetag; bool d_E6_TOW_set; + bool d_there_are_e1_channels; bool d_there_are_e6_channels; bool d_use_ced; }; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.cc index b2cc50cf8..b19c5eb02 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.cc @@ -22,7 +22,6 @@ #include "glonass_gnav_utc_model.h" #include "gnss_sdr_make_unique.h" // for std::make_unique in C++11 #include "tlm_utils.h" -#include #include #include // for make_any #include // for mp @@ -35,6 +34,12 @@ #include // for shared_ptr, make_shared #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #define CRC_ERROR_LIMIT 6 diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h index e6b22ba2a..df679916e 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l1_ca_telemetry_decoder_gs.h @@ -62,7 +62,7 @@ public: ~glonass_l1_ca_telemetry_decoder_gs() override; //!< Class destructor void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN void set_channel(int32_t channel); //!< Set receiver's channel - inline void reset(){}; + inline void reset() {}; /*! * \brief This is where all signal processing takes place diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc index 473e5eb73..9de17d33c 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.cc @@ -22,7 +22,6 @@ #include "glonass_gnav_utc_model.h" #include "gnss_sdr_make_unique.h" // for std::make_unique in C++11 #include "tlm_utils.h" -#include #include #include // for make_any #include // for mp @@ -35,6 +34,12 @@ #include // for shared_ptr, make_shared #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #define CRC_ERROR_LIMIT 6 diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h index fb3a93c38..3a0455d30 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/glonass_l2_ca_telemetry_decoder_gs.h @@ -60,7 +60,7 @@ public: ~glonass_l2_ca_telemetry_decoder_gs() override; //!< Class destructor void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN void set_channel(int32_t channel); //!< Set receiver's channel - inline void reset(){}; + inline void reset() {}; /*! * \brief This is where all signal processing takes place diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc index bd72d4cde..ba4c6d688 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc @@ -24,7 +24,6 @@ #include "gps_iono.h" // for Gps_Iono #include "gps_utc_model.h" // for Gps_Utc_Model #include "tlm_utils.h" -#include #include #include // for make_any #include // for mp @@ -39,6 +38,12 @@ #include // for std::move #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #ifdef COMPILER_HAS_ROTL #include namespace my_rotl = std; @@ -391,10 +396,19 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe(double cn0, bool flag_inver const std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } + if (d_nav.almanac_validation() == true) + { + const std::shared_ptr tmp_obj = std::make_shared(d_nav.get_almanac()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } break; case 5: - // get almanac (if available) - // TODO: implement almanac reader in navigation_message + if (d_nav.almanac_validation() == true) + { + const std::shared_ptr tmp_obj = std::make_shared(d_nav.get_almanac()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + break; default: break; } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.cc index b745738da..ea4f15585 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l2c_telemetry_decoder_gs.cc @@ -24,7 +24,6 @@ #include "gps_cnav_iono.h" // for Gps_CNAV_Iono #include "gps_cnav_utc_model.h" // for Gps_CNAV_Utc_Model #include "tlm_utils.h" -#include #include #include // for make_any #include // for mp @@ -37,6 +36,11 @@ #include // for shared_ptr, make_shared #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif gps_l2c_telemetry_decoder_gs_sptr gps_l2c_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.cc index d664551ea..f6d95d2a5 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l5_telemetry_decoder_gs.cc @@ -23,7 +23,6 @@ #include "gps_cnav_iono.h" #include "gps_cnav_utc_model.h" // for Gps_CNAV_Utc_Model #include "tlm_utils.h" -#include #include #include // for make_any #include // for mp @@ -35,6 +34,12 @@ #include // for std::cout #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + gps_l5_telemetry_decoder_gs_sptr gps_l5_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, const Tlm_Conf &conf) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.cc index 9a15fd2b6..3da46865f 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.cc @@ -17,7 +17,6 @@ #include "sbas_l1_telemetry_decoder_gs.h" #include "gnss_synchro.h" #include "viterbi_decoder_sbas.h" -#include #include #include // for mp #include // for copy @@ -27,6 +26,12 @@ #include // for operator<<, setw #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + // logging levels #define EVENT 2 // logs important events which don't occur every block #define FLOW 3 // logs the function calls of block processing functions @@ -197,8 +202,8 @@ bool sbas_l1_telemetry_decoder_gs::Symbol_Aligner_And_Decoder::get_bits(const st const int32_t nbits_requested = symbols.size() / D_SYMBOLS_PER_BIT; int32_t nbits_decoded; // fill two vectors with the two possible symbol alignments - std::vector symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector - std::vector symbols_vd2; // shifted symbol vector -> add past sample in front of input vector + const std::vector &symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector + std::vector symbols_vd2; // shifted symbol vector -> add past sample in front of input vector symbols_vd2.push_back(d_past_symbol); for (auto symbol_it = symbols.cbegin(); symbol_it != symbols.cend() - 1; ++symbol_it) { diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.h index 6e436b6b6..86fd2dfb6 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/sbas_l1_telemetry_decoder_gs.h @@ -57,7 +57,7 @@ public: ~sbas_l1_telemetry_decoder_gs() override; void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN void set_channel(int32_t channel); //!< Set receiver's channel - inline void reset(){}; + inline void reset() {}; /*! * \brief This is where all signal processing takes place diff --git a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt index befb48ddf..ed35d0111 100644 --- a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt @@ -47,11 +47,16 @@ target_link_libraries(telemetry_decoder_libs PRIVATE Volkgnsssdr::volkgnsssdr algorithms_libs - Gflags::gflags - Glog::glog Matio::matio ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(telemetry_decoder_libs PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(telemetry_decoder_libs PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(telemetry_decoder_libs PRIVATE absl::flags absl::log) +endif() + target_include_directories(telemetry_decoder_libs PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/telemetry_decoder/libs/tlm_conf.cc b/src/algorithms/telemetry_decoder/libs/tlm_conf.cc index 2b9b3c59d..cb520a978 100644 --- a/src/algorithms/telemetry_decoder/libs/tlm_conf.cc +++ b/src/algorithms/telemetry_decoder/libs/tlm_conf.cc @@ -16,6 +16,7 @@ */ #include "tlm_conf.h" +#include void Tlm_Conf::SetFromConfiguration(const ConfigurationInterface *configuration, @@ -30,6 +31,11 @@ void Tlm_Conf::SetFromConfiguration(const ConfigurationInterface *configuration, const std::string default_crc_stats_dumpname("telemetry_crc_stats"); dump_crc_stats_filename = configuration->property(role + ".dump_crc_stats_filename", default_crc_stats_dumpname); enable_navdata_monitor = configuration->property("NavDataMonitor.enable_monitor", false); + if (configuration->property("Channels_1B.count", 0) > 0) + { + there_are_e1_channels = true; + } + if (configuration->property("Channels_E6.count", 0) > 0) { there_are_e6_channels = true; diff --git a/src/algorithms/telemetry_decoder/libs/tlm_conf.h b/src/algorithms/telemetry_decoder/libs/tlm_conf.h index fccbb3f7b..ecddac37e 100644 --- a/src/algorithms/telemetry_decoder/libs/tlm_conf.h +++ b/src/algorithms/telemetry_decoder/libs/tlm_conf.h @@ -42,6 +42,7 @@ public: bool enable_reed_solomon{false}; // for INAV message in Galileo E1B bool dump_crc_stats{false}; // telemetry CRC statistics bool enable_navdata_monitor{false}; + bool there_are_e1_channels{false}; bool there_are_e6_channels{false}; bool use_ced{false}; }; diff --git a/src/algorithms/telemetry_decoder/libs/tlm_crc_stats.cc b/src/algorithms/telemetry_decoder/libs/tlm_crc_stats.cc index 4d6b9d9e6..a5d69c96f 100644 --- a/src/algorithms/telemetry_decoder/libs/tlm_crc_stats.cc +++ b/src/algorithms/telemetry_decoder/libs/tlm_crc_stats.cc @@ -17,11 +17,15 @@ #include "tlm_crc_stats.h" #include "gnss_sdr_create_directory.h" #include "gnss_sdr_filesystem.h" -#include #include // for std::setw() #include // for cerr, cout #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif void Tlm_CRC_Stats::initialize(std::string dump_crc_stats_filename) { diff --git a/src/algorithms/telemetry_decoder/libs/viterbi_decoder_sbas.cc b/src/algorithms/telemetry_decoder/libs/viterbi_decoder_sbas.cc index 7972e708c..02c27e28b 100644 --- a/src/algorithms/telemetry_decoder/libs/viterbi_decoder_sbas.cc +++ b/src/algorithms/telemetry_decoder/libs/viterbi_decoder_sbas.cc @@ -16,10 +16,15 @@ */ #include "viterbi_decoder_sbas.h" -#include #include // for fill_n #include // for operator<<, basic_ostream, char_traits +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + // logging #define EVENT 2 // logs important events which don't occur every block #define FLOW 3 // logs the function calls of block processing functions @@ -272,7 +277,7 @@ int Viterbi_Decoder_Sbas::do_tb_and_decode(int traceback_length, int requested_d VLOG(BLOCK) << "overstep_length=" << overstep_length; for (it = d_trellis_paths.begin() + traceback_length; - it < d_trellis_paths.begin() + traceback_length + overstep_length; ++it) + it < d_trellis_paths.begin() + traceback_length + overstep_length; ++it) { state = it->get_anchestor_state_of_current_state(state); } diff --git a/src/algorithms/tracking/adapters/CMakeLists.txt b/src/algorithms/tracking/adapters/CMakeLists.txt index f37824a3e..b72ae96df 100644 --- a/src/algorithms/tracking/adapters/CMakeLists.txt +++ b/src/algorithms/tracking/adapters/CMakeLists.txt @@ -100,9 +100,15 @@ target_link_libraries(tracking_adapters tracking_gr_blocks PRIVATE gnss_sdr_flags - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(tracking_adapters PRIVATE Glog::glog) + target_compile_definitions(tracking_adapters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(tracking_adapters PRIVATE absl::flags absl::log) +endif() + target_include_directories(tracking_adapters PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces diff --git a/src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.cc index 31ffb9fe8..748d81967 100644 --- a/src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/beidou_b1i_dll_pll_tracking.cc @@ -26,10 +26,14 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif BeidouB1iDllPllTracking::BeidouB1iDllPllTracking( const ConfigurationInterface* configuration, diff --git a/src/algorithms/tracking/adapters/beidou_b3i_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/beidou_b3i_dll_pll_tracking.cc index 633b87689..8408e1861 100644 --- a/src/algorithms/tracking/adapters/beidou_b3i_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/beidou_b3i_dll_pll_tracking.cc @@ -26,10 +26,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + BeidouB3iDllPllTracking::BeidouB3iDllPllTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc index 4483afa1b..16c021217 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking.cc @@ -26,10 +26,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE1DllPllVemlTracking::GalileoE1DllPllVemlTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc index b0571c13d..52c41c3d2 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.cc @@ -28,11 +28,16 @@ #include "galileo_e1_signal_replica.h" #include "gnss_sdr_flags.h" #include "uio_fpga.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE1DllPllVemlTrackingFpga::GalileoE1DllPllVemlTrackingFpga( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h index 722440f32..8de75e087 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/galileo_e1_dll_pll_veml_tracking_fpga.h @@ -65,11 +65,11 @@ public: } /*! - * \brief Returns "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga" + * \brief Returns "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA" */ inline std::string implementation() override { - return "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga"; + return "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA"; } /*! diff --git a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc index 9236e0862..fc79e02ab 100644 --- a/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e1_tcp_connector_tracking.cc @@ -25,9 +25,13 @@ #include "Galileo_E1.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif GalileoE1TcpConnectorTracking::GalileoE1TcpConnectorTracking( const ConfigurationInterface* configuration, @@ -47,15 +51,30 @@ GalileoE1TcpConnectorTracking::GalileoE1TcpConnectorTracking( int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); bool dump = configuration->property(role_ + ".dump", false); float pll_bw_hz = configuration->property(role_ + ".pll_bw_hz", static_cast(50.0)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) { pll_bw_hz = static_cast(FLAGS_pll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) + { + pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); + } +#endif float dll_bw_hz = configuration->property(role_ + ".dll_bw_hz", static_cast(2.0)); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif float early_late_space_chips = configuration->property(role_ + ".early_late_space_chips", static_cast(0.15)); float very_early_late_space_chips = configuration->property(role_ + ".very_early_late_space_chips", static_cast(0.5)); size_t port_ch0 = configuration->property(role_ + ".port_ch0", 2060); diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc index f54f904e6..876ff34c7 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking.cc @@ -26,10 +26,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE5aDllPllTracking::GalileoE5aDllPllTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc index e6dcca1ac..ddf843a3c 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.cc @@ -23,11 +23,16 @@ #include "galileo_e5_signal_replica.h" #include "gnss_sdr_flags.h" #include "uio_fpga.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( const ConfigurationInterface *configuration, const std::string &role, @@ -70,7 +75,7 @@ GalileoE5aDllPllTrackingFpga::GalileoE5aDllPllTrackingFpga( // GNSS-SDR instantiates the tracking channels i L1, L2, L5, E1, E5a // However E5a can use the same tracking HW accelerators as L5 (but not simultaneously). // Therefore for the proper assignment of the FPGA tracking device file numbers to the E5a tracking channels, - // the number of channels that have already been assigned to L5 must not be substracted to this channel number, + // the number of channels that have already been assigned to L5 must not be subtracted to this channel number, // so they are not counted here. uint32_t num_prev_assigned_ch_1C = configuration->property("Channels_1C.count", 0); diff --git a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h index 510df45ea..1b3c8f52b 100644 --- a/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/galileo_e5a_dll_pll_tracking_fpga.h @@ -59,11 +59,11 @@ public: } /*! - * \brief Returns "Galileo_E5a_DLL_PLL_Tracking_Fpga" + * \brief Returns "Galileo_E5a_DLL_PLL_Tracking_FPGA" */ inline std::string implementation() override { - return "Galileo_E5a_DLL_PLL_Tracking_Fpga"; + return "Galileo_E5a_DLL_PLL_Tracking_FPGA"; } /*! diff --git a/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.cc index 61df5df98..6e7191958 100644 --- a/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e5b_dll_pll_tracking.cc @@ -27,10 +27,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE5bDllPllTracking::GalileoE5bDllPllTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/galileo_e6_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/galileo_e6_dll_pll_tracking.cc index ca01034d4..1d1c81e09 100644 --- a/src/algorithms/tracking/adapters/galileo_e6_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/galileo_e6_dll_pll_tracking.cc @@ -22,10 +22,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GalileoE6DllPllTracking::GalileoE6DllPllTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc index 460a6f2df..c8835db47 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -27,7 +27,13 @@ #include "GLONASS_L1_L2_CA.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" +#include + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GlonassL1CaDllPllCAidTracking::GlonassL1CaDllPllCAidTracking( @@ -48,15 +54,30 @@ GlonassL1CaDllPllCAidTracking::GlonassL1CaDllPllCAidTracking( int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); bool dump = configuration->property(role_ + ".dump", false); float pll_bw_hz = configuration->property(role_ + ".pll_bw_hz", static_cast(50.0)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) { pll_bw_hz = static_cast(FLAGS_pll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) + { + pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); + } +#endif float dll_bw_hz = configuration->property(role_ + ".dll_bw_hz", static_cast(2.0)); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif float pll_bw_narrow_hz = configuration->property(role_ + ".pll_bw_narrow_hz", static_cast(20.0)); float dll_bw_narrow_hz = configuration->property(role_ + ".dll_bw_narrow_hz", static_cast(2.0)); int extend_correlation_ms = configuration->property(role_ + ".extend_correlation_ms", 1); diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc index 769c15dd0..12deb5f90 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_tracking.cc @@ -26,7 +26,13 @@ #include "GLONASS_L1_L2_CA.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" +#include + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GlonassL1CaDllPllTracking::GlonassL1CaDllPllTracking( @@ -47,15 +53,30 @@ GlonassL1CaDllPllTracking::GlonassL1CaDllPllTracking( int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); bool dump = configuration->property(role_ + ".dump", false); float pll_bw_hz = configuration->property(role_ + ".pll_bw_hz", static_cast(50.0)); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) { pll_bw_hz = static_cast(FLAGS_pll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) + { + pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); + } +#endif float dll_bw_hz = configuration->property(role_ + ".dll_bw_hz", static_cast(2.0)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif float early_late_space_chips = configuration->property(role_ + ".early_late_space_chips", static_cast(0.5)); const std::string default_dump_filename("./track_ch"); std::string dump_filename = configuration->property(role_ + ".dump_filename", default_dump_filename); diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc index 3da79c423..4150a4ad5 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_c_aid_tracking.cc @@ -25,7 +25,13 @@ #include "GLONASS_L1_L2_CA.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" +#include + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GlonassL2CaDllPllCAidTracking::GlonassL2CaDllPllCAidTracking( @@ -46,15 +52,30 @@ GlonassL2CaDllPllCAidTracking::GlonassL2CaDllPllCAidTracking( int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); bool dump = configuration->property(role_ + ".dump", false); float pll_bw_hz = configuration->property(role_ + ".pll_bw_hz", static_cast(50.0)); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) { pll_bw_hz = static_cast(FLAGS_pll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) + { + pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); + } +#endif float dll_bw_hz = configuration->property(role_ + ".dll_bw_hz", static_cast(2.0)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif float pll_bw_narrow_hz = configuration->property(role_ + ".pll_bw_narrow_hz", static_cast(20.0)); float dll_bw_narrow_hz = configuration->property(role_ + ".dll_bw_narrow_hz", static_cast(2.0)); int extend_correlation_ms = configuration->property(role_ + ".extend_correlation_ms", 1); diff --git a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc index 283f10ed1..e145f2867 100644 --- a/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l2_ca_dll_pll_tracking.cc @@ -24,7 +24,13 @@ #include "GLONASS_L1_L2_CA.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" +#include + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GlonassL2CaDllPllTracking::GlonassL2CaDllPllTracking( @@ -45,15 +51,29 @@ GlonassL2CaDllPllTracking::GlonassL2CaDllPllTracking( int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); bool dump = configuration->property(role_ + ".dump", false); float pll_bw_hz = configuration->property(role_ + ".pll_bw_hz", static_cast(50.0)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) { pll_bw_hz = static_cast(FLAGS_pll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) + { + pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); + } +#endif float dll_bw_hz = configuration->property(role_ + ".dll_bw_hz", static_cast(2.0)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif float early_late_space_chips = configuration->property(role_ + ".early_late_space_chips", static_cast(0.5)); const std::string default_dump_filename("./track_ch"); std::string dump_filename = configuration->property(role_ + ".dump_filename", default_dump_filename); diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc index 00cccbe97..5d0f9973a 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking.cc @@ -27,10 +27,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL1CaDllPllTracking::GpsL1CaDllPllTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc index c0db6265d..6d9981ed5 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.cc @@ -28,11 +28,16 @@ #include "gnss_sdr_flags.h" #include "gps_sdr_signal_replica.h" #include "uio_fpga.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL1CaDllPllTrackingFpga::GpsL1CaDllPllTrackingFpga( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h index dedefd7c5..ed3b23f4a 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_fpga.h @@ -64,11 +64,11 @@ public: } /*! - * \brief Returns "GPS_L1_CA_DLL_PLL_Tracking_Fpga" + * \brief Returns "GPS_L1_CA_DLL_PLL_Tracking_FPGA" */ inline std::string implementation() override { - return "GPS_L1_CA_DLL_PLL_Tracking_Fpga"; + return "GPS_L1_CA_DLL_PLL_Tracking_FPGA"; } /*! diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc index 5477511d6..c52d546a9 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_dll_pll_tracking_gpu.cc @@ -25,7 +25,12 @@ #include "GPS_L1_CA.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GpsL1CaDllPllTrackingGPU::GpsL1CaDllPllTrackingGPU( @@ -49,9 +54,18 @@ GpsL1CaDllPllTrackingGPU::GpsL1CaDllPllTrackingGPU( fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); dump = configuration->property(role + ".dump", false); pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) pll_bw_hz = static_cast(FLAGS_pll_bw_hz); +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); +#endif dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) dll_bw_hz = static_cast(FLAGS_dll_bw_hz); +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); +#endif + early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); const std::string default_dump_filename("./track_ch"); dump_filename = configuration->property(role + ".dump_filename", default_dump_filename); diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_gaussian_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_gaussian_tracking.cc index b5439d319..f9b5f70c9 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_gaussian_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_gaussian_tracking.cc @@ -28,7 +28,13 @@ #include "GPS_L1_CA.h" #include "configuration_interface.h" #include "gnss_sdr_flags.h" +#include + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif GpsL1CaGaussianTracking::GpsL1CaGaussianTracking( @@ -50,10 +56,17 @@ GpsL1CaGaussianTracking::GpsL1CaGaussianTracking( int fs_in = configuration->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); bool dump = configuration->property(role_ + ".dump", false); float dll_bw_hz = configuration->property(role_ + ".dll_bw_hz", static_cast(2.0)); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif float early_late_space_chips = configuration->property(role_ + ".early_late_space_chips", static_cast(0.5)); const std::string default_dump_filename("./track_ch"); std::string dump_filename = configuration->property(role_ + ".dump_filename", default_dump_filename); diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc index d1fbae84d..ad4dd1647 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_kf_tracking.cc @@ -27,10 +27,15 @@ #include "display.h" #include "gnss_sdr_flags.h" #include "kf_conf.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL1CaKfTracking::GpsL1CaKfTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc index fa09c8dcb..887dbdbc5 100644 --- a/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l1_ca_tcp_connector_tracking.cc @@ -24,9 +24,14 @@ #include "gps_l1_ca_tcp_connector_tracking.h" #include "GPS_L1_CA.h" #include "configuration_interface.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL1CaTcpConnectorTracking::GpsL1CaTcpConnectorTracking( const ConfigurationInterface* configuration, diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc index 98692f544..c048686c9 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking.cc @@ -26,10 +26,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL2MDllPllTracking::GpsL2MDllPllTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc index da652be87..0d0fa843a 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.cc @@ -30,13 +30,18 @@ #include "gnss_synchro.h" #include "gps_l2c_signal_replica.h" #include "uio_fpga.h" -#include #include #include #include #include // for round #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL2MDllPllTrackingFpga::GpsL2MDllPllTrackingFpga( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h index 506e8fec6..a89dd5d55 100644 --- a/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l2_m_dll_pll_tracking_fpga.h @@ -57,10 +57,10 @@ public: return role_; } - //! Returns "GPS_L2_M_DLL_PLL_Tracking_Fpga" + //! Returns "GPS_L2_M_DLL_PLL_Tracking_FPGA" inline std::string implementation() override { - return "GPS_L2_M_DLL_PLL_Tracking_Fpga"; + return "GPS_L2_M_DLL_PLL_Tracking_FPGA"; } inline size_t item_size() override diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc index d77303820..fddc9d8c2 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking.cc @@ -26,10 +26,15 @@ #include "display.h" #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL5DllPllTracking::GpsL5DllPllTracking( const ConfigurationInterface* configuration, const std::string& role, diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc index 485afd7c3..2020ef042 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.cc @@ -30,11 +30,16 @@ #include "gnss_sdr_flags.h" #include "gps_l5_signal_replica.h" #include "uio_fpga.h" -#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + GpsL5DllPllTrackingFpga::GpsL5DllPllTrackingFpga( const ConfigurationInterface *configuration, const std::string &role, diff --git a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h index 24fc37a14..ed85735b2 100644 --- a/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h +++ b/src/algorithms/tracking/adapters/gps_l5_dll_pll_tracking_fpga.h @@ -65,11 +65,11 @@ public: } /*! - * \brief Returns "GPS_L5_DLL_PLL_Tracking_Fpga" + * \brief Returns "GPS_L5_DLL_PLL_Tracking_FPGA" */ inline std::string implementation() override { - return "GPS_L5_DLL_PLL_Tracking_Fpga"; + return "GPS_L5_DLL_PLL_Tracking_FPGA"; } /*! diff --git a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt index cad24584d..4f72b86d0 100644 --- a/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/tracking/gnuradio_blocks/CMakeLists.txt @@ -85,9 +85,15 @@ target_link_libraries(tracking_gr_blocks algorithms_libs Matio::matio gnss_sdr_flags - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(tracking_gr_blocks PRIVATE Glog::glog) + target_compile_definitions(tracking_gr_blocks PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(tracking_gr_blocks PRIVATE absl::flags absl::log) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(tracking_gr_blocks PUBLIC -DGNURADIO_USES_STD_POINTERS=1 diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 5ac5f6d62..1f87fcc8d 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -45,7 +45,6 @@ #include "gps_sdr_signal_replica.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include // for io_signature #include // for scoped_lock #include // for Mat_VarCreate @@ -61,6 +60,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -1251,7 +1256,10 @@ void dll_pll_veml_tracking::update_tracking_vars() } tmp_cp1 /= static_cast(d_trk_parameters.smoother_length); tmp_cp2 /= static_cast(d_trk_parameters.smoother_length); - d_code_phase_rate_step_chips = (tmp_cp2 - tmp_cp1) / tmp_samples; + if (tmp_samples >= 1.0) + { + d_code_phase_rate_step_chips = (tmp_cp2 - tmp_cp1) / tmp_samples; + } } } // remnant code phase [chips] @@ -1859,7 +1867,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) if (next_state) { LOG(INFO) << d_systemName << " " << d_signal_pretty_name << " tracking bit synchronization locked in channel " << d_channel - << " for satellite " << Gnss_Satellite(d_systemName, d_acquisition_gnss_synchro->PRN) << '\n'; + << " for satellite " << Gnss_Satellite(d_systemName, d_acquisition_gnss_synchro->PRN); std::cout << d_systemName << " " << d_signal_pretty_name << " tracking bit synchronization locked in channel " << d_channel << " for satellite " << Gnss_Satellite(d_systemName, d_acquisition_gnss_synchro->PRN) << '\n'; } diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 070f0d46f..275892172 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -35,7 +35,6 @@ #include "gps_sdr_signal_replica.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include // for io_signature #include // for scoped_lock #include // for Mat_VarCreate @@ -49,6 +48,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -874,7 +879,10 @@ void dll_pll_veml_tracking_fpga::update_tracking_vars() } tmp_cp1 /= static_cast(d_trk_parameters.smoother_length); tmp_cp2 /= static_cast(d_trk_parameters.smoother_length); - d_code_phase_rate_step_chips = (tmp_cp2 - tmp_cp1) / tmp_samples; + if (tmp_samples >= 1.0) + { + d_code_phase_rate_step_chips = (tmp_cp2 - tmp_cp1) / tmp_samples; + } } } // remnant code phase [chips] @@ -1530,11 +1538,12 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un { boost::mutex::scoped_lock lock(d_mutex); d_worker_is_done = false; + l.unlock(); while (!d_worker_is_done) { d_m_condition.wait(lock); } - + l.lock(); // Signal alignment (skip samples until the incoming signal is aligned with local replica) int64_t acq_trk_diff_samples; double acq_trk_diff_seconds; @@ -1676,7 +1685,7 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un if (next_state) { LOG(INFO) << d_systemName << " " << d_signal_pretty_name << " tracking bit synchronization locked in channel " << d_channel - << " for satellite " << Gnss_Satellite(d_systemName, d_acquisition_gnss_synchro->PRN) << '\n'; + << " for satellite " << Gnss_Satellite(d_systemName, d_acquisition_gnss_synchro->PRN); std::cout << d_systemName << " " << d_signal_pretty_name << " tracking bit synchronization locked in channel " << d_channel << " for satellite " << Gnss_Satellite(d_systemName, d_acquisition_gnss_synchro->PRN) << '\n'; } diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc index d40c99783..e4af28caf 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc @@ -32,7 +32,6 @@ #include "tcp_communication.h" #include "tcp_packet_data.h" #include "tracking_discriminators.h" -#include #include #include #include // for fill_n @@ -42,6 +41,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + galileo_e1_tcp_connector_tracking_cc_sptr galileo_e1_tcp_connector_make_tracking_cc( int64_t fs_in, @@ -111,7 +116,11 @@ Galileo_E1_Tcp_Connector_Tracking_cc::Galileo_E1_Tcp_Connector_Tracking_cc( d_cn0_estimation_counter(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(static_cast(FLAGS_carrier_lock_th)), +#else + d_carrier_lock_threshold(static_cast(absl::GetFlag(FLAGS_carrier_lock_th))), +#endif d_carrier_lock_fail_counter(0), d_enable_tracking(false), d_pull_in(false), @@ -126,8 +135,11 @@ Galileo_E1_Tcp_Connector_Tracking_cc::Galileo_E1_Tcp_Connector_Tracking_cc( // Telemetry message port input this->message_port_register_in(pmt::mp("telemetry_to_trk")); +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); - +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif // Initialization of local code replica // Get space for a vector with the sinboc(1,1) replica sampled 2x/chip d_ca_code = volk_gnsssdr::vector(2 * GALILEO_E1_B_CODE_LENGTH_CHIPS, gr_complex(0.0, 0.0)); @@ -365,10 +377,13 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri T_prn_samples = T_prn_seconds * static_cast(d_fs_in); K_blk_samples = T_prn_samples + d_rem_code_phase_samples + code_error_filt_secs * static_cast(d_fs_in); d_current_prn_length_samples = round(K_blk_samples); // round to a discrete number of samples - // d_rem_code_phase_samples = K_blk_samples - d_current_prn_length_samples; //rounding error < 1 sample // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### +#if USE_GLOG_AND_GFLAGS if (d_cn0_estimation_counter < FLAGS_cn0_samples) +#else + if (d_cn0_estimation_counter < absl::GetFlag(FLAGS_cn0_samples)) +#endif { // fill buffer with prompt correlator output values d_Prompt_buffer[d_cn0_estimation_counter] = *d_Prompt; @@ -379,6 +394,8 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri d_cn0_estimation_counter = 0; // Code lock indicator + +#if USE_GLOG_AND_GFLAGS d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), FLAGS_cn0_samples, GALILEO_E1_CODE_PERIOD_S); // Carrier lock indicator @@ -386,6 +403,14 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri // Loss of lock detection if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples), GALILEO_E1_CODE_PERIOD_S); + + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples)); + + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -396,7 +421,11 @@ int Galileo_E1_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attri d_carrier_lock_fail_counter--; } } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index 32e0a2e2f..1e7b6adad 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -30,7 +30,6 @@ #include "gnss_sdr_flags.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -46,6 +45,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -146,7 +151,11 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_cn0_estimation_counter(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(FLAGS_carrier_lock_th), +#else + d_carrier_lock_threshold(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif d_carrier_lock_fail_counter(0), d_enable_extended_integration(false), d_preamble_synchronized(false), @@ -189,8 +198,12 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_local_code_shift_chips[2] = d_early_late_spc_chips; multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps); - +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif + systemName["R"] = std::string("Glonass"); #if GNURADIO_GREATER_THAN_38 this->set_relative_rate(1, static_cast(d_vector_length)); @@ -747,8 +760,13 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), CN0_ESTIMATION_SAMPLES, GLONASS_L1_CA_CODE_PERIOD_S); // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), CN0_ESTIMATION_SAMPLES); - // Loss of lock detection + // Loss of lock detectionç + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -759,7 +777,11 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_carrier_lock_fail_counter--; } } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; @@ -850,9 +872,25 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at tmp_float = static_cast(d_code_freq_chips); d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // PLL commands - tmp_float = static_cast(1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S)); + auto aux = static_cast(d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = static_cast(1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S)); + aux = (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // DLL commands tmp_float = static_cast(d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S); diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index 99108ee19..ab4a59b65 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -30,7 +30,6 @@ #include "gnss_sdr_flags.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -44,6 +43,13 @@ #include #include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -144,7 +150,11 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_cn0_estimation_counter(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(FLAGS_carrier_lock_th), +#else + d_carrier_lock_threshold(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif d_carrier_lock_fail_counter(0), d_enable_extended_integration(false), d_preamble_synchronized(false), @@ -185,9 +195,11 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_local_code_shift_chips[2] = d_early_late_spc_chips; multicorrelator_cpu_16sc.init(2 * d_correlation_length_samples, d_n_correlator_taps); - +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); - +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif systemName["R"] = std::string("Glonass"); #if GNURADIO_GREATER_THAN_38 @@ -750,7 +762,12 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), CN0_ESTIMATION_SAMPLES); // Loss of lock detection + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -761,7 +778,12 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_carrier_lock_fail_counter--; } } + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; @@ -852,9 +874,25 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at tmp_float = static_cast(d_code_freq_chips); d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // PLL commands - tmp_float = static_cast(1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S)); + auto aux = static_cast(d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = static_cast(1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S)); + aux = (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // DLL commands tmp_float = static_cast(d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S); diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index 61e9e9feb..3829539c9 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -30,7 +30,6 @@ #include "gnss_sdr_flags.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -44,6 +43,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #define CN0_ESTIMATION_SAMPLES 10 glonass_l1_ca_dll_pll_tracking_cc_sptr glonass_l1_ca_dll_pll_make_tracking_cc( @@ -106,7 +111,11 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( d_acq_sample_stamp(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(FLAGS_carrier_lock_th), +#else + d_carrier_lock_threshold(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif d_carrier_lock_fail_counter(0), d_cn0_estimation_counter(0), d_enable_tracking(false), @@ -134,7 +143,11 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( multicorrelator_cpu.init(2 * d_current_prn_length_samples, d_n_correlator_taps); +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif systemName["R"] = std::string("Glonass"); #if GNURADIO_GREATER_THAN_38 @@ -594,7 +607,12 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), CN0_ESTIMATION_SAMPLES); // Loss of lock detection + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -605,7 +623,11 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut d_carrier_lock_fail_counter--; } } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc index 6274a0b26..dcc2de0da 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc @@ -28,7 +28,6 @@ #include "gnss_sdr_flags.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -43,6 +42,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -143,7 +148,11 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc d_cn0_estimation_counter(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(FLAGS_carrier_lock_th), +#else + d_carrier_lock_threshold(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif d_carrier_lock_fail_counter(0), d_enable_extended_integration(false), d_preamble_synchronized(false), @@ -185,8 +194,11 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps); +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); - +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif systemName["R"] = std::string("Glonass"); #if GNURADIO_GREATER_THAN_38 @@ -747,7 +759,12 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), CN0_ESTIMATION_SAMPLES); // Loss of lock detection + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -758,7 +775,12 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at d_carrier_lock_fail_counter--; } } + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; @@ -845,9 +867,25 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at tmp_float = static_cast(d_code_freq_chips); d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // PLL commands - tmp_float = static_cast(1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S)); + auto aux = static_cast(d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = static_cast(1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S)); + aux = (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // DLL commands tmp_float = static_cast(d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S); diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc index f88f217c4..7592e3918 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc @@ -28,7 +28,6 @@ #include "gnss_sdr_flags.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -42,6 +41,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -141,7 +146,11 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc d_acq_sample_stamp(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(FLAGS_carrier_lock_th), +#else + d_carrier_lock_threshold(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif d_carrier_lock_fail_counter(0), d_cn0_estimation_counter(0), d_enable_extended_integration(false), @@ -183,7 +192,11 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc multicorrelator_cpu_16sc.init(2 * d_correlation_length_samples, d_n_correlator_taps); +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif systemName["R"] = std::string("Glonass"); @@ -747,7 +760,12 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), CN0_ESTIMATION_SAMPLES); // Loss of lock detection + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -758,7 +776,11 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at d_carrier_lock_fail_counter--; } } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; @@ -849,9 +871,25 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at tmp_float = static_cast(d_code_freq_chips); d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // PLL commands - tmp_float = static_cast(1.0 / (d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S)); + auto aux = static_cast(d_carr_phase_error_secs_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); - tmp_float = static_cast(1.0 / (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S)); + aux = (d_code_error_filt_chips_Ti * CURRENT_INTEGRATION_TIME_S); + if (aux != 0.0) + { + tmp_float = 1.0 / aux; + } + else + { + tmp_float = 0.0; + } d_dump_file.write(reinterpret_cast(&tmp_float), sizeof(float)); // DLL commands tmp_float = static_cast(d_code_error_chips_Ti * CURRENT_INTEGRATION_TIME_S); diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc index 56b892474..9950a77e8 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc @@ -30,7 +30,6 @@ #include "gnss_sdr_flags.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -44,6 +43,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #define CN0_ESTIMATION_SAMPLES 10 @@ -107,7 +112,11 @@ Glonass_L2_Ca_Dll_Pll_Tracking_cc::Glonass_L2_Ca_Dll_Pll_Tracking_cc( d_acq_sample_stamp(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(FLAGS_carrier_lock_th), +#else + d_carrier_lock_threshold(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif d_cn0_estimation_counter(0), d_carrier_lock_fail_counter(0), d_enable_tracking(false), @@ -135,7 +144,11 @@ Glonass_L2_Ca_Dll_Pll_Tracking_cc::Glonass_L2_Ca_Dll_Pll_Tracking_cc( multicorrelator_cpu.init(2 * d_current_prn_length_samples, d_n_correlator_taps); +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif systemName["R"] = std::string("Glonass"); @@ -596,7 +609,12 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), CN0_ESTIMATION_SAMPLES); // Loss of lock detection + +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -607,7 +625,11 @@ int Glonass_L2_Ca_Dll_Pll_Tracking_cc::general_work(int noutput_items __attribut d_carrier_lock_fail_counter--; } } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc index 9898ad178..2930c5278 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc @@ -22,7 +22,6 @@ #include "lock_detectors.h" #include "tracking_discriminators.h" #include -#include #include #include #include @@ -32,6 +31,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + gps_l1_ca_dll_pll_tracking_gpu_cc_sptr gps_l1_ca_dll_pll_make_tracking_gpu_cc( @@ -127,12 +132,21 @@ Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc( // CN0 estimation and lock detector buffers d_cn0_estimation_counter = 0; +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = std::vector(FLAGS_cn0_samples); +#else + d_Prompt_buffer = std::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif + + d_carrier_lock_test = 1; d_CN0_SNV_dB_Hz = 0; d_carrier_lock_fail_counter = 0; +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold = FLAGS_carrier_lock_th; - +#else + d_carrier_lock_threshold = absl::GetFlag(FLAGS_carrier_lock_th); +#endif systemName["G"] = std::string("GPS"); systemName["S"] = std::string("SBAS"); @@ -421,7 +435,12 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut d_rem_code_phase_chips = d_rem_code_phase_samples * (d_code_freq_chips / static_cast(d_fs_in)); // ####### CN0 ESTIMATION AND LOCK DETECTORS ####################################### + +#if USE_GLOG_AND_GFLAGS if (d_cn0_estimation_counter < FLAGS_cn0_samples) +#else + if (d_cn0_estimation_counter < absl::getFlag(FLAGS_cn0_samples)) +#endif { // fill buffer with prompt correlator output values d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; // prompt @@ -431,11 +450,18 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut { d_cn0_estimation_counter = 0; // Code lock indicator + +#if USE_GLOG_AND_GFLAGS d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), FLAGS_cn0_samples, GPS_L1_CA_CODE_PERIOD_S); // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), FLAGS_cn0_samples); // Loss of lock detection if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples), GPS_L1_CA_CODE_PERIOD_S); + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples)); + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -443,7 +469,11 @@ int Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::general_work(int noutput_items __attribut { if (d_carrier_lock_fail_counter > 0) d_carrier_lock_fail_counter--; } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc index 0b8c3bb84..0d90a799f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc @@ -30,7 +30,6 @@ #include "gps_sdr_signal_replica.h" #include "lock_detectors.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -44,6 +43,11 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif gps_l1_ca_gaussian_tracking_cc_sptr gps_l1_ca_gaussian_make_tracking_cc( uint32_t order, @@ -126,7 +130,11 @@ Gps_L1_Ca_Gaussian_Tracking_cc::Gps_L1_Ca_Gaussian_Tracking_cc( d_cn0_estimation_counter(0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(FLAGS_carrier_lock_th), +#else + d_carrier_lock_threshold(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif d_carrier_lock_fail_counter(0), d_enable_tracking(false), d_pull_in(false), @@ -154,8 +162,11 @@ Gps_L1_Ca_Gaussian_Tracking_cc::Gps_L1_Ca_Gaussian_Tracking_cc( multicorrelator_cpu.init(2 * d_current_prn_length_samples, d_n_correlator_taps); +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); - +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif systemName["G"] = std::string("GPS"); systemName["S"] = std::string("SBAS"); @@ -746,7 +757,12 @@ int Gps_L1_Ca_Gaussian_Tracking_cc::general_work(int noutput_items __attribute__ d_rem_code_phase_chips = d_code_freq_chips * (d_rem_code_phase_samples / static_cast(d_fs_in)); // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### + +#if USE_GLOG_AND_GFLAGS if (d_cn0_estimation_counter < FLAGS_cn0_samples) +#else + if (d_cn0_estimation_counter < absl::GetFlag(FLAGS_cn0_samples)) +#endif { // fill buffer with prompt correlator output values d_Prompt_buffer[d_cn0_estimation_counter] = d_correlator_outs[1]; // prompt @@ -755,12 +771,21 @@ int Gps_L1_Ca_Gaussian_Tracking_cc::general_work(int noutput_items __attribute__ else { d_cn0_estimation_counter = 0; +#if USE_GLOG_AND_GFLAGS // Code lock indicator d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), FLAGS_cn0_samples, GPS_L1_CA_CODE_PERIOD_S); // Carrier lock indicator d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), FLAGS_cn0_samples); // Loss of lock detection if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + // Code lock indicator + d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples), GPS_L1_CA_CODE_PERIOD_S); + // Carrier lock indicator + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples)); + // Loss of lock detection + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { // if (d_channel == 1) // std::cout << "Carrier Lock Test Fail in channel " << d_channel << ": " << d_carrier_lock_test << " < " << d_carrier_lock_threshold << "," << nfail++ << '\n'; @@ -774,7 +799,11 @@ int Gps_L1_Ca_Gaussian_Tracking_cc::general_work(int noutput_items __attribute__ d_carrier_lock_fail_counter--; } } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc index fb94fc2de..7862a2256 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc @@ -30,7 +30,6 @@ #include "tcp_communication.h" #include "tcp_packet_data.h" #include "tracking_discriminators.h" -#include #include #include #include @@ -39,6 +38,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + gps_l1_ca_tcp_connector_tracking_cc_sptr gps_l1_ca_tcp_connector_make_tracking_cc( int64_t fs_in, @@ -102,7 +107,11 @@ Gps_L1_Ca_Tcp_Connector_Tracking_cc::Gps_L1_Ca_Tcp_Connector_Tracking_cc( d_acq_carrier_doppler_hz(0.0), d_carrier_lock_test(1), d_CN0_SNV_dB_Hz(0), +#if USE_GLOG_AND_GFLAGS d_carrier_lock_threshold(static_cast(FLAGS_carrier_lock_th)), +#else + d_carrier_lock_threshold(static_cast(absl::GetFlag(FLAGS_carrier_lock_th))), +#endif d_control_id(0), d_enable_tracking(false), d_pull_in(false), @@ -130,8 +139,11 @@ Gps_L1_Ca_Tcp_Connector_Tracking_cc::Gps_L1_Ca_Tcp_Connector_Tracking_cc( multicorrelator_cpu.init(2 * d_correlation_length_samples, d_n_correlator_taps); +#if USE_GLOG_AND_GFLAGS d_Prompt_buffer = volk_gnsssdr::vector(FLAGS_cn0_samples); - +#else + d_Prompt_buffer = volk_gnsssdr::vector(absl::GetFlag(FLAGS_cn0_samples)); +#endif systemName["G"] = std::string("GPS"); systemName["R"] = std::string("GLONASS"); systemName["S"] = std::string("SBAS"); @@ -400,7 +412,12 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib * \todo Improve the lock detection algorithm! */ // ####### CN0 ESTIMATION AND LOCK DETECTORS ###### + +#if USE_GLOG_AND_GFLAGS if (d_cn0_estimation_counter < FLAGS_cn0_samples) +#else + if (d_cn0_estimation_counter < absl::GetFlag(FLAGS_cn0_samples)) +#endif { // fill buffer with prompt correlator output values d_Prompt_buffer[d_cn0_estimation_counter] = *d_Prompt; @@ -409,11 +426,19 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib else { d_cn0_estimation_counter = 0; +#if USE_GLOG_AND_GFLAGS d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), FLAGS_cn0_samples, GPS_L1_CA_CODE_PERIOD_S); d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), FLAGS_cn0_samples); // ###### TRACKING UNLOCK NOTIFICATION ##### if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < FLAGS_cn0_min) +#else + d_CN0_SNV_dB_Hz = cn0_m2m4_estimator(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples), GPS_L1_CA_CODE_PERIOD_S); + d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer.data(), absl::GetFlag(FLAGS_cn0_samples)); + + // ###### TRACKING UNLOCK NOTIFICATION ##### + if (d_carrier_lock_test < d_carrier_lock_threshold or d_CN0_SNV_dB_Hz < absl::GetFlag(FLAGS_cn0_min)) +#endif { d_carrier_lock_fail_counter++; } @@ -424,7 +449,11 @@ int Gps_L1_Ca_Tcp_Connector_Tracking_cc::general_work(int noutput_items __attrib d_carrier_lock_fail_counter--; } } +#if USE_GLOG_AND_GFLAGS if (d_carrier_lock_fail_counter > FLAGS_max_lock_fail) +#else + if (d_carrier_lock_fail_counter > absl::GetFlag(FLAGS_max_lock_fail)) +#endif { std::cout << "Loss of lock in channel " << d_channel << "!\n"; LOG(INFO) << "Loss of lock in channel " << d_channel << "!"; diff --git a/src/algorithms/tracking/gnuradio_blocks/kf_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/kf_tracking.cc index dd50b4547..27a264096 100644 --- a/src/algorithms/tracking/gnuradio_blocks/kf_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/kf_tracking.cc @@ -43,7 +43,6 @@ #include "lock_detectors.h" #include "tracking_discriminators.h" #include "trackingcmd.h" -#include #include // for io_signature #include // for scoped_lock #include // for Mat_VarCreate @@ -58,6 +57,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -448,9 +453,14 @@ kf_tracking::kf_tracking(const Kf_Conf &conf_) d_code_samples_per_chip = 0U; d_symbols_per_bit = 0; } - - d_beta = d_code_chip_rate / d_signal_carrier_freq; - + if (d_signal_carrier_freq > 1.0) + { + d_beta = d_code_chip_rate / d_signal_carrier_freq; + } + else + { + d_beta = 0.0; + } // Initialization of local code replica // Get space for a vector with the sinboc(1,1) replica sampled 2x/chip d_tracking_code.resize(2 * d_code_length_chips, 0.0); @@ -1275,7 +1285,10 @@ void kf_tracking::update_tracking_vars() } tmp_cp1 /= static_cast(d_trk_parameters.smoother_length); tmp_cp2 /= static_cast(d_trk_parameters.smoother_length); - d_carrier_phase_rate_step_rad = (tmp_cp2 - tmp_cp1) / tmp_samples; + if (tmp_samples >= 1.0) + { + d_carrier_phase_rate_step_rad = (tmp_cp2 - tmp_cp1) / tmp_samples; + } d_x_old_old(3) = d_carrier_phase_rate_step_rad * d_trk_parameters.fs_in / TWO_PI; } } diff --git a/src/algorithms/tracking/libs/CMakeLists.txt b/src/algorithms/tracking/libs/CMakeLists.txt index 5b9520c0a..d207a7cc9 100644 --- a/src/algorithms/tracking/libs/CMakeLists.txt +++ b/src/algorithms/tracking/libs/CMakeLists.txt @@ -88,10 +88,16 @@ target_link_libraries(tracking_libs algorithms_libs PRIVATE gnss_sdr_flags - Glog::glog Gnuradio::runtime ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(tracking_libs PRIVATE Glog::glog) + target_compile_definitions(tracking_libs PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(tracking_libs PRIVATE absl::flags absl::log) +endif() + if(ENABLE_CUDA) if(CMAKE_VERSION VERSION_GREATER 3.11) target_include_directories(tracking_libs diff --git a/src/algorithms/tracking/libs/bayesian_estimation.h b/src/algorithms/tracking/libs/bayesian_estimation.h index d7e40f86e..6190ef8ff 100644 --- a/src/algorithms/tracking/libs/bayesian_estimation.h +++ b/src/algorithms/tracking/libs/bayesian_estimation.h @@ -50,7 +50,7 @@ * a sequence of identically and independently distributed (IID) samples of a stationary * stochastic process by way of Bayesian inference using conjugate priors. The posterior * distribution is assumed to be Gaussian with mean \mathbf{\mu} and covariance \hat{\mathbf{C}}, - * which has a conjugate prior given by a normal-inverse-Wishart distribution with paramemters + * which has a conjugate prior given by a normal-inverse-Wishart distribution with parameters * \mathbf{\mu}_{0}, \kappa_{0}, \nu_{0}, and \mathbf{\Psi}. * * [1] TODO: Ref1 diff --git a/src/algorithms/tracking/libs/cuda_multicorrelator.h b/src/algorithms/tracking/libs/cuda_multicorrelator.h index e23c698ef..561adf2df 100644 --- a/src/algorithms/tracking/libs/cuda_multicorrelator.h +++ b/src/algorithms/tracking/libs/cuda_multicorrelator.h @@ -46,7 +46,7 @@ struct GPU_Complex { float r; float i; - CUDA_CALLABLE_MEMBER_DEVICE GPU_Complex(){}; + CUDA_CALLABLE_MEMBER_DEVICE GPU_Complex() {}; CUDA_CALLABLE_MEMBER_DEVICE GPU_Complex(float a, float b) : r(a), i(b) {} CUDA_CALLABLE_MEMBER_DEVICE float magnitude2(void) { return r * r + i * i; } CUDA_CALLABLE_MEMBER_DEVICE GPU_Complex operator*(const GPU_Complex& a) diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index 0ffa5a395..c41229d7e 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -18,14 +18,26 @@ #include "dll_pll_conf.h" #include "gnss_sdr_flags.h" #include "item_type_helpers.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif - +#if USE_GLOG_AND_GFLAGS Dll_Pll_Conf::Dll_Pll_Conf() : carrier_lock_th(FLAGS_carrier_lock_th), cn0_samples(FLAGS_cn0_samples), cn0_min(FLAGS_cn0_min), max_code_lock_fail(FLAGS_max_lock_fail), max_carrier_lock_fail(FLAGS_max_carrier_lock_fail) +#else +Dll_Pll_Conf::Dll_Pll_Conf() : carrier_lock_th(absl::GetFlag(FLAGS_carrier_lock_th)), + cn0_samples(absl::GetFlag(FLAGS_cn0_samples)), + cn0_min(absl::GetFlag(FLAGS_cn0_min)), + max_code_lock_fail(absl::GetFlag(FLAGS_max_lock_fail)), + max_carrier_lock_fail(absl::GetFlag(FLAGS_max_carrier_lock_fail)) +#endif { signal[0] = '1'; signal[1] = 'C'; @@ -50,18 +62,31 @@ void Dll_Pll_Conf::SetFromConfiguration(const ConfigurationInterface *configurat dump_filename = configuration->property(role + ".dump_filename", dump_filename); dump_mat = configuration->property(role + ".dump_mat", dump_mat); pll_bw_hz = configuration->property(role + ".pll_bw_hz", pll_bw_hz); +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) { pll_bw_hz = static_cast(FLAGS_pll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) + { + pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); + } +#endif pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", pll_bw_narrow_hz); dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", dll_bw_narrow_hz); dll_bw_hz = configuration->property(role + ".dll_bw_hz", dll_bw_hz); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } - +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif dll_filter_order = configuration->property(role + ".dll_filter_order", dll_filter_order); pll_filter_order = configuration->property(role + ".pll_filter_order", pll_filter_order); if (dll_filter_order < 1) diff --git a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc index f2c3ea73a..d784a204b 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf_fpga.cc @@ -19,14 +19,26 @@ #include "dll_pll_conf_fpga.h" #include "gnss_sdr_flags.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif - +#if USE_GLOG_AND_GFLAGS Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() : carrier_lock_th(FLAGS_carrier_lock_th), cn0_samples(FLAGS_cn0_samples), cn0_min(FLAGS_cn0_min), max_code_lock_fail(FLAGS_max_lock_fail), max_carrier_lock_fail(FLAGS_max_carrier_lock_fail) +#else +Dll_Pll_Conf_Fpga::Dll_Pll_Conf_Fpga() : carrier_lock_th(absl::GetFlag(FLAGS_carrier_lock_th)), + cn0_samples(absl::GetFlag(FLAGS_cn0_samples)), + cn0_min(absl::GetFlag(FLAGS_cn0_min)), + max_code_lock_fail(absl::GetFlag(FLAGS_max_lock_fail)), + max_carrier_lock_fail(absl::GetFlag(FLAGS_max_carrier_lock_fail)) +#endif { signal[0] = '1'; signal[1] = 'C'; @@ -88,15 +100,29 @@ void Dll_Pll_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *confi pll_pull_in_bw_hz = 50.0; dll_pull_in_bw_hz = 3.0; pll_bw_hz = configuration->property(role + ".pll_bw_hz", pll_bw_hz); +#if USE_GLOG_AND_GFLAGS if (FLAGS_pll_bw_hz != 0.0) { pll_bw_hz = static_cast(FLAGS_pll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_pll_bw_hz) != 0.0) + { + pll_bw_hz = static_cast(absl::GetFlag(FLAGS_pll_bw_hz)); + } +#endif dll_bw_hz = configuration->property(role + ".dll_bw_hz", dll_bw_hz); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { dll_bw_hz = static_cast(FLAGS_dll_bw_hz); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + dll_bw_hz = static_cast(absl::GetFlag(FLAGS_dll_bw_hz)); + } +#endif pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", pll_bw_narrow_hz); dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", dll_bw_narrow_hz); early_late_space_chips = configuration->property(role + ".early_late_space_chips", early_late_space_chips); diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator.cc b/src/algorithms/tracking/libs/fpga_multicorrelator.cc index 99f5f778c..3b2ed122d 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator.cc +++ b/src/algorithms/tracking/libs/fpga_multicorrelator.cc @@ -21,7 +21,6 @@ */ #include "fpga_multicorrelator.h" -#include #include #include #include // for O_RDWR, O_RSYNC @@ -29,6 +28,12 @@ #include // for PROT_READ, PROT_WRITE, MAP_SHARED #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #ifndef TEMP_FAILURE_RETRY #define TEMP_FAILURE_RETRY(exp) \ ({ \ diff --git a/src/algorithms/tracking/libs/kf_conf.cc b/src/algorithms/tracking/libs/kf_conf.cc index 80b049c38..db4818261 100644 --- a/src/algorithms/tracking/libs/kf_conf.cc +++ b/src/algorithms/tracking/libs/kf_conf.cc @@ -21,13 +21,21 @@ #include "kf_conf.h" #include "gnss_sdr_flags.h" #include "item_type_helpers.h" -#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif Kf_Conf::Kf_Conf() : item_type("gr_complex"), dump_filename("./Kf_dump.dat"), fs_in(2000000.0), +#if USE_GLOG_AND_GFLAGS carrier_lock_th(FLAGS_carrier_lock_th), +#else + carrier_lock_th(absl::GetFlag(FLAGS_carrier_lock_th)), +#endif code_disc_sd_chips(0.2), carrier_disc_sd_rads(0.3), code_phase_sd_chips(0.15), @@ -52,12 +60,22 @@ Kf_Conf::Kf_Conf() : item_type("gr_complex"), vector_length(0U), smoother_length(10), extend_correlation_symbols(1), +#if USE_GLOG_AND_GFLAGS cn0_samples(FLAGS_cn0_samples), +#else + cn0_samples(absl::GetFlag(FLAGS_cn0_samples)), +#endif cn0_smoother_samples(200), carrier_lock_test_smoother_samples(25), +#if USE_GLOG_AND_GFLAGS cn0_min(FLAGS_cn0_min), max_code_lock_fail(FLAGS_max_lock_fail), max_carrier_lock_fail(FLAGS_max_carrier_lock_fail), +#else + cn0_min(absl::GetFlag(FLAGS_cn0_min)), + max_code_lock_fail(absl::GetFlag(FLAGS_max_lock_fail)), + max_carrier_lock_fail(absl::GetFlag(FLAGS_max_carrier_lock_fail)), +#endif system('G'), track_pilot(true), enable_doppler_correction(false), diff --git a/src/algorithms/tracking/libs/lock_detectors.cc b/src/algorithms/tracking/libs/lock_detectors.cc index 7fa08690b..0399ea531 100644 --- a/src/algorithms/tracking/libs/lock_detectors.cc +++ b/src/algorithms/tracking/libs/lock_detectors.cc @@ -57,15 +57,24 @@ float cn0_svn_estimator(const gr_complex* Prompt_buffer, int length, float coh_i float SNR_dB_Hz = 0.0; float Psig = 0.0; float Ptot = 0.0; + if (length == 0 || coh_integration_time_s == 0.0) + { + return -100.0; + } for (int i = 0; i < length; i++) { - Psig += std::abs(Prompt_buffer[i].real()); + Psig += std::fabs(Prompt_buffer[i].real()); Ptot += Prompt_buffer[i].imag() * Prompt_buffer[i].imag() + Prompt_buffer[i].real() * Prompt_buffer[i].real(); } Psig /= static_cast(length); Psig = Psig * Psig; Ptot /= static_cast(length); - SNR = Psig / (Ptot - Psig); + float aux = Ptot - Psig; + if (aux == 0.0) + { + return -100.0; + } + SNR = Psig / aux; SNR_dB_Hz = 10.0F * std::log10(SNR) - 10.0F * std::log10(coh_integration_time_s); return SNR_dB_Hz; } @@ -96,9 +105,13 @@ float cn0_m2m4_estimator(const gr_complex* Prompt_buffer, int length, float coh_ float m_4 = 0.0; float aux; const auto n = static_cast(length); + if (length == 0 || coh_integration_time_s == 0.0) + { + return -100.0; + } for (int i = 0; i < length; i++) { - Psig += std::abs(Prompt_buffer[i].real()); + Psig += std::fabs(Prompt_buffer[i].real()); aux = Prompt_buffer[i].imag() * Prompt_buffer[i].imag() + Prompt_buffer[i].real() * Prompt_buffer[i].real(); m_2 += aux; m_4 += (aux * aux); @@ -108,13 +121,29 @@ float cn0_m2m4_estimator(const gr_complex* Prompt_buffer, int length, float coh_ m_2 /= n; m_4 /= n; aux = std::sqrt(2.0F * m_2 * m_2 - m_4); + float denominator; if (std::isnan(aux)) { - SNR_aux = Psig / (m_2 - Psig); + denominator = m_2 - Psig; + if (denominator == 0) + { + return -100.0; + } + SNR_aux = Psig / denominator; } else { - SNR_aux = aux / (m_2 - aux); + denominator = m_2 - aux; + if (denominator == 0) + { + return -100.0; + } + SNR_aux = aux / denominator; + } + + if (SNR_aux == 0) + { + return -100.0; } SNR_dB_Hz = 10.0F * std::log10(SNR_aux) - 10.0F * std::log10(coh_integration_time_s); @@ -144,5 +173,9 @@ float carrier_lock_detector(const gr_complex* Prompt_buffer, int length) } NBP = tmp_sum_I * tmp_sum_I + tmp_sum_Q * tmp_sum_Q; NBD = tmp_sum_I * tmp_sum_I - tmp_sum_Q * tmp_sum_Q; + if (NBP == 0) + { + return 0.0; + } return NBD / NBP; } diff --git a/src/algorithms/tracking/libs/nonlinear_tracking.h b/src/algorithms/tracking/libs/nonlinear_tracking.h index f00671f8d..f70b753a0 100644 --- a/src/algorithms/tracking/libs/nonlinear_tracking.h +++ b/src/algorithms/tracking/libs/nonlinear_tracking.h @@ -46,7 +46,7 @@ class ModelFunction { public: - ModelFunction(){}; + ModelFunction() {}; virtual arma::vec operator()(const arma::vec& input) = 0; virtual ~ModelFunction() = default; }; diff --git a/src/algorithms/tracking/libs/tracking_loop_filter.cc b/src/algorithms/tracking/libs/tracking_loop_filter.cc index a722f6ffa..8fd66a946 100644 --- a/src/algorithms/tracking/libs/tracking_loop_filter.cc +++ b/src/algorithms/tracking/libs/tracking_loop_filter.cc @@ -19,10 +19,15 @@ #include "tracking_loop_filter.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + const int MAX_LOOP_ORDER = 3; const int MAX_LOOP_HISTORY_LENGTH = 4; diff --git a/src/core/interfaces/gnss_block_interface.h b/src/core/interfaces/gnss_block_interface.h index 0a2de5d6e..4004752c7 100644 --- a/src/core/interfaces/gnss_block_interface.h +++ b/src/core/interfaces/gnss_block_interface.h @@ -83,7 +83,7 @@ public: assert(RF_channel >= 0); if (RF_channel == 0) { - }; // avoid unused param warning + }; // avoid unused param warning return nullptr; // added to support raw array access (non pure virtual to allow left unimplemented)= 0; } virtual gr::basic_block_sptr get_right_block(int RF_channel) @@ -91,14 +91,14 @@ public: assert(RF_channel >= 0); if (RF_channel == 0) { - }; // avoid unused param warning + }; // avoid unused param warning return nullptr; // added to support raw array access (non pure virtual to allow left unimplemented)= 0; } /*! * \brief Start the flow of samples if needed. */ - virtual void start(){}; + virtual void start() {}; }; diff --git a/src/core/interfaces/signal_source_interface.h b/src/core/interfaces/signal_source_interface.h index df4a7baf4..759169c90 100644 --- a/src/core/interfaces/signal_source_interface.h +++ b/src/core/interfaces/signal_source_interface.h @@ -27,7 +27,12 @@ #define GNSS_SDR_SIGNAL_SOURCE_INTERFACE_H #include "gnss_block_interface.h" + +#if USE_GLOG_AND_GFLAGS #include +#else +#include +#endif /** \addtogroup Core * \{ */ diff --git a/src/core/libs/CMakeLists.txt b/src/core/libs/CMakeLists.txt index 994501ecf..5b6ba902f 100644 --- a/src/core/libs/CMakeLists.txt +++ b/src/core/libs/CMakeLists.txt @@ -9,34 +9,42 @@ protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${GNSSSDR_SOURCE_DIR}/docs/protobuf/ add_subdirectory(supl) set(CORE_LIBS_SOURCES - ini.cc - INIReader.cc - string_converter.cc - gnss_sdr_supl_client.cc - gnss_sdr_sample_counter.cc - channel_status_msg_receiver.cc channel_event.cc + channel_status_msg_receiver.cc command_event.cc galileo_e6_has_msg_receiver.cc + galileo_tow_map.cc + gnss_crypto.cc + gnss_sdr_sample_counter.cc + gnss_sdr_supl_client.cc + ini.cc + INIReader.cc nav_message_monitor.cc nav_message_udp_sink.cc - galileo_tow_map.cc + osnma_helper.cc + osnma_msg_receiver.cc + osnma_nav_data_manager.cc + string_converter.cc ) set(CORE_LIBS_HEADERS + channel_event.h + channel_status_msg_receiver.h + command_event.h + galileo_tow_map.h + gnss_crypto.h + gnss_sdr_sample_counter.h + gnss_sdr_supl_client.h ini.h INIReader.h - string_converter.h - gnss_sdr_supl_client.h - gnss_sdr_sample_counter.h - channel_status_msg_receiver.h - channel_event.h - command_event.h + nav_message_monitor.h nav_message_packet.h nav_message_udp_sink.h + osnma_helper.h + osnma_msg_receiver.h + osnma_nav_data_manager.h serdes_nav_message.h - nav_message_monitor.h - galileo_tow_map.h + string_converter.h ) if(ENABLE_FPGA) @@ -91,15 +99,20 @@ target_link_libraries(core_libs core_libs_supl core_system_parameters pvt_libs - algorithms_libs PRIVATE algorithms_libs Boost::serialization - Gflags::gflags - Glog::glog + Boost::system Pugixml::pugixml ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(core_libs PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(core_libs PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(core_libs PRIVATE absl::flags absl::log) +endif() + if(USE_GENERIC_LAMBDAS AND NOT GNURADIO_USES_STD_POINTERS) target_link_libraries(core_libs PUBLIC Boost::headers) else() @@ -117,6 +130,10 @@ target_include_directories(core_libs ${GNSSSDR_SOURCE_DIR}/src/core/interfaces ) +# links to the appropriate library and defines +# USE_GNUTLS_FALLBACK, USE_OPENSSL_3, or USE_OPENSSL_111 accordingly. +link_to_crypto_dependencies(core_libs) + if(USE_GENERIC_LAMBDAS) set(has_generic_lambdas HAS_GENERIC_LAMBDA=1) set(no_has_generic_lambdas HAS_GENERIC_LAMBDA=0) @@ -153,6 +170,14 @@ if(PMT_USES_BOOST_ANY) ) endif() +# Fix for Boost Asio > 1.86. address::from_string was deprecated in Boost 1.71 +if(Boost_VERSION_STRING VERSION_LESS 1.71.0) + target_compile_definitions(core_libs + PRIVATE + -DBOOST_ASIO_USE_FROM_STRING=1 + ) +endif() + # Do not apply clang-tidy fixes to protobuf generated headers get_filename_component(PROTO_INCLUDE_HEADERS_DIR ${PROTO_HDRS} DIRECTORY) target_include_directories(core_libs diff --git a/src/core/libs/channel_status_msg_receiver.cc b/src/core/libs/channel_status_msg_receiver.cc index 4b11abd7e..c96bb51a8 100644 --- a/src/core/libs/channel_status_msg_receiver.cc +++ b/src/core/libs/channel_status_msg_receiver.cc @@ -17,7 +17,6 @@ #include "channel_status_msg_receiver.h" -#include #include #include #include @@ -25,6 +24,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include diff --git a/src/core/libs/galileo_e6_has_msg_receiver.cc b/src/core/libs/galileo_e6_has_msg_receiver.cc index 22e1cd524..250e599a4 100644 --- a/src/core/libs/galileo_e6_has_msg_receiver.cc +++ b/src/core/libs/galileo_e6_has_msg_receiver.cc @@ -23,7 +23,6 @@ #include "galileo_has_page.h" // for Galileo_HAS_page #include "gnss_sdr_make_unique.h" // for std::make_unique in C++11 #include "reed_solomon.h" // for ReedSolomon -#include // for DLOG #include // for gr::io_signature::make #include // for std::find, std::count #include // for std::remainder @@ -34,6 +33,12 @@ #include // for std::out_of_range #include // for typeid +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -630,6 +635,7 @@ void galileo_e6_has_msg_receiver::read_MT1_body(const std::string& message_body) } } + d_iod_ref_map[std::make_pair(d_HAS_data.header.iod_set_id, d_HAS_data.header.mask_id)] = d_HAS_data.gnss_iod; DLOG(INFO) << debug_print_vector("gnss_iod", d_HAS_data.gnss_iod); DLOG(INFO) << debug_print_vector("delta_radial", d_HAS_data.delta_radial); DLOG(INFO) << debug_print_vector("delta_in_track", d_HAS_data.delta_in_track); @@ -655,6 +661,11 @@ void galileo_e6_has_msg_receiver::read_MT1_body(const std::string& message_body) d_HAS_data.delta_clock_correction[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_CLOCK_CORRECTION_LENGTH)); message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_CORRECTION_LENGTH, message.end()); } + auto ref_it = d_iod_ref_map.find(std::make_pair(d_HAS_data.header.iod_set_id, d_HAS_data.header.mask_id)); + if (ref_it != d_iod_ref_map.end()) + { + d_HAS_data.gnss_iod = ref_it->second; + } DLOG(INFO) << debug_print_vector("delta_clock_multiplier", d_HAS_data.delta_clock_multiplier); DLOG(INFO) << debug_print_vector("delta_clock_correction", d_HAS_data.delta_clock_correction); diff --git a/src/core/libs/galileo_e6_has_msg_receiver.h b/src/core/libs/galileo_e6_has_msg_receiver.h index e564ecdc7..8c42c806b 100644 --- a/src/core/libs/galileo_e6_has_msg_receiver.h +++ b/src/core/libs/galileo_e6_has_msg_receiver.h @@ -28,6 +28,7 @@ #include // for pmt::pmt_t #include #include +#include #include // for std::unique_ptr #include #include // std::pair @@ -108,6 +109,8 @@ private: std::vector d_nsys_in_mask; std::vector> d_nav_message_mask; + std::map, std::vector> d_iod_ref_map; + uint8_t d_current_has_status{}; uint8_t d_current_message_id{}; bool d_new_message{}; diff --git a/src/core/libs/galileo_tow_map.cc b/src/core/libs/galileo_tow_map.cc index 6b4da0fb5..831dff044 100644 --- a/src/core/libs/galileo_tow_map.cc +++ b/src/core/libs/galileo_tow_map.cc @@ -16,10 +16,15 @@ #include "galileo_tow_map.h" -#include // for LOG -#include // for std::numeric_limits -#include // for std::shared -#include // for typeid +#include // for std::numeric_limits +#include // for std::shared +#include // for typeid + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif #if HAS_GENERIC_LAMBDA #else diff --git a/src/core/libs/gnss_crypto.cc b/src/core/libs/gnss_crypto.cc new file mode 100644 index 000000000..95589535f --- /dev/null +++ b/src/core/libs/gnss_crypto.cc @@ -0,0 +1,1919 @@ +/*! + * \file gnss_crypto.cc + * \brief Class for computing cryptographic functions + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "gnss_crypto.h" +#include "Galileo_OSNMA.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#if USE_GNUTLS_FALLBACK +#include +#include +#include +#include +#else // OpenSSL +#include +#include +#include +#include +#include +#if USE_OPENSSL_3 +#include +#include +#include +#include +#include +#include +#include +#include +#define OPENSSL_ENGINE nullptr +#else // OpenSSL 1.x +#include +#endif +#endif + +#if USE_GLOG_AND_GFLAGS +#include // for DLOG +#else +#include +#endif + + +Gnss_Crypto::Gnss_Crypto() +{ +#if USE_GNUTLS_FALLBACK + gnutls_global_init(); +#if !HAVE_GNUTLS_SIGN_ECDSA_SHA256 + LOG(WARNING) << "The GnuTLS library version you are linking against is too old for some OSNMA functions." + << " Please do not trust OSNMA outputs or upgrade your system to a newer version of GnuTLS or OpenSSL" + << " and rebuild GNSS-SDR against it."; +#endif +#else // OpenSSL +#if !(USE_OPENSSL_3 || USE_OPENSSL_111) + LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions." + << " Please do not trust OSNMA outputs or upgrade your system to a newer version of OpenSSL" + << " and rebuild GNSS-SDR against it."; +#endif +#endif +} + + +Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath) +{ +#if USE_GNUTLS_FALLBACK + gnutls_global_init(); +#if !HAVE_GNUTLS_SIGN_ECDSA_SHA256 + LOG(WARNING) << "The GnuTLS library version you are linking against is too old for some OSNMA functions." + << " Please do not trust OSNMA outputs or upgrade your system to a newer version of GnuTLS or OpenSSL" + << " and rebuild GNSS-SDR against it."; +#endif +#else // OpenSSL +#if !(USE_OPENSSL_3 || USE_OPENSSL_111) + LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions." + << " Please do not trust OSNMA outputs or upgrade your system to a newer version of OpenSSL" + << " and rebuild GNSS-SDR against it."; +#endif +#endif + if (!readPublicKeyFromCRT(certFilePath)) + { + readPublicKeyFromPEM(certFilePath); + if (!have_public_key()) + { + readPublicKeyFromPEM(PEMFILE_DEFAULT); + } + } + read_merkle_xml(merkleTreePath); +} + + +Gnss_Crypto::~Gnss_Crypto() +{ +#if USE_GNUTLS_FALLBACK + if (d_PublicKey != nullptr) + { + gnutls_pubkey_deinit(d_PublicKey); + d_PublicKey = nullptr; + } + gnutls_global_deinit(); +#else // OpenSSL +#if !USE_OPENSSL_3 + if (d_PublicKey != nullptr) + { + EC_KEY_free(d_PublicKey); + } +#endif +#endif +} + + +bool Gnss_Crypto::have_public_key() const +{ +#if USE_GNUTLS_FALLBACK + return (d_PublicKey != gnutls_pubkey_t{}); +#else // OpenSSL + return (d_PublicKey != nullptr); +#endif +} + + +bool Gnss_Crypto::store_public_key(const std::string& pubKeyFilePath) const +{ + if (!have_public_key()) + { + return false; + } + std::ofstream pubKeyFile(pubKeyFilePath, std::ios::binary); + if (!pubKeyFile.is_open()) + { + LOG(WARNING) << "Unable to open file for storing the Public Key: " << pubKeyFilePath; + return false; + } +#if USE_GNUTLS_FALLBACK + gnutls_datum_t pem_data; +#if HAVE_GNUTLS_PUBKEY_EXPORT2 + int ret = gnutls_pubkey_export2(d_PublicKey, GNUTLS_X509_FMT_PEM, &pem_data); +#else + size_t output_stata_size; + int ret = gnutls_pubkey_export(d_PublicKey, GNUTLS_X509_FMT_PEM, &pem_data, &output_stata_size); +#endif + if (ret != GNUTLS_E_SUCCESS) + { + LOG(WARNING) << "GnuTLS: Failed to export public key: " << gnutls_strerror(ret); + return false; + } + + pubKeyFile.write(reinterpret_cast(pem_data.data), pem_data.size); + pubKeyFile.close(); + gnutls_free(pem_data.data); +#else // OpenSSL + BIO* bio = BIO_new(BIO_s_mem()); + if (!bio) + { + LOG(WARNING) << "OpenSSL: Failed to create BIO"; + return false; + } +#if USE_OPENSSL_3 + if (!PEM_write_bio_PUBKEY(bio, d_PublicKey)) +#else // OpenSSL 1.x + if (!PEM_write_bio_EC_PUBKEY(bio, d_PublicKey)) +#endif + { + LOG(WARNING) << "OpenSSL: Failed to write public key to BIO"; + BIO_free(bio); + return false; + } + + char* bio_data; + auto bio_len = BIO_get_mem_data(bio, &bio_data); + if (bio_len <= 0) + { + LOG(WARNING) << "OpenSSL: Failed to get BIO data"; + BIO_free(bio); + return false; + } + + pubKeyFile.write(bio_data, bio_len); + pubKeyFile.close(); + BIO_free(bio); +#endif + return true; +} + + +bool Gnss_Crypto::verify_signature_ecdsa_p256(const std::vector& message, const std::vector& signature) const +{ + if (!have_public_key()) + { + LOG(WARNING) << "Signature verification error: Public key is not available"; + return false; + } + std::vector digest = this->compute_SHA_256(message); + bool success = false; +#if USE_GNUTLS_FALLBACK +#if HAVE_GNUTLS_SIGN_ECDSA_SHA256 + // Convert signature to DER format + std::vector der_sig; + if (!convert_raw_to_der_ecdsa(signature, der_sig)) + { + LOG(WARNING) << "Failed to convert raw ECDSA signature to DER format"; + return false; + } + + // Prepare the digest datum + gnutls_datum_t digest_data = {const_cast(digest.data()), static_cast(digest.size())}; + gnutls_datum_t der_sig_data = {der_sig.data(), static_cast(der_sig.size())}; + + // Verify the DER-encoded signature + int ret = gnutls_pubkey_verify_hash2(d_PublicKey, GNUTLS_SIGN_ECDSA_SHA256, 0, &digest_data, &der_sig_data); + success = (ret >= 0); + if (success) + { + DLOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully"; + } + else + { + LOG(WARNING) << "GnuTLS: OSNMA message authentication failed: " << gnutls_strerror(ret); + } +#else + if (signature.empty()) + { + // do nothing + } +#endif +#else // OpenSSL +#if USE_OPENSSL_3 + EVP_PKEY_CTX* ctx; + ctx = EVP_PKEY_CTX_new(d_PublicKey, nullptr); + bool do_operation = true; + + if (!ctx) + { + do_operation = false; + } + // convert raw signature into DER format + size_t half_size = signature.size() / 2; + std::vector raw_r(signature.begin(), signature.begin() + half_size); + std::vector raw_s(signature.begin() + half_size, signature.end()); + + // Convert raw R and S to BIGNUMs + BIGNUM* r = BN_bin2bn(raw_r.data(), raw_r.size(), nullptr); + BIGNUM* s = BN_bin2bn(raw_s.data(), raw_s.size(), nullptr); + + ECDSA_SIG* sig = ECDSA_SIG_new(); + if (r == nullptr || s == nullptr || sig == nullptr) + { + LOG(WARNING) << "OpenSSL: Failed to allocate memory for BIGNUMs or ECDSA_SIG"; + return false; + } + + if (ECDSA_SIG_set0(sig, r, s) != 1) + { + LOG(WARNING) << "OpenSSL: Failed to set R and S values in ECDSA_SIG"; + ECDSA_SIG_free(sig); // Free the ECDSA_SIG struct as it is no longer needed + return false; + } + + std::vector derSignature; + unsigned char* derSig = nullptr; + int derSigLength = i2d_ECDSA_SIG(sig, &derSig); + + if (derSigLength <= 0) + { + LOG(WARNING) << "OpenSSL: Failed to convert ECDSA_SIG to DER format"; + return false; + } + + derSignature.assign(derSig, derSig + derSigLength); + + if (EVP_PKEY_verify_init(ctx) <= 0) + { + do_operation = false; + } + if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) + { + do_operation = false; + } + int verification = 0; + if (do_operation) + { + verification = EVP_PKEY_verify(ctx, derSignature.data(), derSignature.size(), digest.data(), digest.size()); + } + EVP_PKEY_CTX_free(ctx); + OPENSSL_free(derSig); + ECDSA_SIG_free(sig); + if (verification == 1) + { + success = true; + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + } + else + { + uint64_t errCode = ERR_get_error(); + char* err = ERR_error_string(errCode, nullptr); + LOG(WARNING) << "OpenSSL: OSNMA message authentication failed: " << err; + } +#else // OpenSSL 1.x + std::vector der_sig; + if (!convert_raw_to_der_ecdsa(signature, der_sig)) + { + LOG(WARNING) << "OpenSSL: Failed to convert raw ECDSA signature to DER format"; + return false; + } + int verification = ECDSA_verify(0, digest.data(), SHA256_DIGEST_LENGTH, der_sig.data(), static_cast(der_sig.size()), d_PublicKey); + if (verification == 1) + { + success = true; + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + } + else if (verification == 0) + { + LOG(WARNING) << "OpenSSL: invalid signature found when verifying message"; + } + else + { + LOG(WARNING) << "OpenSSL: OSNMA message authentication failed"; + } +#endif +#endif + return success; +} + + +bool Gnss_Crypto::verify_signature_ecdsa_p521(const std::vector& message, const std::vector& signature) const +{ + if (!have_public_key()) + { + LOG(WARNING) << "Signature verification error: Public key is not available"; + return false; + } + + if (signature.size() != 132) + { + LOG(WARNING) << "Invalid signature length for P-521. Expected 132 bytes, got " << signature.size(); + return false; + } + + std::vector der_sig; + if (!convert_raw_to_der_ecdsa(signature, der_sig)) + { + LOG(WARNING) << "Failed to convert raw ECDSA signature to DER format"; + return false; + } + bool success = false; +#if USE_GNUTLS_FALLBACK +#if HAVE_GNUTLS_SIGN_ECDSA_SHA512 + std::vector digest(64); + gnutls_hash_hd_t hash; + int ret = gnutls_hash_init(&hash, GNUTLS_DIG_SHA512); + if (ret != GNUTLS_E_SUCCESS) + { + LOG(WARNING) << "GnuTLS: gnutls_hash_init failed: " << gnutls_strerror(ret); + return false; + } + + gnutls_hash(hash, message.data(), message.size()); + gnutls_hash_deinit(hash, digest.data()); + + gnutls_datum_t digest_data = {digest.data(), static_cast(digest.size())}; + gnutls_datum_t signature_data = {der_sig.data(), static_cast(der_sig.size())}; + + // Verify the ECDSA signature + ret = gnutls_pubkey_verify_hash2(d_PublicKey, GNUTLS_SIGN_ECDSA_SHA512, 0, &digest_data, &signature_data); + + if (ret >= 0) + { + DLOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully"; + success = true; + } + else + { + LOG(WARNING) << "GnuTLS: OSNMA message authentication failed: " << gnutls_strerror(ret); + } +#else + if (message.empty()) + { + // do nothing + } +#endif +#else // OpenSSL + // Compute SHA-512 hash of the message + std::vector digest(SHA512_DIGEST_LENGTH); + if (!EVP_Digest(message.data(), message.size(), digest.data(), nullptr, EVP_sha512(), nullptr)) + { + LOG(WARNING) << "OpenSSL: EVP_Digest failed"; + return false; + } +#if USE_OPENSSL_3 + // Verify the signature + EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new(d_PublicKey, nullptr); + if (pctx == nullptr) + { + LOG(WARNING) << "OpenSSL: EVP_PKEY_CTX_new failed"; + return false; + } + + if (EVP_PKEY_verify_init(pctx) <= 0) + { + LOG(WARNING) << "OpenSSL: EVP_PKEY_verify_init failed"; + EVP_PKEY_CTX_free(pctx); + return false; + } + + if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha512()) <= 0) + { + LOG(WARNING) << "OpenSSL: EVP_PKEY_CTX_set_signature_md failed"; + EVP_PKEY_CTX_free(pctx); + return false; + } + + int verification = EVP_PKEY_verify(pctx, der_sig.data(), der_sig.size(), digest.data(), digest.size()); + EVP_PKEY_CTX_free(pctx); + + if (verification == 1) + { + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + success = true; + } + else if (verification == 0) + { + LOG(WARNING) << "OpenSSL: invalid signature found when verifying message"; + } + else + { + LOG(WARNING) << "OpenSSL: OSNMA message authentication failed"; + } +#else // OpenSSL 1.x + const unsigned char* sig_ptr = der_sig.data(); + ECDSA_SIG* ecdsa_sig = d2i_ECDSA_SIG(nullptr, &sig_ptr, der_sig.size()); + if (ecdsa_sig == nullptr) + { + LOG(WARNING) << "OpenSSL: d2i_ECDSA_SIG failed"; + return false; + } + int verification = ECDSA_do_verify(digest.data(), digest.size(), ecdsa_sig, d_PublicKey); + ECDSA_SIG_free(ecdsa_sig); + if (verification == 1) + { + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + success = true; + } + else if (verification == 0) + { + LOG(WARNING) << "OpenSSL: invalid signature found when verifying message"; + } + else + { + LOG(WARNING) << "OpenSSL: OSNMA message authentication failed"; + } +#endif +#endif + return success; +} + + +std::vector Gnss_Crypto::compute_SHA_256(const std::vector& input) const +{ + std::vector output(32); // SHA256 hash size +#if USE_GNUTLS_FALLBACK + std::vector output_aux(32); + gnutls_hash_hd_t hashHandle; + gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA256); + gnutls_hash(hashHandle, input.data(), input.size()); + gnutls_hash_output(hashHandle, output_aux.data()); + output = output_aux; + gnutls_hash_deinit(hashHandle, output_aux.data()); +#else // OpenSSL +#if USE_OPENSSL_3 + unsigned int mdLen; + EVP_MD_CTX* mdCtx = EVP_MD_CTX_new(); + if (!EVP_DigestInit_ex(mdCtx, EVP_sha256(), OPENSSL_ENGINE)) + { + // LOG(WARNING) << "OSNMA SHA-256: Message digest initialization failed."; + EVP_MD_CTX_free(mdCtx); + return output; + } + if (!EVP_DigestUpdate(mdCtx, input.data(), input.size())) + { + // LOG(WARNING) << "OSNMA SHA-256: Message digest update failed."; + EVP_MD_CTX_free(mdCtx); + return output; + } + if (!EVP_DigestFinal_ex(mdCtx, output.data(), &mdLen)) + { + // LOG(WARNING) << "OSNMA SHA-256: Message digest finalization failed."; + EVP_MD_CTX_free(mdCtx); + return output; + } + EVP_MD_CTX_free(mdCtx); +#else // OpenSSL 1.x + SHA256_CTX sha256Context; + SHA256_Init(&sha256Context); + SHA256_Update(&sha256Context, input.data(), input.size()); + SHA256_Final(output.data(), &sha256Context); +#endif +#endif + return output; +} + + +std::vector Gnss_Crypto::compute_SHA3_256(const std::vector& input) const +{ + std::vector output(32); // SHA256 hash size +#if USE_GNUTLS_FALLBACK +#if HAVE_GNUTLS_DIG_SHA3_256 + std::vector output_aux(32); + gnutls_hash_hd_t hashHandle; + gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA3_256); + gnutls_hash(hashHandle, input.data(), input.size()); + gnutls_hash_output(hashHandle, output_aux.data()); + output = output_aux; + gnutls_hash_deinit(hashHandle, output_aux.data()); +#else + if (input.empty()) + { + // do nothing + } +#endif +#else // OpenSSL +#if USE_OPENSSL_3 || USE_OPENSSL_111 + EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); + const EVP_MD* md = EVP_sha3_256(); + + EVP_DigestInit_ex(mdctx, md, nullptr); + EVP_DigestUpdate(mdctx, input.data(), input.size()); + EVP_DigestFinal_ex(mdctx, output.data(), nullptr); + EVP_MD_CTX_free(mdctx); +#else // OpenSSL 1.x + // SHA3-256 not implemented in OpenSSL 1.0, it was introduced in OpenSSL 1.1.1 + if (!input.empty()) + { + // do nothing + } +#endif +#endif + return output; +} + + +std::vector Gnss_Crypto::compute_HMAC_SHA_256(const std::vector& key, const std::vector& input) const +{ + std::vector output(32); +#if USE_GNUTLS_FALLBACK + std::vector output_aux(32); + gnutls_hmac_hd_t hmac; +#if HAVE_GNUTLS_HMAC_INIT_WITH_DIGEST + gnutls_hmac_init(&hmac, GNUTLS_DIG_SHA256, key.data(), key.size()); +#else + gnutls_hmac_init(&hmac, GNUTLS_MAC_SHA256, key.data(), key.size()); +#endif + gnutls_hmac(hmac, input.data(), input.size()); + gnutls_hmac_output(hmac, output_aux.data()); + output = output_aux; + gnutls_hmac_deinit(hmac, output_aux.data()); +#else // OpenSSL +#if USE_OPENSSL_3 + std::vector hmac(EVP_MAX_MD_SIZE); + size_t output_length = 0; + // Create the context for the HMAC operation + EVP_MAC* mac = EVP_MAC_fetch(nullptr, "HMAC", nullptr); + if (!mac) + { + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to fetch HMAC"; + return output; + } + + EVP_MAC_CTX* ctx = EVP_MAC_CTX_new(mac); + if (!ctx) + { + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to create HMAC context"; + return output; + } + + // Initialize the HMAC context with the key and the SHA-256 algorithm + OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST, const_cast("SHA256"), 0), + OSSL_PARAM_construct_end()}; + + if (EVP_MAC_init(ctx, key.data(), key.size(), params) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to initialize HMAC context"; + return output; + } + + // Update the HMAC context with the input data + if (EVP_MAC_update(ctx, input.data(), input.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to update HMAC context"; + return output; + } + + // Finalize the HMAC and retrieve the output + if (EVP_MAC_final(ctx, hmac.data(), &output_length, hmac.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to finalize HMAC"; + return output; + } + + // Clean up the HMAC context + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + hmac.resize(output_length); + output = std::move(hmac); +#else // OpenSSL 1.x + unsigned int outputLength = EVP_MAX_MD_SIZE; + unsigned char* result = HMAC(EVP_sha256(), key.data(), key.size(), input.data(), input.size(), output.data(), &outputLength); + if (result == nullptr) + { + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to compute HMAC-SHA256"; + return output; + } + + // Resize the output vector to the actual length of the HMAC-SHA256 output + output.resize(outputLength); +#endif +#endif + return output; +} + + +std::vector Gnss_Crypto::compute_CMAC_AES(const std::vector& key, const std::vector& input) const +{ + std::vector output(16); +#if USE_GNUTLS_FALLBACK +#if HAVE_GNUTLS_MAC_AES_CMAC_128 + gnutls_hmac_hd_t hmac; + + // Initialize the HMAC context with the CMAC algorithm and key + int ret = gnutls_hmac_init(&hmac, GNUTLS_MAC_AES_CMAC_128, key.data(), key.size()); + if (ret != GNUTLS_E_SUCCESS) + { + LOG(WARNING) << "OSNMA CMAC-AES: gnutls_hmac_init failed: " << gnutls_strerror(ret); + return output; + } + + // Update the HMAC context with the input data + ret = gnutls_hmac(hmac, input.data(), input.size()); + if (ret != GNUTLS_E_SUCCESS) + { + LOG(WARNING) << "OSNMA CMAC-AES: gnutls_hmac failed: " << gnutls_strerror(ret); + gnutls_hmac_deinit(hmac, nullptr); + return output; + } + + // Retrieve the HMAC output + gnutls_hmac_output(hmac, output.data()); + + // Clean up the HMAC context + gnutls_hmac_deinit(hmac, nullptr); +#else + if (!key.empty()) + { + // do nothing + } + if (!input.empty()) + { + // do nothing + } +#endif +#else // OpenSSL +#if USE_OPENSSL_3 + std::vector aux(EVP_MAX_MD_SIZE); // CMAC-AES output size + size_t output_length = 0; + + // Create the context for the CMAC operation + EVP_MAC* mac = EVP_MAC_fetch(nullptr, "CMAC", nullptr); + if (!mac) + { + LOG(WARNING) << "OSNMA CMAC-AES: Failed to fetch CMAC"; + return output; + } + + EVP_MAC_CTX* ctx = EVP_MAC_CTX_new(mac); + if (!ctx) + { + LOG(WARNING) << "OSNMA CMAC-AES: Failed to create CMAC context"; + return output; + } + + // Initialize the CMAC context with the key and the AES algorithm + OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, const_cast("AES-128-CBC"), 0), + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, const_cast(key.data()), key.size()), + OSSL_PARAM_construct_end()}; + + if (EVP_MAC_init(ctx, nullptr, 0, params) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA CMAC-AES: Failed to initialize CMAC context"; + return output; + } + + // Update the CMAC context with the input data + if (EVP_MAC_update(ctx, input.data(), input.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA CMAC-AES: Failed to update CMAC context"; + return output; + } + + // Finalize the CMAC and retrieve the output + if (EVP_MAC_final(ctx, aux.data(), &output_length, aux.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA CMAC-AES: Failed to finalize CMAC"; + return output; + } + + // Clean up the CMAC context + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + + aux.resize(output_length); + output = std::move(aux); +#else // OpenSSL 1.x + size_t mac_length = 0; // to hold the length of the MAC output + + // Create CMAC context + CMAC_CTX* cmacCtx = CMAC_CTX_new(); + if (!cmacCtx) + { + LOG(WARNING) << "OSNMA CMAC-AES: Failed to create CMAC context"; + return output; + } + + // Initialize the CMAC context with the key and cipher + if (CMAC_Init(cmacCtx, key.data(), key.size(), EVP_aes_128_cbc(), nullptr) != 1) + { + LOG(WARNING) << "OSNMA CMAC-AES: MAC_Init failed"; + CMAC_CTX_free(cmacCtx); + return output; + } + + // Compute the CMAC + if (CMAC_Update(cmacCtx, input.data(), input.size()) != 1) + { + LOG(WARNING) << "OSNMA CMAC-AES: CMAC_Update failed"; + CMAC_CTX_free(cmacCtx); + return output; + } + + // Finalize the CMAC computation and retrieve the output + if (CMAC_Final(cmacCtx, output.data(), &mac_length) != 1) + { + LOG(WARNING) << "OSNMA CMAC-AES: CMAC_Final failed"; + CMAC_CTX_free(cmacCtx); + return output; + } + + // Clean up CMAC context + CMAC_CTX_free(cmacCtx); + + // Ensure the output vector is properly sized according to the actual MAC length + output.resize(mac_length); +#endif +#endif + return output; +} + + +std::vector Gnss_Crypto::get_merkle_root() const +{ + return d_x_4_0; +} + + +std::string Gnss_Crypto::get_public_key_type() const +{ + if (d_PublicKeyType.empty()) + { + return {"Unknown"}; + } + return d_PublicKeyType; +} + + +void Gnss_Crypto::set_public_key(const std::vector& publicKey) +{ + d_PublicKeyType = std::string("Unknown"); +#if USE_GNUTLS_FALLBACK + gnutls_pubkey_t pubkey{}; + gnutls_ecc_curve_t curve; + std::vector x; + std::vector y; + + gnutls_pubkey_init(&pubkey); + const size_t size_pk = publicKey.size(); + if (size_pk == 33) + { + curve = GNUTLS_ECC_CURVE_SECP256R1; + d_PublicKeyType = std::string("ECDSA P-256"); + decompress_public_key_secp256r1(publicKey, x, y); + } + else if (size_pk == 67) + { + curve = GNUTLS_ECC_CURVE_SECP521R1; + d_PublicKeyType = std::string("ECDSA P-521"); + decompress_public_key_secp521r1(publicKey, x, y); + } + else + { + LOG(WARNING) << "GnuTLS: Invalid public key size"; + gnutls_pubkey_deinit(pubkey); + return; + } + + gnutls_datum_t x_coord = {x.data(), static_cast(x.size())}; + gnutls_datum_t y_coord = {y.data(), static_cast(y.size())}; + + int ret = gnutls_pubkey_import_ecc_raw(pubkey, curve, &x_coord, &y_coord); + if (ret != GNUTLS_E_SUCCESS) + { + gnutls_pubkey_deinit(pubkey); + LOG(WARNING) << "GnuTLS: error setting the OSNMA public key: " << gnutls_strerror(ret); + d_PublicKeyType = std::string("Unknown"); + return; + } + pubkey_copy(pubkey, &d_PublicKey); + gnutls_pubkey_deinit(pubkey); +#else // OpenSSL + +#if USE_OPENSSL_3 + // Uses the new EVP_PKEY envelope as well as the parameter builder functions + // generate the uncompressed key, then add it into the EVP_PKEY* struct + EVP_PKEY* pkey = nullptr; + EVP_PKEY_CTX* ctx = nullptr; + OSSL_PARAM_BLD* param_bld; + OSSL_PARAM* params = nullptr; + const size_t public_key_size = publicKey.size(); + + param_bld = OSSL_PARAM_BLD_new(); + if (param_bld != nullptr && + OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", (public_key_size == 33) ? "prime256v1" : "secp521r1", 0) && + OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", publicKey.data(), public_key_size)) + { + params = OSSL_PARAM_BLD_to_param(param_bld); + } + + if (public_key_size == 33) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (public_key_size == 67) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + + ctx = EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr); + if (ctx == nullptr || params == nullptr || EVP_PKEY_fromdata_init(ctx) <= 0 || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) + { + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(param_bld); + d_PublicKeyType = std::string("Unknown"); + return; + } + + if (!pubkey_copy(pkey, &d_PublicKey)) + { + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(param_bld); + d_PublicKeyType = std::string("Unknown"); + return; + } + + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(param_bld); +#else // OpenSSL 1.x + EC_KEY* ec_key = nullptr; // ECC Key pair + EC_POINT* point = nullptr; // Represents the point in the EC the public key belongs to + EC_GROUP* group = nullptr; // Defines the curve the public key belongs + if (publicKey.size() == 33) // ECDSA-P-256 + { + group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + d_PublicKeyType = std::string("ECDSA P-256"); + } + else // ECDSA-P-521 + { + group = EC_GROUP_new_by_curve_name(NID_secp521r1); + d_PublicKeyType = std::string("ECDSA P-521"); + } + if (!group) + { + d_PublicKeyType = std::string("Unknown"); + return; + } + + point = EC_POINT_new(group); + if (!point) + { + EC_GROUP_free(group); + d_PublicKeyType = std::string("Unknown"); + return; + } + + if (!EC_POINT_oct2point(group, point, publicKey.data(), publicKey.size(), nullptr)) + { + EC_GROUP_free(group); + EC_POINT_free(point); + d_PublicKeyType = std::string("Unknown"); + return; + } + + if (publicKey.size() == 33) // ECDSA-P-256 + { + ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + } + else // ECDSA-P-521 + { + ec_key = EC_KEY_new_by_curve_name(NID_secp521r1); + } + if (!ec_key) + { + EC_GROUP_free(group); + EC_POINT_free(point); + d_PublicKeyType = std::string("Unknown"); + return; + } + if (!EC_KEY_set_public_key(ec_key, point)) + { + EC_KEY_free(ec_key); + EC_POINT_free(point); + EC_GROUP_free(group); + d_PublicKeyType = std::string("Unknown"); + return; + } + if (!pubkey_copy(ec_key, &d_PublicKey)) + { + EC_KEY_free(ec_key); + EC_POINT_free(point); + EC_GROUP_free(group); + d_PublicKeyType = std::string("Unknown"); + return; + } + EC_KEY_free(ec_key); + EC_POINT_free(point); + EC_GROUP_free(group); +#endif // OpenSSL 1.x +#endif + DLOG(INFO) << "OSNMA Public Key successfully set up."; +} + + +void Gnss_Crypto::set_public_key_type(const std::string& public_key_type) +{ + if (public_key_type == "ECDSA P-256" || public_key_type == "ECDSA P-521") + { + d_PublicKeyType = public_key_type; + } +} + + +void Gnss_Crypto::set_merkle_root(const std::vector& v) +{ + d_x_4_0 = v; +} + + +void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath) +{ + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(merkleFilePath.c_str()); + if (!result) + { + // XML file not found + // If it was not the default, maybe it is a configuration error, warn user + if (merkleFilePath != MERKLEFILE_DEFAULT && !merkleFilePath.empty()) + { + LOG(WARNING) << "File " << merkleFilePath << " not found"; + } + // fill default values + d_x_4_0 = convert_from_hex_str("832E15EDE55655EAC6E399A539477B7C034CCE24C3C93FFC904ACD9BF842F04E"); + return; + } + try + { + pugi::xml_node root = doc.child("signalData"); + pugi::xml_node header = root.child("header"); + pugi::xml_node body = root.child("body"); + + // Accessing data from the header + pugi::xml_node galHeader = header.child("GAL-header"); + pugi::xml_node source = galHeader.child("source").child("GAL-EXT-GOC-SC-GLAd"); + pugi::xml_node destination = galHeader.child("destination").child("GAL-EXT-GOC-SC-GLAd"); + std::string issueDate = galHeader.child("issueDate").text().get(); + std::string signalVersion = galHeader.child("signalVersion").text().get(); + std::string dataVersion = galHeader.child("dataVersion").text().get(); + + LOG(INFO) << "OSNMA Merkletree - Source: " << source.child_value("mission") << " - " << source.child_value("segment") << " - " << source.child_value("element"); + LOG(INFO) << "OSNMA Merkletree - Destination: " << destination.child_value("mission") << " - " << destination.child_value("segment") << " - " << destination.child_value("element"); + LOG(INFO) << "OSNMA Merkletree - Issue Date: " << issueDate; + LOG(INFO) << "OSNMA Merkletree - Signal Version: " << signalVersion; + LOG(INFO) << "OSNMA Merkletree - Data Version: " << dataVersion; + + // Accessing data from the body + pugi::xml_node merkleTree = body.child("MerkleTree"); + + int n = std::stoi(merkleTree.child_value("N")); + std::string hashFunction = merkleTree.child_value("HashFunction"); + + LOG(INFO) << "OSNMA Merkletree - N: " << n; + LOG(INFO) << "OSNMA Merkletree - Hash Function: " << hashFunction; + + for (pugi::xml_node publicKey : merkleTree.children("PublicKey")) + { + int i = std::stoi(publicKey.child_value("i")); + std::string pkid = publicKey.child_value("PKID"); + int lengthInBits = std::stoi(publicKey.child_value("lengthInBits")); + std::string point = publicKey.child_value("point"); + std::string pkType = publicKey.child_value("PKType"); + + LOG(INFO) << "OSNMA Merkletree - Public Key: " << i; + LOG(INFO) << "OSNMA Merkletree - PKID: " << pkid; + LOG(INFO) << "OSNMA Merkletree - Length in Bits: " << lengthInBits; + LOG(INFO) << "OSNMA Merkletree - Point: " << point; + LOG(INFO) << "OSNMA Merkletree - PK Type: " << pkType; + if (pkType == "ECDSA P-256/SHA-256") + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (pkType == "ECDSA P-521/SHA-512") + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + } + for (pugi::xml_node treeNode : merkleTree.children("TreeNode")) + { + int j = std::stoi(treeNode.child_value("j")); + int i = std::stoi(treeNode.child_value("i")); + int lengthInBits = std::stoi(treeNode.child_value("lengthInBits")); + LOG(INFO) << "OSNMA Merkletree - Node length (bits): " << lengthInBits; + std::string x_ji = treeNode.child_value("x_ji"); + LOG(INFO) << "OSNMA Merkletree - Size string (bytes): " << x_ji.size(); + LOG(INFO) << "OSNMA Merkletree - m_" << j << "_" << i << " = " << x_ji; + if (j == 4 && i == 0) + { + d_x_4_0 = convert_from_hex_str(x_ji); + } + } + } + catch (const std::exception& e) + { + LOG(INFO) << "Exception raised reading the " << merkleFilePath << " file: " << e.what(); + d_x_4_0 = convert_from_hex_str("832E15EDE55655EAC6E399A539477B7C034CCE24C3C93FFC904ACD9BF842F04E"); + return; + } + std::cout << "OSNMA Merkle Tree successfully read from file " << merkleFilePath << std::endl; + LOG(INFO) << "OSNMA Merkle Tree successfully read from file " << merkleFilePath; +} + + +void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath) +{ + // Open the .pem file + std::ifstream pemFile(pemFilePath); + if (!pemFile) + { + return; + } + d_PublicKeyType = std::string("Unknown"); + std::string pemContent((std::istreambuf_iterator(pemFile)), std::istreambuf_iterator()); +#if USE_GNUTLS_FALLBACK + // Import the PEM data + gnutls_datum_t pemDatum = {const_cast(reinterpret_cast(const_cast(pemContent.data()))), static_cast(pemContent.size())}; + gnutls_pubkey_t pubkey; + gnutls_pubkey_init(&pubkey); + + int ret = gnutls_pubkey_import(pubkey, &pemDatum, GNUTLS_X509_FMT_PEM); + if (ret != GNUTLS_E_SUCCESS) + { + gnutls_pubkey_deinit(pubkey); + std::cerr << "GnuTLS: error reading the OSNMA Public Key from file " + << pemFilePath + << ". Aborting import" << std::endl; + LOG(WARNING) << "GnuTLS: error reading the OSNMA Public Key from file " + << pemFilePath << ". Aborting import. Error " << gnutls_strerror(ret); + return; + } + + // store the key type - needed for the Kroot in case no DSM-PKR available + gnutls_pk_algorithm_t pk_algorithm; + unsigned int bits; + + ret = gnutls_pubkey_get_pk_algorithm(pubkey, &bits); + if (ret < 0) + { + LOG(WARNING) << "GnuTLS: Failed to get public key algorithm from .pem file: " << gnutls_strerror(ret); + gnutls_pubkey_deinit(pubkey); + return; + } + + pk_algorithm = static_cast(ret); + if (pk_algorithm == GNUTLS_PK_ECC) + { + gnutls_ecc_curve_t curve; + ret = gnutls_pubkey_export_ecc_raw(pubkey, &curve, nullptr, nullptr); + if (ret < 0) + { + LOG(WARNING) << "GnuTLS: Failed to get EC curve from .pem file: " << gnutls_strerror(ret); + gnutls_pubkey_deinit(pubkey); + return; + } + + if (curve == GNUTLS_ECC_CURVE_SECP256R1) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (curve == GNUTLS_ECC_CURVE_SECP521R1) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + else + { + LOG(WARNING) << "GnuTLS: Trying to read unknown EC curve from .pem file"; + gnutls_pubkey_deinit(pubkey); + return; + } + } + else + { + LOG(WARNING) << "GnuTLS: Trying to read unknown key type from .pem file"; + gnutls_pubkey_deinit(pubkey); + return; + } + pubkey_copy(pubkey, &d_PublicKey); + gnutls_pubkey_deinit(pubkey); +#else // OpenSSL + // Create a BIO object from the string data + BIO* bio = BIO_new_mem_buf(const_cast(pemContent.c_str()), pemContent.length()); + if (!bio) + { + LOG(WARNING) << "OpenSSL: error creating a BIO object with data read from file " << pemFilePath << ". Aborting import."; + return; + } +#if USE_OPENSSL_3 + EVP_PKEY* pubkey = nullptr; + pubkey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr); + + // store the key type - needed for the Kroot in case no DSM-PKR available + // Get the key type + int key_type = EVP_PKEY_base_id(pubkey); + if (key_type == EVP_PKEY_EC) + { + // It's an EC key, now we need to determine the curve + char curve_name[256]; + size_t curve_name_len = sizeof(curve_name); + + if (EVP_PKEY_get_utf8_string_param(pubkey, OSSL_PKEY_PARAM_GROUP_NAME, curve_name, curve_name_len, &curve_name_len) == 1) + { + if (strcmp(curve_name, "prime256v1") == 0 || strcmp(curve_name, "P-256") == 0) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (strcmp(curve_name, "secp521r1") == 0 || strcmp(curve_name, "P-521") == 0) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + else + { + LOG(WARNING) << "OpenSSL: Trying to read an unknown EC curve from .pem file"; + BIO_free(bio); + EVP_PKEY_free(pubkey); + return; + } + } + else + { + LOG(WARNING) << "OpenSSL: Trying to read an unknown EC curve from .pem file"; + BIO_free(bio); + EVP_PKEY_free(pubkey); + return; + } + } + else + { + LOG(WARNING) << "OpenSSL: Trying to read an unknown key type from .pem file"; + BIO_free(bio); + EVP_PKEY_free(pubkey); + return; + } + pubkey_copy(pubkey, &d_PublicKey); + EVP_PKEY_free(pubkey); +#else // OpenSSL 1.x + EC_KEY* pubkey = nullptr; + pubkey = PEM_read_bio_EC_PUBKEY(bio, nullptr, nullptr, nullptr); + if (!pubkey) + { + LOG(WARNING) << "OpenSSL: Failed to extract the public key from .pem file"; + BIO_free(bio); + return; + } + const EC_GROUP* group = EC_KEY_get0_group(pubkey); + int nid = EC_GROUP_get_curve_name(group); + if (nid == 0) + { + BIGNUM* p = BN_new(); + if (EC_GROUP_get_curve_GFp(group, p, nullptr, nullptr, nullptr) == 1) + { + char* p_str = BN_bn2hex(p); + const std::string pcstr(p_str); + if (pcstr.size() == 64) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (pcstr.size() == 132) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + OPENSSL_free(p_str); + } + BN_free(p); + } + else + { + const char* curve_name = OBJ_nid2sn(nid); + const std::string curve_str(curve_name); + if (curve_str == "prime256v1") + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (curve_str == "secp521r1") + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + } + + pubkey_copy(pubkey, &d_PublicKey); + EC_KEY_free(pubkey); +#endif + BIO_free(bio); + if (d_PublicKey == nullptr) + { + std::cerr << "OpenSSL: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import" << std::endl; + LOG(WARNING) << "OpenSSL: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import."; + return; + } +#endif + std::cout << "OSNMA Public key successfully read from file " << pemFilePath << std::endl; + LOG(INFO) << "OSNMA Public key successfully read from file " << pemFilePath; +} + + +bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath) +{ + d_PublicKeyType = std::string("Unknown"); + // Open the .crt file + std::ifstream crtFile(crtFilePath, std::ios::binary); + if (!crtFile.is_open()) + { + // CRT file not found + // If it was not the default, maybe it is a configuration error + if (crtFilePath != CRTFILE_DEFAULT && !crtFilePath.empty()) + { + std::cerr << "File " << crtFilePath << " not found" << std::endl; + } + return false; + } + + const std::vector buffer((std::istreambuf_iterator(crtFile)), std::istreambuf_iterator()); +#if USE_GNUTLS_FALLBACK + const gnutls_datum_t buffer_datum = {const_cast(buffer.data()), static_cast(buffer.size())}; + gnutls_x509_crt_t cert; + gnutls_x509_crt_init(&cert); + int ret = gnutls_x509_crt_import(cert, &buffer_datum, GNUTLS_X509_FMT_PEM); + if (ret < 0) + { + LOG(WARNING) << "GnuTLS: Failed to import certificate: " << gnutls_strerror(ret); + gnutls_x509_crt_deinit(cert); + return false; + } + + gnutls_pubkey_t pubkey; + gnutls_pubkey_init(&pubkey); + + ret = gnutls_pubkey_import_x509(pubkey, cert, 0); + if (ret < 0) + { + LOG(WARNING) << "GnuTLS: Failed to import public key: " << gnutls_strerror(ret); + gnutls_pubkey_deinit(pubkey); + gnutls_x509_crt_deinit(cert); + return false; + } + + // store the key type - needed for the Kroot in case no DSM-PKR available + gnutls_pk_algorithm_t pk_algorithm; + unsigned int bits; + + ret = gnutls_pubkey_get_pk_algorithm(pubkey, &bits); + if (ret < 0) + { + LOG(WARNING) << "GnuTLS: Failed to get public key algorithm: " << gnutls_strerror(ret); + gnutls_pubkey_deinit(pubkey); + gnutls_x509_crt_deinit(cert); + return false; + } + + pk_algorithm = static_cast(ret); + if (pk_algorithm == GNUTLS_PK_ECC) + { + gnutls_ecc_curve_t curve; + ret = gnutls_pubkey_export_ecc_raw(pubkey, &curve, nullptr, nullptr); + if (ret < 0) + { + LOG(WARNING) << "GnuTLS: Failed to get EC curve: " << gnutls_strerror(ret); + gnutls_pubkey_deinit(pubkey); + gnutls_x509_crt_deinit(cert); + return false; + } + + if (curve == GNUTLS_ECC_CURVE_SECP256R1) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (curve == GNUTLS_ECC_CURVE_SECP521R1) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + else + { + LOG(WARNING) << "GnuTLS: Trying to read unknown EC curve"; + gnutls_x509_crt_deinit(cert); + gnutls_pubkey_deinit(pubkey); + return false; + } + } + else + { + LOG(WARNING) << "GnuTLS: Trying to read unknown key type"; + gnutls_x509_crt_deinit(cert); + gnutls_pubkey_deinit(pubkey); + return false; + } + + pubkey_copy(pubkey, &d_PublicKey); + gnutls_x509_crt_deinit(cert); + gnutls_pubkey_deinit(pubkey); +#else // OpenSSL + // Read certificate +#if !(USE_OPENSSL_3 || USE_OPENSSL_111) + BIO* bio = BIO_new_mem_buf(const_cast(buffer.data()), buffer.size()); +#else + BIO* bio = BIO_new_mem_buf(buffer.data(), buffer.size()); +#endif + if (!bio) + { + LOG(WARNING) << "OpenSSL: Unable to create BIO for file: " << crtFilePath; + return false; + } + X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); + if (!cert) + { + LOG(WARNING) << "OpenSSL: Unable to read certificate from file: " << crtFilePath; + BIO_free(bio); + return false; + } + + // Read the public key from the certificate + EVP_PKEY* pubkey = X509_get_pubkey(cert); + if (!pubkey) + { + LOG(WARNING) << "OpenSSL: Failed to extract the public key"; + X509_free(cert); + BIO_free(bio); + return false; + } +#if USE_OPENSSL_3 + // store the key type - needed for the Kroot in case no DSM-PKR available + // Get the key type + int key_type = EVP_PKEY_base_id(pubkey); + if (key_type == EVP_PKEY_EC) + { + // It's an EC key, now we need to determine the curve + char curve_name[256]; + size_t curve_name_len = sizeof(curve_name); + + if (EVP_PKEY_get_utf8_string_param(pubkey, OSSL_PKEY_PARAM_GROUP_NAME, curve_name, curve_name_len, &curve_name_len) == 1) + { + if (strcmp(curve_name, "prime256v1") == 0 || strcmp(curve_name, "P-256") == 0) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (strcmp(curve_name, "secp521r1") == 0 || strcmp(curve_name, "P-521") == 0) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + else + { + LOG(WARNING) << "OpenSSL: Trying to read an unknown EC curve"; + X509_free(cert); + BIO_free(bio); + return false; + } + } + else + { + LOG(WARNING) << "OpenSSL: Trying to read an unknown EC curve"; + X509_free(cert); + BIO_free(bio); + return false; + } + } + else + { + LOG(WARNING) << "OpenSSL: Trying to read an unknown key type"; + X509_free(cert); + BIO_free(bio); + return false; + } + pubkey_copy(pubkey, &d_PublicKey); + EVP_PKEY_free(pubkey); +#else // OpenSSL 1.x +#if USE_OPENSSL_111 + // store the key type - needed for the Kroot in case no DSM-PKR available + const auto ec_key = EVP_PKEY_get0_EC_KEY(pubkey); + const EC_GROUP* group = EC_KEY_get0_group(ec_key); + if (!group) + { + X509_free(cert); + EC_KEY_free(ec_key); + BIO_free(bio); + return false; + } + const int nid = EC_GROUP_get_curve_name(group); + if (nid == NID_X9_62_prime256v1) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (nid == NID_secp521r1) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + EC_KEY_free(ec_key); +#else + EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pubkey); + if (!ec_key) + { + X509_free(cert); + BIO_free(bio); + return false; + } + + // Get the EC_GROUP from the EC_KEY + const EC_GROUP* group = EC_KEY_get0_group(ec_key); + if (!group) + { + X509_free(cert); + EC_KEY_free(ec_key); + BIO_free(bio); + return false; + } + const int nid = EC_GROUP_get_curve_name(group); + if (nid == 0) + { + BIGNUM* p = BN_new(); + if (EC_GROUP_get_curve_GFp(group, p, nullptr, nullptr, nullptr) == 1) + { + char* p_str = BN_bn2hex(p); + const std::string pcstr(p_str); + if (pcstr.size() == 64) + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (pcstr.size() == 132) + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + OPENSSL_free(p_str); + } + BN_free(p); + } + else + { + const char* curve_name = OBJ_nid2sn(nid); + const std::string curve_str(curve_name); + if (curve_str == "prime256v1") + { + d_PublicKeyType = std::string("ECDSA P-256"); + } + else if (curve_str == "secp521r1") + { + d_PublicKeyType = std::string("ECDSA P-521"); + } + } + EC_KEY_free(ec_key); +#endif + EC_KEY* ec_pubkey = EVP_PKEY_get1_EC_KEY(pubkey); + EVP_PKEY_free(pubkey); + if (!ec_pubkey) + { + LOG(WARNING) << "OpenSSL: Failed to extract the public key"; + X509_free(cert); + return false; + } + pubkey_copy(ec_pubkey, &d_PublicKey); + EC_KEY_free(ec_pubkey); +#endif + BIO_free(bio); + X509_free(cert); +#endif + std::cout << "OSNMA Public key successfully read from file " << crtFilePath << std::endl; + LOG(INFO) << "OSNMA Public key successfully read from file " << crtFilePath; + return true; +} + + +bool Gnss_Crypto::convert_raw_to_der_ecdsa(const std::vector& raw_signature, std::vector& der_signature) const +{ + if (raw_signature.size() % 2 != 0) + { + LOG(WARNING) << "Invalid raw ECDSA signature size"; + return false; + } + + size_t half_size = raw_signature.size() / 2; + std::vector raw_r(raw_signature.begin(), raw_signature.begin() + half_size); + std::vector raw_s(raw_signature.begin() + half_size, raw_signature.end()); + + auto encode_asn1_integer = [](const std::vector& value) -> std::vector { + std::vector result; + result.push_back(0x02); // INTEGER tag + + if (value[0] & 0x80) + { + result.push_back(value.size() + 1); // Length byte + result.push_back(0x00); // Add leading zero byte to ensure positive integer + } + else + { + result.push_back(value.size()); // Length byte + } + + result.insert(result.end(), value.begin(), value.end()); + return result; + }; + + std::vector der_r = encode_asn1_integer(raw_r); + std::vector der_s = encode_asn1_integer(raw_s); + + size_t total_length = der_r.size() + der_s.size(); + der_signature.push_back(0x30); // SEQUENCE tag + if (total_length > 127) + { + der_signature.push_back(0x81); // Long form length + } + der_signature.push_back(static_cast(total_length)); + + der_signature.insert(der_signature.end(), der_r.begin(), der_r.end()); + der_signature.insert(der_signature.end(), der_s.begin(), der_s.end()); + + return true; +} + + +std::vector Gnss_Crypto::convert_from_hex_str(const std::string& input) const +{ + std::vector result; + + // Iterate over the input string in pairs + for (size_t i = 0; i < input.length(); i += 2) + { + // Extract two hexadecimal characters from the input string + std::string hexByte = input.substr(i, 2); + + // Convert the hexadecimal string to an integer value + auto value = static_cast(std::stoul(hexByte, nullptr, 16)); + + // Append the value to the result vector + result.push_back(value); + } + + return result; +} + + +#if USE_GNUTLS_FALLBACK // GnuTLS-specific functions +bool Gnss_Crypto::pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest) +{ + gnutls_datum_t key_datum; + + // Export the public key from src to memory +#if HAVE_GNUTLS_PUBKEY_EXPORT2 + int ret = gnutls_pubkey_export2(src, GNUTLS_X509_FMT_PEM, &key_datum); +#else + size_t output_stata_size; + int ret = gnutls_pubkey_export(src, GNUTLS_X509_FMT_PEM, &key_datum, &output_stata_size); +#endif + if (ret < 0) + { + gnutls_free(key_datum.data); + return false; + } + + // Initialize dest + ret = gnutls_pubkey_init(dest); + if (ret < 0) + { + gnutls_free(key_datum.data); + return false; + } + + // Import the public key data from key_datum to dest + ret = gnutls_pubkey_import(*dest, &key_datum, GNUTLS_X509_FMT_PEM); + gnutls_free(key_datum.data); + + if (ret < 0) + { + gnutls_pubkey_deinit(*dest); + return false; + } + + return true; +} + + +bool tonelli_shanks(mpz_t& res, const mpz_t& n, const mpz_t& p) +{ + if (mpz_legendre(n, p) != 1) + { + return false; + } + mpz_t q; + mpz_t s; + mpz_t z; + mpz_t m; + mpz_t c; + mpz_t t; + mpz_t r; + mpz_t b; + mpz_t two; + mpz_t p_minus_one; + mpz_inits(q, s, z, m, c, t, r, b, two, p_minus_one, nullptr); + + mpz_set_ui(two, 2); + + mpz_sub_ui(q, p, 1); + mpz_set_ui(s, 0); + while (mpz_even_p(q)) + { + mpz_add_ui(s, s, 1); + mpz_divexact_ui(q, q, 2); + } + + mpz_set_ui(z, 2); + while (mpz_legendre(z, p) != -1) + { + mpz_add_ui(z, z, 1); + } + + mpz_powm(c, z, q, p); + + mpz_add_ui(p_minus_one, p, 1); + mpz_divexact_ui(p_minus_one, p_minus_one, 4); + mpz_powm(r, n, p_minus_one, p); + mpz_powm(t, n, q, p); + mpz_set(m, s); + + while (mpz_cmp_ui(t, 1) != 0) + { + mpz_set(b, t); + unsigned int i; + for (i = 0; mpz_cmp_ui(b, 1) != 0; i++) + { + mpz_powm_ui(b, b, 2, p); + } + if (i == mpz_get_ui(m)) + { + mpz_clears(q, s, z, m, c, t, r, b, two, p_minus_one, nullptr); + return false; + } + + mpz_powm_ui(b, two, mpz_get_ui(m) - i - 1, p); + mpz_powm(c, c, b, p); + mpz_mul(r, r, c); + mpz_mod(r, r, p); + mpz_powm_ui(c, c, 2, p); + mpz_mul(t, t, c); + mpz_mod(t, t, p); + mpz_set_ui(m, mpz_get_ui(m) - i - 1); + } + + mpz_set(res, r); + mpz_clears(q, s, z, m, c, t, r, b, two, p_minus_one, nullptr); + return true; +} + + +void Gnss_Crypto::decompress_public_key_secp256r1(const std::vector& compressed_key, std::vector& x, std::vector& y) const +{ + // Define curve parameters for secp256r1 + const char* p_str = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"; + const char* a_str = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"; + const char* b_str = "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"; + + mpz_t p; + mpz_t a; + mpz_t b; + mpz_t x_coord; + mpz_t y_coord; + mpz_t y_squared; + mpz_t tmp; + mpz_inits(p, a, b, x_coord, y_coord, y_squared, tmp, nullptr); + + // Initialize curve parameters + mpz_set_str(p, p_str, 16); + mpz_set_str(a, a_str, 16); + mpz_set_str(b, b_str, 16); + + // Set x coordinate + mpz_import(x_coord, 32, 1, 1, 1, 0, &compressed_key[1]); + + // Calculate y^2 = x^3 + ax + b (mod p) + mpz_powm_ui(y_squared, x_coord, 3, p); // y_squared = x^3 + mpz_mul(tmp, a, x_coord); // tmp = ax + mpz_add(y_squared, y_squared, tmp); // y_squared = x^3 + ax + mpz_add(y_squared, y_squared, b); // y_squared = x^3 + ax + b + mpz_mod(y_squared, y_squared, p); // y_squared = (x^3 + ax + b) % p + + // Calculate the square root of y_squared to get y + if (!tonelli_shanks(y_coord, y_squared, p)) + { + mpz_clears(p, a, b, x_coord, y_coord, y_squared, tmp, nullptr); + LOG(WARNING) << "GnuTLS: Failed to decompress public key: No valid y coordinate"; + return; + } + + // Select the correct y coordinate based on the parity bit + if ((compressed_key[0] & 1) != (mpz_tstbit(y_coord, 0) & 1)) + { + mpz_sub(y_coord, p, y_coord); // y = p - y + } + + // Export the x and y coordinates to vectors + x.resize(32); + y.resize(32); + mpz_export(x.data(), nullptr, 1, 1, 1, 0, x_coord); + mpz_export(y.data(), nullptr, 1, 1, 1, 0, y_coord); + + mpz_clears(p, a, b, x_coord, y_coord, y_squared, tmp, nullptr); +} + + +void Gnss_Crypto::decompress_public_key_secp521r1(const std::vector& compressed_key, std::vector& x, std::vector& y) const +{ + // Define curve parameters for secp521r1 + const char* p_str = "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; + const char* a_str = "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"; + const char* b_str = "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"; + + mpz_t p; + mpz_t a; + mpz_t b; + mpz_t x_coord; + mpz_t y_coord; + mpz_t y_squared; + mpz_t tmp; + mpz_inits(p, a, b, x_coord, y_coord, y_squared, tmp, nullptr); + + // Initialize curve parameters + mpz_set_str(p, p_str, 16); + mpz_set_str(a, a_str, 16); + mpz_set_str(b, b_str, 16); + + // Set x coordinate + mpz_import(x_coord, 66, 1, 1, 1, 0, &compressed_key[1]); + + // Calculate y^2 = x^3 + ax + b (mod p) + mpz_powm_ui(y_squared, x_coord, 3, p); // y_squared = x^3 + mpz_mul(tmp, a, x_coord); // tmp = ax + mpz_add(y_squared, y_squared, tmp); // y_squared = x^3 + ax + mpz_add(y_squared, y_squared, b); // y_squared = x^3 + ax + b + mpz_mod(y_squared, y_squared, p); // y_squared = (x^3 + ax + b) % p + + // Calculate the square root of y_squared to get y + if (!tonelli_shanks(y_coord, y_squared, p)) + { + mpz_clears(p, a, b, x_coord, y_coord, y_squared, tmp, nullptr); + LOG(WARNING) << "GnuTLS: Failed to decompress public key: No valid y coordinate"; + return; + } + + // Select the correct y coordinate based on the parity bit + if ((compressed_key[0] & 1) != (mpz_tstbit(y_coord, 0) & 1)) + { + mpz_sub(y_coord, p, y_coord); // y = p - y + } + + // Export the x and y coordinates to vectors + x.resize(66, 0); // Ensure 66 bytes with leading zeros if necessary + y.resize(66, 0); + mpz_export(x.data() + 1, nullptr, 1, 1, 1, 0, x_coord); + mpz_export(y.data(), nullptr, 1, 1, 1, 0, y_coord); + + mpz_clears(p, a, b, x_coord, y_coord, y_squared, tmp, nullptr); +} +#else // OpenSSL +#if USE_OPENSSL_3 +bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest) +{ + // Open a memory buffer + BIO* mem_bio = BIO_new(BIO_s_mem()); + if (mem_bio == nullptr) + { + return false; + } + + // Export the public key from src into the memory buffer in PEM format + if (!PEM_write_bio_PUBKEY(mem_bio, src)) + { + BIO_free(mem_bio); + return false; + } + + // Read the data from the memory buffer + char* bio_data; + int64_t data_len = BIO_get_mem_data(mem_bio, &bio_data); + + // Create a new memory buffer and load the data into it + BIO* mem_bio2 = BIO_new_mem_buf(bio_data, data_len); + if (mem_bio2 == nullptr) + { + BIO_free(mem_bio); + return false; + } + + // Read the public key from the new memory buffer + *dest = PEM_read_bio_PUBKEY(mem_bio2, nullptr, nullptr, nullptr); + if (*dest == nullptr) + { + BIO_free(mem_bio); + BIO_free(mem_bio2); + return false; + } + + // Clean up + BIO_free(mem_bio); + BIO_free(mem_bio2); + + return true; +} +#else // OpenSSL 1.x +bool Gnss_Crypto::pubkey_copy(EC_KEY* src, EC_KEY** dest) +{ + // Open a memory buffer + BIO* mem_bio = BIO_new(BIO_s_mem()); + if (mem_bio == nullptr) + { + return false; + } + + // Export the public key from src into the memory buffer in PEM format + if (!PEM_write_bio_EC_PUBKEY(mem_bio, src)) + { + BIO_free(mem_bio); + return false; + } + + // Read the data from the memory buffer + char* bio_data; + long data_len = BIO_get_mem_data(mem_bio, &bio_data); + + // Create a new memory buffer and load the data into it + BIO* mem_bio2 = BIO_new_mem_buf(bio_data, data_len); + if (mem_bio2 == nullptr) + { + BIO_free(mem_bio); + return false; + } + + // Read the public key from the new memory buffer + *dest = PEM_read_bio_EC_PUBKEY(mem_bio2, nullptr, nullptr, nullptr); + if (*dest == nullptr) + { + BIO_free(mem_bio); + BIO_free(mem_bio2); + return false; + } + + // Clean up + BIO_free(mem_bio); + BIO_free(mem_bio2); + + return true; +} +#endif // OpenSSL +#endif diff --git a/src/core/libs/gnss_crypto.h b/src/core/libs/gnss_crypto.h new file mode 100644 index 000000000..9fb16f96e --- /dev/null +++ b/src/core/libs/gnss_crypto.h @@ -0,0 +1,103 @@ +/*! + * \file gnss_crypto.h + * \brief Class for computing cryptographic functions + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GNSS_CRYPTO_H +#define GNSS_SDR_GNSS_CRYPTO_H + +#include +#include +#include +#if USE_GNUTLS_FALLBACK +#include +#include +#else // OpenSSL +#include +#endif + +/** \addtogroup Core + * \{ */ +/** \addtogroup Core_Receiver_Library + * \{ */ + +/*! + * \brief Class implementing cryptographic functions + * for Navigation Message Authentication + */ +class Gnss_Crypto +{ +public: + Gnss_Crypto(); //!< Default constructor + + /*! + * Constructor with a .crt or .pem file for the ECDSA Public Key + * and a XML file for the Merkle Tree root. + * Files can be downloaded by registering at https://www.gsc-europa.eu/ + */ + Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath); + ~Gnss_Crypto(); //!< Default destructor + + bool have_public_key() const; //!< Returns true if the ECDSA Public Key is already loaded + + /*! + * Stores the ECDSA Public Key in a .pem file, which is read in a following run if the .crt file is not found + */ + bool store_public_key(const std::string& pubKeyFilePath) const; + + bool verify_signature_ecdsa_p256(const std::vector& message, const std::vector& signature) const; //!< Verify ECDSA-P256 signature (message in plain hex, signature in raw format) + bool verify_signature_ecdsa_p521(const std::vector& message, const std::vector& signature) const; //!< Verify ECDSA-P521 signature (message in plain hex, signature in raw format) + + std::vector compute_SHA_256(const std::vector& input) const; //!< Computes SHA-256 hash + std::vector compute_SHA3_256(const std::vector& input) const; //!< Computes SHA3-256 hash + std::vector compute_HMAC_SHA_256(const std::vector& key, const std::vector& input) const; //!< Computes HMAC-SHA-256 message authentication code + std::vector compute_CMAC_AES(const std::vector& key, const std::vector& input) const; //!< Computes CMAC-AES message authentication code + + std::vector get_merkle_root() const; //!< Gets the Merkle Tree root node (\f$ x_{4,0} \f$) + std::string get_public_key_type() const; //!< Gets the ECDSA Public Key type (ECDSA P-256 / ECDSA P-521 / Unknown) + + void set_public_key(const std::vector& publickey); //!< Sets the ECDSA Public Key (publickey compressed format) + void set_public_key_type(const std::string& public_key_type); //!< Sets the ECDSA Public Key type (ECDSA P-256 / ECDSA P-521) + void set_merkle_root(const std::vector& v); //!< Sets the Merkle Tree root node x(\f$ x_{4,0} \f$) + void read_merkle_xml(const std::string& merkleFilePath); //!> Reads the XML file provided from the GSC OSNMA server + +private: + void readPublicKeyFromPEM(const std::string& pemFilePath); + bool readPublicKeyFromCRT(const std::string& crtFilePath); + bool convert_raw_to_der_ecdsa(const std::vector& raw_signature, std::vector& der_signature) const; + std::vector convert_from_hex_str(const std::string& input) const; // TODO - deprecate if OSNMA helper is to do this operation +#if USE_GNUTLS_FALLBACK + void decompress_public_key_secp256r1(const std::vector& compressed_key, std::vector& x, std::vector& y) const; + void decompress_public_key_secp521r1(const std::vector& compressed_key, std::vector& x, std::vector& y) const; + bool pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest); + gnutls_pubkey_t d_PublicKey{}; +#else // OpenSSL +#if USE_OPENSSL_3 + bool pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest); + EVP_PKEY* d_PublicKey{}; +#else // OpenSSL 1.x + bool pubkey_copy(EC_KEY* src, EC_KEY** dest); + EC_KEY* d_PublicKey = nullptr; +#endif +#endif + std::vector d_x_4_0; + std::string d_PublicKeyType; +}; + +/** \} */ +/** \} */ + +#endif // GNSS_SDR_GNSS_CRYPTO_H \ No newline at end of file diff --git a/src/core/libs/gnss_sdr_fpga_sample_counter.cc b/src/core/libs/gnss_sdr_fpga_sample_counter.cc index d67ea3b37..5ba9b0f0b 100644 --- a/src/core/libs/gnss_sdr_fpga_sample_counter.cc +++ b/src/core/libs/gnss_sdr_fpga_sample_counter.cc @@ -19,7 +19,6 @@ #include "gnss_sdr_fpga_sample_counter.h" #include "gnss_synchro.h" #include "uio_fpga.h" -#include #include #include // for from_double #include // for mp @@ -29,6 +28,11 @@ #include // libraries used by the GIPO #include // for write, close, read, ssize_t +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif #ifndef TEMP_FAILURE_RETRY #define TEMP_FAILURE_RETRY(exp) \ diff --git a/src/core/libs/gnss_sdr_supl_client.cc b/src/core/libs/gnss_sdr_supl_client.cc index 6e4ec6d1d..a1f779e72 100644 --- a/src/core/libs/gnss_sdr_supl_client.cc +++ b/src/core/libs/gnss_sdr_supl_client.cc @@ -23,7 +23,6 @@ #include #include #include -#include #include #include // for pow #include // for exception @@ -31,6 +30,12 @@ #include // for pair #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + Gnss_Sdr_Supl_Client::Gnss_Sdr_Supl_Client() : server_port(0), request(0), mcc(0), mns(0), lac(0), ci(0) { @@ -866,9 +871,9 @@ bool Gnss_Sdr_Supl_Client::read_gal_almanac_from_gsa(const std::string& file_nam return false; } for (pugi::xml_node almanac : doc.child("signalData") - .child("body") - .child("Almanacs") - .children("svAlmanac")) + .child("body") + .child("Almanacs") + .children("svAlmanac")) { Galileo_Almanac gal_alm; try diff --git a/src/core/libs/nav_message_monitor.cc b/src/core/libs/nav_message_monitor.cc index 105234b81..954f760fd 100644 --- a/src/core/libs/nav_message_monitor.cc +++ b/src/core/libs/nav_message_monitor.cc @@ -17,11 +17,16 @@ #include "nav_message_monitor.h" #include "gnss_sdr_make_unique.h" -#include #include #include // size_t #include // typeid +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include diff --git a/src/core/libs/nav_message_udp_sink.cc b/src/core/libs/nav_message_udp_sink.cc index 760b0520d..eaaca49bd 100644 --- a/src/core/libs/nav_message_udp_sink.cc +++ b/src/core/libs/nav_message_udp_sink.cc @@ -18,13 +18,23 @@ #include "nav_message_udp_sink.h" #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif -Nav_Message_Udp_Sink::Nav_Message_Udp_Sink(const std::vector& addresses, const uint16_t& port) : socket{io_context} +Nav_Message_Udp_Sink::Nav_Message_Udp_Sink(const std::vector& addresses, const uint16_t& port) + : socket{io_context} { for (const auto& address : addresses) { +#if BOOST_ASIO_USE_FROM_STRING boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port); +#else + boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::make_address(address, error), port); +#endif endpoints.push_back(endpoint); } serdes_nav = Serdes_Nav_Message(); @@ -35,22 +45,30 @@ bool Nav_Message_Udp_Sink::write_nav_message(const std::shared_ptr(endpoint.port()) << ": " << error.message(); + return false; + } + + if (socket.send(boost::asio::buffer(outbound_data)) == 0) // this can throw { return false; } } - catch (boost::system::system_error const& e) - { - return false; - } } + catch (const boost::system::system_error& e) + { + std::cerr << "Error sending navigation data: " << e.what() << '\n'; + return false; + } + return true; } diff --git a/src/core/libs/osnma_helper.cc b/src/core/libs/osnma_helper.cc new file mode 100644 index 000000000..23b67707a --- /dev/null +++ b/src/core/libs/osnma_helper.cc @@ -0,0 +1,175 @@ +/*! + * \file osnma_helper.h + * \brief Class for auxiliary osnma functions + * \author Carles Fernandez-Prades, 2024 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "osnma_helper.h" +#include +#include +#include +#include +#include + + +Osnma_Helper::Osnma_Helper() +{ + GST_START_EPOCH.tm_mday = 22; + GST_START_EPOCH.tm_mon = 7; // August (0-based) + GST_START_EPOCH.tm_year = 1999 - 1900; +} + + +uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const +{ + return (WN & 0x00000FFF) << 20 | (TOW & 0x000FFFFF); +} + + +uint32_t Osnma_Helper::compute_gst(tm& input) +{ + auto epoch_time_point = std::chrono::system_clock::from_time_t(mktime(&GST_START_EPOCH)); + auto input_time_point = std::chrono::system_clock::from_time_t(mktime(&input)); + + // Get the duration from epoch in seconds + auto duration_sec = std::chrono::duration_cast(input_time_point - epoch_time_point); + + // Calculate the week number (WN) and time of week (TOW) + const uint32_t sec_in_week = 604800; + const uint32_t week_number = duration_sec.count() / sec_in_week; + const uint32_t time_of_week = duration_sec.count() % sec_in_week; + return compute_gst(week_number, time_of_week); +} + + +uint32_t Osnma_Helper::compute_gst_now() +{ + time_t now = time(nullptr); + struct tm local_tm = *std::localtime(&now); + struct tm utc_tm = *std::gmtime(&now); + auto timezone_offset = std::mktime(&utc_tm) - std::mktime(&local_tm); + auto epoch_time_point = std::chrono::system_clock::from_time_t(std::mktime(&GST_START_EPOCH) - timezone_offset) + std::chrono::seconds(13); + auto duration_sec = std::chrono::duration_cast(std::chrono::system_clock::now() - epoch_time_point); + const uint32_t sec_in_week = 604800; + const uint32_t week_number = duration_sec.count() / sec_in_week; + const uint32_t time_of_week = duration_sec.count() % sec_in_week; + return compute_gst(week_number, time_of_week); +} + + +std::vector Osnma_Helper::gst_to_uint8(uint32_t GST) const +{ + std::vector res; + + res.push_back(static_cast((GST & 0xFF000000) >> 24)); + res.push_back(static_cast((GST & 0x00FF0000) >> 16)); + res.push_back(static_cast((GST & 0x0000FF00) >> 8)); + res.push_back(static_cast(GST & 0x000000FF)); + return res; +} + + +/** + * @brief Convert a binary string to a vector of bytes. + * + * This function takes a binary string and converts it into a vector of uint8_t bytes. + * The binary string is padded with zeros if necessary to ensure that the total number + * of bits is a multiple of a byte. + * + * @param binaryString The binary string to be converted. + * @return The vector of bytes converted from the binary string. + */ +std::vector Osnma_Helper::bytes(const std::string& binaryString) const +{ + std::vector bytes; + + // Determine the size of the padding needed. + size_t padding_size = binaryString.size() % 8; + + std::string padded_binary = binaryString; + + if (padding_size != 0) + { + padding_size = 8 - padding_size; // Compute padding size + padded_binary.append(padding_size, '0'); // Append zeros to the binary string + } + + for (size_t i = 0; i < padded_binary.size(); i += 8) + { + uint8_t byte = std::bitset<8>(padded_binary.substr(i, 8)).to_ulong(); + bytes.push_back(byte); + } + + return bytes; +} + + +std::string Osnma_Helper::verification_status_str(int status) const +{ + switch (status) + { + case 0: + return "SUCCESS"; + case 1: + return "FAIL"; + case 2: + return "UNVERIFIED"; + default: + return "UNKNOWN"; + } +} + + +std::string Osnma_Helper::convert_to_hex_string(const std::vector& vector) const +{ + std::stringstream ss; + ss << std::hex << std::setfill('0'); + for (auto byte : vector) + { + ss << std::setw(2) << static_cast(byte); + } + return ss.str(); +} + + +std::vector Osnma_Helper::convert_from_hex_string(const std::string& hex_string) const +{ + std::vector result; + + std::string adjusted_hex_string = hex_string; + if (hex_string.length() % 2 != 0) + { + adjusted_hex_string = "0" + hex_string; + } + + for (std::size_t i = 0; i < adjusted_hex_string.length(); i += 2) + { + std::string byte_string = adjusted_hex_string.substr(i, 2); + auto byte = static_cast(std::stoul(byte_string, nullptr, 16)); + result.push_back(byte); + } + + return result; +} + + +uint32_t Osnma_Helper::get_WN(uint32_t GST) const +{ + return (GST & 0xFFF00000) >> 20; +} + + +uint32_t Osnma_Helper::get_TOW(uint32_t GST) const +{ + return GST & 0x000FFFFF; +} diff --git a/src/core/libs/osnma_helper.h b/src/core/libs/osnma_helper.h new file mode 100644 index 000000000..a7b2cc332 --- /dev/null +++ b/src/core/libs/osnma_helper.h @@ -0,0 +1,51 @@ +/*! + * \file osnma_helper.h + * \brief Class for auxiliary osnma functions + * \author Carles Fernandez-Prades, 2024 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_OSNMA_HELPER_H +#define GNSS_SDR_OSNMA_HELPER_H + + +#include +#include +#include +#include + +/** \addtogroup Core + * \{ */ +/** \addtogroup Core_Receiver_Library + * \{ */ + +class Osnma_Helper +{ +public: + Osnma_Helper(); + ~Osnma_Helper() = default; + uint32_t compute_gst(uint32_t WN, uint32_t TOW) const; + uint32_t compute_gst(std::tm& input); + uint32_t compute_gst_now(); + uint32_t get_WN(uint32_t GST) const; + uint32_t get_TOW(uint32_t GST) const; + std::vector gst_to_uint8(uint32_t GST) const; + std::vector bytes(const std::string& binaryString) const; + std::string verification_status_str(int status) const; + std::string convert_to_hex_string(const std::vector& vector) const; + std::vector convert_from_hex_string(const std::string& hex_string) const; // TODO remove similar function in gnss_crypto + std::tm GST_START_EPOCH{}; +}; + +/** \} */ +/** \} */ +#endif // GNSS_SDR_OSNMA_HELPER_H diff --git a/src/core/libs/osnma_msg_receiver.cc b/src/core/libs/osnma_msg_receiver.cc new file mode 100644 index 000000000..3f4338bc4 --- /dev/null +++ b/src/core/libs/osnma_msg_receiver.cc @@ -0,0 +1,2080 @@ +/*! + * \file osnma_msg_receiver.cc + * \brief GNU Radio block that processes Galileo OSNMA data received from + * Galileo E1B telemetry blocks. After successful decoding, sends the content to + * the PVT block. + * \author Carles Fernandez-Prades, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#include "osnma_msg_receiver.h" +#include "Galileo_OSNMA.h" +#include "gnss_crypto.h" +#include "gnss_satellite.h" +#include "gnss_sdr_make_unique.h" // for std::make_unique in C++11 +#include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader +#include "osnma_helper.h" // for Osnma_Helper +#include // for gr::io_signature::make +#include +#include +#include +#include // for std::ifstream and std::ofstream +#include // for std::setfill +#include // for std::hex, std::uppercase +#include +#include // for std::accumulate +#include // std::stringstream +#include +#include // for typeid +#include + + +#if USE_GLOG_AND_GFLAGS +#include // for DLOG +#else +#include +#endif + +#if HAS_GENERIC_LAMBDA +#else +#include +#endif + +#if PMT_USES_BOOST_ANY +#include +#include +namespace wht = boost; +#else +#include +namespace wht = std; +#endif + + +osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode) +{ + return osnma_msg_receiver_sptr(new osnma_msg_receiver(pemFilePath, merkleFilePath, strict_mode)); +} + + +osnma_msg_receiver::osnma_msg_receiver(const std::string& crtFilePath, + const std::string& merkleFilePath, + bool strict_mode) : gr::block("osnma_msg_receiver", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(0, 0, 0)), + d_strict_mode(strict_mode) +{ + d_dsm_reader = std::make_unique(); + d_crypto = std::make_unique(crtFilePath, merkleFilePath); + d_helper = std::make_unique(); + d_nav_data_manager = std::make_unique(); + + if (d_crypto->have_public_key()) + { // Hot start is enabled + LOG(WARNING) << "OSNMA Public Key available, trying to find DSM-KROOT saved"; + std::cout << "OSNMA Public Key available, trying to find DSM-KROOT saved" << std::endl; + d_public_key_verified = true; + + auto dsm_nmah = parse_dsm_kroot(); + if (!dsm_nmah.first.empty()) + { + LOG(WARNING) << "OSNMA DSM-KROOT and NMA Header successfully read from file " << KROOTFILE_DEFAULT; + std::cout << "OSNMA DSM-KROOT and NMA Header successfully read from file " << KROOTFILE_DEFAULT << std::endl; + d_flag_hot_start = true; + process_dsm_message(dsm_nmah.first, dsm_nmah.second); + LOG(WARNING) << "OSNMA DSM-KROOT available :: HOT START"; + std::cout << "OSNMA DSM-KROOT available :: HOT START" << std::endl; + } + else + { + LOG(WARNING) << "OSNMA DSM-KROOT not available :: WARM START"; + std::cout << "OSNMA DSM-KROOT not available :: WARM START" << std::endl; + } + } + + // register OSNMA input message port from telemetry blocks + this->message_port_register_in(pmt::mp("OSNMA_from_TLM")); + // register OSNMA output message port to PVT block + this->message_port_register_out(pmt::mp("OSNMA_to_PVT")); + + this->set_msg_handler(pmt::mp("OSNMA_from_TLM"), +#if HAS_GENERIC_LAMBDA + [this](auto&& PH1) { msg_handler_osnma(PH1); }); +#else +#if USE_BOOST_BIND_PLACEHOLDERS + boost::bind(&osnma_msg_receiver::msg_handler_osnma, this, boost::placeholders::_1)); +#else + boost::bind(&osnma_msg_receiver::msg_handler_osnma, this, _1)); +#endif +#endif + + if (d_strict_mode) + { + d_GST_Rx = d_helper->compute_gst_now(); + const auto WN = d_helper->get_WN(d_GST_Rx); + const auto TOW = d_helper->get_TOW(d_GST_Rx); + LOG(INFO) << "Galileo OSNMA: initial receiver time GST=[" << WN << " " << TOW << "]"; + std::cout << "Galileo OSNMA: initial receiver time GST=[" << WN << " " << TOW << "]" << std::endl; + } + else + { + LOG(WARNING) << "Galileo OSNMA: in non-strict mode, local system time is not checked."; + std::cout << "Galileo OSNMA: in non-strict mode, local system time is not checked." << std::endl; + } +} + + +void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg) +{ + // requires mutex with msg_handler_osnma function called by the scheduler + gr::thread::scoped_lock lock(d_setlock); + try + { + const size_t msg_type_hash_code = pmt::any_ref(msg).type().hash_code(); + if (msg_type_hash_code == typeid(std::shared_ptr).hash_code()) + { + const auto nma_msg = wht::any_cast>(pmt::any_ref(msg)); + const auto sat = Gnss_Satellite(std::string("Galileo"), nma_msg->PRN); // TODO remove if unneeded + + std::ostringstream output_message; + output_message << "Galileo OSNMA: data received starting at " + << "WN=" + << nma_msg->WN_sf0 + << ", TOW=" + << nma_msg->TOW_sf0 + << ", from satellite " + << sat; + LOG(INFO) << output_message.str(); + std::cout << output_message.str() << std::endl; + + // Receiver time update + d_GST_SIS = d_helper->compute_gst(nma_msg->WN_sf0, nma_msg->TOW_sf0); + if (d_last_verified_key_GST == 0) + { + d_last_received_GST = d_GST_SIS; + } + else if (d_GST_SIS > d_last_received_GST) + { + d_last_received_GST = d_GST_SIS; + } + if (d_strict_mode) + { + d_GST_Rx = d_helper->compute_gst_now(); + } + else + { + d_GST_Rx = d_last_received_GST; + } + LOG(INFO) << "Galileo OSNMA: Receiver Time GST=[" << d_helper->get_WN(d_GST_Rx) << " " << d_helper->get_TOW(d_GST_Rx) << "]"; + std::cout << "Galileo OSNMA: Receiver Time GST=[" << d_helper->get_WN(d_GST_Rx) << " " << d_helper->get_TOW(d_GST_Rx) << "]" << std::endl; + + // time constraint verification + std::time_t delta_T = std::abs(static_cast(d_GST_Rx - d_GST_SIS)); + if (delta_T <= d_T_L) + { + d_tags_to_verify = {0, 4, 12}; + LOG(INFO) << "Galileo OSNMA: time constraint OK (delta_T=" << delta_T << " s)"; + std::cout << "Galileo OSNMA: time constraint OK (delta_T=" << delta_T << " s)" << std::endl; + } + else if (delta_T > d_T_L && delta_T <= 10 * d_T_L) + { + d_tags_to_verify = {12}; + LOG(WARNING) << "Galileo OSNMA: time constraint allows only slow MACs to be verified"; + std::cout << "Galileo OSNMA: |local_t - GST_SIS| < T_L [ |" << static_cast(d_GST_Rx - d_GST_SIS) << " | < " << static_cast(d_T_L) << " ]" << std::endl; + LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_GST_Rx << " d_GST_SIS: " << d_GST_SIS; + LOG(WARNING) << "Galileo OSNMA: |local_t - GST_SIS| < T_L [ |" << static_cast(d_GST_Rx - d_GST_SIS) << " | < " << static_cast(d_T_L) << " ]"; + } + else + { + d_tags_to_verify = {}; + LOG(WARNING) << "Galileo OSNMA: time constraint violation"; + std::cerr << "Galileo OSNMA: time constraint violation" << std::endl; + std::cerr << "Galileo OSNMA: | local_t - GST_SIS | < T_L [ | " << static_cast(d_GST_Rx - d_GST_SIS) << " | < " << static_cast(d_T_L) << " ]" << std::endl; + LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_GST_Rx << " d_GST_SIS: " << d_GST_SIS; + LOG(WARNING) << "Galileo OSNMA: | local_t - GST_SIS | < T_L [ | " << static_cast(d_GST_Rx - d_GST_SIS) << " | < " << static_cast(d_T_L) << " ]"; + return; + } + + process_osnma_message(nma_msg); + } // OSNMA frame received + else if (msg_type_hash_code == typeid(std::shared_ptr>).hash_code()) // Navigation data bits for OSNMA received + { + const auto inav_data = wht::any_cast>>(pmt::any_ref(msg)); + uint32_t PRNd = std::get<0>(*inav_data); + std::string nav_data = std::get<1>(*inav_data); + uint32_t TOW = std::get<2>(*inav_data); + d_nav_data_manager->add_navigation_data(nav_data, PRNd, TOW); + } + else + { + LOG(WARNING) << "Galileo OSNMA: osnma_msg_receiver received an unknown object type!"; + } + } + catch (const wht::bad_any_cast& e) + { + LOG(WARNING) << "Galileo OSNMA: osnma_msg_receiver Bad any_cast: " << e.what(); + } + + // Send the resulting decoded NMA data (if available) to PVT + if (d_new_data) + { + auto osnma_data_ptr = std::make_shared(d_osnma_data); + this->message_port_pub(pmt::mp("OSNMA_to_PVT"), pmt::make_any(osnma_data_ptr)); + d_new_data = false; + // d_osnma_data = OSNMA_data(); + DLOG(INFO) << "Galileo OSNMA: NMA info sent to the PVT block through the OSNMA_to_PVT async message port"; + } +} + + +void osnma_msg_receiver::read_merkle_xml(const std::string& merklepath) +{ + d_crypto->read_merkle_xml(merklepath); +} + + +void osnma_msg_receiver::process_osnma_message(const std::shared_ptr& osnma_msg) +{ + if (d_flag_alert_message && (d_public_key_verified || d_kroot_verified)) + { + return; + } + read_nma_header(osnma_msg->hkroot[0]); + + // Check for corner cases: renewal, revocation, alert message + if (d_osnma_data.d_nma_header.nmas == 0 /* RES */) + { + LOG(WARNING) << "Galileo OSNMA: NMAS invalid (RES), skipping osnma message"; + return; + } + // TODO - trusting the NMAS and CPKS shall be done upon PKR verification or Tag verification. + // It's ok to activate the flags, but the final decision should happen after verifying it. + // For OAM is solved, but NPK and PKREV I think not yet + if (d_osnma_data.d_nma_header.nmas == 2 /* OP */ && d_osnma_data.d_nma_header.cpks == 4 /* NPK */ && d_GST_PKR_PKREV_start == 0) + { + d_flag_PK_renewal = true; + d_GST_PKR_PKREV_start = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + LOG(INFO) << "Galileo OSNMA: Public Key Renewal :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]"; + std::cout << "Galileo OSNMA: Public Key Renewal :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" << std::endl; + } + if (d_flag_PK_renewal && d_osnma_data.d_nma_header.nmas == 2 /* OP */ && d_osnma_data.d_nma_header.cpks == 1 /* Nominal */) + { + d_flag_PK_renewal = false; + uint32_t final_GST = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + double duration_hours = (final_GST - d_GST_PKR_PKREV_start) / 3600.0; + LOG(INFO) << "Galileo OSNMA: Public Key Renewal :: Finished at GST=" << duration_hours << ", Duration=" << duration_hours << " h"; + std::cout << "Galileo OSNMA: Public Key Renewal :: Finished at GST=" << duration_hours << ", Duration=" << duration_hours << " h" << std::endl; + } + + if (d_osnma_data.d_nma_header.nmas == 3 /* DU */ && d_osnma_data.d_nma_header.cpks == 5 /* PKREV */ && d_GST_PKR_PKREV_start == 0) + { + d_flag_PK_revocation = true; + d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] = 0; + d_public_key_verified = false; + d_kroot_verified = false; + d_tesla_key_verified = false; + d_GST_PKR_PKREV_start = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + LOG(INFO) << "Galileo OSNMA: Public Key Revocation :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]"; + std::cout << "Galileo OSNMA: Public Key Revocation :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" << std::endl; + } + if (d_flag_PK_revocation && d_osnma_data.d_nma_header.nmas == 2 /* OP */ && d_osnma_data.d_nma_header.cpks == 1 /* Nominal */) + { + // step 2 , start using new chain + d_flag_PK_revocation = false; + uint32_t final_GST = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + double duration_hours = (final_GST - d_GST_PKR_PKREV_start) / 3600.0; + LOG(INFO) << "Galileo OSNMA: Public Key Revocation :: Finished at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" + << ", Duration=" << duration_hours << "h"; + std::cout << "Galileo OSNMA: Public Key Revocation :: Finished at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" + << ", Duration=" << duration_hours << "h" << std::endl; + } + + if (d_osnma_data.d_nma_header.nmas == 3 /* DU */ && d_osnma_data.d_nma_header.cpks == 7 /* AM */ && d_GST_PKR_AM_start == 0) + { + d_flag_alert_message = true; + d_GST_PKR_AM_start = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + d_public_key_verified = false; + d_kroot_verified = false; + LOG(INFO) << "Galileo OSNMA: Alert message :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]"; + std::cout << "Galileo OSNMA: Alert message :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" << std::endl; + } + + if (d_osnma_data.d_nma_header.nmas == 2 /* OP */ && d_osnma_data.d_nma_header.cpks == 2 /* EOC */ && d_GST_chain_renewal_start == 0) + { + d_flag_chain_renewal = true; + d_GST_chain_renewal_start = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + LOG(INFO) << "Galileo OSNMA: Chain renewal :: Start at at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]"; + std::cout << "Galileo OSNMA: Chain renewal :: Start at at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" << std::endl; + } + if (d_flag_chain_renewal && d_osnma_data.d_nma_header.nmas == 2 /* OP */ && d_osnma_data.d_nma_header.cpks == 1 /* Nominal */) + { + // Step 2, start using the new kroot + d_flag_chain_renewal = false; + uint32_t final_GST = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + double duration_hours = (final_GST - d_GST_chain_renewal_start) / 3600.0; + LOG(INFO) << "Galileo OSNMA: Chain renewal :: Finished at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" + << ", Duration=" << duration_hours << "h"; + std::cout << "Galileo OSNMA: Chain renewal :: Finished at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" + << ", Duration=" << duration_hours << "h" << std::endl; + d_osnma_data.d_dsm_kroot_message = d_osnma_data.d_dsm_kroot_new_message; // set new kroot as the one to use from now on + d_tesla_key_verified = false; // force the verification up to the Kroot due to chain change + } + + if (d_osnma_data.d_nma_header.nmas == 3 /* DU */ && d_osnma_data.d_nma_header.cpks == 3 /* CREV */ && d_GST_chain_revocation_start == 0) + { + d_flag_chain_revocation = true; + d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] = 0; // delete blocks received up to now, new chain must be received. + // d_public_key_verified = false; + d_kroot_verified = false; + d_tesla_key_verified = false; + d_GST_chain_revocation_start = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + LOG(INFO) << "Galileo OSNMA: Chain revocation :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]"; + std::cout << "Galileo OSNMA: Chain revocation :: Start at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" << std::endl; + } + if (d_flag_chain_revocation && d_osnma_data.d_nma_header.nmas == 2 /* OP */ && d_osnma_data.d_nma_header.cpks == 1 /* Nominal */) + { + d_flag_chain_revocation = false; + uint32_t final_GST = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0); + double duration_hours = (final_GST - d_GST_chain_revocation_start) / 3600.0; + LOG(INFO) << "Galileo OSNMA: Chain revocation :: Finished at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" + << ", Duration=" << duration_hours << "h"; + std::cout << "Galileo OSNMA: Chain revocation :: Finished at GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]" + << ", Duration=" << duration_hours << "h" << std::endl; + } + + read_dsm_header(osnma_msg->hkroot[1]); + read_dsm_block(osnma_msg); + process_dsm_block(osnma_msg); // will process dsm block if received a complete one, then will call mack processing upon re-setting the dsm block to 0 + if (d_osnma_data.d_dsm_kroot_message.towh_k != 0) + { + d_GST_0 = d_helper->compute_gst(d_osnma_data.d_dsm_kroot_message.wn_k, d_osnma_data.d_dsm_kroot_message.towh_k * 3600); + d_GST_Sf = d_GST_0 + 30 * std::floor((d_GST_SIS - d_GST_0) / 30); // Eq. 3 R.G. + } + read_and_process_mack_block(osnma_msg); // only process them if at least 3 available. +} + + +/** + * @brief Reads the NMA header from the given input and stores the values in the d_osnma_data structure. + * + * The NMA header consists of several fields: d_nma_header.nmas, d_nma_header.cid, d_nma_header.cpks, and d_nma_header.reserved. + * Each field is retrieved using the corresponding getter functions from the d_dsm_reader auxiliary object. + * + * @param nma_header The input containing the NMA header. + */ +void osnma_msg_receiver::read_nma_header(uint8_t nma_header) +{ + d_osnma_data.d_nma_header.nmas = d_dsm_reader->get_nmas(nma_header); + d_osnma_data.d_nma_header.cid = d_dsm_reader->get_cid(nma_header); + d_osnma_data.d_nma_header.cpks = d_dsm_reader->get_cpks(nma_header); + d_osnma_data.d_nma_header.reserved = d_dsm_reader->get_nma_header_reserved(nma_header); +} + + +/** + * @brief Read the DSM header from the given dsm_header and populate the d_osnma_data structure. + * + * @param dsm_header The DSM header. + */ +void osnma_msg_receiver::read_dsm_header(uint8_t dsm_header) +{ + d_osnma_data.d_dsm_header.dsm_id = d_dsm_reader->get_dsm_id(dsm_header); + d_osnma_data.d_dsm_header.dsm_block_id = d_dsm_reader->get_dsm_block_id(dsm_header); // BID + LOG(INFO) << "Galileo OSNMA: Received block DSM_BID=" << static_cast(d_osnma_data.d_dsm_header.dsm_block_id) + << " with DSM_ID " << static_cast(d_osnma_data.d_dsm_header.dsm_id); +} + +/* + * accumulates dsm messages + * */ +void osnma_msg_receiver::read_dsm_block(const std::shared_ptr& osnma_msg) +{ + // Fill d_dsm_message. dsm_block_id provides the offset within the dsm message. + size_t index = 0; + for (const auto* it = osnma_msg->hkroot.cbegin() + 2; it != osnma_msg->hkroot.cend(); ++it) + { + d_dsm_message[d_osnma_data.d_dsm_header.dsm_id][SIZE_DSM_BLOCKS_BYTES * d_osnma_data.d_dsm_header.dsm_block_id + index] = *it; + index++; + } + // First block indicates number of blocks in DSM message + if (d_osnma_data.d_dsm_header.dsm_block_id == 0) + { + uint8_t nb = d_dsm_reader->get_number_blocks_index(d_dsm_message[d_osnma_data.d_dsm_header.dsm_id][0]); + uint16_t number_of_blocks = 0; + if (d_osnma_data.d_dsm_header.dsm_id < 12) + { + // DSM-KROOT Table 7 + const auto it = OSNMA_TABLE_7.find(nb); + if (it != OSNMA_TABLE_7.cend()) + { + number_of_blocks = it->second.first; + } + } + else if (d_osnma_data.d_dsm_header.dsm_id >= 12 && d_osnma_data.d_dsm_header.dsm_id < 16) + { + // DSM-PKR Table 3 + const auto it = OSNMA_TABLE_3.find(nb); + if (it != OSNMA_TABLE_3.cend()) + { + number_of_blocks = it->second.first; + } + } + + d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] = number_of_blocks; + LOG(INFO) << "Galileo OSNMA: number of blocks in this message: " << static_cast(number_of_blocks); + if (number_of_blocks == 0) + { + // Something is wrong, start over + LOG(WARNING) << "OSNMA: Wrong number of blocks, start over"; + d_dsm_message[d_osnma_data.d_dsm_header.dsm_id] = std::array{}; + d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id] = std::array{}; + } + } + // Annotate bid + d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id][d_osnma_data.d_dsm_header.dsm_block_id] = 1; + std::stringstream available_blocks; + available_blocks << "Galileo OSNMA: Available blocks for DSM_ID " << static_cast(d_osnma_data.d_dsm_header.dsm_id) << ": [ "; + if (d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] == 0) // block 0 not received yet + { + for (auto id_received : d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id]) + { + if (id_received == 0) + { + available_blocks << "- "; + } + else + { + available_blocks << "X "; + } + } + } + else + { + for (uint16_t k = 0; k < d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id]; k++) + { + if (d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id][k] == 0) + { + available_blocks << "- "; + } + else + { + available_blocks << "X "; + } + } + } + available_blocks << "]"; + LOG(INFO) << available_blocks.str(); + std::cout << available_blocks.str() << std::endl; +} + +/** + * @brief Process DSM block of an OSNMA message. + * + * \details This function checks if all inner blocks of the DSM message are available and if so, calls process_dsm_message(). + * \post It creates a vector to hold the DSM message data, copies the data from the inner blocks into the vector, + * resets the inner block arrays to empty + * + * @param osnma_msg The OSNMA message. + */ +void osnma_msg_receiver::process_dsm_block(const std::shared_ptr& osnma_msg) +{ + // if all inner blocks available -> Process DSM message + if ((d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] != 0) && + (d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] == std::accumulate(d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id].cbegin(), d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id].cend(), 0))) + { + size_t len = std::size_t(d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id]) * SIZE_DSM_BLOCKS_BYTES; + std::vector dsm_msg(len, 0); + for (uint32_t i = 0; i < d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id]; i++) + { + for (size_t j = 0; j < SIZE_DSM_BLOCKS_BYTES; j++) + { + dsm_msg[i * SIZE_DSM_BLOCKS_BYTES + j] = d_dsm_message[d_osnma_data.d_dsm_header.dsm_id][i * SIZE_DSM_BLOCKS_BYTES + j]; + } + } + d_dsm_message[d_osnma_data.d_dsm_header.dsm_id] = std::array{}; + d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id] = std::array{}; + LOG(INFO) << "Galileo OSNMA: DSM message completed :: start processing, GST=[" << osnma_msg->WN_sf0 << " " << osnma_msg->TOW_sf0 << "]"; + process_dsm_message(dsm_msg, osnma_msg->hkroot[0]); + } +} + + +/* + * case DSM-Kroot: + * - computes the padding and compares with received message + * - if successful, tries to verify the digital signature + * case DSM-PKR: + * - calls verify_dsm_pkr to verify the public key + * */ +void osnma_msg_receiver::process_dsm_message(const std::vector& dsm_msg, const uint8_t& nma_header) +{ + // DSM-KROOT message + if ((d_osnma_data.d_dsm_header.dsm_id < 12 || d_flag_hot_start) && d_public_key_verified) + { + bool new_chain = (d_dsm_reader->get_cidkr(dsm_msg) != d_osnma_data.d_nma_header.cid) && d_flag_chain_renewal; + DSM_KROOT_message& applicable_kroot_msg = new_chain ? d_osnma_data.d_dsm_kroot_new_message : d_osnma_data.d_dsm_kroot_message; + + // Parse Kroot message + LOG(INFO) << "Galileo OSNMA: DSM-KROOT message received."; + applicable_kroot_msg.nb_dk = d_dsm_reader->get_number_blocks_index(dsm_msg[0]); + applicable_kroot_msg.pkid = d_dsm_reader->get_pkid(dsm_msg); + applicable_kroot_msg.cidkr = d_dsm_reader->get_cidkr(dsm_msg); + applicable_kroot_msg.reserved1 = d_dsm_reader->get_dsm_reserved1(dsm_msg); + applicable_kroot_msg.hf = d_dsm_reader->get_hf(dsm_msg); + applicable_kroot_msg.mf = d_dsm_reader->get_mf(dsm_msg); + applicable_kroot_msg.ks = d_dsm_reader->get_ks(dsm_msg); + applicable_kroot_msg.ts = d_dsm_reader->get_ts(dsm_msg); + applicable_kroot_msg.maclt = d_dsm_reader->get_maclt(dsm_msg); + applicable_kroot_msg.reserved = d_dsm_reader->get_dsm_reserved(dsm_msg); + applicable_kroot_msg.wn_k = d_dsm_reader->get_wn_k(dsm_msg); + applicable_kroot_msg.towh_k = d_dsm_reader->get_towh_k(dsm_msg); + applicable_kroot_msg.alpha = d_dsm_reader->get_alpha(dsm_msg); + // Kroot field + const uint16_t l_lk_bytes = d_dsm_reader->get_lk_bits(applicable_kroot_msg.ks) / 8; + applicable_kroot_msg.kroot = d_dsm_reader->get_kroot(dsm_msg, l_lk_bytes); + // DS field + uint16_t l_ds_bits = 0; + const auto it = OSNMA_TABLE_15.find(d_crypto->get_public_key_type()); + if (it != OSNMA_TABLE_15.cend()) + { + l_ds_bits = it->second; + } + const uint16_t l_ds_bytes = l_ds_bits / 8; + applicable_kroot_msg.ds = std::vector(l_ds_bytes, 0); // C: this accounts for padding in case needed. + for (uint16_t k = 0; k < l_ds_bytes; k++) + { + applicable_kroot_msg.ds[k] = dsm_msg[13 + l_lk_bytes + k]; + } + // Padding + const uint16_t l_dk_bits = d_dsm_reader->get_l_dk_bits(applicable_kroot_msg.nb_dk); + const uint16_t l_dk_bytes = l_dk_bits / 8; + const uint16_t l_pdk_bytes = (l_dk_bytes - 13 - l_lk_bytes - l_ds_bytes); + applicable_kroot_msg.p_dk = std::vector(l_pdk_bytes, 0); + for (uint16_t k = 0; k < l_pdk_bytes; k++) + { + applicable_kroot_msg.p_dk[k] = dsm_msg[13 + l_lk_bytes + l_ds_bytes + k]; + } + + const uint16_t check_l_dk = 104 * std::ceil(1.0 + static_cast((l_lk_bytes * 8.0) + l_ds_bits) / 104.0); + if (l_dk_bits != check_l_dk) + { + LOG(WARNING) << "Galileo OSNMA: Failed length reading of DSM-KROOT message"; + d_count_failed_Kroot++; + } + else + { + // validation of padding + const uint16_t size_m = 13 + l_lk_bytes; + std::vector MSG; + MSG.reserve(size_m + l_ds_bytes + 1); + MSG.push_back(nma_header); // NMA header + for (uint16_t i = 1; i < size_m; i++) + { + MSG.push_back(dsm_msg[i]); + } + std::vector message = MSG; // MSG = (M | DS) from ICD. Eq. 7 + for (uint16_t k = 0; k < l_ds_bytes; k++) + { + MSG.push_back(applicable_kroot_msg.ds[k]); + } + + std::vector hash; + if (applicable_kroot_msg.hf == 0) // Table 8. + { + hash = d_crypto->compute_SHA_256(MSG); + } + else if (applicable_kroot_msg.hf == 2) + { + hash = d_crypto->compute_SHA3_256(MSG); + } + else + { + hash = std::vector(32); + } + // truncate hash + std::vector p_dk_truncated; + p_dk_truncated.reserve(l_pdk_bytes); + for (uint16_t i = 0; i < l_pdk_bytes; i++) + { + p_dk_truncated.push_back(hash[i]); + } + // Check that the padding bits received match the computed values + if (applicable_kroot_msg.p_dk == p_dk_truncated) + { + LOG(INFO) << "Galileo OSNMA: DSM-KROOT message received ok."; + LOG(INFO) << "Galileo OSNMA: DSM-KROOT with CID=" << static_cast(d_osnma_data.d_nma_header.cid) + << ", PKID=" << static_cast(applicable_kroot_msg.pkid) + << ", WN=" << static_cast(applicable_kroot_msg.wn_k) + << ", TOW=" << static_cast(applicable_kroot_msg.towh_k) * 3600; + + // If new PK verified and the new KROOT arrived, set the new PK before attempting verification + if (d_flag_PK_renewal && applicable_kroot_msg.pkid == d_new_public_key_id && d_flag_NPK_set == false) + { + d_crypto->set_public_key(d_new_public_key); + d_crypto->store_public_key(PEMFILE_DEFAULT); + d_flag_NPK_set = true; + } + if (l_ds_bits == 512) + { + d_kroot_verified = d_crypto->verify_signature_ecdsa_p256(message, applicable_kroot_msg.ds); + } + else if (l_ds_bits == 1056) + { + d_kroot_verified = d_crypto->verify_signature_ecdsa_p521(message, applicable_kroot_msg.ds); + } + if (d_kroot_verified) + { + applicable_kroot_msg.verified = true; + std::cout << "Galileo OSNMA: DSM-KROOT authentication successful!" << std::endl; + LOG(INFO) << "Galileo OSNMA: DSM-KROOT authentication successful!"; + if (d_flag_alert_message) + { + LOG(WARNING) << "Galileo OSNMA: DSM-KROOT :: Alert message verification :: SUCCESS. "; + } + else + { + LOG(INFO) << "Galileo OSNMA: NMA Status is " << d_dsm_reader->get_nmas_status(d_osnma_data.d_nma_header.nmas) << ", " + << "Chain in force is " << static_cast(d_osnma_data.d_nma_header.cid) << ", " + << "Chain and Public Key Status is " << d_dsm_reader->get_cpks_status(d_osnma_data.d_nma_header.cpks); + } + // Save DSM-Kroot and NMA header into a permanent storage + if (d_flag_hot_start) + { + d_flag_hot_start = false; + return; + } + store_dsm_kroot(dsm_msg, nma_header); // TODO - store it only if DSM-KROOT is new + } + else + { + LOG(WARNING) << "Galileo OSNMA: DSM-KROOT authentication failed."; + std::cerr << "Galileo OSNMA: DSM-KROOT authentication failed." << std::endl; + if (d_flag_alert_message) + { + d_flag_alert_message = false; + } + d_count_failed_Kroot++; + } + } + else + { + LOG(WARNING) << "Galileo OSNMA: Error computing padding bits."; + // TODO - here will have to decide if perform the verification or not. Since this step is not mandatory, one could as well have skipped it. + d_count_failed_Kroot++; + } + } + } + // DSM-PKR message + else if (d_osnma_data.d_dsm_header.dsm_id >= 12 && d_osnma_data.d_dsm_header.dsm_id < 16) + { + LOG(INFO) << "Galileo OSNMA: DSM-PKR message received"; + // Save DSM-PKR message + d_osnma_data.d_dsm_pkr_message.nb_dp = d_dsm_reader->get_number_blocks_index(dsm_msg[0]); + d_osnma_data.d_dsm_pkr_message.mid = d_dsm_reader->get_mid(dsm_msg); + for (int k = 0; k < 128; k++) + { + d_osnma_data.d_dsm_pkr_message.itn[k] = dsm_msg[k + 1]; + } + d_osnma_data.d_dsm_pkr_message.npkt = d_dsm_reader->get_npkt(dsm_msg); + uint8_t npktid = d_dsm_reader->get_npktid(dsm_msg); + if (d_flag_PK_renewal && npktid > d_osnma_data.d_dsm_pkr_message.npktid) + { + d_new_public_key_id = npktid; + } + d_osnma_data.d_dsm_pkr_message.npktid = npktid; + + uint32_t l_npk_bytes = 0; + std::string PKT; + const auto it = OSNMA_TABLE_5.find(d_osnma_data.d_dsm_pkr_message.npkt); + if (it != OSNMA_TABLE_5.cend()) + { + PKT = it->second; + const auto it2 = OSNMA_TABLE_6.find(it->second); + if (it2 != OSNMA_TABLE_6.cend()) + { + l_npk_bytes = it2->second / 8; + } + } + uint32_t l_dp_bytes = dsm_msg.size(); + if (d_osnma_data.d_dsm_pkr_message.npkt == 4 && d_osnma_data.d_dsm_pkr_message.npktid == 0) + { + LOG(WARNING) << "Galileo OSNMA: DSM-PKR :: Alert message received. Verifying it."; + std::cout << "Galileo OSNMA: DSM-PKR :: Alert message received. Verifying it." << std::endl; + l_npk_bytes = l_dp_bytes - 130; // bytes + } + + d_osnma_data.d_dsm_pkr_message.npk = std::vector(l_npk_bytes, 0); // ECDSA Public Key + for (uint32_t k = 0; k < l_npk_bytes; k++) + { + d_osnma_data.d_dsm_pkr_message.npk[k] = dsm_msg[k + 130]; + } + + uint32_t l_pd_bytes = l_dp_bytes - 130 - l_npk_bytes; + uint32_t check_l_dp_bytes = 104 * std::ceil(static_cast(1040.0 + l_npk_bytes * 8.0) / 104.0) / 8; + if (l_dp_bytes != check_l_dp_bytes) + { + LOG(WARNING) << "Galileo OSNMA: Failed length reading of DSM-PKR message"; + d_flag_alert_message = false; + } + else + { + d_osnma_data.d_dsm_pkr_message.p_dp = std::vector(l_pd_bytes, 0); + for (uint32_t k = 0; k < l_pd_bytes; k++) + { + d_osnma_data.d_dsm_pkr_message.p_dp[k] = dsm_msg[l_dp_bytes - l_pd_bytes + k]; + } + // TODO: kroot fields are 0 in case no DSM-KROOT received yet, need to take this into account. + // std::vector mi; // (NPKT + NPKID + NPK) + LOG(INFO) << "Galileo OSNMA: DSM-PKR with CID=" << static_cast(d_osnma_data.d_nma_header.cid) + << ", PKID=" << static_cast(d_osnma_data.d_dsm_pkr_message.npktid) << " received"; + // Public key verification against Merkle tree root. + bool verification = verify_dsm_pkr(d_osnma_data.d_dsm_pkr_message); + if (verification) + { + LOG(INFO) << "Galileo OSNMA: DSM-PKR verification :: SUCCESS"; + d_public_key_verified = true; + if (d_flag_PK_renewal) + { + d_new_public_key = d_osnma_data.d_dsm_pkr_message.npk; + } + else if (d_flag_alert_message) + { + LOG(WARNING) << "Galileo OSNMA: DSM-PKR verification :: Alert message verification :: SUCCESS. OSNMA disabled. Contact Galileo Service Centre"; + std::cout << "Galileo OSNMA: DSM-PKR verification :: Alert message verification :: SUCCESS. OSNMA disabled. Contact Galileo Service Centre" << std::endl; + } + else + { + d_crypto->set_public_key_type(PKT); + d_crypto->set_public_key(d_osnma_data.d_dsm_pkr_message.npk); + d_crypto->store_public_key(PEMFILE_DEFAULT); + } + } + else + { + LOG(ERROR) << "Galileo OSNMA: DSM-PKR verification :: FAILURE"; + d_public_key_verified = false; + d_count_failed_pubKey++; + if (d_flag_alert_message) + { + d_flag_alert_message = false; // disregard message as its authenticity could not be verified. + } + } + } + } + else + { + // Reserved message? + LOG(WARNING) << "Galileo OSNMA: Reserved message received"; + std::cerr << "Galileo OSNMA: Reserved message received" << std::endl; + } + d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] = 0; // TODO - reset during header parsing in PKREV? +} + + +/** + * @brief Reads the Mack message from the given OSNMA_msg object + * + * @details Conditions for MACK processing: + * @param osnma_msg The OSNMA_msg object containing the Mack message. + */ +void osnma_msg_receiver::read_and_process_mack_block(const std::shared_ptr& osnma_msg) +{ + // Retrieve Mack message + uint32_t index = 0; + for (uint32_t value : osnma_msg->mack) + { + d_mack_message[index] = static_cast((value & 0xFF000000) >> 24); + d_mack_message[index + 1] = static_cast((value & 0x00FF0000) >> 16); + d_mack_message[index + 2] = static_cast((value & 0x0000FF00) >> 8); + d_mack_message[index + 3] = static_cast(value & 0x000000FF); + index = index + 4; + } + + d_osnma_data.d_nav_data.set_tow_sf0(osnma_msg->TOW_sf0); + bool can_process_mack_block = (d_osnma_data.d_nma_header.nmas != 3 && d_kroot_verified) || // NMAS different than DU + (d_osnma_data.d_nma_header.nmas == 3 && !d_kroot_verified); // NMAS is DU, but must be disregarded + bool can_verify_tesla_key = d_kroot_verified || d_tesla_key_verified; // Either of those suffices for verifying the incoming TESLA key + bool can_parse_tag_fields = d_osnma_data.d_dsm_kroot_message.ts != 0; // calculating the number of tags is based on the TS of the DSM-KROOT. + if (can_verify_tesla_key && can_parse_tag_fields && can_process_mack_block) + { + read_mack_header(); + d_osnma_data.d_mack_message.PRNa = osnma_msg->PRN; // FIXME this is ugly. + d_osnma_data.d_mack_message.TOW = osnma_msg->TOW_sf0; + d_osnma_data.d_mack_message.WN = osnma_msg->WN_sf0; + read_mack_body(); + process_mack_message(); + // TODO - shorten the MACK processing for the cases where no TK verified or no Kroot verified (warm and cold start) + // still, for instance the OSNMA_NavData and Mack storage (within process_mack_message) makes sense. + } + else + { + // TODO - MACKs should be saved because once Kroot available, they could be verified. + LOG(WARNING) << "Galileo OSNMA: Cannot process MACK block. Skipping it."; + std::cout << "Galileo OSNMA: Cannot process MACK block. Skipping it." << std::endl; + } +} + + +/** + * \brief Reads the MACk header from the d_mack_message array and updates the d_osnma_data structure. + * \details This function reads the message MACK header from the d_mack_message array and updates the d_osnma_data structure with the parsed data. The header consists of three fields + *: tag0, macseq, and cop. The size of the fields is determined by the number of tag length (lt) bits specified in OSNMA_TABLE_11 for the corresponding tag size in d_osnma_data.d_dsm_k + *root_message.ts. The lt_bits value is used to calculate tag0, MACSEQ, and COP. + * \pre The d_mack_message array and d_osnma_data.d_dsm_kroot_message.ts field must be properly populated. + * \post The d_osnma_data.d_mack_message.header.tag0, d_osnma_data.d_mack_message.header.macseq, and d_osnma_data.d_mack_message.header.cop fields are updated with the parsed values + *. + * \returns None. + */ +void osnma_msg_receiver::read_mack_header() +{ + uint8_t lt_bits = 0; + const auto it = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts); + if (it != OSNMA_TABLE_11.cend()) + { + lt_bits = it->second; + } + if (lt_bits < 16) + { + return; // The 16 is to avoid negative shifts if shorter tags were defined + } + uint16_t macseq = 0; + uint8_t cop = 0; + uint64_t first_lt_bits = static_cast(d_mack_message[0]) << (lt_bits - 8); + first_lt_bits += (static_cast(d_mack_message[1]) << (lt_bits - 16)); + if (lt_bits == 20) + { + first_lt_bits += (static_cast(d_mack_message[2] & 0xF0) >> 4); + macseq += (static_cast(d_mack_message[2] & 0x0F) << 8); + macseq += static_cast(d_mack_message[3]); + cop += ((d_mack_message[4] & 0xF0) >> 4); + } + else if (lt_bits == 24) + { + first_lt_bits += static_cast(d_mack_message[2]); + macseq += (static_cast(d_mack_message[3]) << 4); + macseq += (static_cast(d_mack_message[4] & 0xF0) >> 4); + cop += (d_mack_message[4] & 0x0F); + } + else if (lt_bits == 28) + { + first_lt_bits += (static_cast(d_mack_message[2]) << 4); + first_lt_bits += (static_cast(d_mack_message[3] & 0xF0) >> 4); + macseq += (static_cast(d_mack_message[3] & 0x0F) << 8); + macseq += (static_cast(d_mack_message[4])); + cop += ((d_mack_message[5] & 0xF0) >> 4); + } + else if (lt_bits == 32) + { + first_lt_bits += (static_cast(d_mack_message[2]) << 8); + first_lt_bits += static_cast(d_mack_message[3]); + macseq += (static_cast(d_mack_message[4]) << 4); + macseq += (static_cast(d_mack_message[5] & 0xF0) >> 4); + cop += (d_mack_message[5] & 0x0F); + } + else if (lt_bits == 40) + { + first_lt_bits += (static_cast(d_mack_message[2]) << 16); + first_lt_bits += (static_cast(d_mack_message[3]) << 8); + first_lt_bits += static_cast(d_mack_message[4]); + macseq += (static_cast(d_mack_message[5]) << 4); + macseq += (static_cast(d_mack_message[6] & 0xF0) >> 4); + cop += (d_mack_message[6] & 0x0F); + } + d_osnma_data.d_mack_message.header.tag0 = first_lt_bits; + d_osnma_data.d_mack_message.header.macseq = macseq; + d_osnma_data.d_mack_message.header.cop = cop; +} + + +/** + * @brief Reads the MACK message body + * + * \details It retrieves all the tags and tag-info associated, as well as the TESLA key. + * \post populates d_osnma_data.d_mack_message with all tags and tag_info associated of MACK message, as well as the TESLA key into d_osnma_data.d_mack_message.key + * @return None + */ +void osnma_msg_receiver::read_mack_body() +{ + // retrieve tag length + uint8_t lt_bits = 0; + const auto it = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts); + if (it != OSNMA_TABLE_11.cend()) + { + lt_bits = it->second; + } + if (lt_bits == 0) + { + return; + } + // retrieve key length + const uint16_t lk_bits = d_dsm_reader->get_lk_bits(d_osnma_data.d_dsm_kroot_message.ks); + // compute number of tags in the given Mack message as per Eq. 8 ICD + uint16_t nt = std::floor((480.0 - float(lk_bits)) / (float(lt_bits) + 16.0)); + d_osnma_data.d_mack_message.tag_and_info = std::vector(nt - 1); + // retrieve tags and tag-info associated with the tags + for (uint16_t k = 0; k < (nt - 1); k++) + { + uint64_t tag = 0; + uint8_t PRN_d = 0; + uint8_t ADKD = 0; + uint8_t cop = 0; + if (lt_bits == 20) + { + const uint16_t step = std::ceil(4.5 * k); + if (k % 2 == 0) + { + tag += (static_cast((d_mack_message[4 + step] & 0x0F)) << 16); + tag += (static_cast(d_mack_message[5 + step]) << 8); + tag += static_cast(d_mack_message[6 + step]); + PRN_d += d_mack_message[7 + step]; + ADKD += ((d_mack_message[8 + step] & 0xF0) >> 4); + cop += (d_mack_message[8 + step] & 0x0F); + if (k == (nt - 2)) + { + d_osnma_data.d_mack_message.key = std::vector(d_osnma_data.d_dsm_kroot_message.kroot.size()); + for (size_t j = 0; j < d_osnma_data.d_dsm_kroot_message.kroot.size(); j++) + { + d_osnma_data.d_mack_message.key[j] = d_mack_message[9 + step + j]; + } + } + } + else + { + tag += (static_cast(d_mack_message[4 + step]) << 12); + tag += (static_cast(d_mack_message[5 + step]) << 4); + tag += (static_cast((d_mack_message[6 + step] & 0xF0)) >> 4); + PRN_d += (d_mack_message[6 + step] & 0x0F) << 4; + PRN_d += (d_mack_message[7 + step] & 0xF0) >> 4; + ADKD += (d_mack_message[7 + step] & 0x0F); + cop += (d_mack_message[8 + step] & 0xF0) >> 4; + if (k == (nt - 2)) + { + d_osnma_data.d_mack_message.key = std::vector(d_osnma_data.d_dsm_kroot_message.kroot.size()); + for (size_t j = 0; j < d_osnma_data.d_dsm_kroot_message.kroot.size(); j++) + { + d_osnma_data.d_mack_message.key[j] = ((d_mack_message[8 + step + j] & 0x0F) << 4) + ((d_mack_message[9 + step + j] & 0xF0) >> 4); + } + } + } + } + else if (lt_bits == 24) + { + tag += (static_cast((d_mack_message[5 + k * 5])) << 16); + tag += (static_cast((d_mack_message[6 + k * 5])) << 8); + tag += static_cast(d_mack_message[7 + k * 5]); + PRN_d += d_mack_message[8 + k * 5]; + ADKD += ((d_mack_message[9 + k * 5] & 0xF0) >> 4); + cop += (d_mack_message[9 + k * 5] & 0x0F); + if (k == (nt - 2)) + { + d_osnma_data.d_mack_message.key = std::vector(d_osnma_data.d_dsm_kroot_message.kroot.size()); + for (size_t j = 0; j < d_osnma_data.d_dsm_kroot_message.kroot.size(); j++) + { + d_osnma_data.d_mack_message.key[j] = d_mack_message[10 + k * 5 + j]; + } + } + } + else if (lt_bits == 28) + { + const uint16_t step = std::ceil(5.5 * k); + if (k % 2 == 0) + { + tag += (static_cast((d_mack_message[5 + step] & 0x0F)) << 24); + tag += (static_cast(d_mack_message[6 + step]) << 16); + tag += (static_cast(d_mack_message[7 + step]) << 8); + tag += static_cast(d_mack_message[8 + step]); + PRN_d += d_mack_message[9 + step]; + ADKD += ((d_mack_message[10 + step] & 0xF0) >> 4); + cop += (d_mack_message[10 + step] & 0x0F); + if (k == (nt - 2)) + { + d_osnma_data.d_mack_message.key = std::vector(d_osnma_data.d_dsm_kroot_message.kroot.size()); + for (size_t j = 0; j < d_osnma_data.d_dsm_kroot_message.kroot.size(); j++) + { + d_osnma_data.d_mack_message.key[j] = d_mack_message[11 + step + j]; + } + } + } + else + { + tag += (static_cast((d_mack_message[5 + step])) << 20); + tag += (static_cast((d_mack_message[6 + step])) << 12); + tag += (static_cast((d_mack_message[7 + step])) << 4); + tag += (static_cast((d_mack_message[8 + step] & 0xF0)) >> 4); + PRN_d += ((d_mack_message[8 + step] & 0x0F) << 4); + PRN_d += ((d_mack_message[9 + step] & 0xF0) >> 4); + ADKD += (d_mack_message[9 + step] & 0x0F); + cop += ((d_mack_message[10 + step] & 0xF0) >> 4); + if (k == (nt - 2)) + { + d_osnma_data.d_mack_message.key = std::vector(d_osnma_data.d_dsm_kroot_message.kroot.size()); + for (size_t j = 0; j < d_osnma_data.d_dsm_kroot_message.kroot.size(); j++) + { + d_osnma_data.d_mack_message.key[j] = ((d_mack_message[10 + step + j] & 0x0F) << 4) + ((d_mack_message[11 + step + j] & 0xF0) >> 4); + } + } + } + } + else if (lt_bits == 32) + { + tag += (static_cast((d_mack_message[6 + k * 6])) << 24); + tag += (static_cast((d_mack_message[7 + k * 6])) << 16); + tag += (static_cast((d_mack_message[8 + k * 6])) << 8); + tag += static_cast(d_mack_message[9 + k * 6]); + PRN_d += d_mack_message[10 + k * 6]; + ADKD += ((d_mack_message[11 + k * 6] & 0xF0) >> 4); + cop += (d_mack_message[11 + k * 6] & 0x0F); + if (k == (nt - 2)) + { + d_osnma_data.d_mack_message.key = std::vector(d_osnma_data.d_dsm_kroot_message.kroot.size()); + for (size_t j = 0; j < d_osnma_data.d_dsm_kroot_message.kroot.size(); j++) + { + d_osnma_data.d_mack_message.key[j] = d_mack_message[12 + k * 6 + j]; + } + } + } + else if (lt_bits == 40) + { + tag += (static_cast((d_mack_message[7 /* bytes of MACK header */ + k * 7 /* offset of k-th tag */])) << 32); + tag += (static_cast((d_mack_message[8 + k * 7])) << 24); + tag += (static_cast((d_mack_message[9 + k * 7])) << 16); + tag += (static_cast((d_mack_message[10 + k * 7])) << 8); + tag += static_cast(d_mack_message[11 + k * 7]); + PRN_d += d_mack_message[12 + k * 7]; + ADKD += ((d_mack_message[13 + k * 7] & 0xF0) >> 4); + cop += (d_mack_message[13 + k * 7] & 0x0F); + if (k == (nt - 2)) // end of Tag&Info + { + d_osnma_data.d_mack_message.key = std::vector(d_osnma_data.d_dsm_kroot_message.kroot.size()); + for (size_t j = 0; j < d_osnma_data.d_dsm_kroot_message.kroot.size(); j++) + { + d_osnma_data.d_mack_message.key[j] = d_mack_message[14 + k * 7 + j]; + } + } + } + d_osnma_data.d_mack_message.tag_and_info[k].tag = tag; + d_osnma_data.d_mack_message.tag_and_info[k].counter = k + 2; // CTR==1 for Tag0, increases subsequently for all other tags. + d_osnma_data.d_mack_message.tag_and_info[k].tag_info.PRN_d = PRN_d; + d_osnma_data.d_mack_message.tag_and_info[k].tag_info.ADKD = ADKD; + d_osnma_data.d_mack_message.tag_and_info[k].tag_info.cop = cop; + } + // rest are padding bits, used for anything ? +} + + +/** + * @brief Verifies the tags transmitted in the past. + * + * \details This function is responsible for processing the MACK message received (480 bits) at time SF(i). + * It stores the last 10 MACK messages and the last 11 OSNMA_NavData messages. + * Then attempts to verify the Tesla Key by computing the number of hashes of distance between the key-to-verify and the + * Kroot and iteratively hashing the result, until the required number of hashes is achieved. + * The result is then compared with the Kroot. If the two values match, the Tesla key is verified. + * It also performs MACSEQ validation and compares the ADKD of Mack tags with MACLT defined ADKDs. + * Finally, it verifies the tags. + * \pre Kroot or already a TESLA key shall be available. Depending on the ADKD of the tag, OSNMA_NavData of SF(i-2)...SF(i-11) + * \post Number of tags bits verified for each ADKD. MACSEQ verification success + * @param osnma_msg A reference to OSNMA_msg containing the MACK message to be processed. + */ +void osnma_msg_receiver::process_mack_message() +{ + if (!d_kroot_verified && !d_tesla_key_verified) + { + LOG(WARNING) << "Galileo OSNMA: MACK cannot be processed, " + << "no Kroot nor TESLA key available."; + return; // early return, cannot proceed further without one of the two verified. this equals to having Kroot but no TESLa key yet. + } + // verify tesla key and add it to the container of verified keys if successful + if (d_tesla_keys.find(d_osnma_data.d_nav_data.get_tow_sf0()) == d_tesla_keys.end()) // check if already available => no need to verify + { + bool retV = verify_tesla_key(d_osnma_data.d_mack_message.key, d_osnma_data.d_nav_data.get_tow_sf0()); + if (retV) + { + d_tesla_keys.insert(std::pair>(d_osnma_data.d_nav_data.get_tow_sf0(), d_osnma_data.d_mack_message.key)); + } + } + + // MACSEQ - verify current macks, then add current retrieved mack to the end. + auto mack = d_macks_awaiting_MACSEQ_verification.begin(); + while (mack != d_macks_awaiting_MACSEQ_verification.end()) + { + if (d_tesla_keys.find(mack->TOW + 30) != d_tesla_keys.end()) + { + // add tag0 first + Tag tag0(*mack); + d_tags_awaiting_verify.insert(std::pair(mack->TOW, tag0)); + LOG(INFO) << "Galileo OSNMA: Add Tag0 Id= " + << tag0.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << tag0.received_tag << std::dec + << ", TOW=" + << tag0.TOW + << ", ADKD=" + << static_cast(tag0.ADKD) + << ", PRNa=" + << static_cast(tag0.PRNa) + << ", PRNd=" + << static_cast(tag0.PRN_d); + std::vector macseq_verified_tags = verify_macseq_new(*mack); + for (auto& tag_and_info : macseq_verified_tags) + { + // add tags of current mack to the verification queue + Tag t(tag_and_info, mack->TOW, mack->WN, mack->PRNa, tag_and_info.counter); + d_tags_awaiting_verify.insert(std::pair(mack->TOW, t)); + LOG(INFO) << "Galileo OSNMA: Add Tag Id= " + << t.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << t.received_tag << std::dec + << ", TOW=" + << t.TOW + << ", ADKD=" + << static_cast(t.ADKD) + << ", PRNa=" + << static_cast(t.PRNa) + << ", PRNd=" + << static_cast(t.PRN_d); + } + LOG(INFO) << "Galileo OSNMA: d_tags_awaiting_verify :: size: " << d_tags_awaiting_verify.size(); + mack = d_macks_awaiting_MACSEQ_verification.erase(mack); + } + else + { + // key not yet available - keep in container until then -- might be deleted if container size exceeds max allowed + ++mack; + } + } + // add current received MACK to the container to be verified in the next iteration (on this one no key available) + d_macks_awaiting_MACSEQ_verification.push_back(d_osnma_data.d_mack_message); + + // Tag verification + for (auto& it : d_tags_awaiting_verify) + { + bool ret; + if (tag_has_key_available(it.second) && d_nav_data_manager->have_nav_data(it.second)) // tag_has_nav_data_available(it.second)) + { + ret = verify_tag(it.second); + /* TODO - take into account: + * - COP: if + * - ADKD type + * - OSNMA_NavData the tag verifies (min. number of bits verified to consider OSNMA_NavData OK) + * */ + if (ret) + { + d_count_successful_tags++; + it.second.status = Tag::SUCCESS; + LOG(INFO) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id=" + << it.second.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << it.second.received_tag << std::dec + << ", TOW=" + << it.second.TOW + << ", ADKD=" + << static_cast(it.second.ADKD) + << ", PRNa=" + << static_cast(it.second.PRNa) + << ", PRNd=" + << static_cast(it.second.PRN_d); + std::cout << "Galileo OSNMA: Tag verification :: SUCCESS for tag ADKD=" + << static_cast(it.second.ADKD) + << ", PRNa=" + << static_cast(it.second.PRNa) + << ", PRNd=" + << static_cast(it.second.PRN_d) << std::endl; + } + /* TODO notify PVT via pmt + * have_new_data() true + * signal which one is verified + * communicate to PVT*/ + else + { + d_count_failed_tags++; + it.second.status = Tag::FAIL; + LOG(WARNING) << "Galileo OSNMA: Tag verification :: FAILURE for tag Id=" + << it.second.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << it.second.received_tag << std::dec + << ", TOW=" + << it.second.TOW + << ", ADKD=" + << static_cast(it.second.ADKD) + << ", PRNa=" + << static_cast(it.second.PRNa) + << ", PRNd=" + << static_cast(it.second.PRN_d); + std::cerr << "Galileo OSNMA: Tag verification :: FAILURE for tag ADKD=" + << static_cast(it.second.ADKD) + << ", PRNa=" + << static_cast(it.second.PRNa) + << ", PRNd=" + << static_cast(it.second.PRN_d) << std::endl; + } + } + else if (it.second.TOW > d_osnma_data.d_nav_data.get_tow_sf0()) + { + // TODO - I dont understand logic. This needs to be reviewed. + // case 1: adkd=12 and t.Tow + 300 < current TOW + // case 2: adkd=0/4 and t.Tow + 30 < current TOW + // case 3: any adkd and t.Tow > current TOW + it.second.skipped++; + LOG(WARNING) << "Galileo OSNMA: Tag verification :: SKIPPED (x" << it.second.skipped << ")for Tag Id= " + << it.second.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << it.second.received_tag << std::dec + << ", TOW=" + << it.second.TOW + << ", ADKD=" + << static_cast(it.second.ADKD) + << ", PRNa=" + << static_cast(it.second.PRNa) + << ", PRNd=" + << static_cast(it.second.PRN_d) + << ". Key available (" << tag_has_key_available(it.second) << "), navData (" << tag_has_nav_data_available(it.second) << "). "; + } + } + uint8_t tag_size = 0; + const auto it = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts); + if (it != OSNMA_TABLE_11.cend()) + { + tag_size = it->second; + } + d_nav_data_manager->update_nav_data(d_tags_awaiting_verify, tag_size); + auto data_to_send = d_nav_data_manager->get_verified_data(); + d_nav_data_manager->log_status(); + send_data_to_pvt(data_to_send); + + remove_verified_tags(); + + control_tags_awaiting_verify_size(); // remove the oldest tags if size is too big. +} + + +/** + * @brief Verify received DSM-PKR message + * + * \details This method provides the functionality to verify the DSM-PKR message. The verification includes generating the base leaf + * and intermediate leafs, and comparing the computed merkle root leaf with the received one. + * \pre DSM_PKR_message correctly filled in, especially the 1024-bit intermediate tree nodes fields + * \returns true if computed merkle root matches received one, false otherwise + */ +bool osnma_msg_receiver::verify_dsm_pkr(const DSM_PKR_message& message) const +{ + const auto base_leaf = get_merkle_tree_leaves(message); // m_i + const auto computed_merkle_root = compute_merkle_root(message, base_leaf); // x_4_0 + const auto msg_id = static_cast(message.mid); + LOG(INFO) << "Galileo OSNMA: DSM-PKR verification :: leaf provided for Message ID " << msg_id; + + if (computed_merkle_root == d_crypto->get_merkle_root()) + { + LOG(INFO) << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: SUCCESS. PKID=" << static_cast(message.npktid); + std::cout << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: SUCCESS. PKID=" << static_cast(message.npktid) << std::endl; + return true; + } + else + { + LOG(WARNING) << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: FAILURE."; + std::cerr << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: FAILURE." << std::endl; + return false; + } +} + + +std::vector osnma_msg_receiver::compute_merkle_root(const DSM_PKR_message& dsm_pkr_message, const std::vector& m_i) const +{ + std::vector x_next; + std::vector x_current = d_crypto->compute_SHA_256(m_i); + for (size_t i = 0; i < 4; i++) + { + x_next.clear(); + bool leaf_is_on_right = ((dsm_pkr_message.mid / (1 << (i))) % 2) == 1; + + if (leaf_is_on_right) + { + // Leaf is on the right -> first the itn, then concatenate the leaf + x_next.insert(x_next.end(), &dsm_pkr_message.itn[32 * i], &dsm_pkr_message.itn[32 * i + 32]); + x_next.insert(x_next.end(), x_current.begin(), x_current.end()); + } + else + { + // Leaf is on the left -> first the leaf, then concatenate the itn + x_next.insert(x_next.end(), x_current.begin(), x_current.end()); + x_next.insert(x_next.end(), &dsm_pkr_message.itn[32 * i], &dsm_pkr_message.itn[32 * i + 32]); + } + + // Compute the next node. + x_current = d_crypto->compute_SHA_256(x_next); + } + return x_current; +} + + +/** + * @brief Get the Merkle tree base leave from a DSM_PKR_message. + * + * @param dsm_pkr_message The DSM_PKR_message object from which to retrieve the Merkle tree leave. + * @return std::vector The Merkle tree base leave from the DSM_PKR_message object. + */ +std::vector osnma_msg_receiver::get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const +{ + // build base leaf m_i according to OSNMA SIS ICD v1.1, section 6.2 DSM-PKR Verification + std::vector m_i; + m_i.push_back(static_cast((dsm_pkr_message.npkt << 4) + dsm_pkr_message.npktid)); + m_i.insert(m_i.end(), dsm_pkr_message.npk.begin(), dsm_pkr_message.npk.end()); + return m_i; +} + + +bool osnma_msg_receiver::verify_tag(Tag& tag) const +{ + // Debug + // LOG(INFO) << "Galileo OSNMA: Tag verification :: Start for tag Id= " + // << tag.tag_id + // << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + // << tag.received_tag << std::dec; + // build message + std::vector m = build_message(tag); + + std::vector mac; + std::vector applicable_key; + if (tag.ADKD == 0 || tag.ADKD == 4) + { + const auto it = d_tesla_keys.find(tag.TOW + 30); + if (it != d_tesla_keys.cend()) + { + applicable_key = it->second; + } + else + { + return false; + } + // LOG(INFO) << "|---> Galileo OSNMA :: applicable key: 0x" << d_helper->convert_to_hex_string(applicable_key) << "TOW="<(tag.TOW + 30); + } + else // ADKD 12 + { + const auto it = d_tesla_keys.find(tag.TOW + 330); + if (it != d_tesla_keys.cend()) + { + applicable_key = it->second; + } + else + { + return false; + } + // LOG(INFO) << "|---> Galileo OSNMA :: applicable key: 0x" << d_helper->convert_to_hex_string(applicable_key) << "TOW="<(tag.TOW + 330); + } + + if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256 + { + mac = d_crypto->compute_HMAC_SHA_256(applicable_key, m); + } + else if (d_osnma_data.d_dsm_kroot_message.mf == 1) // C: CMAC-AES + { + mac = d_crypto->compute_CMAC_AES(applicable_key, m); + } + + // truncate the computed mac: trunc(l_t, mac(K,m)) Eq. 23 ICD + uint8_t lt_bits = 0; // TODO - remove this duplication of code. + const auto it2 = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts); + if (it2 != OSNMA_TABLE_11.cend()) + { + lt_bits = it2->second; + } + if (lt_bits < 16) + { + return false; + } + uint64_t computed_mac = static_cast(mac[0]) << (lt_bits - 8); + computed_mac += (static_cast(mac[1]) << (lt_bits - 16)); + if (lt_bits == 20) + { + computed_mac += (static_cast(mac[1] & 0xF0) >> 4); + } + else if (lt_bits == 24) + { + computed_mac += static_cast(mac[2]); + } + else if (lt_bits == 28) + { + computed_mac += (static_cast(mac[2]) << 4); + computed_mac += (static_cast(mac[3] & 0xF0) >> 4); + } + else if (lt_bits == 32) + { + computed_mac += (static_cast(mac[2]) << 8); + computed_mac += static_cast(mac[3]); + } + else if (lt_bits == 40) + { + computed_mac += (static_cast(mac[2]) << 16); + computed_mac += (static_cast(mac[3]) << 8); + computed_mac += static_cast(mac[4]); + } + + tag.computed_tag = computed_mac; // update with computed value + // Compare computed tag with received one truncated + if (tag.received_tag == computed_mac) + { + return true; + } + return false; +} + + +/** + * \brief generates the message for computing the tag + * \remarks It also sets some parameters to the Tag object, based on the verification process. + * + * \param tag The tag containing the information to be included in the message. + * + * \return The built OSNMA message as a vector of uint8_t. + */ +std::vector osnma_msg_receiver::build_message(Tag& tag) const +{ + std::vector m; + if (tag.CTR != 1) + { + m.push_back(static_cast(tag.PRN_d)); + } + m.push_back(static_cast(tag.PRNa)); + // TODO: maybe here I have to use d_receiver_time instead of d_GST_SIS which is what I am computing + uint32_t GST = d_helper->compute_gst(tag.WN, tag.TOW); + std::vector GST_uint8 = d_helper->gst_to_uint8(GST); + m.insert(m.end(), GST_uint8.begin(), GST_uint8.end()); + m.push_back(tag.CTR); + // Extracts only two bits from d_osnma_data.d_nma_header.nmas + uint8_t two_bits_nmas = d_osnma_data.d_nma_header.nmas & 0b00000011; + two_bits_nmas = two_bits_nmas << 6; + m.push_back(two_bits_nmas); + + // Add applicable NavData bits to message + std::string applicable_nav_data = d_nav_data_manager->get_navigation_data(tag); + std::vector applicable_nav_data_bytes = d_helper->bytes(applicable_nav_data); + tag.nav_data = std::move(applicable_nav_data); // update tag with applicable data + + // Convert and add OSNMA_NavData bytes into the message, taking care of that NMAS has only 2 bits + for (uint8_t byte : applicable_nav_data_bytes) + { + m.back() |= (byte >> 2); // First take the 6 MSB bits of byte and add to m + m.push_back(byte << 6); // Then take the last 2 bits of byte, shift them to MSB position and insert the new element into m + } + if (m.back() == 0) + { + m.pop_back(); // Remove the last element if its value is 0 (only padding was added) + } + else + { + // Pad with zeros if the last element wasn't full + for (int bits = 2; bits < 8; bits += 2) + { + // Check if the last element in the vector has 2 '00' bits in its LSB position + if ((m.back() & 0b00000011) == 0) + { + m.back() <<= 2; // Shift the existing bits to make room for new 2 bits + } + else + { + break; // If it does not have 2 '00' bits in its LSB position, then the padding is complete + } + } + } + return m; +} + + +void osnma_msg_receiver::display_data() +{ + // if(d_satellite_nav_data.empty()) + // return; + // + // for(const auto& satellite : d_satellite_nav_data) { + // std::cout << "SV_ID: " << satellite.first << std::endl; + // for(const auto& towData : satellite.second) { + // std::cout << "\tTOW: " << towData.first << " key: "; + // for(size_t i = 0; i < towData.second.d_mack_message.key.size(); i++) { + // std::cout << std::hex << std::setfill('0') << std::setw(2) + // << static_cast(towData.second.d_mack_message.key[i]) << " "; + // } + // } + // } +} + + +bool osnma_msg_receiver::verify_tesla_key(std::vector& key, uint32_t TOW) +{ + uint32_t num_of_hashes_needed; + uint32_t GST_SFi = d_GST_Sf - 30; // GST of target key is to be used. + std::vector hash; + const uint8_t lk_bytes = d_dsm_reader->get_lk_bits(d_osnma_data.d_dsm_kroot_message.ks) / 8; + std::vector validated_key; + if (d_tesla_key_verified) + { // have to go up to last verified key + validated_key = d_tesla_keys.rbegin()->second; + num_of_hashes_needed = (d_GST_Sf - d_last_verified_key_GST) / 30; // Eq. 19 ICD modified + LOG(INFO) << "Galileo OSNMA: TESLA verification (" << num_of_hashes_needed << " hashes) need to be performed up to closest verified TESLA key"; + + hash = hash_chain(num_of_hashes_needed, key, GST_SFi, lk_bytes); + } + else + { // have to go until Kroot + validated_key = d_osnma_data.d_dsm_kroot_message.kroot; + num_of_hashes_needed = (d_GST_Sf - d_GST_0) / 30 + 1; // Eq. 19 IC + LOG(INFO) << "Galileo OSNMA: TESLA verification (" << num_of_hashes_needed << " hashes) need to be performed up to Kroot"; + + hash = hash_chain(num_of_hashes_needed, key, GST_SFi, lk_bytes); + } + // truncate hash + std::vector computed_key; + computed_key.reserve(key.size()); + for (size_t i = 0; i < key.size(); i++) + { + computed_key.push_back(hash[i]); + } + if (computed_key == validated_key && num_of_hashes_needed > 0) + { + LOG(INFO) << "Galileo OSNMA: TESLA key verification :: SUCCESS!"; + std::cout << "Galileo OSNMA: TESLA key verification :: SUCCESS!" << std::endl; + d_tesla_keys.insert(std::pair>(TOW, key)); + d_tesla_key_verified = true; + d_last_verified_key_GST = d_GST_Sf; + } + else if (num_of_hashes_needed > 0) + { + LOG(WARNING) << "Galileo OSNMA: TESLA key verification :: FAILED"; + std::cerr << "Galileo OSNMA: TESLA key verification :: FAILED" << std::endl; + } + return d_tesla_key_verified; +} + + +/** + * @brief Removes the tags that have been verified from the multimap d_tags_awaiting_verify. + * + * This function iterates through the multimap d_tags_awaiting_verify, and removes the tags that have a status of SUCCESS or FAIL. + * \remarks it also prints the current unverified tags + */ +void osnma_msg_receiver::remove_verified_tags() +{ + for (auto it = d_tags_awaiting_verify.begin(); it != d_tags_awaiting_verify.end();) + { + if (it->second.status == Tag::SUCCESS || it->second.status == Tag::FAIL) + { + LOG(INFO) << "Galileo OSNMA: Tag verification :: DELETE tag Id=" + << it->second.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << it->second.received_tag << std::dec + << ", TOW=" + << it->second.TOW + << ", ADKD=" + << static_cast(it->second.ADKD) + << ", PRNa=" + << static_cast(it->second.PRNa) + << ", PRNd=" + << static_cast(it->second.PRN_d) + << ", status=" + << d_helper->verification_status_str(it->second.status); + it = d_tags_awaiting_verify.erase(it); + } + else if ((it->second.ADKD != 12 && !d_nav_data_manager->have_nav_data(it->second)) || (it->second.ADKD == 12 && (it->second.TOW + 30 * 11 < d_helper->get_TOW(d_last_verified_key_GST)))) + { + LOG(INFO) << "Galileo OSNMA: Tag verification :: DELETE tag Id=" + << it->second.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << it->second.received_tag << std::dec + << ", TOW=" + << it->second.TOW + << ", ADKD=" + << static_cast(it->second.ADKD) + << ", PRNa=" + << static_cast(it->second.PRNa) + << ", PRNd=" + << static_cast(it->second.PRN_d) + << ", status=" + << d_helper->verification_status_str(it->second.status) + << ". SV out of sight / NavData unavailable."; + it = d_tags_awaiting_verify.erase(it); + } + else + { + ++it; + } + } + LOG(INFO) << "Galileo OSNMA: d_tags_awaiting_verify :: size: " << d_tags_awaiting_verify.size(); + for (const auto& it : d_tags_awaiting_verify) + { + LOG(INFO) << "Galileo OSNMA: Tag verification :: status tag Id=" + << it.second.tag_id + << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << it.second.received_tag << std::dec + << ", TOW=" + << it.second.TOW + << ", ADKD=" + << static_cast(it.second.ADKD) + << ", PRNa=" + << static_cast(it.second.PRNa) + << ", PRNd=" + << static_cast(it.second.PRN_d) + << ", status=" + << d_helper->verification_status_str(it.second.status); + } +} + + +/** + * @brief Control the size of the tags awaiting verification multimap. + * + * This function checks the size of the multimap `d_tags_awaiting_verify` and removes + * elements from the beginning until the size is no longer greater than 60. + * The purpose is to limit the size of the multimap and prevent it from consuming + * excessive memory. + */ +void osnma_msg_receiver::control_tags_awaiting_verify_size() +{ + while (d_tags_awaiting_verify.size() > 500) + { + auto it = d_tags_awaiting_verify.begin(); + LOG(INFO) << "Galileo OSNMA: Tag verification :: DELETED tag due to exceeding buffer size. " + << "Tag Id= " << it->second.tag_id + << ", TOW=" << it->first + << ", ADKD=" << static_cast(it->second.ADKD) + << ", from satellite " << it->second.PRNa; + d_tags_awaiting_verify.erase(it); + } +} + + +// TODO - remove this method +/** + * @brief Verifies the MACSEQ of a received MACK_message. + * + * \details checks for each tag in the retrieved mack message if its flexible (MACSEQ) or not (MACSEQ/MACLT depending on configuration param, and + * verifies according to Eqs. 20, 21 SIS ICD. + * @param message The MACK_message to verify. + * @return True if the MACSEQ is valid, false otherwise. + */ +bool osnma_msg_receiver::verify_macseq(const MACK_message& mack) +{ + // MACSEQ verification + uint32_t GST_SFi = d_GST_Sf - 30; // time of the start of SF containing MACSEQ + std::vector applicable_key = d_tesla_keys[mack.TOW + 30]; // current tesla key ie transmitted in the next subframe + std::vector sq1{}; + std::vector sq2{}; + std::vector applicable_sequence; + const auto it = OSNMA_TABLE_16.find(d_osnma_data.d_dsm_kroot_message.maclt); + // TODO as per RG example appears that the seq. q shall also be validated against either next or former Sf (depending on GST) + if (it != OSNMA_TABLE_16.cend()) + { + sq1 = it->second.sequence1; + sq2 = it->second.sequence2; + } + // Assign relevant sequence based on subframe time + if (mack.TOW % 60 < 30) // tried GST_Sf and it does not support the data present. + { + applicable_sequence = std::move(sq1); + } + else if (mack.TOW % 60 >= 30) + { + applicable_sequence = std::move(sq2); + } + if (mack.tag_and_info.size() != applicable_sequence.size() - 1) + { + LOG(WARNING) << "Galileo OSNMA: Number of retrieved tags does not match MACLT sequence size!"; + return false; + } + std::vector flxTags{}; + std::string tempADKD; + // MACLT verification + for (size_t i = 0; i < mack.tag_and_info.size(); i++) + { + tempADKD = applicable_sequence[i + 1]; + if (tempADKD == "FLX") + { + flxTags.push_back(i); // C: just need to save the index in the sequence + } + else if (mack.tag_and_info[i].tag_info.ADKD != std::stoi(applicable_sequence[i + 1])) + { + // fill index of tags failed + LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: ADKD mismatch against MAC Look-up table."; + return false; // TODO macseq shall be individual to each tag, a wrongly verified macseq should not discard the whole MACK tags + } + } + + if (flxTags.empty()) + { + LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD matches MAC Look-up table."; + return true; + } + // Fixed as well as FLX Tags share first part - Eq. 22 ICD + std::vector m(5 + 2 * flxTags.size()); // each flx tag brings two bytes + m[0] = static_cast(mack.PRNa); // PRN_A - SVID of the satellite transmitting the tag + m[1] = static_cast((GST_SFi & 0xFF000000) >> 24); + m[2] = static_cast((GST_SFi & 0x00FF0000) >> 16); + m[3] = static_cast((GST_SFi & 0x0000FF00) >> 8); + m[4] = static_cast(GST_SFi & 0x000000FF); + // Case tags flexible - Eq. 21 ICD + for (size_t i = 0; i < flxTags.size(); i++) + { + m[2 * i + 5] = mack.tag_and_info[flxTags[i]].tag_info.PRN_d; + m[2 * i + 6] = mack.tag_and_info[flxTags[i]].tag_info.ADKD << 4 | + mack.tag_and_info[flxTags[i]].tag_info.cop; + } + // compute mac + std::vector mac; + if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256 + { + mac = d_crypto->compute_HMAC_SHA_256(applicable_key, m); + } + else if (d_osnma_data.d_dsm_kroot_message.mf == 1) // C: CMAC-AES + { + mac = d_crypto->compute_CMAC_AES(applicable_key, m); + } + // Truncate the twelve MSBits and compare with received MACSEQ + uint16_t mac_msb = 0; + if (!mac.empty()) + { + mac_msb = (mac[0] << 8) + mac[1]; + } + uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4; + if (computed_macseq == mack.header.macseq) + { + LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: FLX tags verification OK"; + return true; + } + else + { + LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: FLX tags verification failed"; + return false; + } +} + + +bool osnma_msg_receiver::tag_has_nav_data_available(const Tag& t) const +{ + auto prn_it = d_satellite_nav_data.find(t.PRN_d); + if (prn_it != d_satellite_nav_data.end()) + { + // PRN was found, check if TOW exists in inner map + // LOG(INFO) << "Galileo OSNMA: hasData = true " << std::endl; + std::map tow_map = prn_it->second; + auto tow_it = tow_map.find(t.TOW - 30); + if (tow_it != tow_map.end()) + { + return true; + } + else + { + // TOW not found + return false; + } + } + else + { + // PRN was not found + // LOG(INFO) << "Galileo OSNMA: hasData = false " << std::endl; + return false; + } + return false; +} + + +bool osnma_msg_receiver::tag_has_key_available(const Tag& t) const +{ + // check adkd of tag + // if adkd = 0 or 4 => look for d_tesla_keys[t.TOW+30] + // if adkd = 12 => look for d_tesla_keys[t.TOW+300] + // return true if available, otherwise false + + if (t.ADKD == 0 || t.ADKD == 4) + { + auto it = d_tesla_keys.find(t.TOW + 30); + if (it != d_tesla_keys.end()) + { + // LOG(INFO) << "Galileo OSNMA: hasKey = true " << std::endl; + return true; + } + } + else if (t.ADKD == 12) + { + auto it = d_tesla_keys.find(t.TOW + 330); + if (it != d_tesla_keys.end()) + { + // LOG(INFO) << "Galileo OSNMA: hasKey = true " << std::endl; + return true; + } + } + // LOG(INFO) << "Galileo OSNMA: hasKey = false "; + return false; +} + + +std::vector osnma_msg_receiver::hash_chain(uint32_t num_of_hashes_needed, const std::vector& key, uint32_t GST_SFi, const uint8_t lk_bytes) const +{ + std::vector K_II = key; + std::vector K_I; // result of the recursive hash operations + std::vector msg; + // compute the tesla key for current SF (GST_SFi and K_II change in each iteration) + for (uint32_t i = 1; i <= num_of_hashes_needed; i++) + { + // build message digest m = (K_I+1 || GST_SFi || alpha) + msg.reserve(K_II.size() + sizeof(GST_SFi) + sizeof(d_osnma_data.d_dsm_kroot_message.alpha)); + std::copy(K_II.begin(), K_II.end(), std::back_inserter(msg)); + + msg.push_back((GST_SFi & 0xFF000000) >> 24); + msg.push_back((GST_SFi & 0x00FF0000) >> 16); + msg.push_back((GST_SFi & 0x0000FF00) >> 8); + msg.push_back(GST_SFi & 0x000000FF); + // extract alpha + // d_osnma_data.d_dsm_kroot_message.alpha = 0xa06221261ad9; + for (int k = 5; k >= 0; k--) + { + // TODO: static extracts the MSB in case from larger to shorter int? + msg.push_back(static_cast((d_osnma_data.d_dsm_kroot_message.alpha >> (k * 8)) & 0xFF)); // extract first 6 bytes of alpha. + } + // compute hash + std::vector hash; + if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8. + { + hash = d_crypto->compute_SHA_256(msg); + } + else if (d_osnma_data.d_dsm_kroot_message.hf == 2) + { + hash = d_crypto->compute_SHA3_256(msg); + } + else + { + hash = std::vector(32); + } + // truncate hash + K_I.reserve(lk_bytes); // TODO - case hash function has 512 bits + for (int k = 0; k < lk_bytes; k++) + { + K_I.push_back(hash[k]); + } + // set parameters for next iteration + GST_SFi -= 30; // next SF time is the actual minus 30 seconds + K_II = K_I; // next key is the actual one + K_I.clear(); // empty the actual one for a new computation + msg.clear(); + } + + // check that the final time matches the Kroot time + bool check; + if (!d_tesla_key_verified) + { + check = GST_SFi + 30 == d_GST_0 - 30; + } + else + { + check = GST_SFi + 30 == d_last_verified_key_GST; + } + if (!check) + { + LOG(WARNING) << "Galileo OSNMA: TESLA key chain verification error: KROOT time mismatch!"; // ICD. Eq. 18 + std::cerr << "Galileo OSNMA: TESLA key chain verification error: KROOT time mismatch!" << std::endl; + } + else + { + LOG(INFO) << "Galileo OSNMA: TESLA key chain verification: KROOT time matches."; // ICD. Eq. 18 + } + return K_II; +} + + +/** + * @brief Verifies the MAC sequence of a received MACK message. + * + * This function is responsible for verifying the MAC sequence of a received MACK message. + * It takes a reference to a constant MACK_message object as input and returns a vector containing + * the tags for which the MACSEQ verification was successful + * + * @param mack The MACK message object to verify the MAC sequence for. + * @return vector MACK_tag_and_info for which the MACSEQ was successful + */ +std::vector osnma_msg_receiver::verify_macseq_new(const MACK_message& mack) +{ + std::vector verified_tags{}; + + // MACSEQ verification + uint32_t GST_Sfi = d_GST_Sf - 30; // time of the start of SF containing MACSEQ + std::vector applicable_key; + const auto key_it = d_tesla_keys.find(mack.TOW + 30); // current tesla key ie transmitted in the next subframe + if (key_it != d_tesla_keys.cend()) + { + applicable_key = key_it->second; + } + std::vector sq1{}; + std::vector sq2{}; + std::vector applicable_sequence; + const auto it = OSNMA_TABLE_16.find(d_osnma_data.d_dsm_kroot_message.maclt); + if (it != OSNMA_TABLE_16.cend()) + { + sq1 = it->second.sequence1; + sq2 = it->second.sequence2; + } + + // Assign relevant sequence based on subframe time + if (mack.TOW % 60 < 30) // tried GST_Sf and it does not support the data present. + { + applicable_sequence = std::move(sq1); + } + else if (mack.TOW % 60 >= 30) + { + applicable_sequence = std::move(sq2); + } + if (mack.tag_and_info.size() != applicable_sequence.size() - 1) + { + LOG(WARNING) << "Galileo OSNMA: Number of retrieved tags does not match MACLT sequence size!"; + d_count_failed_macseq += mack.tag_and_info.size(); + return verified_tags; + } + std::vector flxTags{}; + std::string tempADKD; + // MACLT verification + for (size_t i = 0; i < mack.tag_and_info.size(); i++) + { + tempADKD = applicable_sequence[i + 1]; + if (tempADKD == "FLX") + { + flxTags.push_back(i); // C: just need to save the index in the sequence + } + else if (mack.tag_and_info[i].tag_info.ADKD == std::stoi(applicable_sequence[i + 1])) + { + // fill index of tags failed + LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD match against MAC Look-up table for Tag=0x" + << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << mack.tag_and_info[i].tag << std::dec; + verified_tags.push_back(mack.tag_and_info[i]); + } + else + { + // discard tag + LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: ADKD mismatch against MAC Look-up table for Tag=0x" + << std::setfill('0') << std::setw(10) << std::hex << std::uppercase + << mack.tag_and_info[i].tag << std::dec; + d_count_failed_macseq++; + } + } + + if (flxTags.empty() /*TODO add check d_flag_check_mackseq_fixed_tags*/) + { + LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: No FLX tags to verify."; + return verified_tags; + } + // Fixed as well as FLX Tags share first part - Eq. 22 ICD + std::vector m(5 + 2 * flxTags.size()); // each flx tag brings two bytes + m[0] = static_cast(mack.PRNa); // PRN_A - SVID of the satellite transmitting the tag + m[1] = static_cast((GST_Sfi & 0xFF000000) >> 24); + m[2] = static_cast((GST_Sfi & 0x00FF0000) >> 16); + m[3] = static_cast((GST_Sfi & 0x0000FF00) >> 8); + m[4] = static_cast(GST_Sfi & 0x000000FF); + // Case tags flexible - Eq. 21 ICD + for (size_t i = 0; i < flxTags.size(); i++) + { + m[2 * i + 5] = mack.tag_and_info[flxTags[i]].tag_info.PRN_d; + m[2 * i + 6] = mack.tag_and_info[flxTags[i]].tag_info.ADKD << 4 | + mack.tag_and_info[flxTags[i]].tag_info.cop; + } + // compute mac + std::vector mac; + if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256 + { + mac = d_crypto->compute_HMAC_SHA_256(applicable_key, m); + } + else if (d_osnma_data.d_dsm_kroot_message.mf == 1) // C: CMAC-AES + { + mac = d_crypto->compute_CMAC_AES(applicable_key, m); + } + // Truncate the twelve MSBits and compare with received MACSEQ + uint16_t mac_msb = 0; + if (!mac.empty()) + { + mac_msb = (mac[0] << 8) + mac[1]; + } + uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4; + if (computed_macseq == mack.header.macseq) + { + LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: FLX tags verification OK"; + for (uint8_t flxTag : flxTags) + { + verified_tags.push_back(mack.tag_and_info[flxTag]); + } + return verified_tags; + } + else + { + LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: FLX tags verification failed"; + d_count_failed_macseq += flxTags.size(); + return verified_tags; + } +} + + +void osnma_msg_receiver::send_data_to_pvt(const std::vector& data) +{ + if (!data.empty()) + { + for (const auto& i : data) + { + const auto tmp_obj = std::make_shared(i); + this->message_port_pub(pmt::mp("OSNMA_to_PVT"), pmt::make_any(tmp_obj)); + } + } +} + + +bool osnma_msg_receiver::store_dsm_kroot(const std::vector& dsm, const uint8_t nma_header) const +{ + std::ofstream file(KROOTFILE_DEFAULT, std::ios::binary | std::ios::out); + + if (!file.is_open()) + { + return false; + } + + // NMA header + file.write(reinterpret_cast(&nma_header), 1); + + // Then writing the entire dsm_msg vector to the file + file.write(reinterpret_cast(dsm.data()), dsm.size()); + + return file.good(); +} + + +std::pair, uint8_t> osnma_msg_receiver::parse_dsm_kroot() const +{ + std::ifstream file(KROOTFILE_DEFAULT, std::ios::binary | std::ios::in); + if (!file) + { + return {std::vector(), 0}; + } + + // Read the first byte into hkroot[0] + uint8_t nma_header; + file.read(reinterpret_cast(&nma_header), 1); + + // Read the remaining file content into dsm_msg + std::vector dsm_msg((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + + file.close(); + + if (file.bad()) + { + return {std::vector(), 0}; + } + + return {dsm_msg, nma_header}; +} + +void osnma_msg_receiver::set_merkle_root(const std::vector& v) +{ + d_crypto->set_merkle_root(v); +} diff --git a/src/core/libs/osnma_msg_receiver.h b/src/core/libs/osnma_msg_receiver.h new file mode 100644 index 000000000..4240d7df8 --- /dev/null +++ b/src/core/libs/osnma_msg_receiver.h @@ -0,0 +1,176 @@ +/*! + * \file osnma_msg_receiver.h + * \brief GNU Radio block that processes Galileo OSNMA data received from + * Galileo E1B telemetry blocks. After successful decoding, sends the content to + * the PVT block. + * \author Carles Fernandez-Prades, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_OSNMA_MSG_RECEIVER_H +#define GNSS_SDR_OSNMA_MSG_RECEIVER_H + +#define FRIEND_TEST(test_case_name, test_name) \ + friend class test_case_name##_##test_name##_Test + +#include "galileo_inav_message.h" // for OSNMA_msg +#include "gnss_block_interface.h" // for gnss_shared_ptr +#include "osnma_data.h" // for OSNMA_data structures +#include "osnma_nav_data_manager.h" // for OSNMA_NavDataManager +#include // for gr::block +#include // for pmt::pmt_t +#include // for std::array +#include // for uint8_t +#include // for std::time_t +#include // for std::map, std::multimap +#include // for std::shared_ptr +#include // for std::string +#include // for std::pair +#include // for std::vector + +/** \addtogroup Core + * \{ */ +/** \addtogroup Core_Receiver_Library + * \{ */ + +class OSNMA_DSM_Reader; +class Gnss_Crypto; +class Osnma_Helper; +class osnma_msg_receiver; + +using osnma_msg_receiver_sptr = gnss_shared_ptr; + +osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode = false); + +/*! + * \brief GNU Radio block that receives asynchronous OSNMA messages + * from the telemetry blocks, stores them in memory, and decodes OSNMA info + * when enough data have been received. + * The decoded OSNMA data is sent to the PVT block. + */ +class osnma_msg_receiver : public gr::block +{ +public: + ~osnma_msg_receiver() = default; //!< Default destructor + bool verify_dsm_pkr(const DSM_PKR_message& message) const; //!< Public for benchmarking purposes + void msg_handler_osnma(const pmt::pmt_t& msg); //!< For testing purposes + void read_merkle_xml(const std::string& merklepath); //!< Public for testing purposes + void set_merkle_root(const std::vector& v); //!< Public for benchmarking purposes + +private: + friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode); + osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath, bool strict_mode); + + void process_osnma_message(const std::shared_ptr& osnma_msg); + void read_nma_header(uint8_t nma_header); + void read_dsm_header(uint8_t dsm_header); + void read_dsm_block(const std::shared_ptr& osnma_msg); + void process_dsm_block(const std::shared_ptr& osnma_msg); + void process_dsm_message(const std::vector& dsm_msg, const uint8_t& nma_header); + void read_and_process_mack_block(const std::shared_ptr& osnma_msg); + void read_mack_header(); + void read_mack_body(); + void process_mack_message(); + void remove_verified_tags(); + void control_tags_awaiting_verify_size(); + void display_data(); + void send_data_to_pvt(const std::vector& data); + + bool verify_tesla_key(std::vector& key, uint32_t TOW); + bool verify_tag(Tag& tag) const; + bool tag_has_nav_data_available(const Tag& t) const; + bool tag_has_key_available(const Tag& t) const; + bool verify_macseq(const MACK_message& mack); + + bool store_dsm_kroot(const std::vector& dsm, const uint8_t nma_header) const; + + std::pair, uint8_t> parse_dsm_kroot() const; + std::vector get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const; + std::vector compute_merkle_root(const DSM_PKR_message& dsm_pkr_message, const std::vector& m_i) const; + std::vector build_message(Tag& tag) const; + std::vector hash_chain(uint32_t num_of_hashes_needed, const std::vector& key, uint32_t GST_SFi, const uint8_t lk_bytes) const; + std::vector verify_macseq_new(const MACK_message& mack); + + std::map> d_satellite_nav_data; // map holding OSNMA_NavData sorted by SVID (first key) and TOW (second key). + std::map> d_tesla_keys; // tesla keys over time, sorted by TOW + std::multimap d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW + + std::vector d_new_public_key; + std::vector d_tags_to_verify{0, 4, 12}; + std::vector d_macks_awaiting_MACSEQ_verification; + + std::array, 16> d_dsm_message{}; // structure for recording DSM blocks, when filled it sends them to parse and resets itself. + std::array, 16> d_dsm_id_received{}; + std::array d_number_of_blocks{}; + std::array d_mack_message{}; // C: 480 b + + std::unique_ptr d_crypto; // class for cryptographic functions + std::unique_ptr d_dsm_reader; // osnma parameters parser + std::unique_ptr d_helper; // helper class with auxiliary functions + std::unique_ptr d_nav_data_manager; // refactor for holding and processing navigation data + + OSNMA_data d_osnma_data{}; + + uint32_t d_last_received_GST{0}; // latest GST received + uint32_t d_GST_Sf{}; // Scaled GST time for cryptographic computations + uint32_t d_GST_Rx{0}; // local GST receiver time + uint32_t d_last_verified_key_GST{0}; // GST for the latest verified TESLA key + uint32_t d_GST_0{}; // Time of applicability GST (KROOT + 30 s) + uint32_t d_GST_SIS{}; // GST coming from W6 and W5 of SIS + uint32_t d_GST_PKR_PKREV_start{}; + uint32_t d_GST_PKR_AM_start{}; + uint32_t d_GST_chain_renewal_start{}; + uint32_t d_GST_chain_revocation_start{}; + + uint32_t d_count_successful_tags{0}; + uint32_t d_count_failed_tags{0}; + uint32_t d_count_failed_Kroot{0}; + uint32_t d_count_failed_pubKey{0}; // failed public key verifications against Merkle root + uint32_t d_count_failed_macseq{0}; + + uint8_t const d_T_L{30}; // s RG Section 2.1 + uint8_t d_new_public_key_id{}; + + bool d_new_data{false}; + bool d_public_key_verified{false}; + bool d_kroot_verified{false}; + bool d_tesla_key_verified{false}; + bool d_strict_mode{false}; + bool d_flag_hot_start{false}; + bool d_flag_PK_renewal{false}; + bool d_flag_PK_revocation{false}; + bool d_flag_NPK_set{false}; + bool d_flag_alert_message{false}; + bool d_flag_chain_renewal{false}; + bool d_flag_chain_revocation{false}; + + // Provide access to inner functions to Gtest + FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification); + FRIEND_TEST(OsnmaMsgReceiverTest, TagVerification); + FRIEND_TEST(OsnmaMsgReceiverTest, BuildTagMessageM0); + FRIEND_TEST(OsnmaMsgReceiverTest, VerifyPublicKey); + FRIEND_TEST(OsnmaMsgReceiverTest, ComputeBaseLeaf); + FRIEND_TEST(OsnmaMsgReceiverTest, ComputeMerkleRoot); + FRIEND_TEST(OsnmaTestVectors, NominalTestConf1); + FRIEND_TEST(OsnmaTestVectors, NominalTestConf2); + FRIEND_TEST(OsnmaTestVectors, PublicKeyRenewal); + FRIEND_TEST(OsnmaTestVectors, PublicKeyRevocation); + FRIEND_TEST(OsnmaTestVectors, ChainRenewal); + FRIEND_TEST(OsnmaTestVectors, ChainRevocation); + FRIEND_TEST(OsnmaTestVectors, AlertMessage); +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_OSNMA_MSG_RECEIVER_H diff --git a/src/core/libs/osnma_nav_data_manager.cc b/src/core/libs/osnma_nav_data_manager.cc new file mode 100644 index 000000000..73392db5b --- /dev/null +++ b/src/core/libs/osnma_nav_data_manager.cc @@ -0,0 +1,322 @@ +/*! + * \file osnma_nav_data_manager.cc + * \brief Class for Galileo OSNMA navigation data management + * \author Cesare Ghionoiu-Martinez, 2020-2023 cesare.martinez(at)proton.me + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "osnma_nav_data_manager.h" +#if USE_GLOG_AND_GFLAGS +#include // for DLOG +#else +#include +#endif + +/** + * @brief Adds the navigation data bits to the container holding OSNMA_NavData objects. + * + * @param nav_bits The navigation bits. + * @param PRNd The satellite ID. + * @param TOW The TOW of the received data. + */ +void OSNMA_NavDataManager::add_navigation_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW) +{ + if (not have_nav_data(nav_bits, PRNd, TOW)) + { + d_satellite_nav_data[PRNd][TOW].add_nav_data(nav_bits); + d_satellite_nav_data[PRNd][TOW].set_prn_d(PRNd); + d_satellite_nav_data[PRNd][TOW].set_tow_sf0(TOW); + d_satellite_nav_data[PRNd][TOW].set_last_received_TOW(TOW); + } +} + + +/** + * @brief loops over the verified tags and updates the navigation data tag length + */ +void OSNMA_NavDataManager::update_nav_data(const std::multimap& tags_verified, uint8_t tag_size) +{ + if (d_satellite_nav_data.empty()) + { + return; + } + // loop through all tags + for (const auto& tag : tags_verified) + { + // if tag status is verified, look for corresponding OSNMA_NavData and add increase verified tag bits. + if (tag.second.status == Tag::e_verification_status::SUCCESS) + { + auto sat_it = d_satellite_nav_data.find(tag.second.PRN_d); + if (sat_it == d_satellite_nav_data.end()) + { + continue; + } + auto& tow_map = sat_it->second; + for (auto& tow_it : tow_map) // note: starts with smallest (i.e. oldest) navigation dataset + { + std::string nav_data; + if (tag.second.ADKD == 0 || tag.second.ADKD == 12) + { + nav_data = tow_it.second.get_ephemeris_data(); + } + else if (tag.second.ADKD == 4) + { + nav_data = tow_it.second.get_utc_data(); + } + // find associated OSNMA_NavData + if (tag.second.nav_data == nav_data) + { + d_satellite_nav_data[tag.second.PRN_d][tow_it.first].set_update_verified_bits(tag_size); + } + } + } + } +} + + +std::vector OSNMA_NavDataManager::get_verified_data() +{ + std::vector result; + for (const auto& prna : d_satellite_nav_data) + { + for (const auto& tow_navdata : prna.second) + { + if (tow_navdata.second.get_verified_bits() >= L_t_min) + { + result.push_back(tow_navdata.second); + d_satellite_nav_data[prna.first][tow_navdata.first].set_verified_status(true); + } + } + } + return result; +} + + +bool OSNMA_NavDataManager::have_nav_data(uint32_t PRNd, uint32_t TOW, uint8_t ADKD) const +{ + const auto sat_it = d_satellite_nav_data.find(PRNd); + if (sat_it == d_satellite_nav_data.cend()) + { + return false; + } + + const auto tow_it = sat_it->second.find(TOW); + if (tow_it == sat_it->second.cend()) + { + return false; + } + + switch (ADKD) + { + case 0: + case 12: + return !tow_it->second.get_ephemeris_data().empty(); + case 4: + return !tow_it->second.get_utc_data().empty(); + default: + return false; + } +} + + +std::string OSNMA_NavDataManager::get_navigation_data(const Tag& tag) const +{ + // Check if Dummy Tag, navData is all zeros + if (tag.cop == 0) + { + if (tag.ADKD == 0 || tag.ADKD == 12) + { + return {std::string(549, '0')}; + } + else if (tag.ADKD == 4) + { + return {std::string(141, '0')}; + } + } + auto prn_it = d_satellite_nav_data.find(tag.PRN_d); + if (prn_it == d_satellite_nav_data.end()) + { + return ""; + } + // satellite was found, check if TOW exists in inner map + auto nav_data = prn_it->second.find(tag.TOW - 30); + if (nav_data != prn_it->second.end()) + { + if (tag.ADKD == 0 || tag.ADKD == 12) + { + if (!nav_data->second.get_ephemeris_data().empty()) + { + return nav_data->second.get_ephemeris_data(); + } + } + else if (tag.ADKD == 4) + { + if (!nav_data->second.get_utc_data().empty()) + { + return nav_data->second.get_utc_data(); + } + } + } + else + { + for (auto rev_it = prn_it->second.rbegin(); rev_it != prn_it->second.rend(); ++rev_it) // NOLINT(modernize-loop-convert) + { + // note: starts with largest (i.e. newest) navigation dataset + // Check if current key (TOW) fulfills condition + if ((tag.TOW - 30 * tag.cop <= rev_it->first || tag.TOW - 30 * tag.cop <= rev_it->second.get_last_received_TOW()) && rev_it->first < tag.TOW) + { + if (tag.ADKD == 0 || tag.ADKD == 12) + { + if (!rev_it->second.get_ephemeris_data().empty()) + { + return rev_it->second.get_ephemeris_data(); + } + } + else if (tag.ADKD == 4) + { + if (!rev_it->second.get_utc_data().empty()) + { + return rev_it->second.get_utc_data(); + } + } + } + } + } + return ""; +} + + +/** + * @brief Checks if the OSNMA_NavData bits are already present. In case affirmative, it updates the OSNMA_NavData 'last received' timestamp + * @remarks e.g.: a SV may repeat the bits over several subframes. In that case, need to save them only once. + * @param nav_bits + * @param PRNd + * @return + */ +bool OSNMA_NavDataManager::have_nav_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW) +{ + if (d_satellite_nav_data.find(PRNd) != d_satellite_nav_data.end()) + { + for (auto& data_timestamp : d_satellite_nav_data[PRNd]) + { + if (nav_bits.size() == EPH_SIZE) + { + if (data_timestamp.second.get_ephemeris_data() == nav_bits) + { + data_timestamp.second.set_last_received_TOW(TOW); + return true; + } + } + else if (nav_bits.size() == UTC_SIZE) + { + if (data_timestamp.second.get_utc_data() == nav_bits) + { + data_timestamp.second.set_last_received_TOW(TOW); + return true; + } + } + } + } + return false; +} + + +/** + * @brief Checks if there is a OSNMA_NavData element within the COP time interval for a Tag t + * @param t Tag object + * @return True if the needed navigation data for the tag is available (oldest possible OSNMA_NavData available) + */ +bool OSNMA_NavDataManager::have_nav_data(const Tag& t) const +{ + if (t.cop == 0) + { + return true; + } + auto prn_it = d_satellite_nav_data.find(t.PRN_d); + if (prn_it == d_satellite_nav_data.end()) + { + return false; + } + // satellite was found, check if TOW exists in inner map + // try find target TOW directly first + auto nav_data = prn_it->second.find(t.TOW - 30); + if (nav_data != prn_it->second.end()) + { + if (t.ADKD == 0 || t.ADKD == 12) + { + if (!nav_data->second.get_ephemeris_data().empty()) + { + return true; + } + } + else if (t.ADKD == 4) + { + if (!nav_data->second.get_utc_data().empty()) + { + return true; + } + } + } + else + { + // iterate in reverse order to find matching TOW with Tag's COP value + std::map tow_map = prn_it->second; + for (auto rev_it = tow_map.rbegin(); rev_it != tow_map.rend(); ++rev_it) // NOLINT(modernize-loop-convert) + { + // note: starts with largest (i.e. newest) navigation dataset + // Check if current key (TOW) fulfills cut-off point and is not received after the tag + if ((t.TOW - 30 * t.cop <= rev_it->first || t.TOW - 30 * t.cop <= rev_it->second.get_last_received_TOW()) && rev_it->first < t.TOW) + { + if (t.ADKD == 0 || t.ADKD == 12) + { + if (!rev_it->second.get_ephemeris_data().empty()) + { + return true; + } + } + else if (t.ADKD == 4) + { + if (!rev_it->second.get_utc_data().empty()) + { + return true; + } + } + } + } + } + return false; +} + + +void OSNMA_NavDataManager::log_status() const +{ + for (const auto& satellite : d_satellite_nav_data) + { + LOG(INFO) << "Galileo OSNMA: NavData status :: SVID=" << satellite.first; + const auto& tow_data = satellite.second; + for (const auto& nav_data : tow_data) + { + LOG(INFO) << "Galileo OSNMA: IOD_nav=0b" << std::uppercase + << std::bitset<10>(nav_data.second.get_IOD_nav()) + << ", TOW_start=" + << nav_data.second.get_tow_sf0() + << ", TOW_last=" + << nav_data.second.get_last_received_TOW() + << ", l_t=" + << nav_data.second.get_verified_bits() + << ", PRNd=" + << nav_data.second.get_prn_d() + << ", verified=" + << nav_data.second.get_verified_status(); + } + } +} diff --git a/src/core/libs/osnma_nav_data_manager.h b/src/core/libs/osnma_nav_data_manager.h new file mode 100644 index 000000000..6beaa907d --- /dev/null +++ b/src/core/libs/osnma_nav_data_manager.h @@ -0,0 +1,59 @@ +/*! + * \file osnma_nav_data_manager.h + * \brief Class for Galileo OSNMA navigation data management + * \author Cesare Ghionoiu-Martinez, 2020-2023 cesare.martinez(at)proton.me + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_OSNMA_NAV_DATA_MANAGER_H +#define GNSS_SDR_OSNMA_NAV_DATA_MANAGER_H + +#include "osnma_data.h" // for OSNMA_NavData, Tag +#include // for uint32_t +#include +#include +#include + +/** \addtogroup Core + * \{ */ +/** \addtogroup Core_Receiver_Library + * \{ */ + +/** + * @class OSNMA_NavDataManager + * @brief Class for managing OSNMA navigation data + */ +class OSNMA_NavDataManager +{ +public: + OSNMA_NavDataManager() = default; + + void log_status() const; + bool have_nav_data(const Tag& t) const; + bool have_nav_data(uint32_t PRNd, uint32_t TOW, uint8_t ADKD) const; + std::string get_navigation_data(const Tag& t) const; + + void add_navigation_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW); + void update_nav_data(const std::multimap& tags_verified, uint8_t tag_size); + bool have_nav_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW); + std::vector get_verified_data(); + +private: + std::map> d_satellite_nav_data{}; // NavData sorted by [PRNd][TOW_start] + const uint32_t L_t_min{40}; + const uint16_t EPH_SIZE{549}; + const uint16_t UTC_SIZE{141}; +}; + +/** \} */ +/** \} */ +#endif // GNSS_SDR_OSNMA_NAV_DATA_MANAGER_H diff --git a/src/core/libs/supl/CMakeLists.txt b/src/core/libs/supl/CMakeLists.txt index a08631e91..78ab2b80e 100644 --- a/src/core/libs/supl/CMakeLists.txt +++ b/src/core/libs/supl/CMakeLists.txt @@ -46,15 +46,9 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU" AND (CMAKE_VERSION VERSION_GREATER "3 target_compile_options(core_libs_supl PUBLIC $<$:${MY_C_FLAGS}>) endif() -if(OPENSSL_FOUND) - target_compile_definitions(core_libs_supl PUBLIC -DUSE_OPENSSL_FALLBACK=1) -endif() - -target_link_libraries(core_libs_supl - PUBLIC - ${GNUTLS_LIBRARIES} - ${GNUTLS_OPENSSL_LIBRARY} -) +# links to the appropriate library and defines +# USE_GNUTLS_FALLBACK, USE_OPENSSL_3, or USE_OPENSSL_111 accordingly. +link_to_crypto_dependencies(core_libs_supl) target_include_directories(core_libs_supl PUBLIC diff --git a/src/core/libs/supl/asn-rrlp/converter-sample.c b/src/core/libs/supl/asn-rrlp/converter-sample.c index 5723cb1d2..bfed937c9 100644 --- a/src/core/libs/supl/asn-rrlp/converter-sample.c +++ b/src/core/libs/supl/asn-rrlp/converter-sample.c @@ -721,8 +721,8 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, rval.consumed = 0; for (tolerate_eof = 1; /* Allow EOF first time buffer is non-empty */ - (rd = fread(fbuf, 1, fbuf_size, file)) || feof(file) == 0 || - (tolerate_eof && DynamicBuffer.length);) + (rd = fread(fbuf, 1, fbuf_size, file)) || feof(file) == 0 || + (tolerate_eof && DynamicBuffer.length);) { int ecbits = 0; /* Extra consumed bits in case of PER */ uint8_t *i_bptr; diff --git a/src/core/libs/supl/asn-supl/GeneralizedTime.c b/src/core/libs/supl/asn-supl/GeneralizedTime.c index 235a215a2..54a2eb5fa 100644 --- a/src/core/libs/supl/asn-supl/GeneralizedTime.c +++ b/src/core/libs/supl/asn-supl/GeneralizedTime.c @@ -147,8 +147,7 @@ static long GMTOFF(struct tm a) } \ while (0); \ } \ - while (0) \ - ; + while (0); #ifdef _EMULATE_TIMEGM static time_t timegm(struct tm *tm) @@ -428,21 +427,21 @@ time_t asn_GT2time_frac(const GeneralizedTime_t *st, int *frac_value, memset(&tm_s, 0, sizeof(tm_s)); #undef B2F #undef B2T -#define B2F(var) \ - do \ - { \ - unsigned ch = *buf; \ - if (ch < 0x30 || ch > 0x39) \ - { \ - errno = EINVAL; \ - return -1; \ - } \ - else \ - { \ - (var) = (var)*10 + (ch - 0x30); \ - buf++; \ - } \ - } \ +#define B2F(var) \ + do \ + { \ + unsigned ch = *buf; \ + if (ch < 0x30 || ch > 0x39) \ + { \ + errno = EINVAL; \ + return -1; \ + } \ + else \ + { \ + (var) = (var) * 10 + (ch - 0x30); \ + buf++; \ + } \ + } \ while (0) #define B2T(var) B2F(tm_s.var) diff --git a/src/core/libs/supl/supl.h b/src/core/libs/supl/supl.h index c879112f6..8c9bef533 100644 --- a/src/core/libs/supl/supl.h +++ b/src/core/libs/supl/supl.h @@ -24,18 +24,18 @@ #define EXPORT #endif // clang-format off -#if USE_OPENSSL_FALLBACK -#include -#include -#include -#include -#include -#else +#if USE_GNUTLS_FALLBACK #include #include #include #include #include +#else +#include +#include +#include +#include +#include #endif // clang-format on #include diff --git a/src/core/libs/supl/types/INTEGER.c b/src/core/libs/supl/types/INTEGER.c index 86d014599..c8d0291d2 100644 --- a/src/core/libs/supl/types/INTEGER.c +++ b/src/core/libs/supl/types/INTEGER.c @@ -294,7 +294,7 @@ static int INTEGER__compar_enum2value(const void *kp, const void *am) /* Compare strings */ for (ptr = key->start, end = key->stop, name = el->enum_name; ptr < end; - ptr++, name++) + ptr++, name++) { if (*ptr != *name) { diff --git a/src/core/libs/supl/types/OCTET_STRING.c b/src/core/libs/supl/types/OCTET_STRING.c index 140ecc5ad..1866de1ef 100644 --- a/src/core/libs/supl/types/OCTET_STRING.c +++ b/src/core/libs/supl/types/OCTET_STRING.c @@ -775,10 +775,9 @@ static struct OCTET_STRING__xer_escape_table_s char *string; int size; } OCTET_STRING__xer_escape_table[] = { -#define OSXET(s) \ - { \ - s, sizeof(s) - 1 \ - } +#define OSXET(s) \ + { \ + s, sizeof(s) - 1} OSXET("\074\156\165\154\057\076"), /* */ OSXET("\074\163\157\150\057\076"), /* */ OSXET("\074\163\164\170\057\076"), /* */ diff --git a/src/core/libs/supl/types/asn_internal.h b/src/core/libs/supl/types/asn_internal.h index 20edeab1a..8f921edd1 100644 --- a/src/core/libs/supl/types/asn_internal.h +++ b/src/core/libs/supl/types/asn_internal.h @@ -19,7 +19,7 @@ extern "C" { #endif -// clang-format off + // clang-format off /* Environment version might be used to avoid running with the old library */ #define ASN1C_ENVIRONMENT_VERSION 922 /* Compile-time version */ int get_asn1c_environment_version(void); /* Run-time version */ diff --git a/src/core/libs/supl/types/asn_system.h b/src/core/libs/supl/types/asn_system.h index 0b462b6eb..a6fa3ef8d 100644 --- a/src/core/libs/supl/types/asn_system.h +++ b/src/core/libs/supl/types/asn_system.h @@ -29,7 +29,7 @@ /* To avoid linking with ws2_32.lib, here's the definition of ntohl() */ #define sys_ntohl(l) \ ((((l) << 24) & 0xff000000) | (((l) << 16) & 0xff0000) | \ - (((l) << 8) & 0xff00) | ((l)&0xff)) + (((l) << 8) & 0xff00) | ((l) & 0xff)) #ifdef _MSC_VER /* MSVS.Net */ #ifndef __cplusplus diff --git a/src/core/libs/supl/types/ber_tlv_length.c b/src/core/libs/supl/types/ber_tlv_length.c index 3d2d79be2..547ccef2c 100644 --- a/src/core/libs/supl/types/ber_tlv_length.c +++ b/src/core/libs/supl/types/ber_tlv_length.c @@ -45,7 +45,7 @@ ssize_t ber_fetch_length(int _is_constructed, const void *bufptr, size_t size, oct &= 0x7F; /* Leave only the 7 LS bits */ for (len = 0, buf++, skipped = 1; oct && (++skipped <= size); - buf++, oct--) + buf++, oct--) { len = (len << 8) | *buf; if (len < 0 || (len >> ((8 * sizeof(len)) - 8) && oct > 1)) diff --git a/src/core/libs/supl/types/ber_tlv_tag.c b/src/core/libs/supl/types/ber_tlv_tag.c index 47ac813df..154975f14 100644 --- a/src/core/libs/supl/types/ber_tlv_tag.c +++ b/src/core/libs/supl/types/ber_tlv_tag.c @@ -34,7 +34,7 @@ ssize_t ber_fetch_tag(const void *ptr, size_t size, ber_tlv_tag_t *tag_r) * The MSB is 0 if it is the last octet of the tag. */ for (val = 0, ptr = ((const char *)ptr) + 1, skipped = 2; skipped <= size; - ptr = ((const char *)ptr) + 1, skipped++) + ptr = ((const char *)ptr) + 1, skipped++) { unsigned int oct = *(const uint8_t *)ptr; if (oct & 0x80) diff --git a/src/core/libs/supl/types/ber_tlv_tag.h b/src/core/libs/supl/types/ber_tlv_tag.h index fc0208c3e..25614de23 100644 --- a/src/core/libs/supl/types/ber_tlv_tag.h +++ b/src/core/libs/supl/types/ber_tlv_tag.h @@ -22,7 +22,7 @@ extern "C" /* * Tag class is encoded together with tag value for optimization purposes. */ -#define BER_TAG_CLASS(tag) ((tag)&0x3) +#define BER_TAG_CLASS(tag) ((tag) & 0x3) #define BER_TAG_VALUE(tag) ((tag) >> 2) #define BER_TLV_CONSTRUCTED(tagptr) \ (((*(const uint8_t *)tagptr) & 0x20) ? 1 : 0) diff --git a/src/core/libs/supl/types/constr_SEQUENCE.c b/src/core/libs/supl/types/constr_SEQUENCE.c index 62101bc55..1c64bc773 100644 --- a/src/core/libs/supl/types/constr_SEQUENCE.c +++ b/src/core/libs/supl/types/constr_SEQUENCE.c @@ -216,7 +216,7 @@ asn_dec_rval_t SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, * step = ( * 2 + ). */ for (edx = (ctx->step >> 1); edx < td->elements_count; - edx++, ctx->step = (ctx->step & ~1) + 2) + edx++, ctx->step = (ctx->step & ~1) + 2) { void *memb_ptr; /* Pointer to the member */ void **memb_ptr2; /* Pointer to that pointer */ @@ -1518,7 +1518,7 @@ asn_dec_rval_t SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, /* Fill DEFAULT members in extensions */ for (edx = specs->roms_count; edx < specs->roms_count + specs->aoms_count; - edx++) + edx++) { asn_TYPE_member_t *elm = &td->elements[edx]; void **memb_ptr2; /* Pointer to member pointer */ @@ -1700,7 +1700,7 @@ asn_enc_rval_t SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td, td->elements_count, specs->ext_before); for (edx = 0; edx < ((specs->ext_after < 0) ? td->elements_count : specs->ext_before - 1); - edx++) + edx++) { asn_TYPE_member_t *elm = &td->elements[edx]; void *memb_ptr; /* Pointer to the member */ diff --git a/src/core/libs/supl/types/xer_support.c b/src/core/libs/supl/types/xer_support.c index e920bfabc..23375eb33 100644 --- a/src/core/libs/supl/types/xer_support.c +++ b/src/core/libs/supl/types/xer_support.c @@ -248,7 +248,7 @@ ssize_t pxml_parse(int *stateContext, const void *xmlbuf, size_t size, } break; } /* switch(*ptr) */ - } /* for() */ + } /* for() */ /* * Flush the partially processed chunk, state permitting. diff --git a/src/core/monitor/CMakeLists.txt b/src/core/monitor/CMakeLists.txt index cfd2cdab3..8ac8045d1 100644 --- a/src/core/monitor/CMakeLists.txt +++ b/src/core/monitor/CMakeLists.txt @@ -97,6 +97,14 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif() endif() +# Fix for Boost Asio > 1.86. address::from_string was deprecated in Boost 1.71 +if(Boost_VERSION_STRING VERSION_LESS 1.71.0) + target_compile_definitions(core_monitor + PRIVATE + -DBOOST_ASIO_USE_FROM_STRING=1 + ) +endif() + set_property(TARGET core_monitor APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $ diff --git a/src/core/monitor/gnss_synchro_monitor.cc b/src/core/monitor/gnss_synchro_monitor.cc index 502a5ed48..f63811a73 100644 --- a/src/core/monitor/gnss_synchro_monitor.cc +++ b/src/core/monitor/gnss_synchro_monitor.cc @@ -26,30 +26,30 @@ gnss_synchro_monitor_sptr gnss_synchro_make_monitor(int n_channels, int decimation_factor, - int udp_port, + const std::vector& udp_ports, const std::vector& udp_addresses, bool enable_protobuf) { return gnss_synchro_monitor_sptr(new gnss_synchro_monitor(n_channels, decimation_factor, - udp_port, + udp_ports, udp_addresses, enable_protobuf)); } - gnss_synchro_monitor::gnss_synchro_monitor(int n_channels, int decimation_factor, - int udp_port, + const std::vector& udp_ports, const std::vector& udp_addresses, bool enable_protobuf) : gr::block("gnss_synchro_monitor", gr::io_signature::make(n_channels, n_channels, sizeof(Gnss_Synchro)), gr::io_signature::make(0, 0, 0)), + count(0), d_nchannels(n_channels), d_decimation_factor(decimation_factor) { - udp_sink_ptr = std::make_unique(udp_addresses, udp_port, enable_protobuf); + udp_sink_ptr = std::make_unique(udp_addresses, udp_ports, enable_protobuf); } @@ -73,7 +73,6 @@ int gnss_synchro_monitor::general_work(int noutput_items __attribute__((unused)) for (int channel_index = 0; channel_index < d_nchannels; channel_index++) { // Loop through each item in each input stream channel - int count = 0; for (int item_index = 0; item_index < ninput_items[channel_index]; item_index++) { // Use the count variable to limit how many items are sent per channel diff --git a/src/core/monitor/gnss_synchro_monitor.h b/src/core/monitor/gnss_synchro_monitor.h index b45b7cc5b..4edd012e1 100644 --- a/src/core/monitor/gnss_synchro_monitor.h +++ b/src/core/monitor/gnss_synchro_monitor.h @@ -41,7 +41,7 @@ using gnss_synchro_monitor_sptr = gnss_shared_ptr; gnss_synchro_monitor_sptr gnss_synchro_make_monitor(int n_channels, int decimation_factor, - int udp_port, + const std::vector& udp_ports, const std::vector& udp_addresses, bool enable_protobuf); @@ -61,19 +61,20 @@ public: private: friend gnss_synchro_monitor_sptr gnss_synchro_make_monitor(int n_channels, int decimation_factor, - int udp_port, + const std::vector& udp_ports, const std::vector& udp_addresses, bool enable_protobuf); gnss_synchro_monitor(int n_channels, int decimation_factor, - int udp_port, + const std::vector& udp_ports, const std::vector& udp_addresses, bool enable_protobuf); + std::unique_ptr udp_sink_ptr; + int count; int d_nchannels; int d_decimation_factor; - std::unique_ptr udp_sink_ptr; }; diff --git a/src/core/monitor/gnss_synchro_udp_sink.cc b/src/core/monitor/gnss_synchro_udp_sink.cc index 84d484385..3f9e6a1d1 100644 --- a/src/core/monitor/gnss_synchro_udp_sink.cc +++ b/src/core/monitor/gnss_synchro_udp_sink.cc @@ -17,12 +17,14 @@ #include "gnss_synchro_udp_sink.h" #include +#include #include #include #include -Gnss_Synchro_Udp_Sink::Gnss_Synchro_Udp_Sink(const std::vector& addresses, - const uint16_t& port, +Gnss_Synchro_Udp_Sink::Gnss_Synchro_Udp_Sink( + const std::vector& addresses, + const std::vector& ports, bool enable_protobuf) : socket{io_context}, use_protobuf(enable_protobuf) @@ -33,8 +35,17 @@ Gnss_Synchro_Udp_Sink::Gnss_Synchro_Udp_Sink(const std::vector& add } for (const auto& address : addresses) { - boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port); - endpoints.push_back(endpoint); + for (const auto& port : ports) + { + boost::asio::ip::udp::endpoint endpoint( +#if BOOST_ASIO_USE_FROM_STRING + boost::asio::ip::address::from_string(address, error), +#else + boost::asio::ip::make_address(address, error), +#endif + boost::lexical_cast(port)); + endpoints.push_back(endpoint); + } } } @@ -53,22 +64,24 @@ bool Gnss_Synchro_Udp_Sink::write_gnss_synchro(const std::vector& { outbound_data = serdes.createProtobuffer(stocks); } - for (const auto& endpoint : endpoints) - { - socket.open(endpoint.protocol(), error); - try + try + { + for (const auto& endpoint : endpoints) { - if (socket.send_to(boost::asio::buffer(outbound_data), endpoint) == 0) + socket.open(endpoint.protocol(), error); // NOLINT(bugprone-unused-return-value) + + if (socket.send_to(boost::asio::buffer(outbound_data), endpoint) == 0) // this can throw { - std::cerr << "Gnss_Synchro_Udp_Sink sent 0 bytes\n"; + return false; } } - catch (boost::system::system_error const& e) - { - std::cerr << e.what() << '\n'; - return false; - } } + catch (const boost::system::system_error& e) + { + std::cerr << "Error sending data: " << e.what() << '\n'; + return false; + } + return true; } diff --git a/src/core/monitor/gnss_synchro_udp_sink.h b/src/core/monitor/gnss_synchro_udp_sink.h index cf777cc12..699a6043f 100644 --- a/src/core/monitor/gnss_synchro_udp_sink.h +++ b/src/core/monitor/gnss_synchro_udp_sink.h @@ -45,7 +45,7 @@ using b_io_context = boost::asio::io_service; class Gnss_Synchro_Udp_Sink { public: - Gnss_Synchro_Udp_Sink(const std::vector& addresses, const uint16_t& port, bool enable_protobuf); + Gnss_Synchro_Udp_Sink(const std::vector& addresses, const std::vector& ports, bool enable_protobuf); bool write_gnss_synchro(const std::vector& stocks); private: diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index 418ee72ab..dde1ba039 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -70,6 +70,10 @@ if(ENABLE_FPGA) target_compile_definitions(core_receiver PUBLIC -DENABLE_FPGA=1) endif() +if(ENABLE_ION) + target_compile_definitions(core_receiver PRIVATE -DENABLE_ION_SOURCE=1) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(core_receiver PUBLIC -DGNURADIO_USES_STD_POINTERS=1) endif() @@ -90,6 +94,10 @@ if(ENABLE_PLUTOSDR) target_compile_definitions(core_receiver PRIVATE -DPLUTOSDR_DRIVER=1) endif() +if(ENABLE_AD936X_SDR) + target_compile_definitions(core_receiver PRIVATE -DAD936X_SDR_DRIVER=1) +endif() + if(ENABLE_FMCOMMS2) target_compile_definitions(core_receiver PRIVATE -DFMCOMMS2_DRIVER=1) endif() @@ -98,6 +106,14 @@ if(ENABLE_AD9361) target_compile_definitions(core_receiver PRIVATE -DAD9361_DRIVER=1) endif() +if(ENABLE_MAX2771) + target_compile_definitions(core_receiver PRIVATE -DMAX2771_DRIVER=1) +endif() + +if(ENABLE_DMA_PROXY) + target_compile_definitions(core_receiver PRIVATE -DDMA_PROXY_DRIVER=1) +endif() + if(ENABLE_OSMOSDR) if(GROSMOSDR_FOUND) target_compile_definitions(core_receiver PRIVATE -DOSMOSDR_DRIVER=1) @@ -172,12 +188,25 @@ target_link_libraries(core_receiver telemetry_decoder_adapters obs_adapters pvt_adapters + gnss_sdr_flags Boost::headers - Gflags::gflags - Glog::glog Armadillo::armadillo ) +if(NOT HAVE_SHM_OPEN) + find_library(LIBRT_LIBRARY rt) + if(LIBRT_LIBRARY) + target_link_libraries(core_receiver PRIVATE ${LIBRT_LIBRARY}) + endif() +endif() + +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(core_receiver PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(core_receiver PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(core_receiver PRIVATE absl::flags absl::log) +endif() + if(ENABLE_ARMA_NO_DEBUG) target_compile_definitions(core_receiver PRIVATE -DARMA_NO_BOUND_CHECKING=1 diff --git a/src/core/receiver/concurrent_map.h b/src/core/receiver/concurrent_map.h index 330ab02ef..d16a963d7 100644 --- a/src/core/receiver/concurrent_map.h +++ b/src/core/receiver/concurrent_map.h @@ -36,52 +36,48 @@ template */ class Concurrent_Map { - typedef typename std::map::iterator Data_iterator; // iterator is scope dependent public: void write(int key, Data const& data) { - std::unique_lock lock(the_mutex); - Data_iterator data_iter; - data_iter = the_map.find(key); + std::lock_guard lock(the_mutex); + auto data_iter = the_map.find(key); if (data_iter != the_map.end()) { data_iter->second = data; // update } else { - the_map.insert(std::pair(key, data)); // insert SILENTLY fails if the item already exists in the map! + the_map.insert(std::pair(key, data)); // insert does not overwrite if the item already exists in the map! } - lock.unlock(); } - std::map get_map_copy() + std::map get_map_copy() const& { - std::unique_lock lock(the_mutex); - std::map map_aux = the_map; - lock.unlock(); - return map_aux; + std::lock_guard lock(the_mutex); + return the_map; // This implicitly creates a copy } - size_t size() + std::map get_map_copy() && { - std::unique_lock lock(the_mutex); - size_t size_ = the_map.size(); - lock.unlock(); - return size_; + std::lock_guard lock(the_mutex); + return std::move(the_map); } - bool read(int key, Data& p_data) + size_t size() const { - std::unique_lock lock(the_mutex); - Data_iterator data_iter; - data_iter = the_map.find(key); + std::lock_guard lock(the_mutex); + return the_map.size(); + } + + bool read(int key, Data& p_data) const + { + std::lock_guard lock(the_mutex); + auto data_iter = the_map.find(key); if (data_iter != the_map.end()) { p_data = data_iter->second; - lock.unlock(); return true; } - lock.unlock(); return false; } diff --git a/src/core/receiver/concurrent_queue.h b/src/core/receiver/concurrent_queue.h index ac7be0f17..ed4e68b0a 100644 --- a/src/core/receiver/concurrent_queue.h +++ b/src/core/receiver/concurrent_queue.h @@ -19,9 +19,10 @@ #include #include +#include #include #include -#include +#include /** \addtogroup Core * \{ */ @@ -33,48 +34,53 @@ template /*! * \brief This class implements a thread-safe std::queue - * - * Thread-safe object queue which uses the library - * boost_thread to perform MUTEX based on the code available at - * https://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html */ class Concurrent_Queue { public: - void push(Data const& data) + void push(const Data& data) { - std::unique_lock lock(the_mutex); - the_queue.push(data); - lock.unlock(); + { + std::lock_guard lock(the_mutex); + the_queue.push(data); + } the_condition_variable.notify_one(); } - bool empty() const + void push(Data&& data) { - std::unique_lock lock(the_mutex); - return the_queue.empty(); + { + std::lock_guard lock(the_mutex); + the_queue.push(std::move(data)); + } + the_condition_variable.notify_one(); } - size_t size() const + bool empty() const noexcept { - std::unique_lock lock(the_mutex); + return size() == 0; + } + + size_t size() const noexcept + { + std::lock_guard lock(the_mutex); return the_queue.size(); } void clear() { - std::unique_lock lock(the_mutex); - the_queue = std::queue(); + std::lock_guard lock(the_mutex); + std::queue().swap(the_queue); } bool try_pop(Data& popped_value) { - std::unique_lock lock(the_mutex); + std::lock_guard lock(the_mutex); if (the_queue.empty()) { return false; } - popped_value = the_queue.front(); + popped_value = std::move(the_queue.front()); the_queue.pop(); return true; } @@ -82,26 +88,21 @@ public: void wait_and_pop(Data& popped_value) { std::unique_lock lock(the_mutex); - while (the_queue.empty()) - { - the_condition_variable.wait(lock); - } - popped_value = the_queue.front(); + the_condition_variable.wait(lock, [this] { return !the_queue.empty(); }); + popped_value = std::move(the_queue.front()); the_queue.pop(); } bool timed_wait_and_pop(Data& popped_value, int wait_ms) { std::unique_lock lock(the_mutex); - if (the_queue.empty()) + if (!the_condition_variable.wait_for(lock, + std::chrono::milliseconds(wait_ms), + [this] { return !the_queue.empty(); })) { - the_condition_variable.wait_for(lock, std::chrono::milliseconds(wait_ms)); - if (the_queue.empty()) - { - return false; - } + return false; } - popped_value = the_queue.front(); + popped_value = std::move(the_queue.front()); the_queue.pop(); return true; } diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index a6791fd52..9a265254d 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -36,35 +36,40 @@ #include "gnss_flowgraph.h" #include "gnss_satellite.h" #include "gnss_sdr_flags.h" -#include "gps_acq_assist.h" // for Gps_Acq_Assist -#include "gps_almanac.h" // for Gps_Almanac -#include "gps_cnav_ephemeris.h" // for Gps_CNAV_Ephemeris -#include "gps_cnav_utc_model.h" // for Gps_CNAV_Utc_Model -#include "gps_ephemeris.h" // for Gps_Ephemeris -#include "gps_iono.h" // for Gps_Iono -#include "gps_utc_model.h" // for Gps_Utc_Model -#include "pvt_interface.h" // for PvtInterface -#include "rtklib.h" // for gtime_t, alm_t -#include "rtklib_conversions.h" // for alm_to_rtklib -#include "rtklib_ephemeris.h" // for alm2pos, eph2pos -#include "rtklib_rtkcmn.h" // for utc2gpst -#include // for interaction with geofunctions -#include // for bad_lexical_cast -#include // for LOG -#include // for make_any -#include // for find, min -#include // for milliseconds -#include // for floor, fmod, log -#include // for signal, SIGINT -#include // for time_t, gmtime, strftime -#include // for exception -#include // for operator<< -#include // for numeric_limits -#include // for map -#include // for pthread_cancel -#include // for invalid_argument -#include // for IPC_CREAT -#include // for msgctl, msgget +#include "gnss_sdr_make_unique.h" +#include "gps_acq_assist.h" // for Gps_Acq_Assist +#include "gps_almanac.h" // for Gps_Almanac +#include "gps_cnav_ephemeris.h" // for Gps_CNAV_Ephemeris +#include "gps_cnav_utc_model.h" // for Gps_CNAV_Utc_Model +#include "gps_ephemeris.h" // for Gps_Ephemeris +#include "gps_iono.h" // for Gps_Iono +#include "gps_utc_model.h" // for Gps_Utc_Model +#include "pvt_interface.h" // for PvtInterface +#include "rtklib.h" // for gtime_t, alm_t +#include "rtklib_conversions.h" // for alm_to_rtklib +#include "rtklib_ephemeris.h" // for alm2pos, eph2pos +#include "rtklib_rtkcmn.h" // for utc2gpst +#include // for interaction with geofunctions +#include // for message_queue +#include // for bad_lexical_cast +#include // for make_any +#include // for find, min +#include // for milliseconds +#include // for floor, fmod, log +#include // for signal, SIGINT +#include // for time_t, gmtime, strftime +#include // for exception +#include // for operator<< +#include // for numeric_limits +#include // for map +#include // for pthread_cancel +#include // for invalid_argument + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif #ifdef ENABLE_FPGA #include // for steady_clock @@ -89,7 +94,7 @@ ControlThread::ControlThread() signal(SIGINT, ControlThread::handle_signal); signal(SIGTERM, ControlThread::handle_signal); signal(SIGHUP, ControlThread::handle_signal); - +#if USE_GLOG_AND_GFLAGS if (FLAGS_c == "-") { configuration_ = std::make_shared(FLAGS_config_file); @@ -98,6 +103,16 @@ ControlThread::ControlThread() { configuration_ = std::make_shared(FLAGS_c); } +#else + if (absl::GetFlag(FLAGS_c) == "-") + { + configuration_ = std::make_shared(absl::GetFlag(FLAGS_config_file)); + } + else + { + configuration_ = std::make_shared(absl::GetFlag(FLAGS_c)); + } +#endif // Basic configuration checks auto aux = std::dynamic_pointer_cast(configuration_); conf_file_has_section_ = aux->has_section(); @@ -182,7 +197,7 @@ void ControlThread::init() supl_mns_ = 0; supl_lac_ = 0; supl_ci_ = 0; - msqid_ = -1; + agnss_ref_location_ = Agnss_Ref_Location(); agnss_ref_time_ = Agnss_Ref_Time(); @@ -229,9 +244,7 @@ void ControlThread::init() else { // fill agnss_ref_time_ - struct tm tm - { - }; + struct tm tm{}; if (strptime(ref_time_str.c_str(), "%d/%m/%Y %H:%M:%S", &tm) != nullptr) { agnss_ref_time_.seconds = timegm(&tm); @@ -258,14 +271,11 @@ void ControlThread::init() ControlThread::~ControlThread() // NOLINT(modernize-use-equals-default) { DLOG(INFO) << "Control Thread destructor called"; - if (msqid_ != -1) - { - msgctl(msqid_, IPC_RMID, nullptr); - } + boost::interprocess::message_queue::remove(control_message_queue_name_.c_str()); - if (sysv_queue_thread_.joinable()) + if (message_queue_thread_.joinable()) { - sysv_queue_thread_.join(); + message_queue_thread_.join(); } if (cmd_interface_thread_.joinable()) @@ -405,12 +415,16 @@ int ControlThread::run() // launch GNSS assistance process AFTER the flowgraph is running because the GNU Radio asynchronous queues must be already running to transport msgs assist_GNSS(); - // start the keyboard_listener thread +// start the keyboard_listener thread +#if USE_GLOG_AND_GFLAGS if (FLAGS_keyboard) +#else + if (absl::GetFlag(FLAGS_keyboard)) +#endif { keyboard_thread_ = std::thread(&ControlThread::keyboard_listener, this); } - sysv_queue_thread_ = std::thread(&ControlThread::sysv_queue_listener, this); + message_queue_thread_ = std::thread(&ControlThread::message_queue_listener, this); // start the telecommand listener thread cmd_interface_.set_pvt(flowgraph_->get_pvt()); @@ -445,7 +459,11 @@ int ControlThread::run() #endif // Terminate keyboard thread +#if USE_GLOG_AND_GFLAGS if (FLAGS_keyboard && keyboard_thread_.joinable()) +#else + if (absl::GetFlag(FLAGS_keyboard) && keyboard_thread_.joinable()) +#endif { pthread_t id = keyboard_thread_.native_handle(); keyboard_thread_.detach(); @@ -540,8 +558,8 @@ bool ControlThread::read_assistance_from_XML() { std::map::const_iterator gps_eph_iter; for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); - gps_eph_iter++) + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); + gps_eph_iter++) { std::cout << "From XML file: Read NAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_eph_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); @@ -570,8 +588,8 @@ bool ControlThread::read_assistance_from_XML() { std::map::const_iterator gps_alm_iter; for (gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.cbegin(); - gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); - gps_alm_iter++) + gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); + gps_alm_iter++) { std::cout << "From XML file: Read GPS almanac for satellite " << Gnss_Satellite("GPS", gps_alm_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(gps_alm_iter->second); @@ -588,8 +606,8 @@ bool ControlThread::read_assistance_from_XML() { std::map::const_iterator gal_eph_iter; for (gal_eph_iter = supl_client_ephemeris_.gal_ephemeris_map.cbegin(); - gal_eph_iter != supl_client_ephemeris_.gal_ephemeris_map.cend(); - gal_eph_iter++) + gal_eph_iter != supl_client_ephemeris_.gal_ephemeris_map.cend(); + gal_eph_iter++) { std::cout << "From XML file: Read ephemeris for satellite " << Gnss_Satellite("Galileo", gal_eph_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(gal_eph_iter->second); @@ -618,8 +636,8 @@ bool ControlThread::read_assistance_from_XML() { std::map::const_iterator gal_alm_iter; for (gal_alm_iter = supl_client_ephemeris_.gal_almanac_map.cbegin(); - gal_alm_iter != supl_client_ephemeris_.gal_almanac_map.cend(); - gal_alm_iter++) + gal_alm_iter != supl_client_ephemeris_.gal_almanac_map.cend(); + gal_alm_iter++) { std::cout << "From XML file: Read Galileo almanac for satellite " << Gnss_Satellite("Galileo", gal_alm_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(gal_alm_iter->second); @@ -635,8 +653,8 @@ bool ControlThread::read_assistance_from_XML() { std::map::const_iterator gps_cnav_eph_iter; for (gps_cnav_eph_iter = supl_client_ephemeris_.gps_cnav_ephemeris_map.cbegin(); - gps_cnav_eph_iter != supl_client_ephemeris_.gps_cnav_ephemeris_map.cend(); - gps_cnav_eph_iter++) + gps_cnav_eph_iter != supl_client_ephemeris_.gps_cnav_ephemeris_map.cend(); + gps_cnav_eph_iter++) { std::cout << "From XML file: Read CNAV ephemeris for satellite " << Gnss_Satellite("GPS", gps_cnav_eph_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(gps_cnav_eph_iter->second); @@ -660,8 +678,8 @@ bool ControlThread::read_assistance_from_XML() { std::map::const_iterator glo_gnav_eph_iter; for (glo_gnav_eph_iter = supl_client_ephemeris_.glonass_gnav_ephemeris_map.cbegin(); - glo_gnav_eph_iter != supl_client_ephemeris_.glonass_gnav_ephemeris_map.cend(); - glo_gnav_eph_iter++) + glo_gnav_eph_iter != supl_client_ephemeris_.glonass_gnav_ephemeris_map.cend(); + glo_gnav_eph_iter++) { std::cout << "From XML file: Read GLONASS GNAV ephemeris for satellite " << Gnss_Satellite("GLONASS", glo_gnav_eph_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(glo_gnav_eph_iter->second); @@ -789,8 +807,8 @@ void ControlThread::assist_GNSS() { std::map::const_iterator gps_eph_iter; for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); - gps_eph_iter++) + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); + gps_eph_iter++) { std::cout << "SUPL: Received ephemeris data for satellite " << Gnss_Satellite("GPS", gps_eph_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); @@ -826,8 +844,8 @@ void ControlThread::assist_GNSS() { std::map::const_iterator gps_alm_iter; for (gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.cbegin(); - gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); - gps_alm_iter++) + gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.cend(); + gps_alm_iter++) { std::cout << "SUPL: Received almanac data for satellite " << Gnss_Satellite("GPS", gps_alm_iter->second.PRN) << '\n'; const std::shared_ptr tmp_obj = std::make_shared(gps_alm_iter->second); @@ -880,8 +898,8 @@ void ControlThread::assist_GNSS() { std::map::const_iterator gps_acq_iter; for (gps_acq_iter = supl_client_acquisition_.gps_acq_map.cbegin(); - gps_acq_iter != supl_client_acquisition_.gps_acq_map.cend(); - gps_acq_iter++) + gps_acq_iter != supl_client_acquisition_.gps_acq_map.cend(); + gps_acq_iter++) { std::cout << "SUPL: Received acquisition assistance data for satellite " << Gnss_Satellite("GPS", gps_acq_iter->second.PRN) << '\n'; global_gps_acq_assist_map.write(gps_acq_iter->second.PRN, gps_acq_iter->second); @@ -1026,9 +1044,7 @@ std::vector> ControlThread::get_visible_sats(time std::vector visible_gps; std::vector visible_gal; const std::shared_ptr pvt_ptr = flowgraph_->get_pvt(); - struct tm tstruct - { - }; + struct tm tstruct{}; char buf[80]; tstruct = *gmtime(&rx_utc_time); strftime(buf, sizeof(buf), "%d/%m/%Y %H:%M:%S ", &tstruct); @@ -1191,40 +1207,55 @@ void ControlThread::gps_acq_assist_data_collector() const } -void ControlThread::sysv_queue_listener() +void ControlThread::message_queue_listener() { - typedef struct - { - long mtype; // NOLINT(google-runtime-int) required by SysV queue messaging - double stop_message; - } stop_msgbuf; - bool read_queue = true; - stop_msgbuf msg; double received_message = 0.0; - const int msgrcv_size = sizeof(msg.stop_message); - - const key_t key = 1102; - - if ((msqid_ = msgget(key, 0644 | IPC_CREAT)) == -1) + try { - std::cerr << "GNSS-SDR cannot create SysV message queues\n"; - read_queue = false; - } + // Remove any existing queue with the same name + boost::interprocess::message_queue::remove(control_message_queue_name_.c_str()); - while (read_queue && !stop_) - { - if (msgrcv(msqid_, &msg, msgrcv_size, 1, 0) != -1) + // Create a new message queue + auto mq = std::make_unique( + boost::interprocess::create_only, // Create a new queue + control_message_queue_name_.c_str(), // Queue name + 10, // Maximum number of messages + sizeof(double) // Maximum message size + ); + + while (read_queue && !stop_) { - received_message = msg.stop_message; - if ((std::abs(received_message - (-200.0)) < 10 * std::numeric_limits::epsilon())) + unsigned int priority; + std::size_t received_size; + // Receive a message (non-blocking) + if (mq->try_receive(&received_message, sizeof(received_message), received_size, priority)) { - std::cout << "Quit order received, stopping GNSS-SDR !!\n"; - control_queue_->push(pmt::make_any(command_event_make(200, 0))); - read_queue = false; + // Validate the size of the received message + if (received_size == sizeof(double)) + { + if (std::abs(received_message - (-200.0)) < 10 * std::numeric_limits::epsilon()) + { + std::cout << "Quit order received, stopping GNSS-SDR !!\n"; + + // Push the control command to the control queue + control_queue_->push(pmt::make_any(command_event_make(200, 0))); + read_queue = false; + } + } + } + else + { + // No message available, add a small delay to prevent busy-waiting + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } } } + catch (const boost::interprocess::interprocess_exception &e) + { + std::cerr << "Error in message queue listener: " << e.what() << '\n'; + read_queue = false; + } } diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index b3340e94b..e1b29dcb6 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -160,7 +160,7 @@ private: void telecommand_listener(); void keyboard_listener(); - void sysv_queue_listener(); + void message_queue_listener(); void print_help_at_exit() const; // default filename for assistance data @@ -179,6 +179,8 @@ private: const std::string gal_almanac_default_xml_filename_ = "./gal_almanac.xml"; const std::string gps_almanac_default_xml_filename_ = "./gps_almanac.xml"; + const std::string control_message_queue_name_ = "receiver_control_queue"; + const size_t channel_event_type_hash_code_ = typeid(channel_event_sptr).hash_code(); const size_t command_event_type_hash_code_ = typeid(command_event_sptr).hash_code(); @@ -188,7 +190,7 @@ private: std::thread cmd_interface_thread_; std::thread keyboard_thread_; - std::thread sysv_queue_thread_; + std::thread message_queue_thread_; std::thread gps_acq_assist_data_collector_thread_; #ifdef ENABLE_FPGA @@ -210,7 +212,6 @@ private: unsigned int processed_control_messages_; unsigned int applied_actions_; - int msqid_; bool well_formatted_configuration_; bool conf_file_has_section_; diff --git a/src/core/receiver/file_configuration.cc b/src/core/receiver/file_configuration.cc index 5e8fff282..4f873f1d4 100644 --- a/src/core/receiver/file_configuration.cc +++ b/src/core/receiver/file_configuration.cc @@ -21,10 +21,14 @@ #include "file_configuration.h" #include "gnss_sdr_make_unique.h" -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif FileConfiguration::FileConfiguration(std::string filename) : filename_(std::move(filename)) @@ -71,7 +75,7 @@ std::string FileConfiguration::property(std::string property_name, std::string d { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), std::move(default_value)); } return ini_reader_->Get("GNSS-SDR", property_name, default_value); } @@ -81,7 +85,7 @@ bool FileConfiguration::property(std::string property_name, bool default_value) { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -92,7 +96,7 @@ int64_t FileConfiguration::property(std::string property_name, int64_t default_v { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -103,7 +107,7 @@ uint64_t FileConfiguration::property(std::string property_name, uint64_t default { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -114,7 +118,7 @@ int FileConfiguration::property(std::string property_name, int default_value) co { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -125,7 +129,7 @@ unsigned int FileConfiguration::property(std::string property_name, unsigned int { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -136,7 +140,7 @@ uint16_t FileConfiguration::property(std::string property_name, uint16_t default { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -147,7 +151,7 @@ int16_t FileConfiguration::property(std::string property_name, int16_t default_v { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -158,7 +162,7 @@ float FileConfiguration::property(std::string property_name, float default_value { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); @@ -169,7 +173,7 @@ double FileConfiguration::property(std::string property_name, double default_val { if (overrided_->is_present(property_name)) { - return overrided_->property(property_name, default_value); + return overrided_->property(std::move(property_name), default_value); } const std::string empty; return converter_->convert(property(std::move(property_name), empty), default_value); diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 5742bca83..1635aa5f5 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -36,6 +36,7 @@ #include "byte_to_short.h" #include "channel.h" #include "configuration_interface.h" +#include "cshort_to_grcomplex.h" #include "direct_resampler_conditioner.h" #include "fifo_signal_source.h" #include "file_signal_source.h" @@ -113,11 +114,17 @@ #include "tracking_interface.h" #include "two_bit_cpx_file_signal_source.h" #include "two_bit_packed_file_signal_source.h" -#include +#include // for exit #include // for exception #include // for cerr #include // for move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if RAW_UDP #include "custom_udp_signal_source.h" #endif @@ -157,12 +164,25 @@ #include "plutosdr_signal_source.h" #endif +#if AD936X_SDR_DRIVER +#include "ad936x_custom_signal_source.h" +#endif + #if FMCOMMS2_DRIVER #include "fmcomms2_signal_source.h" #endif -#if AD9361_DRIVER -#include "ad9361_fpga_signal_source.h" +#if ENABLE_FPGA and AD9361_DRIVER +#include "adrv9361_z7035_signal_source_fpga.h" +#include "fmcomms5_signal_source_fpga.h" +#endif + +#if MAX2771_DRIVER +#include "max2771_evkit_signal_source_fpga.h" +#endif + +#if DMA_PROXY_DRIVER +#include "dma_signal_source_fpga.h" #endif #if LIMESDR_DRIVER @@ -181,6 +201,11 @@ #include "gps_l1_ca_dll_pll_tracking_gpu.h" #endif +#if ENABLE_ION_SOURCE +#undef Owner +#include "ion_gsms_signal_source.h" +#endif + using namespace std::string_literals; namespace @@ -744,7 +769,14 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } #endif - +#if ENABLE_ION_SOURCE + else if (implementation == "ION_GSMS_Signal_Source") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } +#endif #if RAW_ARRAY_DRIVER else if (implementation == "Raw_Array_Signal_Source") { @@ -780,6 +812,8 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams, queue); block = std::move(block_); } +#endif +#if PLUTOSDR_DRIVER || AD936X_SDR_DRIVER else if (implementation == "Ad936x_Custom_Signal_Source") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, @@ -806,12 +840,34 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } #endif -#if AD9361_DRIVER - // The AD9361_DRIVER Driver must be instantiated last. In this way, when using the FPGA, and when using the GNSS receiver - // in post-processing mode, the receiver is configured and ready when the DMA starts sending samples to the receiver. - else if (implementation == "Ad9361_Fpga_Signal_Source") +#if ENABLE_FPGA and AD9361_DRIVER + else if (implementation == "ADRV9361_Z7035_Signal_Source_FPGA") { - std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } + else if (implementation == "FMCOMMS5_Signal_Source_FPGA") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } +#endif + +#if ENABLE_FPGA and MAX2771_DRIVER + else if (implementation == "MAX2771_EVKIT_Signal_Source_FPGA") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } +#endif + +#if ENABLE_FPGA and DMA_PROXY_DRIVER + else if (implementation == "DMA_Signal_Source_FPGA") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams, queue); block = std::move(block_); } @@ -864,6 +920,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams); block = std::move(block_); } + else if (implementation == "Cshort_To_Gr_Complex") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams); + block = std::move(block_); + } // INPUT FILTER ------------------------------------------------------------ else if (implementation == "Fir_Filter") @@ -1048,31 +1110,31 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L1_CA_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") + else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L2_M_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L5i_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L5i_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_Pcps_Acquisition_Fpga") + else if (implementation == "Galileo_E5a_Pcps_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); @@ -1198,31 +1260,31 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_Fpga") or (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")) + else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_FPGA") or (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA")) { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); @@ -1486,31 +1548,31 @@ std::unique_ptr GNSSBlockFactory::GetAcqBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L1_CA_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga") + else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L2_M_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L5i_PCPS_Acquisition_Fpga") + else if (implementation == "GPS_L5i_PCPS_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_Pcps_Acquisition_Fpga") + else if (implementation == "Galileo_E5a_Pcps_Acquisition_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); @@ -1654,31 +1716,31 @@ std::unique_ptr GNSSBlockFactory::GetTrkBlock( } #endif #if ENABLE_FPGA - else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L2_M_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_Fpga") or (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga")) + else if ((implementation == "GPS_L5i_DLL_PLL_Tracking_FPGA") or (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA")) { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); block = std::move(block_); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams); diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 47e35bfbd..3dc601130 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -27,6 +27,7 @@ #include "Galileo_E5a.h" #include "Galileo_E5b.h" #include "Galileo_E6.h" +#include "Galileo_OSNMA.h" #include "channel.h" #include "channel_fsm.h" #include "channel_interface.h" @@ -40,7 +41,6 @@ #include "signal_source_interface.h" #include // for boost::lexical_cast #include // for boost::tokenizer -#include // for LOG #include // for basic_block #include // for gr::filter::firdes #include // for io_signature @@ -49,6 +49,7 @@ #include // for transform, sort, unique #include // for floor #include // for size_t +#include // for exit #include // for exception #include // for operator<< #include // for insert_iterator, inserter @@ -59,6 +60,12 @@ #include // for std::thread #include // for std::move +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #ifdef GR_GREATER_38 #include #else @@ -76,6 +83,7 @@ GNSSFlowgraph::GNSSFlowgraph(std::shared_ptr configurati connected_(false), running_(false), multiband_(GNSSFlowgraph::is_multiband()), + enable_osnma_rx_(false), enable_e6_has_rx_(false) { enable_fpga_offloading_ = configuration_->property("GNSS-SDR.enable_FPGA", false); @@ -114,14 +122,32 @@ void GNSSFlowgraph::init() galileo_tow_map_ = nullptr; } + if (configuration_->property("Channels_1B.count", 0) > 0 && configuration_->property("GNSS-SDR.osnma_enable", true)) + { + enable_osnma_rx_ = true; + const auto certFilePath = configuration_->property("GNSS-SDR.osnma_public_key", CRTFILE_DEFAULT); + const auto merKleTreePath = configuration_->property("GNSS-SDR.osnma_merkletree", MERKLEFILE_DEFAULT); + std::string osnma_mode = configuration_->property("GNSS-SDR.osnma_mode", std::string("")); + bool strict_mode = false; + if (osnma_mode == "strict") + { + strict_mode = true; + } + osnma_rx_ = osnma_msg_receiver_make(certFilePath, merKleTreePath, strict_mode); + } + else + { + osnma_rx_ = nullptr; + } + // 1. read the number of RF front-ends available (one file_source per RF front-end) int sources_count_deprecated = configuration_->property("Receiver.sources_count", 1); sources_count_ = configuration_->property("GNSS-SDR.num_sources", sources_count_deprecated); // Avoid segmentation fault caused by wrong configuration - if (sources_count_ == 2 && block_factory->GetSignalSource(configuration_.get(), queue_.get(), 0)->implementation() == "Multichannel_File_Signal_Source") + if (sources_count_ == 2 && configuration_->property("SignalSource.implementation", std::string("")) == "Multichannel_File_Signal_Source") { - std::cout << " * Please set GNSS-SDR.num_sources=1 in your configuraiion file\n"; + std::cout << " * Please set GNSS-SDR.num_sources=1 in your configuration file\n"; std::cout << " if you are using the Multichannel_File_Signal_Source implementation.\n"; sources_count_ = 1; } @@ -131,7 +157,13 @@ void GNSSFlowgraph::init() for (int i = 0; i < sources_count_; i++) { DLOG(INFO) << "Creating source " << i; - sig_source_.push_back(block_factory->GetSignalSource(configuration_.get(), queue_.get(), i)); + auto check_not_nullptr = block_factory->GetSignalSource(configuration_.get(), queue_.get(), i); + if (!check_not_nullptr) + { + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } + sig_source_.push_back(std::move(check_not_nullptr)); if (enable_fpga_offloading_ == false) { auto& src = sig_source_.back(); @@ -205,11 +237,17 @@ void GNSSFlowgraph::init() std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end()); + std::string udp_port_string = configuration_->property("Monitor.udp_port", std::string("1234")); + std::vector udp_port_vec = split_string(udp_port_string, '_'); + std::sort(udp_port_vec.begin(), udp_port_vec.end()); + udp_port_vec.erase(std::unique(udp_port_vec.begin(), udp_port_vec.end()), udp_port_vec.end()); + // Instantiate monitor object GnssSynchroMonitor_ = gnss_synchro_make_monitor(channels_count_, configuration_->property("Monitor.decimation_factor", 1), - configuration_->property("Monitor.udp_port", 1234), - udp_addr_vec, enable_protobuf); + udp_port_vec, + udp_addr_vec, + enable_protobuf); } /* @@ -229,10 +267,16 @@ void GNSSFlowgraph::init() std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end()); + std::string udp_port_string = configuration_->property("AcquisitionMonitor.udp_port", std::string("1235")); + std::vector udp_port_vec = split_string(udp_port_string, '_'); + std::sort(udp_port_vec.begin(), udp_port_vec.end()); + udp_port_vec.erase(std::unique(udp_port_vec.begin(), udp_port_vec.end()), udp_port_vec.end()); + GnssSynchroAcquisitionMonitor_ = gnss_synchro_make_monitor(channels_count_, configuration_->property("AcquisitionMonitor.decimation_factor", 1), - configuration_->property("AcquisitionMonitor.udp_port", 1235), - udp_addr_vec, enable_protobuf); + udp_port_vec, + udp_addr_vec, + enable_protobuf); } /* @@ -252,14 +296,20 @@ void GNSSFlowgraph::init() std::sort(udp_addr_vec.begin(), udp_addr_vec.end()); udp_addr_vec.erase(std::unique(udp_addr_vec.begin(), udp_addr_vec.end()), udp_addr_vec.end()); + std::string udp_port_string = configuration_->property("TrackingMonitor.udp_port", std::string("1236")); + std::vector udp_port_vec = split_string(udp_port_string, '_'); + std::sort(udp_port_vec.begin(), udp_port_vec.end()); + udp_port_vec.erase(std::unique(udp_port_vec.begin(), udp_port_vec.end()), udp_port_vec.end()); + GnssSynchroTrackingMonitor_ = gnss_synchro_make_monitor(channels_count_, configuration_->property("TrackingMonitor.decimation_factor", 1), - configuration_->property("TrackingMonitor.udp_port", 1236), - udp_addr_vec, enable_protobuf); + udp_port_vec, + udp_addr_vec, + enable_protobuf); } /* - * Instantiate the receiver av message monitor block, if required + * Instantiate the receiver nav message monitor block, if required */ enable_navdata_monitor_ = configuration_->property("NavDataMonitor.enable_monitor", false); if (enable_navdata_monitor_) @@ -490,6 +540,14 @@ int GNSSFlowgraph::connect_desktop_flowgraph() } } + if (enable_osnma_rx_) + { + if (connect_osnma() != 0) + { + return 1; + } + } + // Activate acquisition in enabled channels std::lock_guard lock(signal_list_mutex_); for (int i = 0; i < channels_count_; i++) @@ -542,7 +600,7 @@ int GNSSFlowgraph::connect_fpga_flowgraph() if (src == nullptr) { help_hint_ += " * Check implementation name for SignalSource block.\n"; - help_hint_ += " Signal Source block implementation for FPGA off-loading should be Ad9361_Fpga_Signal_Source\n"; + help_hint_ += " Signal Source block implementation for FPGA off-loading should be Ad9361_Signal_Source_Fpga or Fpga_DMA_2Signal_Source\n"; return 1; } if (src->item_size() == 0) @@ -610,6 +668,14 @@ int GNSSFlowgraph::connect_fpga_flowgraph() } } + if (enable_osnma_rx_) + { + if (connect_osnma() != 0) + { + return 1; + } + } + check_desktop_conf_in_fpga_env(); LOG(INFO) << "The GNU Radio flowgraph for the current GNSS-SDR configuration with FPGA off-loading has been successfully connected"; @@ -681,7 +747,7 @@ int GNSSFlowgraph::connect_signal_conditioners() reported_error.replace(pos, len, "Pass_Through"); pos = reported_error.find(replace_me, pos + 1); } - help_hint_ += " * Blocks within the Signal Conditioner are connected with mismatched input/ouput item size\n"; + help_hint_ += " * Blocks within the Signal Conditioner are connected with mismatched input/output item size\n"; help_hint_ += " Reported error: " + reported_error + '\n'; help_hint_ += " Check the Signal Conditioner documentation at https://gnss-sdr.org/docs/sp-blocks/signal-conditioner/\n"; } @@ -961,7 +1027,7 @@ int GNSSFlowgraph::connect_signal_sources_to_signal_conditioners() } else { - if (j == 0) + if (j == 0 || !src->get_right_block(j)) { // RF_channel 0 backward compatibility with single channel sources LOG(INFO) << "connecting sig_source_ " << i << " stream " << 0 << " to conditioner " << signal_conditioner_ID; @@ -1244,7 +1310,7 @@ int GNSSFlowgraph::connect_acquisition_monitor() top_block_->disconnect_all(); return 1; } - DLOG(INFO) << "acqusition_monitor successfully connected to Channel blocks"; + DLOG(INFO) << "acquisition_monitor successfully connected to Channel blocks"; return 0; } @@ -1335,6 +1401,42 @@ int GNSSFlowgraph::connect_monitors() } +int GNSSFlowgraph::connect_osnma() +{ + try + { + bool gal_e1_channels = false; + for (int i = 0; i < channels_count_; i++) + { + const std::string gnss_signal = channels_.at(i)->get_signal().get_signal_str(); + switch (mapStringValues_[gnss_signal]) + { + case evGAL_1B: + top_block_->msg_connect(channels_.at(i)->get_right_block(), pmt::mp("OSNMA_from_TLM"), osnma_rx_, pmt::mp("OSNMA_from_TLM")); + gal_e1_channels = true; + break; + + default: + break; + } + } + + if (gal_e1_channels == true) + { + top_block_->msg_connect(osnma_rx_, pmt::mp("OSNMA_to_PVT"), pvt_->get_left_block(), pmt::mp("OSNMA_to_PVT")); + } + } + catch (const std::exception& e) + { + LOG(ERROR) << "Can't connect Galileo OSNMA msg ports: " << e.what(); + top_block_->disconnect_all(); + return 1; + } + DLOG(INFO) << "Galileo OSNMA message ports connected"; + return 0; +} + + int GNSSFlowgraph::connect_gal_e6_has() { try @@ -2181,7 +2283,7 @@ void GNSSFlowgraph::set_signals_list() std::string sv_list = configuration_->property("Galileo.prns", std::string("")); - if (sv_list.length() > 0) + if (!sv_list.empty()) { // Reset the available prns: std::set tmp_set; @@ -2221,7 +2323,7 @@ void GNSSFlowgraph::set_signals_list() sv_list = configuration_->property("GPS.prns", std::string("")); - if (sv_list.length() > 0) + if (!sv_list.empty()) { // Reset the available prns: std::set tmp_set; @@ -2261,7 +2363,7 @@ void GNSSFlowgraph::set_signals_list() sv_list = configuration_->property("SBAS.prns", std::string("")); - if (sv_list.length() > 0) + if (!sv_list.empty()) { // Reset the available prns: std::set tmp_set; @@ -2301,7 +2403,7 @@ void GNSSFlowgraph::set_signals_list() sv_list = configuration_->property("Glonass.prns", std::string("")); - if (sv_list.length() > 0) + if (!sv_list.empty()) { // Reset the available prns: std::set tmp_set; @@ -2341,7 +2443,7 @@ void GNSSFlowgraph::set_signals_list() sv_list = configuration_->property("Beidou.prns", std::string("")); - if (sv_list.length() > 0) + if (!sv_list.empty()) { // Reset the available prns: std::set tmp_set; @@ -2383,8 +2485,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create GPS L1 C/A signals for (available_gnss_prn_iter = available_gps_prn.cbegin(); - available_gnss_prn_iter != available_gps_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_gps_prn.cend(); + available_gnss_prn_iter++) { available_GPS_1C_signals_.emplace_back( Gnss_Satellite(std::string("GPS"), *available_gnss_prn_iter), @@ -2396,8 +2498,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create GPS L2C M signals for (available_gnss_prn_iter = available_gps_prn.cbegin(); - available_gnss_prn_iter != available_gps_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_gps_prn.cend(); + available_gnss_prn_iter++) { available_GPS_2S_signals_.emplace_back( Gnss_Satellite(std::string("GPS"), *available_gnss_prn_iter), @@ -2409,8 +2511,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create GPS L5 signals for (available_gnss_prn_iter = available_gps_prn.cbegin(); - available_gnss_prn_iter != available_gps_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_gps_prn.cend(); + available_gnss_prn_iter++) { available_GPS_L5_signals_.emplace_back( Gnss_Satellite(std::string("GPS"), *available_gnss_prn_iter), @@ -2422,8 +2524,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create SBAS L1 C/A signals for (available_gnss_prn_iter = available_sbas_prn.cbegin(); - available_gnss_prn_iter != available_sbas_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_sbas_prn.cend(); + available_gnss_prn_iter++) { available_SBAS_1C_signals_.emplace_back( Gnss_Satellite(std::string("SBAS"), *available_gnss_prn_iter), @@ -2435,8 +2537,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of Galileo E1B signals for (available_gnss_prn_iter = available_galileo_prn.cbegin(); - available_gnss_prn_iter != available_galileo_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_galileo_prn.cend(); + available_gnss_prn_iter++) { available_GAL_1B_signals_.emplace_back( Gnss_Satellite(std::string("Galileo"), *available_gnss_prn_iter), @@ -2448,8 +2550,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of Galileo E5a signals for (available_gnss_prn_iter = available_galileo_prn.cbegin(); - available_gnss_prn_iter != available_galileo_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_galileo_prn.cend(); + available_gnss_prn_iter++) { available_GAL_5X_signals_.emplace_back( Gnss_Satellite(std::string("Galileo"), *available_gnss_prn_iter), @@ -2461,8 +2563,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of Galileo E5b signals for (available_gnss_prn_iter = available_galileo_prn.cbegin(); - available_gnss_prn_iter != available_galileo_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_galileo_prn.cend(); + available_gnss_prn_iter++) { available_GAL_7X_signals_.emplace_back( Gnss_Satellite(std::string("Galileo"), *available_gnss_prn_iter), @@ -2474,8 +2576,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of Galileo E6 signals for (available_gnss_prn_iter = available_galileo_prn.cbegin(); - available_gnss_prn_iter != available_galileo_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_galileo_prn.cend(); + available_gnss_prn_iter++) { available_GAL_E6_signals_.emplace_back( Gnss_Satellite(std::string("Galileo"), *available_gnss_prn_iter), @@ -2487,8 +2589,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of GLONASS L1 C/A signals for (available_gnss_prn_iter = available_glonass_prn.cbegin(); - available_gnss_prn_iter != available_glonass_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_glonass_prn.cend(); + available_gnss_prn_iter++) { available_GLO_1G_signals_.emplace_back( Gnss_Satellite(std::string("Glonass"), *available_gnss_prn_iter), @@ -2500,8 +2602,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of GLONASS L2 C/A signals for (available_gnss_prn_iter = available_glonass_prn.cbegin(); - available_gnss_prn_iter != available_glonass_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_glonass_prn.cend(); + available_gnss_prn_iter++) { available_GLO_2G_signals_.emplace_back( Gnss_Satellite(std::string("Glonass"), *available_gnss_prn_iter), @@ -2513,8 +2615,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of BeiDou B1C signals for (available_gnss_prn_iter = available_beidou_prn.cbegin(); - available_gnss_prn_iter != available_beidou_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_beidou_prn.cend(); + available_gnss_prn_iter++) { available_BDS_B1_signals_.emplace_back( Gnss_Satellite(std::string("Beidou"), *available_gnss_prn_iter), @@ -2526,8 +2628,8 @@ void GNSSFlowgraph::set_signals_list() { // Loop to create the list of BeiDou B1C signals for (available_gnss_prn_iter = available_beidou_prn.cbegin(); - available_gnss_prn_iter != available_beidou_prn.cend(); - available_gnss_prn_iter++) + available_gnss_prn_iter != available_beidou_prn.cend(); + available_gnss_prn_iter++) { available_BDS_B3_signals_.emplace_back( Gnss_Satellite(std::string("Beidou"), *available_gnss_prn_iter), diff --git a/src/core/receiver/gnss_flowgraph.h b/src/core/receiver/gnss_flowgraph.h index be7c5e8bf..b544079ee 100644 --- a/src/core/receiver/gnss_flowgraph.h +++ b/src/core/receiver/gnss_flowgraph.h @@ -30,6 +30,7 @@ #include "galileo_tow_map.h" #include "gnss_sdr_sample_counter.h" #include "gnss_signal.h" +#include "osnma_msg_receiver.h" #include "pvt_interface.h" #include // for null_sink #include // for basic_block_sptr, top_block_sptr @@ -152,7 +153,7 @@ public: } /*! - * \brief Priorize visible satellites in the specified vector + * \brief Prioritize visible satellites in the specified vector */ void priorize_satellites(const std::vector>& visible_satellites); @@ -179,6 +180,7 @@ private: int connect_channels_to_observables(); int connect_observables_to_pvt(); int connect_monitors(); + int connect_osnma(); int connect_gal_e6_has(); int connect_gnss_synchro_monitor(); int connect_acquisition_monitor(); @@ -234,6 +236,7 @@ private: channel_status_msg_receiver_sptr channels_status_; // class that receives and stores the current status of the receiver channels galileo_e6_has_msg_receiver_sptr gal_e6_has_rx_; galileo_tow_map_sptr galileo_tow_map_; + osnma_msg_receiver_sptr osnma_rx_; gnss_sdr_sample_counter_sptr ch_out_sample_counter_; #if ENABLE_FPGA @@ -290,6 +293,7 @@ private: bool enable_tracking_monitor_; bool enable_navdata_monitor_; bool enable_fpga_offloading_; + bool enable_osnma_rx_; bool enable_e6_has_rx_; }; diff --git a/src/core/receiver/tcp_cmd_interface.cc b/src/core/receiver/tcp_cmd_interface.cc index 1a47fb269..713c3e726 100644 --- a/src/core/receiver/tcp_cmd_interface.cc +++ b/src/core/receiver/tcp_cmd_interface.cc @@ -146,9 +146,7 @@ std::string TcpCmdInterface::status(const std::vector &commandLine &course_over_ground_deg, &UTC_time) == true) { - struct tm tstruct - { - }; + struct tm tstruct{}; std::array buf1{}; tstruct = *gmtime(&UTC_time); strftime(buf1.data(), buf1.size(), "%d/%m/%Y %H:%M:%S", &tstruct); @@ -179,9 +177,7 @@ std::string TcpCmdInterface::hotstart(const std::vector &commandLin if (commandLine.size() > 5) { // Read commandline time parameter - struct tm tm - { - }; + struct tm tm{}; const std::string tmp_str = commandLine.at(1) + commandLine.at(2); if (strptime(tmp_str.c_str(), "%d/%m/%Y %H:%M:%S", &tm) == nullptr) { @@ -227,9 +223,7 @@ std::string TcpCmdInterface::warmstart(const std::vector &commandLi if (commandLine.size() > 5) { // Read commandline time parameter - struct tm tm - { - }; + struct tm tm{}; const std::string tmp_str = commandLine.at(1) + commandLine.at(2); if (strptime(tmp_str.c_str(), "%d/%m/%Y %H:%M:%S", &tm) == nullptr) { @@ -323,10 +317,10 @@ void TcpCmdInterface::run_cmd_server(int tcp_port) std::cout << "TcpCmdInterface: Telecommand TCP interface listening on port " << tcp_port << '\n'; boost::asio::ip::tcp::socket socket(context); - acceptor.accept(socket, not_throw); + acceptor.accept(socket, not_throw); // NOLINT(bugprone-unused-return-value) if (not_throw) { - std::cerr << "TcpCmdInterface: Error when binding the port in the socket\n"; + std::cerr << "TcpCmdInterface: Error when binding the port to the socket: " << not_throw.message() << '\n'; continue; } diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index 3e25387ed..896da9cbb 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -19,6 +19,7 @@ set(SYSTEM_PARAMETERS_SOURCES galileo_fnav_message.cc galileo_has_data.cc galileo_inav_message.cc + galileo_ism.cc galileo_reduced_ced.cc beidou_dnav_navigation_message.cc beidou_dnav_ephemeris.cc @@ -28,6 +29,8 @@ set(SYSTEM_PARAMETERS_SOURCES glonass_gnav_utc_model.cc glonass_gnav_navigation_message.cc reed_solomon.cc + osnma_data.cc + osnma_dsm_reader.cc ) set(SYSTEM_PARAMETERS_HEADERS @@ -55,6 +58,7 @@ set(SYSTEM_PARAMETERS_HEADERS galileo_fnav_message.h galileo_has_data.h galileo_inav_message.h + galileo_ism.h galileo_reduced_ced.h sbas_ephemeris.h gps_cnav_ephemeris.h @@ -89,6 +93,9 @@ set(SYSTEM_PARAMETERS_HEADERS MATH_CONSTANTS.h reed_solomon.h galileo_has_page.h + Galileo_OSNMA.h + osnma_data.h + osnma_dsm_reader.h ) list(SORT SYSTEM_PARAMETERS_HEADERS) @@ -114,11 +121,18 @@ target_link_libraries(core_system_parameters PUBLIC Boost::date_time Boost::serialization + Boost::headers PRIVATE - Gflags::gflags - Glog::glog + Pugixml::pugixml ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(core_system_parameters PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(core_system_parameters PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(core_system_parameters PRIVATE absl::flags absl::log) +endif() + # for gnss_sdr_make_unique.h target_include_directories(core_system_parameters PUBLIC diff --git a/src/core/system_parameters/GLONASS_L1_L2_CA.h b/src/core/system_parameters/GLONASS_L1_L2_CA.h index 042754742..0194e78db 100644 --- a/src/core/system_parameters/GLONASS_L1_L2_CA.h +++ b/src/core/system_parameters/GLONASS_L1_L2_CA.h @@ -87,10 +87,9 @@ constexpr int32_t GLONASS_CA_NBR_SATS = 24; // STRING DATA WITHOUT PREAMBLE constexpr int32_t GLONASS_L1_CA_HISTORY_DEEP = 100; // NAVIGATION MESSAGE DEMODULATION AND DECODING -#define GLONASS_GNAV_PREAMBLE \ - { \ - 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 \ - } +#define GLONASS_GNAV_PREAMBLE \ + { \ + 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0} constexpr double GLONASS_GNAV_PREAMBLE_DURATION_S = 0.300; constexpr int32_t GLONASS_GNAV_PREAMBLE_LENGTH_BITS = 30; constexpr int32_t GLONASS_GNAV_PREAMBLE_LENGTH_SYMBOLS = 300; diff --git a/src/core/system_parameters/GPS_CNAV.h b/src/core/system_parameters/GPS_CNAV.h index 7d6a41c27..4ef6816da 100644 --- a/src/core/system_parameters/GPS_CNAV.h +++ b/src/core/system_parameters/GPS_CNAV.h @@ -95,7 +95,7 @@ const std::vector > CNAV_CUC({{249, 21}}); constexpr double CNAV_CUC_LSB = TWO_N30; -// MESSAGE TYPE 30 (CLOCK, IONO, GRUP DELAY) +// MESSAGE TYPE 30 (CLOCK, IONO, GROUP DELAY) const std::vector > CNAV_TOP2({{39, 11}}); constexpr int32_t CNAV_TOP2_LSB = 300; const std::vector > CNAV_URA_NED0({{50, 5}}); diff --git a/src/core/system_parameters/GPS_L1_CA.h b/src/core/system_parameters/GPS_L1_CA.h index 842dbbf3b..1f9866d48 100644 --- a/src/core/system_parameters/GPS_L1_CA.h +++ b/src/core/system_parameters/GPS_L1_CA.h @@ -226,6 +226,29 @@ const std::vector> HEALTH_SV23({{253, 6}}); const std::vector> HEALTH_SV24({{259, 6}}); +// Almanac +const std::vector> ALM_ECC({{69, 16}}); +constexpr double ALM_ECC_LSB = TWO_N21; +const std::vector> ALM_TOA({{91, 8}}); +constexpr int32_t ALM_TOA_LSB = static_cast(TWO_P12); +const std::vector> ALM_DELTAI({{99, 16}}); +constexpr double ALM_DELTAI_LSB = TWO_N19; +const std::vector> ALM_OMEGADOT({{121, 16}}); +constexpr double ALM_OMEGADOT_LSB = TWO_N38; +const std::vector> ALM_SVHEALTH({{137, 8}}); +const std::vector> ALM_SQUAREA({{151, 24}}); +constexpr double ALM_SQUAREA_LSB = TWO_N11; +const std::vector> ALM_OMEGAZERO({{181, 24}}); +constexpr double ALM_OMEGAZERO_LSB = TWO_N23; +const std::vector> ALM_OMEGA({{211, 24}}); +constexpr double ALM_OMEGA_LSB = TWO_N23; +const std::vector> ALM_MZERO({{241, 24}}); +constexpr double ALM_MZERO_LSB = TWO_N23; + +const std::vector> ALM_AF0({{271, 8}, {290, 3}}); +constexpr double ALM_AF0_LSB = TWO_N20; +const std::vector> ALM_AF1({{279, 11}}); +constexpr double ALM_AF1_LSB = TWO_N38; /** \} */ /** \} */ #endif // GNSS_SDR_GPS_L1_CA_H diff --git a/src/core/system_parameters/Galileo_CNAV.h b/src/core/system_parameters/Galileo_CNAV.h index ebb7d5bba..b1bd4882d 100644 --- a/src/core/system_parameters/Galileo_CNAV.h +++ b/src/core/system_parameters/Galileo_CNAV.h @@ -1,6 +1,6 @@ /*! * \file Galileo_CNAV.h - * \brief Galileo CNAV mesage constants. Data from: + * \brief Galileo CNAV message constants. Data from: * Galileo High Accuracy Service Signal-In-Space Interface Control Document * (HAS SIS ICD) Issue 1.0, May 2022 * \author Carles Fernandez-Prades, 2020-2022. cfernandez(at)cttc.es @@ -57,7 +57,7 @@ constexpr size_t HAS_MSG_PHASE_DISCONTINUITY_INDICATOR_LENGTH = 2; // HAS SIS constexpr uint64_t MAX_SECONDS_REMEMBERING_MID = 150; // HAS SIS ICD 1.0 Section 6.4.1 HAS Message Completion Time-out // Galileo CNAV message structure -constexpr int32_t GALILEO_CNAV_SYMBOLS_PER_PAGE = 1000; // Total numer of symbols per HAS page including the sync pattern +constexpr int32_t GALILEO_CNAV_SYMBOLS_PER_PAGE = 1000; // Total number of symbols per HAS page including the sync pattern constexpr int32_t GALILEO_CNAV_PREAMBLE_PERIOD_SYMBOLS = 1000; constexpr int32_t GALILEO_CNAV_PAGE_MS = 1; // Duration in ms of a CNAV page constexpr int32_t GALILEO_CNAV_INTERLEAVER_ROWS = 8; // HAS SIS ICD 1.0 Table 4 diff --git a/src/core/system_parameters/Galileo_FNAV.h b/src/core/system_parameters/Galileo_FNAV.h index cef9fe26f..d94df7408 100644 --- a/src/core/system_parameters/Galileo_FNAV.h +++ b/src/core/system_parameters/Galileo_FNAV.h @@ -1,6 +1,6 @@ /*! * \file Galileo_FNAV.h - * \brief Galileo FNAV mesage constants + * \brief Galileo FNAV message constants * \author Carles Fernandez, 2020. cfernandez(at)cttc.es * * diff --git a/src/core/system_parameters/Galileo_INAV.h b/src/core/system_parameters/Galileo_INAV.h index 72222baf2..eeea60760 100644 --- a/src/core/system_parameters/Galileo_INAV.h +++ b/src/core/system_parameters/Galileo_INAV.h @@ -1,6 +1,6 @@ /*! * \file Galileo_INAV.h - * \brief Galileo INAV mesage constants + * \brief Galileo INAV message constants * \author Carles Fernandez, 2020. cfernandez(at)cttc.es * * @@ -274,12 +274,29 @@ constexpr int32_t BITS_IN_OCTET = 8; constexpr int32_t FIRST_RS_BIT = 7; constexpr int32_t FIRST_RS_BIT_AFTER_IODNAV = 17; +/* Page 22 */ +const std::vector> ISM_CONSTELLATION_ID_BIT({{7, 3}}); +const std::vector> ISM_SERVICE_LEVEL_ID_BIT({{10, 3}}); +const std::vector> ISM_WN_BIT({{13, 12}}); +const std::vector> ISM_T0_BIT({{25, 9}}); +const std::vector> ISM_MASK_MSB_BIT({{34, 1}}); +const std::vector> ISM_MASK_BIT({{35, 32}}); +const std::vector> ISM_PCONST_BIT({{67, 4}}); +const std::vector> ISM_PSAT_BIT({{71, 4}}); +const std::vector> ISM_URA_BIT({{75, 4}}); +const std::vector> ISM_URE_BIT({{79, 4}}); +const std::vector> ISM_BNOM_BIT({{83, 4}}); +const std::vector> ISM_TVALIDITY_BIT({{87, 4}}); +const std::vector> ISM_CRC_BIT({{97, 32}}); +constexpr int32_t GALILEO_ISM_CRC_DATA_BITS = 96; +constexpr int32_t GALILEO_ISM_CRC_DATA_BYTES = 12; + /* Page 0 */ const std::vector> TIME_0_BIT({{7, 2}}); const std::vector> WN_0_BIT({{97, 12}}); const std::vector> TOW_0_BIT({{109, 20}}); -/* Secondary Synchronization Patters */ +/* Secondary Synchronization Patterns */ constexpr char GALILEO_INAV_PLAIN_SSP1[9] = "00000100"; constexpr char GALILEO_INAV_PLAIN_SSP2[9] = "00101011"; constexpr char GALILEO_INAV_PLAIN_SSP3[9] = "00101111"; diff --git a/src/core/system_parameters/Galileo_OSNMA.h b/src/core/system_parameters/Galileo_OSNMA.h new file mode 100644 index 000000000..89ea0ec10 --- /dev/null +++ b/src/core/system_parameters/Galileo_OSNMA.h @@ -0,0 +1,199 @@ +/*! + * \file Galileo_OSNMA.h + * \brief Galileo OSNMA message constants + * \author Carles Fernandez, 2023. cfernandez(at)cttc.es + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_GALILEO_OSNMA_H +#define GNSS_SDR_GALILEO_OSNMA_H + +#include +#include +#include +#include +#include +#include + +/** \addtogroup Core + * \{ */ +/** \addtogroup System_Parameters + * \{ */ + +constexpr size_t SIZE_DSM_BLOCKS_BYTES = 13; + +// OSNMA User ICD, Issue 1.1, Table 1 +const std::unordered_map OSNMA_TABLE_1 = { + {0, std::string("Reserved")}, + {1, std::string("Test")}, + {2, std::string("Operational")}, + {3, std::string("Don't use")}}; // key: nmas, value: nmas status + + +// OSNMA User ICD, Issue 1.1, Table 2 +const std::unordered_map OSNMA_TABLE_2 = { + {0, std::string("Reserved")}, + {1, std::string("Nominal")}, + {2, std::string("End of Chain (EOC)")}, + {3, std::string("Chain Revoked (CREV)")}, + {4, std::string("New Public Key (NPK)")}, + {5, std::string("Public Key Revoked (PKREV)")}, + {6, std::string("New Merkle Tree (NMT)")}, + {7, std::string("Alert Message (AM)")}}; // key: cpks, value: cpks status + +// OSNMA User ICD for the Test Phase, Issue 1.0, Table 3 +const std::unordered_map> OSNMA_TABLE_3 = { + {0, {0, 0}}, + {1, {0, 0}}, + {2, {0, 0}}, + {3, {0, 0}}, + {4, {0, 0}}, + {5, {0, 0}}, + {6, {0, 0}}, + {7, {13, 1352}}, + {8, {14, 1456}}, + {9, {15, 1560}}, + {10, {16, 1664}}, + {11, {0, 0}}, + {12, {0, 0}}, + {13, {0, 0}}, + {14, {0, 0}}, + {15, {0, 0}}}; // key: nb_dp, value: {num_blocks, l_dp_bits} + +const std::unordered_map OSNMA_TABLE_5 = { + {0, std::string("Reserved")}, + {1, std::string("ECDSA P-256")}, + {2, std::string("Reserved")}, + {3, std::string("ECDSA P-521")}, + {4, std::string("OAM")}, + {5, std::string("Reserved")}, + {6, std::string("Reserved")}, + {7, std::string("Reserved")}, + {8, std::string("Reserved")}, + {9, std::string("Reserved")}, + {10, std::string("Reserved")}, + {11, std::string("Reserved")}, + {12, std::string("Reserved")}, + {13, std::string("Reserved")}, + {14, std::string("Reserved")}, + {15, std::string("Reserved")}}; // key: nptk, value: message + +const std::unordered_map OSNMA_TABLE_6 = { + {std::string("ECDSA P-256"), 264}, + {std::string("ECDSA P-521"), 536}}; + +// OSNMA User ICD, Issue 1.1, Table 7 +const std::unordered_map> OSNMA_TABLE_7 = { + {0, {0, 0}}, + {1, {7, 728}}, + {2, {8, 832}}, + {3, {9, 936}}, + {4, {10, 1040}}, + {5, {11, 1144}}, + {6, {12, 1248}}, + {7, {13, 1352}}, + {8, {14, 1456}}, + {9, {0, 0}}, + {10, {0, 0}}, + {11, {0, 0}}, + {12, {0, 0}}, + {13, {0, 0}}, + {14, {0, 0}}, + {15, {0, 0}}}; // key: nb_dk, value: {num_blocks, l_dk_bits} + +const std::unordered_map OSNMA_TABLE_8 = { + {0, std::string("SHA-256")}, + {1, std::string("Reserved")}, + {2, std::string("SHA3-256")}, + {3, std::string("Reserved")}}; // key: hs, value: hash_function + +const std::unordered_map OSNMA_TABLE_10 = { + {0, 96}, + {1, 104}, + {2, 112}, + {3, 120}, + {4, 128}, + {5, 160}, + {6, 192}, + {7, 224}, + {8, 256}, + {9, 0}, + {10, 0}, + {11, 0}, + {12, 0}, + {13, 0}, + {15, 0}, + {15, 0}}; // key: ks, value: lk_bits + +const std::unordered_map OSNMA_TABLE_11 = { + {0, 0}, + {1, 0}, + {2, 0}, + {3, 0}, + {4, 0}, + {5, 20}, + {6, 24}, + {7, 28}, + {8, 32}, + {9, 40}, + {10, 0}, + {11, 0}, + {12, 0}, + {13, 0}, + {14, 0}, + {15, 0}, +}; + +const std::unordered_map OSNMA_TABLE_15 = { + {std::string("ECDSA P-256"), 512}, + {std::string("ECDSA P-521"), 1056}}; // key: ECDSA Curve and hash function, value: {l_ds_bits} + +const std::string PEMFILE_DEFAULT("./OSNMA_PublicKey.pem"); +const std::string CRTFILE_DEFAULT("./OSNMA_PublicKey_20240115100000_newPKID_1.crt"); +const std::string MERKLEFILE_DEFAULT("./OSNMA_MerkleTree_20240115100000_newPKID_1.xml"); +const std::string KROOTFILE_DEFAULT("./OSNMA_DSM_KROOT_NMAHeader.bin"); + +class Mack_lookup +{ +public: + Mack_lookup() = default; + Mack_lookup(uint8_t msg_, + uint8_t nt_, + const std::vector& s1_, + const std::vector& s2_) : msg(msg_), + nt(nt_), + sequence1(s1_), + sequence2(s2_) {}; + uint8_t msg{}; + uint8_t nt{}; + std::vector sequence1; + std::vector sequence2; +}; + +const std::unordered_map OSNMA_TABLE_16 = { + {27, {2, 6, {"00S", "00E", "00E", "00E", "12S", "00E"}, {"00S ", "00E", "00E", "04S", "12S", "00E"}}}, + {28, {2, 10, {"00S", "00E", "00E", "00E", "00S", "00E", "00E", "12S", "00E", "00E"}, {"00S", "00E", "00E", "00S", "00E", "00E", "04S", "12S", "00E", "00E"}}}, + {31, {2, 5, {"00S", "00E", "00E", "12S", "00E"}, {"00S", "00E", "00E", "12S", "04S"}}}, + {33, {2, 6, {"00S", "00E", "04S", "00E", "12S", "00E"}, {"00S", "00E", "00E", "12S", "00E", "12E"}}}, + {34, {2, 6, {"00S", "FLX", "04S", "FLX", "12S", "00E"}, {"00S", "FLX", "00E", "12S", "00E", "12E"}}}, + {35, {2, 6, {"00S", "FLX", "04S", "FLX", "12S", "FLX"}, {"00S", "FLX", "FLX", "12S", "FLX", "FLX"}}}, + {36, {2, 5, {"00S", "FLX", "04S", "FLX", "12S"}, {"00S", "FLX", "00E", "12S", "12E"}}}, + {37, {2, 5, {"00S", "00E", "04S", "00E", "12S"}, {"00S", "00E", "00E", "12S", "12E"}}}, + {38, {2, 5, {"00S", "FLX", "04S", "FLX", "12S"}, {"00S", "FLX", "FLX", "12S", "FLX"}}}, + {39, {2, 4, {"00S", "FLX", "04S", "FLX"}, {"00S", "FLX", "00E", "12S"}}}, + {40, {2, 4, {"00S", "00E", "04S", "12S"}, {"00S", "00E", "00E", "12E"}}}, + {41, {2, 4, {"00S", "FLX", "04S", "FLX"}, {"00S", "FLX", "FLX", "12S"}}}}; + +/** \} */ +/** \} */ +#endif // GNSS_SDR_GALILEO_OSNMA_H \ No newline at end of file diff --git a/src/core/system_parameters/beidou_dnav_navigation_message.cc b/src/core/system_parameters/beidou_dnav_navigation_message.cc index 0444a3555..76a621de9 100644 --- a/src/core/system_parameters/beidou_dnav_navigation_message.cc +++ b/src/core/system_parameters/beidou_dnav_navigation_message.cc @@ -353,7 +353,7 @@ int32_t Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const& s d_DeltaT_LSF = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_T_LSF)); i_WN_LSF = static_cast(read_navigation_signed(subframe_bits, D1_WN_LSF)); d_A0UTC = static_cast(read_navigation_signed(subframe_bits, D1_A0UTC)); - d_A0UTC = d_A0GPS * D1_A0GPS_LSB; + d_A0UTC = d_A0UTC * D1_A0UTC_LSB; d_A1UTC = static_cast(read_navigation_signed(subframe_bits, D1_A1UTC)); d_A1UTC = d_A1UTC * D1_A1UTC_LSB; diff --git a/src/core/system_parameters/galileo_cnav_message.cc b/src/core/system_parameters/galileo_cnav_message.cc index e514b00b7..488d8f49f 100644 --- a/src/core/system_parameters/galileo_cnav_message.cc +++ b/src/core/system_parameters/galileo_cnav_message.cc @@ -19,11 +19,16 @@ #include "galileo_cnav_message.h" #include // for boost::crc_basic, boost::crc_optimal #include // for boost::dynamic_bitset -#include -#include // for reverse +#include // for reverse #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using CRC_Galileo_CNAV_type = boost::crc_optimal<24, 0x1864CFBU, 0x0, 0x0, false, false>; diff --git a/src/core/system_parameters/galileo_fnav_message.cc b/src/core/system_parameters/galileo_fnav_message.cc index 5dea81898..0ea44e6a7 100644 --- a/src/core/system_parameters/galileo_fnav_message.cc +++ b/src/core/system_parameters/galileo_fnav_message.cc @@ -23,11 +23,16 @@ #include "galileo_fnav_message.h" #include // for boost::crc_basic, boost::crc_optimal #include -#include #include // for reverse #include // for string, operator<< #include // for back_insert_iterator +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using CRC_Galileo_FNAV_type = boost::crc_optimal<24, 0x1864CFBU, 0x0, 0x0, false, false>; diff --git a/src/core/system_parameters/galileo_has_data.cc b/src/core/system_parameters/galileo_has_data.cc index cf52b9a99..566f59757 100644 --- a/src/core/system_parameters/galileo_has_data.cc +++ b/src/core/system_parameters/galileo_has_data.cc @@ -392,7 +392,7 @@ std::vector Galileo_HAS_data::get_delta_clock_subset_correction_m(uint8_t } auto subset_corr_matrix = this->get_delta_clock_subset_correction_m(); - std::vector delta_clock_subset_correction_m_v = subset_corr_matrix[nsys_sub_index]; + const std::vector& delta_clock_subset_correction_m_v = subset_corr_matrix[nsys_sub_index]; std::vector delta_clock_subset_correction_m_aux; std::vector num_satellites_subset = this->get_num_subset_satellites(); uint8_t num_sats_in_this_system_subset = num_satellites_subset[nsys_sub_index]; diff --git a/src/core/system_parameters/galileo_has_data.h b/src/core/system_parameters/galileo_has_data.h index b69eeff82..6deada5f0 100644 --- a/src/core/system_parameters/galileo_has_data.h +++ b/src/core/system_parameters/galileo_has_data.h @@ -124,7 +124,7 @@ public: uint8_t has_status; //!< HASS - HAS Status (from HAS page header). See HAS SIS ICD 1.0 Section 3.1.1 uint8_t message_id; //!< MID - Message ID (from HAS page header). See HAS SIS ICD 1.0 Section 3.1 - uint8_t Nsys; //!< Number of GNSS for which corrections are provided. See HAS SIS ICD 1.0 Setion 5.2.1 + uint8_t Nsys; //!< Number of GNSS for which corrections are provided. See HAS SIS ICD 1.0 Section 5.2.1 uint8_t Nsys_sub; //!< Number of GNSS for which corrections are provided in clock subset corrections. See HAS SIS ICD 1.0 Section 5.2.2.1 uint8_t validity_interval_index_orbit_corrections; //!< VI - Validity Interval Index for Orbit corrections. See HAS SIS ICD 1.0 Section 5.2.2.1 diff --git a/src/core/system_parameters/galileo_inav_message.cc b/src/core/system_parameters/galileo_inav_message.cc index 81c47c3bb..4152434ee 100644 --- a/src/core/system_parameters/galileo_inav_message.cc +++ b/src/core/system_parameters/galileo_inav_message.cc @@ -21,12 +21,16 @@ #include "reed_solomon.h" #include // for boost::crc_basic, boost::crc_optimal #include // for boost::dynamic_bitset -#include // for DLOG #include // for reverse #include // for operator<< #include // for std::numeric_limits #include // for std::accumulate +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif using CRC_Galileo_INAV_type = boost::crc_optimal<24, 0x1864CFBU, 0x0, 0x0, false, false>; @@ -40,7 +44,7 @@ Galileo_Inav_Message::Galileo_Inav_Message() } -// here the compiler knows how to destrcut rs +// here the compiler knows how to destroy rs Galileo_Inav_Message::~Galileo_Inav_Message() = default; @@ -139,8 +143,6 @@ bool Galileo_Inav_Message::read_navigation_bool(const std::bitset page_type_bits(page_number_bits); // from string to bitset - Page_type = static_cast(read_page_type_unsigned(page_type_bits, TYPE)); - Page_type_time_stamp = Page_type; const std::string Data_jk_ephemeris = Data_k + Data_j; page_jk_decoder(Data_jk_ephemeris.c_str()); + + // Fill OSNMA data + if (page_position_in_inav_subframe != 255) + { + if (page_position_in_inav_subframe == 0) + { // TODO - is it redundant? receiving Word 2 already resets this + nma_position_filled = std::array{}; + nma_msg.mack = std::array{}; + nma_msg.hkroot = std::array{}; + } + std::bitset<8> hkroot_bs(osnma_sis.substr(0, 8)); + std::bitset<32> mack_bs(osnma_sis.substr(8, 32)); + if (hkroot_bs.count() != 0 && mack_bs.count() != 0) + { + hkroot_sis = static_cast(hkroot_bs.to_ulong()); + mack_sis = static_cast(mack_bs.to_ulong()); + nma_msg.mack[page_position_in_inav_subframe] = mack_sis; + nma_msg.hkroot[page_position_in_inav_subframe] = hkroot_sis; + nma_position_filled[page_position_in_inav_subframe] = 1; + } + } } else { @@ -189,7 +208,7 @@ void Galileo_Inav_Message::split_page(std::string page_string, int32_t flag_even flag_CRC_test = false; } } // end of CRC checksum control - } // end if (page_string.at(0)=='1') + } // end if (page_string.at(0)=='1') else { page_Even = page_string.substr(0, 114); @@ -197,6 +216,7 @@ void Galileo_Inav_Message::split_page(std::string page_string, int32_t flag_even } +// C: tells if W1-->W4 available from same block bool Galileo_Inav_Message::have_new_ephemeris() // Check if we have a new ephemeris stored in the galileo navigation class { if ((flag_ephemeris_1 == true) and (flag_ephemeris_2 == true) and (flag_ephemeris_3 == true) and (flag_ephemeris_4 == true) and (flag_iono_and_GST == true)) @@ -331,6 +351,7 @@ bool Galileo_Inav_Message::have_new_ephemeris() // Check if we have a new ephem } +// C: tells if W5 is available bool Galileo_Inav_Message::have_new_iono_and_GST() // Check if we have a new iono data set stored in the galileo navigation class { if ((flag_iono_and_GST == true) and (flag_utc_model == true)) // the condition on flag_utc_model is added to have a time stamp for iono @@ -343,6 +364,7 @@ bool Galileo_Inav_Message::have_new_iono_and_GST() // Check if we have a new io } +// C: tells if W6 is available bool Galileo_Inav_Message::have_new_utc_model() // Check if we have a new utc data set stored in the galileo navigation class { if (flag_utc_model == true) @@ -355,6 +377,7 @@ bool Galileo_Inav_Message::have_new_utc_model() // Check if we have a new utc d } +// flag_almanac_4 tells if W10 available. bool Galileo_Inav_Message::have_new_almanac() // Check if we have a new almanac data set stored in the galileo navigation class { if ((flag_almanac_1 == true) and (flag_almanac_2 == true) and (flag_almanac_3 == true) and (flag_almanac_4 == true)) @@ -384,6 +407,17 @@ bool Galileo_Inav_Message::have_new_reduced_ced() } +bool Galileo_Inav_Message::have_new_ism() +{ + if (have_ISM) + { + have_ISM = false; + return true; + } + return false; +} + + Galileo_Ephemeris Galileo_Inav_Message::get_ephemeris() const { Galileo_Ephemeris ephemeris; @@ -595,6 +629,7 @@ void Galileo_Inav_Message::read_page_1(const std::bitset& DLOG(INFO) << "A_1= " << A_1; flag_ephemeris_1 = true; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; + nav_bits_word_1 = data_bits.to_string().substr(6, 120); } @@ -616,6 +651,7 @@ void Galileo_Inav_Message::read_page_2(const std::bitset& DLOG(INFO) << "iDot_2= " << iDot_2; flag_ephemeris_2 = true; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; + nav_bits_word_2 = data_bits.to_string().substr(6, 120); } @@ -645,6 +681,7 @@ void Galileo_Inav_Message::read_page_3(const std::bitset& DLOG(INFO) << "SISA_3= " << SISA_3; flag_ephemeris_3 = true; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; + nav_bits_word_3 = data_bits.to_string().substr(6, 122); } @@ -653,6 +690,7 @@ void Galileo_Inav_Message::read_page_4(const std::bitset& IOD_nav_4 = static_cast(read_navigation_unsigned(data_bits, IOD_NAV_4_BIT)); DLOG(INFO) << "IOD_nav_4= " << IOD_nav_4; SV_ID_PRN_4 = static_cast(read_navigation_unsigned(data_bits, SV_ID_PRN_4_BIT)); + nma_msg.PRN = static_cast(SV_ID_PRN_4); DLOG(INFO) << "SV_ID_PRN_4= " << SV_ID_PRN_4; C_ic_4 = static_cast(read_navigation_signed(data_bits, C_IC_4_BIT)); C_ic_4 = C_ic_4 * C_IC_4_LSB; @@ -677,6 +715,7 @@ void Galileo_Inav_Message::read_page_4(const std::bitset& DLOG(INFO) << "spare_4 = " << spare_4; flag_ephemeris_4 = true; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; + nav_bits_word_4 = data_bits.to_string().substr(6, 120); } @@ -811,6 +850,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) { case 1: // Word type 1: Ephemeris (1/4) { + page_position_in_inav_subframe = 10; read_page_1(data_jk_bits); if (enable_rs) { @@ -847,6 +887,14 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) case 2: // Word type 2: Ephemeris (2/4) { + // start of subframe, reset osnma parameters TODO - refactor + page_position_in_inav_subframe = 0; + nma_msg.mack = std::array{}; + nma_msg.hkroot = std::array{}; + nma_position_filled = std::array{}; + reset_osnma_nav_bits_adkd4(); + reset_osnma_nav_bits_adkd0_12(); + read_page_2(data_jk_bits); if (enable_rs) { @@ -878,6 +926,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) } case 3: // Word type 3: Ephemeris (3/4) and SISA { + page_position_in_inav_subframe = 11; read_page_3(data_jk_bits); if (enable_rs) { @@ -910,6 +959,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) case 4: // Word type 4: Ephemeris (4/4) and Clock correction parameters { + page_position_in_inav_subframe = 1; read_page_4(data_jk_bits); if (enable_rs) { @@ -941,6 +991,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) } case 5: // Word type 5: Ionospheric correction, BGD, signal health and data validity status and GST + page_position_in_inav_subframe = 12; // Ionospheric correction ai0_5 = static_cast(read_navigation_unsigned(data_jk_bits, AI0_5_BIT)); ai0_5 = ai0_5 * AI0_5_LSB; @@ -988,9 +1039,11 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) flag_iono_and_GST = true; // set to false externally flag_TOW_set = true; // set to false externally DLOG(INFO) << "flag_tow_set" << flag_TOW_set; + nav_bits_word_5 = data_jk_bits.to_string().substr(6, 67); break; case 6: // Word type 6: GST-UTC conversion parameters + page_position_in_inav_subframe = 2; A0_6 = static_cast(read_navigation_signed(data_jk_bits, A0_6_BIT)); A0_6 = A0_6 * A0_6_LSB; DLOG(INFO) << "A0_6= " << A0_6; @@ -1016,9 +1069,11 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) flag_utc_model = true; // set to false externally flag_TOW_set = true; // set to false externally DLOG(INFO) << "flag_tow_set" << flag_TOW_set; + nav_bits_word_6 = data_jk_bits.to_string().substr(6, 99); break; case 7: // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number + page_position_in_inav_subframe = 3; IOD_a_7 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_A_7_BIT)); DLOG(INFO) << "IOD_a_7= " << IOD_a_7; WN_a_7 = static_cast(read_navigation_unsigned(data_jk_bits, WN_A_7_BIT)); @@ -1053,7 +1108,8 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; - case 8: // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2)*/ + case 8: // Word type 8: Almanac for SVID1 (2/2) and SVID2 (1/2) + page_position_in_inav_subframe = 4; IOD_a_8 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_A_8_BIT)); DLOG(INFO) << "IOD_a_8= " << IOD_a_8; af0_8 = static_cast(read_navigation_signed(data_jk_bits, AF0_8_BIT)); @@ -1091,6 +1147,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) break; case 9: // Word type 9: Almanac for SVID2 (2/2) and SVID3 (1/2) + page_position_in_inav_subframe = 3; IOD_a_9 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_A_9_BIT)); DLOG(INFO) << "IOD_a_9= " << IOD_a_9; WN_a_9 = static_cast(read_navigation_unsigned(data_jk_bits, WN_A_9_BIT)); @@ -1130,6 +1187,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) break; case 10: // Word type 10: Almanac for SVID3 (2/2) and GST-GPS conversion parameters + page_position_in_inav_subframe = 4; IOD_a_10 = static_cast(read_navigation_unsigned(data_jk_bits, IOD_A_10_BIT)); DLOG(INFO) << "IOD_a_10= " << IOD_a_10; Omega0_10 = static_cast(read_navigation_signed(data_jk_bits, OMEGA0_10_BIT)); @@ -1168,6 +1226,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) DLOG(INFO) << "WN_0G_10= " << WN_0G_10; flag_almanac_4 = true; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; + nav_bits_word_10 = data_jk_bits.to_string().substr(86, 42); break; case 16: // Word type 16: Reduced Clock and Ephemeris Data (CED) parameters @@ -1201,6 +1260,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) case 17: // Word type 17: FEC2 Reed-Solomon for CED { + page_position_in_inav_subframe = 5; if (enable_rs) { IODnav_LSB17 = read_octet_unsigned(data_jk_bits, RS_IODNAV_LSBS); @@ -1230,6 +1290,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) case 18: // Word type 18: FEC2 Reed-Solomon for CED { + page_position_in_inav_subframe = 5; if (enable_rs) { IODnav_LSB18 = read_octet_unsigned(data_jk_bits, RS_IODNAV_LSBS); @@ -1259,6 +1320,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) case 19: // Word type 19: FEC2 Reed-Solomon for CED { + page_position_in_inav_subframe = 6; if (enable_rs) { IODnav_LSB19 = read_octet_unsigned(data_jk_bits, RS_IODNAV_LSBS); @@ -1288,6 +1350,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) case 20: // Word type 20: FEC2 Reed-Solomon for CED { + page_position_in_inav_subframe = 6; if (enable_rs) { IODnav_LSB20 = read_octet_unsigned(data_jk_bits, RS_IODNAV_LSBS); @@ -1315,6 +1378,50 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) break; } + case 22: // Word Type 22: ARAIM Integrity Support Message (ISM) + DLOG(INFO) << "Word type 22 arrived"; + ism_constellation_id = read_octet_unsigned(data_jk_bits, ISM_CONSTELLATION_ID_BIT); + ism_service_level_id = read_octet_unsigned(data_jk_bits, ISM_SERVICE_LEVEL_ID_BIT); + if (gal_ism.check_ism_crc(data_jk_bits)) + { + DLOG(INFO) << "I/NAV ARAIM Integrity Support Message CRC OK"; + gal_ism.set_ism_constellation_id(ism_constellation_id); + gal_ism.set_ism_service_level_id(ism_service_level_id); + if (ism_constellation_id == 0) + { + LOG(INFO) << "I/NAV ARAIM Integrity Support Message in Test"; + } + if (ism_constellation_id == 1) + { + if (ism_service_level_id == 2) + { + gal_ism.set_ism_wn(static_cast(read_navigation_unsigned(data_jk_bits, ISM_WN_BIT))); + gal_ism.set_ism_t0(static_cast(read_navigation_unsigned(data_jk_bits, ISM_T0_BIT))); + gal_ism.set_ism_mask_msb(read_navigation_bool(data_jk_bits, ISM_MASK_MSB_BIT)); + gal_ism.set_ism_mask(static_cast(read_navigation_unsigned(data_jk_bits, ISM_MASK_BIT))); + gal_ism.set_ism_pconst(read_octet_unsigned(data_jk_bits, ISM_PCONST_BIT)); + gal_ism.set_ism_psat(read_octet_unsigned(data_jk_bits, ISM_PSAT_BIT)); + gal_ism.set_ism_ura(read_octet_unsigned(data_jk_bits, ISM_URA_BIT)); + gal_ism.set_ism_ure(read_octet_unsigned(data_jk_bits, ISM_URE_BIT)); + gal_ism.set_ism_bnom(read_octet_unsigned(data_jk_bits, ISM_BNOM_BIT)); + gal_ism.set_ism_Tvalidity(read_octet_unsigned(data_jk_bits, ISM_TVALIDITY_BIT)); + LOG(INFO) << "I/NAV ARAIM Integrity Support Message: " + << "WN_ISM=" << static_cast(gal_ism.get_WN_ISM()) << ", " + << "t0_ISM=" << static_cast(gal_ism.get_t0_ISM()) << ", " + << "Mask_MSB_ISM=" << static_cast(gal_ism.get_ism_mask_msb()) << ", " + << "Mask_ISM=" << gal_ism.get_mask_ISM() << ", " + << "Pconst=" << gal_ism.get_pconst_value() << ", " + << "Psat=" << gal_ism.get_psat_value() << ", " + << "URA=" << gal_ism.get_ura_m() << " [m], " + << "URE=" << gal_ism.get_ure_m() << " [m], " + << "Bnom=" << gal_ism.get_bnom_m() << " [m], " + << "Tvalidity=" << static_cast(gal_ism.get_Tvalidity_hours()) << " [h]"; + } + } + have_ISM = true; + } + break; + case 0: // Word type 0: I/NAV Spare Word Time_0 = static_cast(read_navigation_unsigned(data_jk_bits, TIME_0_BIT)); DLOG(INFO) << "Time_0= " << Time_0; @@ -1334,5 +1441,91 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) default: break; } + + if (page_position_in_inav_subframe > 14 && + page_position_in_inav_subframe != 255) + { + // something weird happened, reset + page_position_in_inav_subframe = 255; + nma_position_filled = std::array{}; + nma_msg.mack = std::array{}; + nma_msg.hkroot = std::array{}; + reset_osnma_nav_bits_adkd4(); + reset_osnma_nav_bits_adkd0_12(); + } + return page_number; } + + +Galileo_ISM Galileo_Inav_Message::get_galileo_ism() const +{ + return gal_ism; +} + + +/** + * @brief Get data relevant for Galileo OSNMA + * + * \details This function retrieves various parameters and data to compose the OSNMA_msg. + * It fills the TOW and WN fields of the message and retrieves ephemeris, iono, and + * + * @return The OSNMA message + */ +OSNMA_msg Galileo_Inav_Message::get_osnma_msg() +{ + nma_position_filled = std::array{}; + // Fill TOW and WN + nma_msg.WN_sf0 = WN_0; + int32_t TOW_sf0 = TOW_5 - 25; + if (TOW_sf0 < 0) + { + TOW_sf0 += 604800; + } + nma_msg.TOW_sf0 = static_cast(TOW_sf0); + return nma_msg; +} + + +bool Galileo_Inav_Message::have_new_nma() +{ + if (std::all_of(nma_position_filled.begin(), nma_position_filled.end(), [](int8_t element) { return element == 1; })) + { + return true; + } + else + { + return false; + } +} + + +std::string Galileo_Inav_Message::get_osnma_adkd_4_nav_bits() +{ + nav_bits_adkd_4 = nav_bits_word_6 + nav_bits_word_10; + return nav_bits_adkd_4; +} + + +std::string Galileo_Inav_Message::get_osnma_adkd_0_12_nav_bits() +{ + nav_bits_adkd_0_12 = nav_bits_word_1 + nav_bits_word_2 + nav_bits_word_3 + nav_bits_word_4 + nav_bits_word_5; + return nav_bits_adkd_0_12; +} + + +void Galileo_Inav_Message::reset_osnma_nav_bits_adkd0_12() +{ + nav_bits_word_1 = ""; + nav_bits_word_2 = ""; + nav_bits_word_3 = ""; + nav_bits_word_4 = ""; + nav_bits_word_5 = ""; +} + + +void Galileo_Inav_Message::reset_osnma_nav_bits_adkd4() +{ + nav_bits_word_6 = ""; + nav_bits_word_10 = ""; +} diff --git a/src/core/system_parameters/galileo_inav_message.h b/src/core/system_parameters/galileo_inav_message.h index 1b37e9083..f60c884d5 100644 --- a/src/core/system_parameters/galileo_inav_message.h +++ b/src/core/system_parameters/galileo_inav_message.h @@ -23,8 +23,10 @@ #include "galileo_almanac_helper.h" #include "galileo_ephemeris.h" #include "galileo_iono.h" +#include "galileo_ism.h" #include "galileo_utc_model.h" #include "gnss_sdr_make_unique.h" // for std::unique_ptr in C++11 +#include #include #include #include @@ -38,7 +40,19 @@ class ReedSolomon; // Forward declaration of the ReedSolomon class * \{ */ /** \addtogroup System_Parameters * \{ */ - +/*! + * \brief This class fills the OSNMA_msg structure with the data received from the telemetry blocks. + */ +class OSNMA_msg +{ +public: + OSNMA_msg() = default; + std::array mack{}; + std::array hkroot{}; + uint32_t PRN{}; // PRN_a authentication data PRN + uint32_t WN_sf0{}; // Week number at the start of OSNMA subframe + uint32_t TOW_sf0{}; // TOW at the start of OSNMA subframe +}; /*! * \brief This class handles the Galileo I/NAV Data message, as described in the @@ -57,13 +71,6 @@ public: */ void split_page(std::string page_string, int32_t flag_even_word); - /* - * \brief Takes in input Data_jk (128 bit) and split it in ephemeris parameters according ICD 4.3.5 - * - * Takes in input Data_jk (128 bit) and split it in ephemeris parameters according ICD 4.3.5 - */ - int32_t page_jk_decoder(const char* data_jk); - /* * \brief Returns true if new Ephemeris has arrived. The flag is set to false when the function is executed */ @@ -89,6 +96,16 @@ public: */ bool have_new_reduced_ced(); + /* + * \brief Returns true if new ISM data have arrived. The flag is set to false when the function is executed + */ + bool have_new_ism(); + + /* + * \brief Returns true if new NMA data have arrived. The flag is set to false when the function is executed + */ + bool have_new_nma(); + /* * \brief Returns a Galileo_Ephemeris object filled with the latest navigation data received */ @@ -114,6 +131,36 @@ public: */ Galileo_Ephemeris get_reduced_ced() const; + /* + * \brief Returns a Galileo_ISMs object filled with the latest ISM data received + */ + Galileo_ISM get_galileo_ism() const; + + /* + * \brief Returns an OSNMA_msg object filled with the latest NMA message received. Resets msg buffer. + */ + OSNMA_msg get_osnma_msg(); + + /* + * @brief Retrieves the OSNMA ADKD 4 NAV bits. Resets the string. + */ + std::string get_osnma_adkd_4_nav_bits(); + + /* + * @brief Resets the OSNMA ADKD 4 NAV bits. + */ + void reset_osnma_nav_bits_adkd4(); + + /* + * @brief Retrieves the OSNMA ADKD 0/12 NAV bits. Resets the string. + */ + std::string get_osnma_adkd_0_12_nav_bits(); + + /* + * @brief Resets the OSNMA ADKD 0/12 NAV bits. + */ + void reset_osnma_nav_bits_adkd0_12(); + inline bool get_flag_CRC_test() const { return flag_CRC_test; @@ -210,6 +257,11 @@ public: inline void init_PRN(uint32_t prn) { SV_ID_PRN_4 = prn; + nma_msg.PRN = prn; + nma_msg.mack = std::array{}; + nma_msg.hkroot = std::array{}; + page_position_in_inav_subframe = 255; + nma_position_filled = std::array{}; } /* @@ -236,13 +288,14 @@ private: std::bitset regenerate_page_3(const std::vector& decoded) const; std::bitset regenerate_page_4(const std::vector& decoded) const; + Galileo_ISM gal_ism{}; std::string page_Even{}; std::vector rs_buffer; // Reed-Solomon buffer std::unique_ptr rs; // The Reed-Solomon decoder std::vector inav_rs_pages; // Pages 1,2,3,4,17,18,19,20. Holds 1 if the page has arrived, 0 otherwise. - int32_t Page_type_time_stamp{}; + int32_t page_jk_decoder(const char* data_jk); int32_t IOD_ephemeris{}; // Word type 1: Ephemeris (1/4) @@ -394,11 +447,30 @@ private: int32_t current_IODnav{}; + // OSNMA + uint32_t mack_sis{}; + uint8_t hkroot_sis{}; + uint8_t page_position_in_inav_subframe{255}; + std::array nma_position_filled{}; + OSNMA_msg nma_msg{}; + std::string nav_bits_adkd_4{}; + std::string nav_bits_word_6{}; + std::string nav_bits_word_10{}; + std::string nav_bits_adkd_0_12{}; + std::string nav_bits_word_1{}; + std::string nav_bits_word_2{}; + std::string nav_bits_word_3{}; + std::string nav_bits_word_4{}; + std::string nav_bits_word_5{}; + uint8_t IODnav_LSB17{}; uint8_t IODnav_LSB18{}; uint8_t IODnav_LSB19{}; uint8_t IODnav_LSB20{}; + uint8_t ism_constellation_id{}; + uint8_t ism_service_level_id{}; + bool flag_CRC_test{}; bool flag_all_ephemeris{}; // Flag indicating that all words containing ephemeris have been received bool flag_ephemeris_1{}; // Flag indicating that ephemeris 1/4 (word 1) have been received @@ -426,6 +498,7 @@ private: bool flag_CED{}; bool enable_rs{}; + bool have_ISM{}; }; diff --git a/src/core/system_parameters/galileo_ism.cc b/src/core/system_parameters/galileo_ism.cc new file mode 100644 index 000000000..2cad8b410 --- /dev/null +++ b/src/core/system_parameters/galileo_ism.cc @@ -0,0 +1,253 @@ +/*! + * \file galileo_ism.cc + * \brief Interface of a Galileo Integrity Support Message + * \author Carles Fernandez, 2024. cfernandez(at)cttc.cat + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "galileo_ism.h" +#include + +void Galileo_ISM::set_ism_constellation_id(uint8_t const_id) +{ + this->d_ism_constellation_id = const_id; +} + + +void Galileo_ISM::set_ism_service_level_id(uint8_t sl_id) +{ + this->d_ism_service_level_id = sl_id; +} + + +void Galileo_ISM::set_ism_wn(uint16_t wn_ism) +{ + this->d_ism_wn = wn_ism; +} + + +void Galileo_ISM::set_ism_t0(uint16_t t0) +{ + this->d_ism_t0 = t0; +} + + +void Galileo_ISM::set_ism_mask_msb(bool mask_msb) +{ + this->d_ism_mask_msb = mask_msb; +} + + +void Galileo_ISM::set_ism_mask(uint32_t mask) +{ + this->d_ism_mask = mask; +} + + +void Galileo_ISM::set_ism_pconst(uint8_t pconst) +{ + this->d_ism_pconst = pconst; +} + + +void Galileo_ISM::set_ism_psat(uint8_t psat) +{ + this->d_ism_psat = psat; +} + + +void Galileo_ISM::set_ism_ura(uint8_t ura) +{ + this->d_ism_ura = ura; +} + + +void Galileo_ISM::set_ism_ure(uint8_t ure) +{ + this->d_ism_ure = ure; +} + + +void Galileo_ISM::set_ism_bnom(uint8_t bnom) +{ + this->d_ism_bnom = bnom; +} + + +void Galileo_ISM::set_ism_Tvalidity(uint8_t tvalidity) +{ + this->d_ism_Tvalidity = tvalidity; +} + + +uint16_t Galileo_ISM::get_WN_ISM() const +{ + return this->d_ism_wn; +} + + +uint16_t Galileo_ISM::get_t0_ISM() const +{ + return (this->d_ism_t0 * 1800); +} + + +double Galileo_ISM::get_pconst_value() const +{ + auto it = d_ISM_PCONST_MAP.find(this->d_ism_pconst); + if (it == d_ISM_PCONST_MAP.end()) + { + return 0.0; + } + return it->second; +} + + +double Galileo_ISM::get_psat_value() const +{ + auto it = d_ISM_PSAT_MAP.find(this->d_ism_psat); + if (it == d_ISM_PSAT_MAP.end()) + { + return 0.0; + } + return it->second; +} + + +bool Galileo_ISM::get_ism_mask_msb() const +{ + return d_ism_mask_msb; +} + + +float Galileo_ISM::get_ura_m() const +{ + auto it = d_ISM_URA_MAP.find(this->d_ism_ura); + if (it == d_ISM_URA_MAP.end()) + { + return 0.0; + } + return it->second; +} + + +float Galileo_ISM::get_ure_m() const +{ + auto it = d_ISM_URE_MAP.find(this->d_ism_ure); + if (it == d_ISM_URE_MAP.end()) + { + return 0.0; + } + return it->second; +} + + +uint32_t Galileo_ISM::get_mask_ISM() const +{ + return d_ism_mask; +} + + +float Galileo_ISM::get_bnom_m() const +{ + auto it = d_ISM_BNOM_MAP.find(this->d_ism_bnom); + if (it == d_ISM_BNOM_MAP.end()) + { + return 5.0; // + } + return it->second; +} + + +uint16_t Galileo_ISM::get_Tvalidity_hours() const +{ + auto it = d_ISM_TVALIDITY_MAP.find(this->d_ism_Tvalidity); + if (it == d_ISM_TVALIDITY_MAP.end()) + { + return 0.0; + } + return it->second; +} + + +bool Galileo_ISM::check_ism_crc(const std::bitset& bits) +{ + std::bitset data_bits; + for (int32_t i = 0; i < GALILEO_ISM_CRC_DATA_BITS; ++i) + { + data_bits[i] = bits[i + 32]; + } + std::bitset<32> crc_bits; + for (int32_t i = 0; i < 32; ++i) + { + crc_bits[i] = bits[i]; + } + this->d_ism_crc = crc_bits.to_ulong(); + + std::vector data_bytes((data_bits.size() + 7) / 8); + for (size_t i = 0; i < data_bits.size(); i += 8) + { + uint8_t byte = 0; + for (size_t j = 0; j < 8 && i + j < data_bits.size(); ++j) + { + byte |= (data_bits[i + j] << j); + } + data_bytes[i / 8] = byte; + } + + std::reverse(data_bytes.begin(), data_bytes.end()); + const uint32_t crc_computed = this->compute_crc(data_bytes); + + if (this->d_ism_crc == crc_computed) + { + return true; + } + + return false; +} + + +uint32_t Galileo_ISM::compute_crc(const std::vector& data) +{ + d_crc32_ism.process_bytes(data.data(), data.size()); + const uint32_t crc = d_crc32_ism.checksum(); + d_crc32_ism.reset(); + return crc; +} + + +bool Galileo_ISM::ism_parameters_apply(uint32_t prn) const +{ + // ICD 2.1 Table 96 + if (prn == 0 || prn > 63 || d_ism_service_level_id != 2 || d_ism_constellation_id != 1) + { + return false; + } + std::bitset<32> b(d_ism_mask); + if (d_ism_mask_msb == false) + { + // For numbering in the ICD, the most significant bit/byte is numbered as bit/byte 0 + if (prn > 32) + { + return false; + } + return b.test(32 - prn); + } + else + { + if (prn <= 32) + { + return false; + } + return b.test(64 - prn); + } +} diff --git a/src/core/system_parameters/galileo_ism.h b/src/core/system_parameters/galileo_ism.h new file mode 100644 index 000000000..359754176 --- /dev/null +++ b/src/core/system_parameters/galileo_ism.h @@ -0,0 +1,210 @@ +/*! + * \file galileo_ism.h + * \brief Interface of a Galileo Integrity Support Message + * \author Carles Fernandez, 2024. cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GALILEO_ISM_H +#define GNSS_SDR_GALILEO_ISM_H + +#include "Galileo_INAV.h" +#include +#include +#include +#include +#include + +/** \addtogroup Core + * \{ */ +/** \addtogroup System_Parameters + * \{ */ + + +/*! + * \brief This class is a storage for the GALILEO Integrity Support Message as described + * in Galileo ICD paragraph 5.2 + * + * See https://www.gsc-europa.eu/sites/default/files/sites/all/files/Galileo_OS_SIS_ICD_v2.1.pdf + */ +class Galileo_ISM +{ +public: + /*! + * Default constructor + */ + Galileo_ISM() = default; + + void set_ism_constellation_id(uint8_t const_id); + void set_ism_service_level_id(uint8_t sl_id); + void set_ism_wn(uint16_t wn_ism); + void set_ism_t0(uint16_t t0); + void set_ism_mask_msb(bool mask_msb); + void set_ism_mask(uint32_t mask); + void set_ism_pconst(uint8_t pconst); + void set_ism_psat(uint8_t psat); + void set_ism_ura(uint8_t ura); + void set_ism_ure(uint8_t ure); + void set_ism_bnom(uint8_t bnom); + void set_ism_Tvalidity(uint8_t tvalidity); + + bool check_ism_crc(const std::bitset& bits); + + double get_pconst_value() const; + double get_psat_value() const; + float get_ura_m() const; + float get_ure_m() const; + float get_bnom_m() const; + uint32_t get_mask_ISM() const; + uint16_t get_WN_ISM() const; + uint16_t get_t0_ISM() const; + uint16_t get_Tvalidity_hours() const; + bool get_ism_mask_msb() const; + bool ism_parameters_apply(uint32_t prn) const; + +private: + uint32_t compute_crc(const std::vector& data); + boost::crc_optimal<32, 0x814141AB, 0, 0, false, false> d_crc32_ism; + + // ICD 2.1 Table 97 + std::unordered_map d_ISM_PCONST_MAP = { + {0, 1.0e-8}, + {1, 1.0e-7}, + {2, 1.0e-6}, + {3, 3.0e-6}, + {4, 6.0e-6}, + {5, 8.0e-6}, + {6, 1.0e-5}, + {7, 2.0e-5}, + {8, 4.0e-5}, + {9, 6.0e-5}, + {10, 8.0e-5}, + {11, 1.0e-4}, + {12, 1.25e-4}, + {13, 1.5e-4}, + {14, 1.75e-4}, + {15, 2.0e-4}}; + + // ICD 2.1 Table 98 + std::unordered_map d_ISM_PSAT_MAP = { + {0, 1.0e-7}, + {1, 3.0e-7}, + {2, 6.0e-7}, + {3, 1.0e-6}, + {4, 2.0e-6}, + {5, 3.0e-6}, + {6, 5.0e-6}, + {7, 7.0e-6}, + {8, 1.0e-5}, + {9, 1.2e-5}, + {10, 1.4e-5}, + {11, 1.7e-5}, + {12, 2.05e-5}, + {13, 2.4e-5}, + {14, 2.8e-5}, + {15, 3.0e-5}}; + + // ICD 2.1 Table 99 + std::unordered_map d_ISM_URA_MAP = { + {0, 0.75}, + {1, 1.0}, + {2, 1.5}, + {3, 2.0}, + {4, 2.25}, + {5, 2.50}, + {6, 2.75}, + {7, 3.0}, + {8, 3.25}, + {9, 3.50}, + {10, 3.75}, + {11, 4.0}, + {12, 4.50}, + {13, 5.0}, + {14, 5.50}, + {15, 6.0}}; + + // ICD 2.1 Table 100 + std::unordered_map d_ISM_URE_MAP = { + {0, 0.25}, + {1, 0.50}, + {2, 0.75}, + {3, 1.00}, + {4, 1.25}, + {5, 1.50}, + {6, 1.75}, + {7, 2.0}, + {8, 2.25}, + {9, 2.50}, + {10, 2.75}, + {11, 3.0}, + {12, 3.25}, + {13, 3.50}, + {14, 3.75}, + {15, 4.00}}; + + // ICD 2.1 Table 101 + std::unordered_map d_ISM_BNOM_MAP = { + {0, 0.0}, + {1, 0.10}, + {2, 0.20}, + {3, 0.30}, + {4, 0.40}, + {5, 0.50}, + {6, 0.60}, + {7, 0.75}, + {8, 0.85}, + {9, 1.0}, + {10, 1.20}, + {11, 1.40}, + {12, 1.60}, + {13, 1.80}, + {14, 2.0}, + {15, 2.4}}; + + // ICD 2.1 Table 102 + std::unordered_map d_ISM_TVALIDITY_MAP = { + {0, 1}, + {1, 2}, + {2, 3}, + {3, 4}, + {4, 6}, + {5, 8}, + {6, 12}, + {7, 18}, + {8, 24}, + {9, 36}, + {10, 48}, + {11, 72}, + {12, 120}, + {13, 168}, + {14, 720}, + {15, 1440}}; + + uint32_t d_ism_crc{}; + uint32_t d_ism_mask{}; + uint16_t d_ism_wn{}; + uint16_t d_ism_t0{}; + uint8_t d_ism_constellation_id{}; + uint8_t d_ism_service_level_id{}; + uint8_t d_ism_pconst{}; + uint8_t d_ism_psat{}; + uint8_t d_ism_ura{}; + uint8_t d_ism_ure{}; + uint8_t d_ism_bnom{}; + uint8_t d_ism_Tvalidity{}; + bool d_ism_mask_msb{}; +}; + +/** \} */ +/** \} */ +#endif // GNSS_SDR_GALILEO_ISM_H \ No newline at end of file diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index 9428875c4..d30f6057f 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -19,10 +19,15 @@ #include "glonass_gnav_navigation_message.h" #include "MATH_CONSTANTS.h" // for TWO_N20, TWO_N30, TWO_N14, TWO_N15, TWO_N18 #include "gnss_satellite.h" -#include #include // for size_t #include // for operator<< +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message() { @@ -360,7 +365,7 @@ int32_t Glonass_Gnav_Navigation_Message::string_decoder(const std::string& frame flag_TOW_new = true; } - // 4) Set time of day (tod) when ephemeris data is complety decoded + // 4) Set time of day (tod) when ephemeris data is completely decoded gnav_ephemeris.d_tod = gnav_ephemeris.d_t_k + 2 * d_string_ID; } diff --git a/src/core/system_parameters/gnss_almanac.cc b/src/core/system_parameters/gnss_almanac.cc index 923416832..66ae631f6 100644 --- a/src/core/system_parameters/gnss_almanac.cc +++ b/src/core/system_parameters/gnss_almanac.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include double Gnss_Almanac::check_t(double time) const diff --git a/src/core/system_parameters/gnss_ephemeris.cc b/src/core/system_parameters/gnss_ephemeris.cc index d95d14a28..e49bf8b81 100644 --- a/src/core/system_parameters/gnss_ephemeris.cc +++ b/src/core/system_parameters/gnss_ephemeris.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index 2a974cc0a..2867a36da 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -15,9 +15,14 @@ */ #include "gnss_satellite.h" -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + Gnss_Satellite::Gnss_Satellite(const std::string& system_, uint32_t PRN_) { @@ -73,11 +78,22 @@ bool operator==(const Gnss_Satellite& sat1, const Gnss_Satellite& sat2) // Copy constructor Gnss_Satellite::Gnss_Satellite(const Gnss_Satellite& other) noexcept - : system(other.system), - block(other.block), - PRN(other.PRN), + : PRN(other.PRN), rf_link(other.rf_link) { + try + { + system = other.system; + block = other.block; + } + catch (...) + { + // Handle failure by creating a valid but empty object + system.clear(); + block.clear(); + PRN = 0; + rf_link = 0; + } } @@ -87,10 +103,22 @@ Gnss_Satellite& Gnss_Satellite::operator=(const Gnss_Satellite& rhs) noexcept // Only do assignment if RHS is a different object from this. if (this != &rhs) { - this->system = rhs.system; - this->block = rhs.block; - this->PRN = rhs.PRN; - this->rf_link = rhs.rf_link; + try + { + // Copy strings first + std::string tmp_system = rhs.system; + std::string tmp_block = rhs.block; + + // If we get here, string copies succeeded + system = std::move(tmp_system); + block = std::move(tmp_block); + PRN = rhs.PRN; + rf_link = rhs.rf_link; + } + catch (...) + { + // Keep object in valid state by not modifying it + } } return *this; } @@ -386,7 +414,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ block_ = std::string("IIF"); // Plane C break; case 28: - block_ = std::string("IIR"); // Plane B + block_ = std::string("III"); // Plane B break; case 29: block_ = std::string("IIR-M"); // Plane C @@ -543,7 +571,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ switch (PRN_) { case 1: - block_ = std::string("FOC-FM10"); // Galileo Full Operational Capability (FOC) satellite FM10 / GSAT-0210, launched on May 24, 2016. + block_ = std::string("FOC-FM10"); // Galileo Full Operational Capability (FOC) satellite FM10 / GSAT-0210, launched on May 24, 2016. NOT USABLE. break; case 2: block_ = std::string("FOC-FM11"); // Galileo Full Operational Capability (FOC) satellite FM11 / GSAT-0211, launched on May 24, 2016. @@ -557,6 +585,9 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ case 5: block_ = std::string("FOC-FM14"); // Galileo Full Operational Capability (FOC) satellite FM14 / GSAT-0214, launched on November 17, 2016. break; + case 6: + block_ = std::string("FOC-FM27"); // Galileo Full Operational Capability (FOC) satellite FM27 / GSAT0227, launched on Apr. 28, 2024. UNDER COMMISSIONING. + break; case 7: block_ = std::string("FOC-FM7"); // Galileo Full Operational Capability (FOC) satellite FM7 / GSAT-0207, launched on November 17, 2016. break; @@ -576,16 +607,16 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ block_ = std::string("IOV-FM2"); // Galileo In-Orbit Validation (IOV) satellite FM2 (Flight Model 2) also known as GSAT0102, from French Guiana at 10:30 GMT on October 21, 2011. break; case 13: - block_ = std::string("FOC-FM20"); // Galileo Full Operational Capability (FOC) satellite FM20 / GSAT0220, launched on Jul. 25, 2018. UNDER COMMISSIONING. + block_ = std::string("FOC-FM20"); // Galileo Full Operational Capability (FOC) satellite FM20 / GSAT0220, launched on Jul. 25, 2018. break; case 14: - block_ = std::string("FOC-FM2*"); // Galileo Full Operational Capability (FOC) satellite FM2 / GSAT0202, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in March, 2015. UNDER TESTING. + block_ = std::string("FOC-FM2*"); // Galileo Full Operational Capability (FOC) satellite FM2 / GSAT0202, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in March, 2015. Not usable since 18/02/2021. break; case 15: - block_ = std::string("FOC-FM21"); // Galileo Full Operational Capability (FOC) satellite FM21 / GSAT0221, launched on Jul. 25, 2018. UNDER COMMISSIONING. + block_ = std::string("FOC-FM21"); // Galileo Full Operational Capability (FOC) satellite FM21 / GSAT0221, launched on Jul. 25, 2018. break; case 18: - block_ = std::string("FOC-FM1*"); // Galileo Full Operational Capability (FOC) satellite FM1 / GSAT0201, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in December, 2014. UNDER TESTING. + block_ = std::string("FOC-FM1*"); // Galileo Full Operational Capability (FOC) satellite FM1 / GSAT0201, launched into incorrect orbit on August 22, 2014. Moved to usable orbit in December, 2014. Not usable since 18/02/2021. break; case 19: block_ = std::string("IOV-FM3"); // Galileo In-Orbit Validation (IOV) satellite FM3 (Flight Model 3) / GSAT0103, launched on October 12, 2012. @@ -594,7 +625,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ block_ = std::string("IOV-FM4**"); // Galileo In-Orbit Validation (IOV) satellite FM4 (Flight Model 4) / GSAT0104, launched on October 12, 2012. Payload power problem beginning May 27, 2014 led to permanent loss of E5 and E6 transmissions, E1 transmission restored. UNAVAILABLE FROM 2014-05-27 UNTIL FURTHER NOTICE break; case 21: - block_ = std::string("FOC-FM15"); // Galileo Full Operational Capability (FOC) satellite FM15 / GSAT0215, launched on Dec. 12, 2017. UNDER COMMISSIONING. + block_ = std::string("FOC-FM15"); // Galileo Full Operational Capability (FOC) satellite FM15 / GSAT0215, launched on Dec. 12, 2017. break; case 22: block_ = std::string("FOC-FM4**"); // Galileo Full Operational Capability (FOC) satellite FM4 / GSAT0204, launched on March 27, 2015. REMOVED FROM ACTIVE SERVICE ON 2017-12-08 UNTIL FURTHER NOTICE FOR CONSTELLATION MANAGEMENT PURPOSES. @@ -603,28 +634,31 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ block_ = std::string("FOC-FM5"); // Galileo Full Operational Capability (FOC) satellite FM5 / GSAT0205, launched on Sept. 11, 2015. break; case 25: - block_ = std::string("FOC-FM16"); // Galileo Full Operational Capability (FOC) satellite FM16 / GSAT0216, launched on Dec. 12, 2017. UNDER COMMISSIONING. + block_ = std::string("FOC-FM16"); // Galileo Full Operational Capability (FOC) satellite FM16 / GSAT0216, launched on Dec. 12, 2017. break; case 26: block_ = std::string("FOC-FM3"); // Galileo Full Operational Capability (FOC) satellite FM3 / GSAT0203, launched on March 27, 2015. break; case 27: - block_ = std::string("FOC-FM17"); // Galileo Full Operational Capability (FOC) satellite FM17 / GSAT0217, launched on Dec. 12, 2017. UNDER COMMISSIONING. + block_ = std::string("FOC-FM17"); // Galileo Full Operational Capability (FOC) satellite FM17 / GSAT0217, launched on Dec. 12, 2017. + break; + case 29: + block_ = std::string("FOC-FM25"); // Galileo Full Operational Capability (FOC) satellite FM25 / GSAT0225, launched on Apr. 28, 2024. UNDER COMMISSIONING. break; case 30: block_ = std::string("FOC-FM6"); // Galileo Full Operational Capability (FOC) satellite FM6 / GSAT0206, launched on Sept. 11, 2015. break; case 31: - block_ = std::string("FOC-FM18"); // Galileo Full Operational Capability (FOC) satellite FM18 / GSAT0218, launched on Dec. 12, 2017. UNDER COMMISSIONING. + block_ = std::string("FOC-FM18"); // Galileo Full Operational Capability (FOC) satellite FM18 / GSAT0218, launched on Dec. 12, 2017. break; case 33: - block_ = std::string("FOC-FM22"); // Galileo Full Operational Capability (FOC) satellite FM22 / GSAT0222, launched on Jul. 25, 2018. UNDER COMMISSIONING. + block_ = std::string("FOC-FM22"); // Galileo Full Operational Capability (FOC) satellite FM22 / GSAT0222, launched on Jul. 25, 2018. break; case 34: block_ = std::string("FOC-FM23"); // Galileo Full Operational Capability (FOC) satellite FM23 / GSAT0223, launched on December 5, 2021. break; case 36: - block_ = std::string("FOC-FM19"); // Galileo Full Operational Capability (FOC) satellite FM19 / GSAT0219, launched on Jul. 25, 2018. UNDER COMMISSIONING. + block_ = std::string("FOC-FM19"); // Galileo Full Operational Capability (FOC) satellite FM19 / GSAT0219, launched on Jul. 25, 2018. break; default: block_ = std::string("Unknown"); diff --git a/src/core/system_parameters/gps_cnav_navigation_message.cc b/src/core/system_parameters/gps_cnav_navigation_message.cc index 9b9b2e907..5751e94c2 100644 --- a/src/core/system_parameters/gps_cnav_navigation_message.cc +++ b/src/core/system_parameters/gps_cnav_navigation_message.cc @@ -145,7 +145,7 @@ void Gps_CNAV_Navigation_Message::decode_page(const std::bitset(read_navigation_unsigned(data_bits, CNAV_TOC)); ephemeris_record.toc *= CNAV_TOC_LSB; @@ -159,7 +159,7 @@ void Gps_CNAV_Navigation_Message::decode_page(const std::bitset(read_navigation_signed(data_bits, CNAV_AF2)); ephemeris_record.af2 *= CNAV_AF2_LSB; // group delays - // Check if the grup delay values are not available. See IS-GPS-200, Table 30-IV. + // Check if the group delay values are not available. See IS-GPS-200, Table 30-IV. // Bit string "1000000000000" is -4096 in 2 complement ephemeris_record.TGD = static_cast(read_navigation_signed(data_bits, CNAV_TGD)); if (ephemeris_record.TGD < -4095.9) diff --git a/src/core/system_parameters/gps_navigation_message.cc b/src/core/system_parameters/gps_navigation_message.cc index b17458da7..2dfcc84fe 100644 --- a/src/core/system_parameters/gps_navigation_message.cc +++ b/src/core/system_parameters/gps_navigation_message.cc @@ -201,9 +201,31 @@ int32_t Gps_Navigation_Message::subframe_decoder(const char* subframe) SV_page = static_cast(read_navigation_unsigned(subframe_bits, SV_PAGE)); if (SV_page > 24 && SV_page < 33) // Page 4 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M) { - //! \TODO read almanac if (SV_data_ID != 0) { + a_M_0 = static_cast(read_navigation_signed(subframe_bits, ALM_MZERO)); + a_M_0 = a_M_0 * ALM_MZERO_LSB; + a_ecc = static_cast(read_navigation_unsigned(subframe_bits, ALM_ECC)); + a_ecc = a_ecc * ALM_ECC_LSB; + a_sqrtA = static_cast(read_navigation_unsigned(subframe_bits, ALM_SQUAREA)); + a_sqrtA = a_sqrtA * ALM_SQUAREA_LSB; + a_OMEGA_0 = static_cast(read_navigation_signed(subframe_bits, ALM_OMEGAZERO)); + a_OMEGA_0 = a_OMEGA_0 * ALM_OMEGAZERO_LSB; + a_omega = static_cast(read_navigation_signed(subframe_bits, ALM_OMEGA)); + a_omega = a_omega * ALM_OMEGA_LSB; + a_OMEGAdot = static_cast(read_navigation_signed(subframe_bits, ALM_OMEGADOT)); + a_OMEGAdot = a_OMEGAdot * ALM_OMEGADOT_LSB; + a_delta_i = static_cast(read_navigation_signed(subframe_bits, ALM_DELTAI)); + a_delta_i = a_delta_i * ALM_DELTAI_LSB; + a_af0 = static_cast(read_navigation_signed(subframe_bits, ALM_AF0)); + a_af0 = a_af0 * ALM_AF0_LSB; + a_af1 = static_cast(read_navigation_signed(subframe_bits, ALM_AF1)); + a_af1 = a_af1 * ALM_AF1_LSB; + a_PRN = SV_page; + i_Toa = static_cast(read_navigation_unsigned(subframe_bits, ALM_TOA)); + i_Toa = i_Toa * ALM_TOA_LSB; + + flag_almanac_valid = true; } } @@ -276,11 +298,33 @@ int32_t Gps_Navigation_Message::subframe_decoder(const char* subframe) b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); SV_data_ID_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); SV_page_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_PAGE)); - if (SV_page_5 < 25) + if ((SV_page_5 > 0) && (SV_page_5 < 25)) { - //! \TODO read almanac if (SV_data_ID_5 != 0) { + a_M_0 = static_cast(read_navigation_signed(subframe_bits, ALM_MZERO)); + a_M_0 = a_M_0 * ALM_MZERO_LSB; + a_ecc = static_cast(read_navigation_unsigned(subframe_bits, ALM_ECC)); + a_ecc = a_ecc * ALM_ECC_LSB; + a_sqrtA = static_cast(read_navigation_unsigned(subframe_bits, ALM_SQUAREA)); + a_sqrtA = a_sqrtA * ALM_SQUAREA_LSB; + a_OMEGA_0 = static_cast(read_navigation_signed(subframe_bits, ALM_OMEGAZERO)); + a_OMEGA_0 = a_OMEGA_0 * ALM_OMEGAZERO_LSB; + a_omega = static_cast(read_navigation_signed(subframe_bits, ALM_OMEGA)); + a_omega = a_omega * ALM_OMEGA_LSB; + a_OMEGAdot = static_cast(read_navigation_signed(subframe_bits, ALM_OMEGADOT)); + a_OMEGAdot = a_OMEGAdot * ALM_OMEGADOT_LSB; + a_delta_i = static_cast(read_navigation_signed(subframe_bits, ALM_DELTAI)); + a_delta_i = a_delta_i * ALM_DELTAI_LSB; + a_af0 = static_cast(read_navigation_signed(subframe_bits, ALM_AF0)); + a_af0 = a_af0 * ALM_AF0_LSB; + a_af1 = static_cast(read_navigation_signed(subframe_bits, ALM_AF1)); + a_af1 = a_af1 * ALM_AF1_LSB; + a_PRN = SV_page_5; + i_Toa = static_cast(read_navigation_unsigned(subframe_bits, ALM_TOA)); + i_Toa = i_Toa * ALM_TOA_LSB; + SV_Health = static_cast(read_navigation_unsigned(subframe_bits, ALM_SVHEALTH)); + flag_almanac_valid = true; } } if (SV_page_5 == 51) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M) @@ -288,6 +332,7 @@ int32_t Gps_Navigation_Message::subframe_decoder(const char* subframe) i_Toa = static_cast(read_navigation_unsigned(subframe_bits, T_OA)); i_Toa = i_Toa * T_OA_LSB; i_WN_A = static_cast(read_navigation_unsigned(subframe_bits, WN_A)); + flag_almanac_week_valid = true; almanacHealth[1] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV1)); almanacHealth[2] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV2)); almanacHealth[3] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV3)); @@ -435,6 +480,27 @@ Gps_Ephemeris Gps_Navigation_Message::get_ephemeris() const } +Gps_Almanac Gps_Navigation_Message::get_almanac() +{ + Gps_Almanac almanac; + almanac.SV_health = SV_Health; + almanac.PRN = a_PRN; + almanac.delta_i = a_delta_i; + almanac.toa = i_Toa; + almanac.WNa = i_WN_A; + almanac.M_0 = a_M_0; + almanac.ecc = a_ecc; + almanac.sqrtA = a_sqrtA; + almanac.OMEGA_0 = a_OMEGA_0; + almanac.omega = a_omega; + almanac.OMEGAdot = a_OMEGAdot; + almanac.af0 = a_af0; + almanac.af1 = a_af1; + flag_almanac_valid = false; + return almanac; +} + + Gps_Iono Gps_Navigation_Message::get_iono() { Gps_Iono iono; @@ -490,3 +556,9 @@ bool Gps_Navigation_Message::satellite_validation() } return flag_data_valid; } + + +bool Gps_Navigation_Message::almanac_validation() const +{ + return flag_almanac_valid && (i_WN_A > 0); +} diff --git a/src/core/system_parameters/gps_navigation_message.h b/src/core/system_parameters/gps_navigation_message.h index 16e8b2a9f..727b88005 100644 --- a/src/core/system_parameters/gps_navigation_message.h +++ b/src/core/system_parameters/gps_navigation_message.h @@ -21,6 +21,7 @@ #include "GPS_L1_CA.h" +#include "gps_almanac.h" #include "gps_ephemeris.h" #include "gps_iono.h" #include "gps_utc_model.h" @@ -61,7 +62,12 @@ public: Gps_Iono get_iono(); /*! - * \brief Obtain a GPS UTC model parameters class filled with current SV data + * \brief Obtain a GPS almanac class filled with current SV data + */ + Gps_Almanac get_almanac(); + + /*! + * \brief Obtain a GPS Almanac model parameters class filled with current SV data */ Gps_Utc_Model get_utc_model(); @@ -133,6 +139,7 @@ public: } bool satellite_validation(); + bool almanac_validation() const; private: uint64_t read_navigation_unsigned(const std::bitset& bits, const std::vector>& parameter) const; @@ -192,8 +199,19 @@ private: double d_A_f2{}; // Coefficient 2 of code phase offset model [s/s^2] // Almanac - int32_t i_Toa{}; // Almanac reference time [s] - int32_t i_WN_A{}; // Modulo 256 of the GPS week number to which the almanac reference time (i_Toa) is referenced + int32_t i_Toa{}; // Almanac reference time [s] + int32_t i_WN_A{}; // Modulo 256 of the GPS week number to which the almanac reference time (i_Toa) is referenced + int32_t SV_Health{}; // Almanac SV health + uint32_t a_PRN{}; // Almanac PRN + double a_delta_i{}; // Inclination Angle at Reference Time (relative to i_0 = 0.30 semi-circles) + double a_M_0{}; // Mean Anomaly at Reference Time [semi-circles] + double a_ecc{}; // Eccentricity [dimensionless] + double a_sqrtA{}; // Square Root of the Semi-Major Axis [sqrt(m)] + double a_OMEGA_0{}; // Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] + double a_omega{}; // Argument of Perigee [semi-cicles] + double a_OMEGAdot{}; // Rate of Right Ascension [semi-circles/s] + double a_af0{}; // Coefficient 0 of code phase offset model [s] + double a_af1{}; // Coefficient 1 of code phase offset model [s/s] // satellite identification info int32_t i_channel_ID{}; @@ -224,7 +242,8 @@ private: bool b_valid_ephemeris_set_flag{}; // flag indicating that this ephemeris set have passed the validation check bool flag_iono_valid{}; // If set, it indicates that the ionospheric parameters are filled (page 18 has arrived and decoded) bool flag_utc_model_valid{}; // If set, it indicates that the UTC model parameters are filled - + bool flag_almanac_valid{}; // If set, it indicates that the almanac is filled + bool flag_almanac_week_valid{}; // If set, it indicates that the almanac week is valid /* If true, enhanced level of integrity assurance. * * If false, indicates that the conveying signal is provided with the legacy level of integrity assurance. diff --git a/src/core/system_parameters/osnma_data.cc b/src/core/system_parameters/osnma_data.cc new file mode 100644 index 000000000..b56d3b940 --- /dev/null +++ b/src/core/system_parameters/osnma_data.cc @@ -0,0 +1,45 @@ +/*! + * \file osnma_data.cc + * \brief Class for Galileo OSNMA data storage + * \author Carles Fernandez-Prades, 2020-2023 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "osnma_data.h" + +uint32_t Tag::id_counter = 0; +uint32_t OSNMA_NavData::id_counter = 0; + +bool OSNMA_NavData::add_nav_data(const std::string& nav_data) +{ + if (nav_data.size() == 549) + { + d_ephemeris_iono = nav_data; + std::bitset<10> bits(nav_data.substr(0, 10)); + IOD_nav = static_cast(bits.to_ulong()); + return true; + } + else if (nav_data.size() == 141) + { + d_utc = nav_data; + return true; + } + return false; +} +std::string OSNMA_NavData::get_utc_data() const +{ + return d_utc; +} +std::string OSNMA_NavData::get_ephemeris_data() const +{ + return d_ephemeris_iono; +} diff --git a/src/core/system_parameters/osnma_data.h b/src/core/system_parameters/osnma_data.h new file mode 100644 index 000000000..c071c1994 --- /dev/null +++ b/src/core/system_parameters/osnma_data.h @@ -0,0 +1,250 @@ +/*! + * \file osnma_data.h + * \brief Class for Galileo OSNMA data storage + * \author Carles Fernandez-Prades, 2020-2023 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_OSNMA_DATA_H +#define GNSS_SDR_OSNMA_DATA_H + +#include "galileo_inav_message.h" // for OSNMA_msg +#include +#include +#include +#include +#include + +/** \addtogroup Core + * \{ */ +/** \addtogroup System_Parameters + * \{ */ + +class DSM_nma_header +{ +public: + DSM_nma_header() = default; + uint8_t nmas{}; + uint8_t cid{}; + uint8_t cpks{}; + bool reserved{}; +}; + + +class DSM_dsm_header +{ +public: + DSM_dsm_header() = default; + uint8_t dsm_id{}; + uint8_t dsm_block_id{}; +}; + + +class MACK_header +{ +public: + MACK_header() = default; + uint64_t tag0{}; + uint16_t macseq{}; + uint8_t cop{}; +}; + + +class MACK_tag_info +{ +public: + MACK_tag_info() = default; + uint8_t PRN_d{}; + uint8_t ADKD{}; + uint8_t cop{}; +}; + + +class MACK_tag_and_info +{ +public: + MACK_tag_and_info() = default; + uint64_t tag; // C: 20-40 bits + MACK_tag_info tag_info; + uint32_t counter; // CTR +}; + + +class DSM_PKR_message +{ +public: + DSM_PKR_message() = default; + + std::array itn{}; // bitset<1024> + std::vector npk; + std::vector p_dp; + uint8_t nb_dp{}; + uint8_t mid{}; + uint8_t npkt{}; + uint8_t npktid{}; +}; + + +class DSM_KROOT_message +{ +public: + DSM_KROOT_message() = default; + + std::vector kroot; + std::vector ds; + std::vector p_dk; + uint64_t alpha{}; + uint16_t wn_k{}; + uint8_t nb_dk{}; + uint8_t pkid{}; + uint8_t cidkr{}; + uint8_t reserved1{}; + uint8_t hf{}; + uint8_t mf{}; + uint8_t ks{}; // key size, in bits + uint8_t ts{}; + uint8_t maclt{}; + uint8_t reserved{}; + uint8_t towh_k{}; + bool verified{false}; +}; + + +class MACK_message +{ +public: + MACK_message() = default; + MACK_header header; + std::vector tag_and_info; + std::vector key; + uint32_t TOW; // TODO duplicated variable, also in OSNMA_NavData + uint32_t WN; + uint32_t PRNa; +}; + + +class OSNMA_NavData +{ +public: + OSNMA_NavData() : nav_data_id(id_counter++) {} + const uint32_t nav_data_id; + std::string get_utc_data() const; + std::string get_ephemeris_data() const; + uint32_t get_verified_bits() const { return verified_bits; } + uint32_t get_prn_d() const { return PRNd; } + uint32_t get_IOD_nav() const { return IOD_nav; } + uint32_t get_last_received_TOW() const { return d_last_received_TOW; } + uint32_t get_tow_sf0() const { return d_TOW_sf0; } + bool have_this_bits(std::string nav_data); + bool get_verified_status() const { return verified; } + bool add_nav_data(const std::string& nav_data); + void set_tow_sf0(int value) { d_TOW_sf0 = value; } + void set_ephemeris_data(std::string value) { d_ephemeris_iono = value; } + void set_utc_data(std::string value) { d_utc = value; } + void update_last_received_timestamp(uint32_t TOW); + void set_prn_d(uint32_t value) { PRNd = value; } + void set_last_received_TOW(uint32_t TOW) { d_last_received_TOW = TOW; }; + void set_update_verified_bits(uint32_t morebits) { verified_bits += morebits; } + void set_verified_status(bool value) { verified = value; } + void set_IOD_nav(uint32_t value) { IOD_nav = value; } + +private: + static uint32_t id_counter; + std::string d_ephemeris_iono{""}; + std::string d_utc{""}; + uint32_t d_TOW_sf0{0}; + uint32_t d_last_received_TOW{0}; + uint32_t PRNd{0}; + uint32_t verified_bits{0}; + uint32_t IOD_nav{0}; + bool verified{false}; +}; + + +/*! + * \brief This class handles ONSMA data + * See https://www.gsc-europa.eu/sites/default/files/sites/all/files/Galileo_OSNMA_User_ICD_for_Test_Phase_v1.0.pdf + */ +class OSNMA_data +{ +public: + OSNMA_data() = default; + DSM_nma_header d_nma_header; + DSM_dsm_header d_dsm_header; + DSM_PKR_message d_dsm_pkr_message; + DSM_KROOT_message d_dsm_kroot_message; + DSM_KROOT_message d_dsm_kroot_new_message; + MACK_message d_mack_message; + OSNMA_NavData d_nav_data; +}; + + +class Tag +{ +public: + enum e_verification_status + { + SUCCESS, + FAIL, + UNVERIFIED + }; + Tag(const MACK_tag_and_info& MTI, uint32_t TOW, uint32_t WN, uint32_t PRNa, uint8_t CTR) // standard tag constructor, for tags within Tag&Info field + : tag_id(id_counter++), + TOW(TOW), // TODO missing for build_message WN for GST computation, CTR, NMAS, OSNMA_NavData missing + WN(WN), + PRNa(PRNa), + CTR(CTR), + status(UNVERIFIED), + received_tag(MTI.tag), + computed_tag(0), + PRN_d(MTI.tag_info.PRN_d), + ADKD(MTI.tag_info.ADKD), + cop(MTI.tag_info.cop), + skipped(0) + { + } + explicit Tag(const MACK_message& mack) // constructor for Tag0 + : tag_id(id_counter++), + TOW(mack.TOW), // TODO missing for build_message WN for GST computation, CTR, NMAS, OSNMA_NavData missing + WN(mack.WN), + PRNa(mack.PRNa), + CTR(1), + status(UNVERIFIED), + received_tag(mack.header.tag0), + computed_tag(0), + PRN_d(mack.PRNa), // Tag0 are self-authenticating + ADKD(0), + cop(mack.header.cop), + skipped(0) + { + } + const uint32_t tag_id; + static uint32_t id_counter; + uint32_t TOW; + uint32_t WN; + uint32_t PRNa; + uint8_t CTR; + e_verification_status status; + uint64_t received_tag; + uint64_t computed_tag; + uint8_t PRN_d; + uint8_t ADKD; + uint8_t cop; + uint32_t skipped; + std::string nav_data; +}; + +/** \} */ +/** \} */ + +#endif // GNSS_SDR_OSNMA_DATA_H diff --git a/src/core/system_parameters/osnma_dsm_reader.cc b/src/core/system_parameters/osnma_dsm_reader.cc new file mode 100644 index 000000000..16bd12114 --- /dev/null +++ b/src/core/system_parameters/osnma_dsm_reader.cc @@ -0,0 +1,228 @@ +/*! + * \file osnma_dsm_reader.cc + * \brief Class for reading OSNMA DSM messages + * \author Carles Fernandez-Prades, 2023 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "osnma_dsm_reader.h" +#include "Galileo_OSNMA.h" + + +uint8_t OSNMA_DSM_Reader::get_nmas(uint8_t nma_header) const +{ + return (nma_header & mask_nmas) >> 6; +} + + +uint8_t OSNMA_DSM_Reader::get_cid(uint8_t nma_header) const +{ + return (nma_header & mask_cid) >> 4; +} + + +uint8_t OSNMA_DSM_Reader::get_cpks(uint8_t nma_header) const +{ + return (nma_header & mask_cpks) >> 1; +} + + +bool OSNMA_DSM_Reader::get_nma_header_reserved(uint8_t nma_header) const +{ + return (nma_header & mask_nma_header_reserved) != 0; +} + + +uint8_t OSNMA_DSM_Reader::get_dsm_id(uint8_t dsm_header) const +{ + return (dsm_header & mask_dsm_id) >> 4; +} + + +uint8_t OSNMA_DSM_Reader::get_dsm_block_id(uint8_t dsm_header) const +{ + return dsm_header & mask_dsm_block_id; +} + + +uint8_t OSNMA_DSM_Reader::get_number_blocks_index(uint8_t dsm_msg_0) const +{ + return (dsm_msg_0 & mask_dsm_number_blocks) >> 4; +} + + +uint8_t OSNMA_DSM_Reader::get_pkid(const std::vector& dsm_msg) const +{ + return (dsm_msg[0] & mask_dsm_pkid); +} + + +uint8_t OSNMA_DSM_Reader::get_cidkr(const std::vector& dsm_msg) const +{ + return (dsm_msg[1] & mask_dsm_cidkr) >> 6; +} + + +uint8_t OSNMA_DSM_Reader::get_dsm_reserved1(const std::vector& dsm_msg) const +{ + return (dsm_msg[1] & mask_dsm_reserved1) >> 4; +} + + +uint8_t OSNMA_DSM_Reader::get_hf(const std::vector& dsm_msg) const +{ + return (dsm_msg[1] & mask_dsm_hf) >> 2; +} + + +uint8_t OSNMA_DSM_Reader::get_mf(const std::vector& dsm_msg) const +{ + return (dsm_msg[1] & mask_dsm_mf); +} + + +uint8_t OSNMA_DSM_Reader::get_ks(const std::vector& dsm_msg) const +{ + return (dsm_msg[2] & mask_dsm_ks) >> 4; +} + + +uint8_t OSNMA_DSM_Reader::get_ts(const std::vector& dsm_msg) const +{ + return (dsm_msg[2] & mask_dsm_ts); +} + + +uint8_t OSNMA_DSM_Reader::get_maclt(const std::vector& dsm_msg) const +{ + return dsm_msg[3]; +} + + +uint8_t OSNMA_DSM_Reader::get_dsm_reserved(const std::vector& dsm_msg) const +{ + return (dsm_msg[4] & mask_dsm_reserved) >> 4; +} + + +uint16_t OSNMA_DSM_Reader::get_wn_k(const std::vector& dsm_msg) const +{ + return (static_cast((dsm_msg[4] & mask_dsm_wk_k_msbyte) << 8) + static_cast(dsm_msg[5])); +} + + +uint8_t OSNMA_DSM_Reader::get_towh_k(const std::vector& dsm_msg) const +{ + return dsm_msg[6]; +} + + +uint64_t OSNMA_DSM_Reader::get_alpha(const std::vector& dsm_msg) const +{ + uint64_t alpha = (static_cast(dsm_msg[7]) << 40) + + (static_cast(dsm_msg[8]) << 32) + + (static_cast(dsm_msg[9]) << 24) + + (static_cast(dsm_msg[10]) << 16) + + (static_cast(dsm_msg[11]) << 8) + + (static_cast(dsm_msg[12])); + return alpha; +} + + +uint16_t OSNMA_DSM_Reader::get_l_dk_bits(uint8_t nb_dk) const +{ + const auto it = OSNMA_TABLE_7.find(nb_dk); + if (it != OSNMA_TABLE_7.cend()) + { + return it->second.second; + } + return 0; +} + + +uint16_t OSNMA_DSM_Reader::get_lk_bits(uint8_t ks) const +{ + const auto it = OSNMA_TABLE_10.find(ks); + if (it != OSNMA_TABLE_10.cend()) + { + return it->second; + } + return 0; +} + + +std::vector OSNMA_DSM_Reader::get_kroot(const std::vector& dsm_msg, uint16_t bytes_lk) const +{ + std::vector kroot = std::vector(bytes_lk, 0); + if (dsm_msg.size() > static_cast(13 + bytes_lk)) + { + for (uint16_t k = 0; k < bytes_lk; k++) + { + kroot[k] = dsm_msg[13 + k]; + } + } + return kroot; +} + + +std::string OSNMA_DSM_Reader::get_hash_function(uint8_t hf) const +{ + std::string hash_; + const auto it = OSNMA_TABLE_8.find(hf); + if (it != OSNMA_TABLE_8.cend()) + { + hash_ = it->second; + } + return hash_; +} + + +uint8_t OSNMA_DSM_Reader::get_mid(const std::vector& dsm_msg) const +{ + return (dsm_msg[0] & mask_dsm_mid); +} + + +uint8_t OSNMA_DSM_Reader::get_npkt(const std::vector& dsm_msg) const +{ + return ((dsm_msg[129] & mask_dsm_npkt) >> 4); +} + + +uint8_t OSNMA_DSM_Reader::get_npktid(const std::vector& dsm_msg) const +{ + return (dsm_msg[129] & mask_dsm_npktid); +} + + +std::string OSNMA_DSM_Reader::get_nmas_status(uint8_t nmas) const +{ + std::string status_; + const auto it = OSNMA_TABLE_1.find(nmas); + if (it != OSNMA_TABLE_1.cend()) + { + status_ = it->second; + } + return status_; +} + + +std::string OSNMA_DSM_Reader::get_cpks_status(uint8_t cpks) const +{ + std::string status_; + const auto it = OSNMA_TABLE_2.find(cpks); + if (it != OSNMA_TABLE_2.cend()) + { + status_ = it->second; + } + return status_; +} \ No newline at end of file diff --git a/src/core/system_parameters/osnma_dsm_reader.h b/src/core/system_parameters/osnma_dsm_reader.h new file mode 100644 index 000000000..121746052 --- /dev/null +++ b/src/core/system_parameters/osnma_dsm_reader.h @@ -0,0 +1,89 @@ +/*! + * \file osnma_dsm_reader.h + * \brief Class for reading OSNMA DSM messages + * \author Carles Fernandez-Prades, 2023 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_OSNMA_DSM_READER_H +#define GNSS_SDR_OSNMA_DSM_READER_H + +#include +#include +#include + +/** \addtogroup Core + * \{ */ +/** \addtogroup System_Parameters + * \{ */ + +class OSNMA_DSM_Reader +{ +public: + OSNMA_DSM_Reader() = default; + uint8_t get_nmas(uint8_t nma_header) const; + uint8_t get_cid(uint8_t nma_header) const; + uint8_t get_cpks(uint8_t nma_header) const; + bool get_nma_header_reserved(uint8_t nma_header) const; + + uint8_t get_dsm_id(uint8_t dsm_header) const; + uint8_t get_dsm_block_id(uint8_t dsm_header) const; + + uint8_t get_number_blocks_index(uint8_t dsm_msg_0) const; + uint8_t get_pkid(const std::vector& dsm_msg) const; + uint8_t get_cidkr(const std::vector& dsm_msg) const; + uint8_t get_dsm_reserved1(const std::vector& dsm_msg) const; + uint8_t get_hf(const std::vector& dsm_msg) const; + uint8_t get_mf(const std::vector& dsm_msg) const; + uint8_t get_ks(const std::vector& dsm_msg) const; + uint8_t get_ts(const std::vector& dsm_msg) const; + uint8_t get_maclt(const std::vector& dsm_msg) const; + uint8_t get_dsm_reserved(const std::vector& dsm_msg) const; + uint16_t get_wn_k(const std::vector& dsm_msg) const; + uint8_t get_towh_k(const std::vector& dsm_msg) const; + uint64_t get_alpha(const std::vector& dsm_msg) const; + uint16_t get_l_dk_bits(uint8_t nb_dk) const; + uint16_t get_lk_bits(uint8_t ks) const; + std::vector get_kroot(const std::vector& dsm_msg, uint16_t bytes_lk) const; + std::string get_hash_function(uint8_t hf) const; + std::string get_nmas_status(uint8_t nmas) const; + std::string get_cpks_status(uint8_t cpks) const; + + uint8_t get_mid(const std::vector& dsm_msg) const; + uint8_t get_npkt(const std::vector& dsm_msg) const; + uint8_t get_npktid(const std::vector& dsm_msg) const; + +private: + static constexpr std::uint8_t mask_nmas{0xC0}; + static constexpr std::uint8_t mask_cid{0x30}; + static constexpr std::uint8_t mask_cpks{0x0E}; + static constexpr std::uint8_t mask_nma_header_reserved{0x01}; + static constexpr std::uint8_t mask_dsm_id{0xF0}; + static constexpr std::uint8_t mask_dsm_block_id{0x0F}; + static constexpr std::uint8_t mask_dsm_number_blocks{0xF0}; + static constexpr std::uint8_t mask_dsm_pkid{0x0F}; + static constexpr std::uint8_t mask_dsm_cidkr{0xC0}; + static constexpr std::uint8_t mask_dsm_reserved1{0x30}; + static constexpr std::uint8_t mask_dsm_hf{0x0C}; + static constexpr std::uint8_t mask_dsm_mf{0x03}; + static constexpr std::uint8_t mask_dsm_ks{0xF0}; + static constexpr std::uint8_t mask_dsm_ts{0x0F}; + static constexpr std::uint8_t mask_dsm_reserved{0xF0}; + static constexpr std::uint8_t mask_dsm_wk_k_msbyte{0x0F}; + static constexpr std::uint8_t mask_dsm_mid{0x0F}; + static constexpr std::uint8_t mask_dsm_npkt{0xF0}; + static constexpr std::uint8_t mask_dsm_npktid{0x0F}; +}; + +/** \} */ +/** \} */ +#endif // GNSS_SDR_OSNMA_DSM_READER_H \ No newline at end of file diff --git a/src/core/system_parameters/reed_solomon.h b/src/core/system_parameters/reed_solomon.h index 049091ae1..42eb0da82 100644 --- a/src/core/system_parameters/reed_solomon.h +++ b/src/core/system_parameters/reed_solomon.h @@ -156,7 +156,7 @@ private: int d_shortening{}; // shortening parameter uint8_t d_min_poly{}; // primitive polynomial - uint8_t d_a0{}; // auxiliar variable + uint8_t d_a0{}; // auxiliary variable }; /** \} */ diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index 2895d5973..a5e68b546 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -16,13 +16,24 @@ target_link_libraries(gnss-sdr PRIVATE algorithms_libs core_receiver + gnss_sdr_flags Boost::headers Boost::thread - Gflags::gflags - Glog::glog Threads::Threads ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(gnss-sdr PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(gnss-sdr PUBLIC -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(gnss-sdr PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize absl::log_sink absl::log_sink_registry) + target_link_libraries(gnss-sdr INTERFACE "$") +endif() + +if(NOT ENABLE_LOG) + target_compile_definitions(gnss-sdr PRIVATE -DGOOGLE_STRIP_LOG=1) +endif() + target_compile_definitions(gnss-sdr PRIVATE -DGNSS_SDR_VERSION="${VERSION}") if(ENABLE_CUDA) @@ -65,6 +76,9 @@ if(ENABLE_STRIP) set_target_properties(gnss-sdr PROPERTIES LINK_FLAGS "-s") endif() +include(XcodeRemoveWarningDuplicates) +xcode_remove_warning_duplicates(gnss-sdr) + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(gnss-sdr @@ -106,13 +120,8 @@ if(NOT VOLKGNSSSDR_FOUND) ) endif() -find_program(GZIP - gzip - /bin - /usr/bin - /usr/local/bin - /opt/local/bin - /sbin +find_program(GZIP gzip + ${GNSSSDR_BIN_PATHS} ) if(NOT GZIP_NOTFOUND) diff --git a/src/main/main.cc b/src/main/main.cc index e4715a5c3..c32b9f081 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -18,7 +18,7 @@ */ #ifndef GNSS_SDR_VERSION -#define GNSS_SDR_VERSION "0.0.19" +#define GNSS_SDR_VERSION "0.0.20" #endif #ifndef GOOGLE_STRIP_LOG @@ -29,30 +29,72 @@ #include "concurrent_queue.h" #include "control_thread.h" #include "gnss_sdr_filesystem.h" +#include "gnss_sdr_flags.h" #include "gnss_sdr_make_unique.h" #include "gps_acq_assist.h" #include // for diagnostic_information #include // for exception #include // for thread_resource_error -#include // for ShutDownCommandLineFlags -#include // for FLAGS_log_dir #include // for time_point #include // for exception +#include // for ofstream #include // for operator<< #include // for unique_ptr +#include // for std::flush #include // for string -#if CUDA_GPU_ACCEL -// For the CUDA runtime routines (prefixed with "cuda_") -#include -#endif - +#if USE_GLOG_AND_GFLAGS +#include // for ShutDownCommandLineFlags +#include #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } #endif +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +std::string GnssSdrVersionString() { return std::string("gnss-sdr version ") + std::string(GNSS_SDR_VERSION) + "\n"; } +class GnssSdrLogSink : public absl::LogSink +{ +public: + GnssSdrLogSink() + { + if (!absl::GetFlag(FLAGS_log_dir).empty()) + { + filename = absl::GetFlag(FLAGS_log_dir) + "/gnss-sdr.log"; + } + else + { + filename = GetTempDir() + "/gnss-sdr.log"; + } + logfile.open(filename); + } + void Send(const absl::LogEntry& entry) override + { + logfile << entry.text_message_with_prefix_and_newline() << std::flush; + } + +private: + std::ofstream logfile; + std::string filename; +}; +#endif + +#if CUDA_GPU_ACCEL +// For the CUDA runtime routines (prefixed with "cuda_") +#include +#endif + /* * Concurrent queues that communicates the Telemetry Decoder @@ -69,14 +111,27 @@ int main(int argc, char** argv) { const std::string intro_help( std::string("\nGNSS-SDR is an Open Source GNSS Software Defined Receiver\n") + - "Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)\n" + + "Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)\n" + "This program comes with ABSOLUTELY NO WARRANTY;\n" + "See COPYING file to see a copy of the General Public License\n \n"); - const std::string gnss_sdr_version(GNSS_SDR_VERSION); +#if USE_GLOG_AND_GFLAGS gflags::SetUsageMessage(intro_help); gflags::SetVersionString(gnss_sdr_version); gflags::ParseCommandLineFlags(&argc, &argv, true); +#else + absl::FlagsUsageConfig empty_config; + empty_config.version_string = &GnssSdrVersionString; + absl::SetFlagsUsageConfig(empty_config); + absl::SetProgramUsageMessage(intro_help); + absl::ParseCommandLine(argc, argv); + if (!ValidateFlags()) + { + std::cout << "GNSS-SDR program ended.\n"; + return 1; + } + +#endif std::cout << "Initializing GNSS-SDR v" << gnss_sdr_version << " ... Please wait.\n"; } catch (const std::exception& e) @@ -99,8 +154,15 @@ int main(int argc, char** argv) if (GOOGLE_STRIP_LOG == 0) { +#if USE_GLOG_AND_GFLAGS google::InitGoogleLogging(argv[0]); if (FLAGS_log_dir.empty()) +#else + absl::LogSink* theSink = new GnssSdrLogSink; + absl::AddLogSink(theSink); + absl::InitializeLog(); + if (absl::GetFlag(FLAGS_log_dir).empty()) +#endif { std::cout << "Logging will be written at " << fs::temp_directory_path() @@ -111,32 +173,58 @@ int main(int argc, char** argv) { try { +#if USE_GLOG_AND_GFLAGS const fs::path p(FLAGS_log_dir); +#else + const fs::path p(absl::GetFlag(FLAGS_log_dir)); +#endif if (!fs::exists(p)) { std::cout << "The path " +#if USE_GLOG_AND_GFLAGS << FLAGS_log_dir +#else + << absl::GetFlag(FLAGS_log_dir) +#endif << " does not exist, attempting to create it.\n"; errorlib::error_code ec; if (!fs::create_directory(p, ec)) { +#if USE_GLOG_AND_GFLAGS std::cerr << "Could not create the " << FLAGS_log_dir << " folder. GNSS-SDR program ended.\n"; gflags::ShutDownCommandLineFlags(); +#else + std::cerr << "Could not create the " << absl::GetFlag(FLAGS_log_dir) << " folder. GNSS-SDR program ended.\n"; +#endif return 1; } } +#if USE_GLOG_AND_GFLAGS std::cout << "Logging will be written at " << FLAGS_log_dir << '\n'; +#else + std::cout << "Logging will be written at " << absl::GetFlag(FLAGS_log_dir) << '\n'; +#endif } catch (const std::exception& e) { std::cerr << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS std::cerr << "Could not create the " << FLAGS_log_dir << " folder. GNSS-SDR program ended.\n"; gflags::ShutDownCommandLineFlags(); +#else + std::cerr << "Could not create the " << absl::GetFlag(FLAGS_log_dir) << " folder. GNSS-SDR program ended.\n"; +#endif return 1; } } } - +#if USE_GLOG_AND_GFLAGS +#else + else + { + absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfinity); // do not log + } +#endif std::chrono::time_point start; std::chrono::time_point end; start = std::chrono::system_clock::now(); @@ -201,7 +289,11 @@ int main(int argc, char** argv) << elapsed_seconds.count() << " [seconds]\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#else + absl::FlushLogSinks(); +#endif std::cout << "GNSS-SDR program ended.\n"; return return_code; } diff --git a/src/utils/nav-listener/nav_msg_udp_listener.cc b/src/utils/nav-listener/nav_msg_udp_listener.cc deleted file mode 100644 index 7961c8c8d..000000000 --- a/src/utils/nav-listener/nav_msg_udp_listener.cc +++ /dev/null @@ -1,64 +0,0 @@ -/*! - * \file nav_msg_udp_listener.cc - * \author Carles Fernandez-Prades, 2021. cfernandez(at)cttc.es - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: BSD-3-Clause - * - * ----------------------------------------------------------------------------- - */ - -#include "nav_msg_udp_listener.h" -#include -#include -#include - -Nav_Msg_Udp_Listener::Nav_Msg_Udp_Listener(unsigned short port) - : socket{io_service}, endpoint{boost::asio::ip::udp::v4(), port} -{ - socket.open(endpoint.protocol(), error); // Open socket. - socket.bind(endpoint, error); // Bind the socket to the given local endpoint. -} - -/** - * !\brief blocking call to read nav_message from UDP port - * \param[out] message navigation message class to contain parsed output - * \return true if message parsed succesfully, false ow - */ -bool Nav_Msg_Udp_Listener::receive_and_parse_nav_message(gnss_sdr::navMsg &message) -{ - char buff[8192]; // Buffer for storing the received data. - - // This call will block until one or more bytes of data has been received. - int bytes = socket.receive(boost::asio::buffer(buff)); - - std::string data(&buff[0], bytes); - // Deserialize a stock of Nav_Msg objects from the binary string. - return message.ParseFromString(data); -} - -/* - * !\brief prints navigation message content - * \param[in] message nav message to be printed - */ -void Nav_Msg_Udp_Listener::print_message(gnss_sdr::navMsg &message) const -{ - std::string system = message.system(); - std::string signal = message.signal(); - int prn = message.prn(); - int tow_at_current_symbol_ms = message.tow_at_current_symbol_ms(); - std::string nav_message = message.nav_message(); - - std::cout << "\nNew Data received:\n"; - std::cout << "System: " << system << '\n'; - std::cout << "Signal: " << signal << '\n'; - std::cout << "PRN: " << prn << '\n'; - std::cout << "TOW of last symbol [ms]: " - << tow_at_current_symbol_ms << '\n'; - std::cout << "Nav message: " << nav_message << "\n\n"; -} diff --git a/src/tests/CMakeLists.txt b/tests/CMakeLists.txt similarity index 82% rename from src/tests/CMakeLists.txt rename to tests/CMakeLists.txt index 5863284ba..4d93fcf01 100644 --- a/src/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,6 +7,9 @@ add_subdirectory(unit-tests/signal-processing-blocks/libs) add_subdirectory(system-tests/libs) +include_directories("${GNSSSDR_SOURCE_DIR}/src/core/receiver") + +include(XcodeRemoveWarningDuplicates) ################################################################################ # Google Test - https://github.com/google/googletest @@ -35,7 +38,7 @@ if(NOT GOOGLETEST_FOUND) set(GTEST_BUILD_COMMAND ${GTEST_BUILD_COMMAND} "--parallel 1") endif() if(CMAKE_GENERATOR STREQUAL Xcode) - set(GTEST_BUILD_COMMAND "xcodebuild" "-configuration" $<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel> "-target" "gtest_main") + set(GTEST_BUILD_COMMAND "xcodebuild" "-configuration" $<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug> "-target" "gtest_main") endif() if(GNSSSDR_GTEST_LOCAL_VERSION VERSION_LESS 1.12.0) set(DEBUG_DECORATION "d") @@ -303,7 +306,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) else() set(GNSS_SIM_BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}") if(CMAKE_GENERATOR STREQUAL Xcode) - set(GNSS_SIM_BUILD_COMMAND "xcodebuild" "-configuration" "${CMAKE_BUILD_TYPE}" "-target" "gnss_sim") + set(GNSS_SIM_BUILD_COMMAND "xcodebuild" "-configuration" $<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug> "-target" "gnss_sim") endif() if(TOOLCHAIN_ARG) set(TOOLCHAIN_ARG_GNSS_SIM "-DCMAKE_NO_SYSTEM_FROM_IMPORTED=ON") @@ -315,7 +318,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) GIT_TAG ${GNSSSDR_GNSS_SIM_LOCAL_VERSION} SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-sim BINARY_DIR ${GNSSSDR_BINARY_DIR}/gnss-sim - CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} ${CROSS_INSTALL_DIR} ${TOOLCHAIN_ARG_GNSS_SIM} + CMAKE_ARGS ${GTEST_COMPILER} ${TOOLCHAIN_ARG} ${CROSS_INSTALL_DIR} ${TOOLCHAIN_ARG_GNSS_SIM} -DBoost_DIR=${Boost_DIR} BUILD_COMMAND ${GNSS_SIM_BUILD_COMMAND} UPDATE_COMMAND "" PATCH_COMMAND "" @@ -332,7 +335,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) else() set(SW_GENERATOR_BIN ${GNSSSDR_BINARY_DIR}/gnss-sim/gnss_sim) if(CMAKE_GENERATOR STREQUAL Xcode) - set(SW_GENERATOR_BIN ${GNSSSDR_BINARY_DIR}/gnss-sim/${CMAKE_BUILD_TYPE}/gnss_sim) + set(SW_GENERATOR_BIN ${GNSSSDR_BINARY_DIR}/gnss-sim/$<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug>/gnss_sim) endif() add_definitions(-DSW_GENERATOR_BIN="${SW_GENERATOR_BIN}") add_definitions(-DDEFAULT_RINEX_NAV="${GNSSSDR_BINARY_DIR}/thirdparty/gnss-sim/brdc3540.14n") @@ -353,7 +356,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) endif() set(GNSSTK_BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}") if(CMAKE_GENERATOR STREQUAL Xcode) - set(GNSSTK_BUILD_COMMAND "xcodebuild" "-configuration" "${CMAKE_BUILD_TYPE}") + set(GNSSTK_BUILD_COMMAND "xcodebuild" "-configuration" $<$:None>$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:NoOptWithASM>$<$:Coverage>$<$:O2WithASM>$<$:O3WithASM>$<$:Debug>) endif() include(GNUInstallDirs) find_program(Patch_EXECUTABLE NAME patch PATHS ENV PATH) @@ -363,14 +366,14 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) if(CMAKE_VERSION VERSION_GREATER 3.17.0) set(GNSSTK_PATCH_COMMAND cd ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION} && - ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_static14.patch && - ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/core/lib/GNSSCore/ObsID.hpp < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_gcc13.patch + ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/tests/data/gnsstk_static14.patch && + ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/core/lib/GNSSCore/ObsID.hpp < ${GNSSSDR_SOURCE_DIR}/tests/data/gnsstk_gcc13.patch ) else() set(GNSSTK_PATCH_COMMAND cd ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION} && - ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_static13.patch && - ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/core/lib/GNSSCore/ObsID.hpp < ${GNSSSDR_SOURCE_DIR}/src/tests/data/gnsstk_gcc13.patch + ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/CMakeLists.txt < ${GNSSSDR_SOURCE_DIR}/tests/data/gnsstk_static13.patch && + ${Patch_EXECUTABLE} ${GNSSSDR_BINARY_DIR}/thirdparty/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/core/lib/GNSSCore/ObsID.hpp < ${GNSSSDR_SOURCE_DIR}/tests/data/gnsstk_gcc13.patch ) endif() # Patch only once @@ -483,7 +486,12 @@ if(NOT (ENABLE_PACKAGING OR ENABLE_UNIT_TESTING_MINIMAL)) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat SHOW_PROGRESS EXPECTED_HASH MD5=d57a02d3c7361bba2e137329b66458ef + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat) + endif() endif() if(NOT EXISTS ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat) message(STATUS "Downloading file: GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat") @@ -491,7 +499,12 @@ if(NOT (ENABLE_PACKAGING OR ENABLE_UNIT_TESTING_MINIMAL)) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat SHOW_PROGRESS EXPECTED_HASH MD5=f12ada80a2ad1bab061262e010643529 + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat) + endif() endif() if(NOT EXISTS ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat) message(STATUS "Downloading file: GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat") @@ -499,7 +512,12 @@ if(NOT (ENABLE_PACKAGING OR ENABLE_UNIT_TESTING_MINIMAL)) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat SHOW_PROGRESS EXPECTED_HASH MD5=b98d6d82885354f168f279817de284b5 + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/GSoC_CTTC_capture_2012_07_26_4Msps_4ms.dat) + endif() endif() if(NOT EXISTS ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin) message(STATUS "Downloading file: NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin") @@ -507,7 +525,12 @@ if(NOT (ENABLE_PACKAGING OR ENABLE_UNIT_TESTING_MINIMAL)) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin SHOW_PROGRESS EXPECTED_HASH MD5=0e2dc212309141d236897bc0af187074 + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin) + endif() endif() message(STATUS "Done.") endif() @@ -521,7 +544,12 @@ if(ENABLE_UNIT_TESTING_EXTRA) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat SHOW_PROGRESS EXPECTED_HASH MD5=a6fcbefe155137945d3c33c5ef7bd0f9 + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/gps_l2c_m_prn7_5msps.dat) + endif() endif() if(NOT EXISTS ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) message(STATUS "Downloading file: Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat") @@ -529,7 +557,12 @@ if(ENABLE_UNIT_TESTING_EXTRA) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat SHOW_PROGRESS EXPECTED_HASH MD5=ffb72fc63c116be58d5e5ccb1daaed3a + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/Glonass_L1_CA_SIM_Fs_62Msps_4ms.dat) + endif() endif() if(NOT EXISTS ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/BdsB1IStr01_fs25e6_if0_4ms.dat) message(STATUS "Downloading file: BdsB1IStr01_fs25e6_if0_4ms.dat") @@ -537,7 +570,12 @@ if(ENABLE_UNIT_TESTING_EXTRA) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/BdsB1IStr01_fs25e6_if0_4ms.dat SHOW_PROGRESS EXPECTED_HASH MD5=5a4336dad9d80f3313a16dec4fff9233 + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/BdsB1IStr01_fs25e6_if0_4ms.dat) + endif() endif() if(NOT EXISTS ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/BdsB3IStr01_fs50e6_if0_4ms.dat) message(STATUS "Downloading file: BdsB3IStr01_fs50e6_if0_4ms.dat") @@ -545,7 +583,30 @@ if(ENABLE_UNIT_TESTING_EXTRA) ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/BdsB3IStr01_fs50e6_if0_4ms.dat SHOW_PROGRESS EXPECTED_HASH MD5=066d0d8434a8bc81e161778b7c34cc07 + STATUS status_download ) + list(GET status_download 0 result_download) + if(NOT (${result_download} EQUAL 0)) + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/BdsB3IStr01_fs50e6_if0_4ms.dat) + endif() + endif() + if(NOT EXISTS ${GNSSSDR_BINARY_DIR}/thirdparty/osnma_tests/Test_vectors.zip) + message(STATUS "Downloading file: Test_vectors.zip") + file(DOWNLOAD https://www.gsc-europa.eu/sites/default/files/sites/all/files/Test_vectors.zip + ${GNSSSDR_BINARY_DIR}/thirdparty/osnma_tests/Test_vectors.zip + SHOW_PROGRESS + EXPECTED_HASH MD5=8158aebee735652c9398e5bb6d944364 + STATUS status_download + ) + list(GET status_download 0 result_download) + if(${result_download} EQUAL 0) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xzf ${GNSSSDR_BINARY_DIR}/thirdparty/osnma_tests/Test_vectors.zip + WORKING_DIRECTORY ${GNSSSDR_BINARY_DIR}/thirdparty/osnma_tests/ + ) + else() + file(REMOVE ${GNSSSDR_BINARY_DIR}/thirdparty/osnma_tests/Test_vectors.zip) + endif() endif() message(STATUS "Done.") if(ENABLE_INSTALL_TESTS) @@ -562,12 +623,12 @@ if(NOT ENABLE_PACKAGING) install(FILES ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/Galileo_E1_ID_1_Fs_4Msps_8ms.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat DESTINATION share/gnss-sdr/signal_samples) install(FILES ${GNSSSDR_BINARY_DIR}/thirdparty/signal_samples/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_4ms.bin DESTINATION share/gnss-sdr/signal_samples) - install(FILES ${GNSSSDR_SOURCE_DIR}/src/tests/data/rtklib_test/obs_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test) - install(FILES ${GNSSSDR_SOURCE_DIR}/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test) + install(FILES ${GNSSSDR_SOURCE_DIR}/tests/data/rtklib_test/obs_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test) + install(FILES ${GNSSSDR_SOURCE_DIR}/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION share/gnss-sdr/data/rtklib_test) add_definitions(-DTEST_PATH="${CMAKE_INSTALL_PREFIX}/share/gnss-sdr/") else() - file(COPY ${GNSSSDR_SOURCE_DIR}/src/tests/data/rtklib_test/obs_test1.xml DESTINATION ${GNSSSDR_BINARY_DIR}/thirdparty/data/rtklib_test) - file(COPY ${GNSSSDR_SOURCE_DIR}/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION ${GNSSSDR_BINARY_DIR}/thirdparty/data/rtklib_test) + file(COPY ${GNSSSDR_SOURCE_DIR}/tests/data/rtklib_test/obs_test1.xml DESTINATION ${GNSSSDR_BINARY_DIR}/thirdparty/data/rtklib_test) + file(COPY ${GNSSSDR_SOURCE_DIR}/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml DESTINATION ${GNSSSDR_BINARY_DIR}/thirdparty/data/rtklib_test) add_definitions(-DTEST_PATH="${GNSSSDR_BINARY_DIR}/thirdparty/") endif() endif() @@ -589,8 +650,6 @@ if(ENABLE_UNIT_TESTING) PRIVATE Boost::thread Armadillo::armadillo - Gflags::gflags - Glog::glog Gnuradio::runtime Gnuradio::blocks Gnuradio::filter @@ -619,9 +678,16 @@ if(ENABLE_UNIT_TESTING) system_testing_lib core_receiver ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(run_tests PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(run_tests PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(run_tests PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(run_tests INTERFACE "$") + endif() target_include_directories(run_tests INTERFACE - ${GNSSSDR_SOURCE_DIR}/src/tests/common-files + ${GNSSSDR_SOURCE_DIR}/tests/common-files ) if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(run_tests @@ -644,7 +710,9 @@ if(ENABLE_UNIT_TESTING) if(GNSSTK_OLDER_THAN_9) target_compile_definitions(run_tests PRIVATE -DGNSSTK_OLDER_THAN_9=1) endif() + target_compile_definitions(run_tests PRIVATE -DBASE_OSNMA_TEST_VECTORS="${GNSSSDR_BINARY_DIR}/thirdparty/osnma_tests/Test_vectors/") endif() + xcode_remove_warning_duplicates(run_tests) if(ENABLE_STRIP) set_target_properties(run_tests PROPERTIES LINK_FLAGS "-s") endif() @@ -749,8 +817,6 @@ if(ENABLE_FPGA) PRIVATE Armadillo::armadillo Boost::thread - Gflags::gflags - Glog::glog Gnuradio::runtime Gnuradio::blocks GTest::GTest @@ -764,9 +830,17 @@ if(ENABLE_FPGA) algorithms_libs core_receiver ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga INTERFACE "$") + endif() target_include_directories(gps_l1_ca_dll_pll_tracking_test_fpga - INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files + INTERFACE ${GNSSSDR_SOURCE_DIR}/tests/common-files ) + xcode_remove_warning_duplicates(gps_l1_ca_dll_pll_tracking_test_fpga) install(TARGETS gps_l1_ca_dll_pll_tracking_test_fpga RUNTIME DESTINATION bin COMPONENT "fpga-test" @@ -799,9 +873,12 @@ function(add_system_test executable) endif() target_include_directories(${executable} PRIVATE ${OPT_INCLUDES_} - INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files + INTERFACE ${GNSSSDR_SOURCE_DIR}/tests/common-files ) target_link_libraries(${executable} PRIVATE ${OPT_LIBS_} algorithms_libs) + if(NOT ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(${executable} INTERFACE "$") + endif() if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(${executable} PRIVATE -DGNURADIO_USES_STD_POINTERS=1 @@ -823,6 +900,9 @@ function(add_system_test executable) ${LOCAL_INSTALL_BASE_DIR}/install/$ ) endif() + + xcode_remove_warning_duplicates(${executable}) + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(${executable} @@ -848,14 +928,24 @@ if(ENABLE_SYSTEM_TESTING) #### TTFF set(OPT_LIBS_ Boost::thread Boost::date_time - Threads::Threads Gflags::gflags Glog::glog + Threads::Threads Gnuradio::runtime GTest::GTest GTest::Main Gnuradio::blocks Gnuradio::filter Gnuradio::analog algorithms_libs core_receiver ) + if(ENABLE_GLOG_AND_GFLAGS) + set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog) + else() + set(OPT_LIBS_ ${OPT_LIBS_} absl::flags_parse absl::flags absl::log absl::log_initialize absl::log_sink absl::log_sink_registry) + endif() if(NOT ENABLE_PACKAGING) - add_system_test(ttff) + add_system_test(ttff + CMAKE_ARGS -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + ) + if(ENABLE_GLOG_AND_GFLAGS) + target_compile_definitions(ttff PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + endif() endif() if(ENABLE_SYSTEM_TESTING_EXTRA) @@ -863,12 +953,22 @@ if(ENABLE_SYSTEM_TESTING) set(OPT_LIBS_ algorithms_libs core_receiver core_system_parameters gnss_sdr_flags system_testing_lib signal_processing_testing_lib - Boost::thread Threads::Threads Gflags::gflags Glog::glog + Boost::thread Threads::Threads GTest::GTest GTest::Main Gnuradio::runtime Gnuradio::blocks Gnuradio::filter Gnuradio::analog Matio::matio Volkgnsssdr::volkgnsssdr ) - add_system_test(position_test) + if(ENABLE_GLOG_AND_GFLAGS) + set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog) + else() + set(OPT_LIBS_ ${OPT_LIBS_} absl::flags_parse absl::log absl::log_initialize absl::log_sink absl::log_sink_registry) + endif() + add_system_test(position_test + CMAKE_ARGS -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> + ) + if(ENABLE_GLOG_AND_GFLAGS) + target_compile_definitions(position_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + endif() if(ENABLE_GPERFTOOLS) if(GPERFTOOLS_FOUND) target_link_libraries(position_test @@ -920,8 +1020,6 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) target_link_libraries(flowgraph_test PRIVATE Boost::thread - Gflags::gflags - Glog::glog Gnuradio::runtime GTest::GTest GTest::Main @@ -932,11 +1030,21 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) core_receiver algorithms_libs ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(flowgraph_test PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(flowgraph_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(flowgraph_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(flowgraph_test INTERFACE "$") + endif() target_include_directories(flowgraph_test PRIVATE ${GNSSSDR_SOURCE_DIR}/src/algorithms/libs ) + + xcode_remove_warning_duplicates(flowgraph_test) + add_test(flowgraph_test flowgraph_test) set_property(TEST flowgraph_test PROPERTY TIMEOUT 30) @@ -966,8 +1074,6 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) target_link_libraries(gnss_block_test PRIVATE Boost::thread - Gflags::gflags - Glog::glog Gnuradio::runtime Gnuradio::blocks Gnuradio::filter @@ -982,16 +1088,25 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) core_receiver algorithms_libs ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(gnss_block_test PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(gnss_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(gnss_block_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(gnss_block_test INTERFACE "$") + endif() target_include_directories(gnss_block_test PRIVATE ${GNSSSDR_SOURCE_DIR}/src/algorithms/libs - INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files + INTERFACE ${GNSSSDR_SOURCE_DIR}/tests/common-files ) if(ENABLE_FPGA) target_compile_definitions(gnss_block_test PRIVATE -DENABLE_FPGA=1) endif() + xcode_remove_warning_duplicates(gnss_block_test) + add_test(gnss_block_test gnss_block_test) set_property(TEST gnss_block_test PROPERTY TIMEOUT 60) @@ -1014,8 +1129,6 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) target_link_libraries(gnuradio_block_test PRIVATE Boost::thread - Gflags::gflags - Glog::glog Gnuradio::runtime Gnuradio::blocks Gnuradio::filter @@ -1028,6 +1141,15 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) core_receiver algorithms_libs ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(gnuradio_block_test PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(gnuradio_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(gnuradio_block_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(gnuradio_block_test INTERFACE "$") + endif() + + xcode_remove_warning_duplicates(gnuradio_block_test) add_test(gnuradio_block_test gnuradio_block_test) @@ -1050,19 +1172,27 @@ endif() target_link_libraries(matio_test PRIVATE algorithms_libs - Gflags::gflags - Glog::glog GTest::GTest GTest::Main Matio::matio core_receiver ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(matio_test PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(matio_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(matio_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(matio_test INTERFACE "$") +endif() + target_include_directories(matio_test INTERFACE - ${GNSSSDR_SOURCE_DIR}/src/tests/common-files + ${GNSSSDR_SOURCE_DIR}/tests/common-files ) +xcode_remove_warning_duplicates(matio_test) + add_test(matio_test matio_test) set_property(TEST matio_test PROPERTY TIMEOUT 30) @@ -1084,8 +1214,6 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) target_link_libraries(acq_test PRIVATE Boost::thread - Gflags::gflags - Glog::glog Gnuradio::runtime Gnuradio::blocks Gnuradio::filter @@ -1101,9 +1229,16 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) signal_processing_testing_lib core_receiver ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(acq_test PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(acq_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(acq_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(acq_test INTERFACE "$") + endif() target_include_directories(acq_test INTERFACE - ${GNSSSDR_SOURCE_DIR}/src/tests/common-files + ${GNSSSDR_SOURCE_DIR}/tests/common-files ) if(PMT_USES_BOOST_ANY) target_compile_definitions(acq_test @@ -1112,6 +1247,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) ) endif() + xcode_remove_warning_duplicates(acq_test) + add_test(acq_test acq_test) if(USE_GENERIC_LAMBDAS) @@ -1165,8 +1302,6 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) target_link_libraries(trk_test PRIVATE Boost::thread - Gflags::gflags - Glog::glog Gnuradio::runtime Gnuradio::blocks Gnuradio::filter @@ -1181,6 +1316,13 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) signal_generator_gr_blocks core_receiver ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(trk_test PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(trk_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(trk_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(trk_test INTERFACE "$") + endif() if(USE_GENERIC_LAMBDAS) set(has_generic_lambdas HAS_GENERIC_LAMBDA=1) set(no_has_generic_lambdas HAS_GENERIC_LAMBDA=0) @@ -1208,6 +1350,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) ) endif() + xcode_remove_warning_duplicates(trk_test) + add_test(trk_test trk_test) set_property(TEST trk_test PROPERTY TIMEOUT 30) @@ -1230,14 +1374,21 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) target_link_libraries(control_thread_test PRIVATE Boost::thread - Gflags::gflags - Glog::glog GTest::GTest GTest::Main signal_source_adapters algorithms_libs core_receiver ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(control_thread_test PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(control_thread_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(control_thread_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize) + target_link_libraries(control_thread_test INTERFACE "$") + endif() + + xcode_remove_warning_duplicates(control_thread_test) add_test(control_thread_test control_thread_test) diff --git a/src/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt similarity index 92% rename from src/tests/benchmarks/CMakeLists.txt rename to tests/benchmarks/CMakeLists.txt index 133174871..7d94d9e9b 100644 --- a/src/tests/benchmarks/CMakeLists.txt +++ b/tests/benchmarks/CMakeLists.txt @@ -104,11 +104,18 @@ macro(add_benchmark) ) endmacro() -add_benchmark(benchmark_copy) -add_benchmark(benchmark_preamble core_system_parameters) -add_benchmark(benchmark_detector core_system_parameters) -add_benchmark(benchmark_reed_solomon core_system_parameters) +set(EXTRA_BENCHMARK_DEPENDENCIES "") +if(ENABLE_GLOG_AND_GFLAGS) + set(EXTRA_BENCHMARK_DEPENDENCIES "Gflags::gflags;Glog::glog") +endif() + add_benchmark(benchmark_atan2 Gnuradio::runtime) +add_benchmark(benchmark_copy) +add_benchmark(benchmark_crypto core_libs Boost::headers ${EXTRA_BENCHMARK_DEPENDENCIES}) +# add_benchmark(benchmark_osnma core_libs Boost::headers ${EXTRA_BENCHMARK_DEPENDENCIES}) +add_benchmark(benchmark_detector core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) +add_benchmark(benchmark_preamble core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) +add_benchmark(benchmark_reed_solomon core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) if(has_std_plus_void) target_compile_definitions(benchmark_detector PRIVATE -DCOMPILER_HAS_STD_PLUS_VOID=1) diff --git a/src/tests/benchmarks/README.md b/tests/benchmarks/README.md similarity index 100% rename from src/tests/benchmarks/README.md rename to tests/benchmarks/README.md diff --git a/src/tests/benchmarks/benchmark_atan2.cc b/tests/benchmarks/benchmark_atan2.cc similarity index 100% rename from src/tests/benchmarks/benchmark_atan2.cc rename to tests/benchmarks/benchmark_atan2.cc diff --git a/src/tests/benchmarks/benchmark_copy.cc b/tests/benchmarks/benchmark_copy.cc similarity index 100% rename from src/tests/benchmarks/benchmark_copy.cc rename to tests/benchmarks/benchmark_copy.cc diff --git a/tests/benchmarks/benchmark_crypto.cc b/tests/benchmarks/benchmark_crypto.cc new file mode 100644 index 000000000..ec1945ab9 --- /dev/null +++ b/tests/benchmarks/benchmark_crypto.cc @@ -0,0 +1,184 @@ +/*! + * \file benchmark_crypto.cc + * \brief Benchmarks for cryptographic functions + * \author Carles Fernandez-Prades, 2024. cfernandez(at)cttc.es + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "gnss_crypto.h" +#include +#include + +void bm_SHA_256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_SHA_256(message); + } +} + + +void bm_SHA3_256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_SHA3_256(message); + } +} + + +void bm_HMAC_SHA_256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector key = { + 0x24, 0x24, 0x3B, 0x76, 0xF9, 0x14, 0xB1, 0xA7, + 0x7D, 0x48, 0xE7, 0xF1, 0x48, 0x0C, 0xC2, 0x98, + 0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3, + 0xB4, 0xD4, 0xDB, 0x31, 0xEE, 0x96, 0xAB, 0xFA}; + + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_HMAC_SHA_256(key, message); + } +} + + +void bm_CMAC_AES(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector key = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; + + std::vector message{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_CMAC_AES(key, message); + } +} + + +void bm_verify_ecdsa_p256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + // RG example - import crt certificate + std::vector message = { + 0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, + 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, + 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; + + // ECDSA P-256 signature, raw format + std::vector signature = { + 0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, + 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, + 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, + 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, + 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, + 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, + 0x28, 0xC1, 0x77, 0xFB}; + + // compressed ECDSA P-256 format + std::vector publicKey = { + 0x03, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, + 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, + 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, + 0x79, 0x80, 0xEA}; + + d_crypto->set_public_key(publicKey); + + while (state.KeepRunning()) + { + bool output = d_crypto->verify_signature_ecdsa_p256(message, signature); + if (output) + { + // Avoid unused-but-set-variable warning + } + } +} + + +void bm_verify_ecdsa_p521(benchmark::State& state) +{ + std::unique_ptr d_crypto = std::make_unique(); + + // Message to be verified + std::vector message = { + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // "Hello world\n" + + // Public key in compressed X format + std::vector publicKey = { + 0x03, 0x00, 0x28, 0x35, 0xBB, 0xE9, 0x24, 0x59, 0x4E, 0xF0, + 0xE3, 0xA2, 0xDB, 0xC0, 0x49, 0x30, 0x60, 0x7C, 0x61, 0x90, + 0xE4, 0x03, 0xE0, 0xC7, 0xB8, 0xC2, 0x62, 0x37, 0xF7, 0x58, + 0x56, 0xBE, 0x63, 0x5C, 0x97, 0xF7, 0x53, 0x64, 0x7E, 0xE1, + 0x0C, 0x07, 0xD3, 0x97, 0x8D, 0x58, 0x46, 0xFD, 0x6E, 0x06, + 0x44, 0x01, 0xA7, 0xAA, 0xC4, 0x95, 0x13, 0x5D, 0xC9, 0x77, + 0x26, 0xE9, 0xF8, 0x72, 0x0C, 0xD3, 0x88}; + + // ECDSA P-521 signature, raw format + std::vector signature = { + 0x01, 0x5C, 0x23, 0xC0, 0xBE, 0xAD, 0x1E, 0x44, 0x60, 0xD4, + 0xE0, 0x81, 0x38, 0xF2, 0xBA, 0xF5, 0xB5, 0x37, 0x5A, 0x34, + 0xB5, 0xCA, 0x6B, 0xC8, 0x0F, 0xCD, 0x75, 0x1D, 0x5E, 0xC0, + 0x8A, 0xD3, 0xD7, 0x79, 0xA7, 0xC1, 0xB8, 0xA2, 0xC6, 0xEA, + 0x5A, 0x7D, 0x60, 0x66, 0x50, 0x97, 0x37, 0x6C, 0xF9, 0x0A, + 0xF6, 0x3D, 0x77, 0x9A, 0xE2, 0x19, 0xF7, 0xF9, 0xDD, 0x52, + 0xC4, 0x0F, 0x98, 0xAA, 0xA2, 0xA4, 0x01, 0xC9, 0x41, 0x0B, + 0xD0, 0x25, 0xDD, 0xC9, 0x7C, 0x3F, 0x70, 0x32, 0x23, 0xCF, + 0xFE, 0x37, 0x67, 0x3A, 0xBC, 0x0B, 0x76, 0x16, 0x82, 0x83, + 0x27, 0x3D, 0x1D, 0x19, 0x15, 0x78, 0x08, 0x2B, 0xD4, 0xA7, + 0xC2, 0x0F, 0x11, 0xF4, 0xDD, 0xE5, 0x5A, 0x5D, 0x04, 0x8D, + 0x6D, 0x5E, 0xC4, 0x1F, 0x54, 0x44, 0xA9, 0x13, 0x34, 0x71, + 0x0F, 0xF7, 0x57, 0x9A, 0x9F, 0x2E, 0xF4, 0x97, 0x7D, 0xAE, + 0x28, 0xEF}; + + d_crypto->set_public_key(publicKey); + + while (state.KeepRunning()) + { + bool output = d_crypto->verify_signature_ecdsa_p521(message, signature); + if (output) + { + // Avoid unused-but-set-variable warning + } + } +} + + +BENCHMARK(bm_SHA_256); +BENCHMARK(bm_SHA3_256); +BENCHMARK(bm_HMAC_SHA_256); +BENCHMARK(bm_CMAC_AES); +BENCHMARK(bm_verify_ecdsa_p256); +BENCHMARK(bm_verify_ecdsa_p521); + +BENCHMARK_MAIN(); diff --git a/src/tests/benchmarks/benchmark_detector.cc b/tests/benchmarks/benchmark_detector.cc similarity index 92% rename from src/tests/benchmarks/benchmark_detector.cc rename to tests/benchmarks/benchmark_detector.cc index 5679e9c3b..61da0f70c 100644 --- a/src/tests/benchmarks/benchmark_detector.cc +++ b/tests/benchmarks/benchmark_detector.cc @@ -42,9 +42,9 @@ void bm_forloop(benchmark::State& state) std::generate(d_preamble_samples.begin(), d_preamble_samples.end(), [n = 0]() mutable { return (GPS_CA_PREAMBLE_SYMBOLS_STR[n++] == '1' ? 1 : -1); }); + int32_t corr_value = 0; while (state.KeepRunning()) { - int32_t corr_value = 0; for (size_t i = 0; i < d_preamble_samples.size(); i++) { if (d_symbol_history[i] < 0.0) @@ -57,6 +57,10 @@ void bm_forloop(benchmark::State& state) } } } + if (corr_value) + { + // avoidl warning + }; } @@ -73,14 +77,18 @@ void bm_accumulate(benchmark::State& state) std::generate(d_preamble_samples.begin(), d_preamble_samples.end(), [n = 0]() mutable { return (GPS_CA_PREAMBLE_SYMBOLS_STR[n++] == '1' ? 1 : -1); }); + int32_t corr_value = 0; while (state.KeepRunning()) { - int32_t corr_value = 0; corr_value += std::accumulate(d_symbol_history.begin(), d_symbol_history.end(), 0, [&d_preamble_samples, n = 0](float a, float b) mutable { return (b > 0.0 ? a + d_preamble_samples[n++] : a - d_preamble_samples[n++]); }); } + if (corr_value) + { + // avoidl warning + }; } @@ -97,9 +105,9 @@ void bm_inner_product(benchmark::State& state) std::generate(d_preamble_samples.begin(), d_preamble_samples.end(), [n = 0]() mutable { return (GPS_CA_PREAMBLE_SYMBOLS_STR[n++] == '1' ? 1 : -1); }); + int32_t corr_value = 0; while (state.KeepRunning()) { - int32_t corr_value = 0; corr_value += std::inner_product(d_symbol_history.begin(), d_symbol_history.end(), d_preamble_samples.begin(), @@ -111,6 +119,10 @@ void bm_inner_product(benchmark::State& state) #endif [](float a, int32_t b) { return (std::signbit(a) ? -b : b); }); } + if (corr_value) + { + // avoidl warning + }; } @@ -128,9 +140,9 @@ void bm_transform_reduce(benchmark::State& state) std::generate(d_preamble_samples.begin(), d_preamble_samples.end(), [n = 0]() mutable { return (GPS_CA_PREAMBLE_SYMBOLS_STR[n++] == '1' ? 1 : -1); }); + int32_t corr_value = 0; while (state.KeepRunning()) { - int32_t corr_value = 0; corr_value += std::transform_reduce(d_symbol_history.begin(), d_symbol_history.end(), d_preamble_samples.begin(), @@ -138,6 +150,10 @@ void bm_transform_reduce(benchmark::State& state) std::plus<>(), [](auto a, auto b) { return (std::signbit(a) ? -b : b); }); } + if (corr_value) + { + // avoidl warning + }; } #endif @@ -156,9 +172,9 @@ void bm_transform_reduce_policy(benchmark::State& state) std::generate(d_preamble_samples.begin(), d_preamble_samples.end(), [n = 0]() mutable { return (GPS_CA_PREAMBLE_SYMBOLS_STR[n++] == '1' ? 1 : -1); }); + int32_t corr_value = 0; while (state.KeepRunning()) { - int32_t corr_value = 0; corr_value += std::transform_reduce( std::execution::par, d_symbol_history.begin(), @@ -168,6 +184,10 @@ void bm_transform_reduce_policy(benchmark::State& state) std::plus<>(), [](auto a, auto b) { return (std::signbit(a) ? -b : b); }); } + if (corr_value) + { + // avoidl warning + }; } #endif diff --git a/tests/benchmarks/benchmark_osnma.cc b/tests/benchmarks/benchmark_osnma.cc new file mode 100644 index 000000000..b99c3efd0 --- /dev/null +++ b/tests/benchmarks/benchmark_osnma.cc @@ -0,0 +1,127 @@ +/*! + * \file benchmark_osnma.cc + * \brief Benchmarks for osnma functions + * \author Carles Fernandez-Prades, 2024. cfernandez(at)cttc.es + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "Galileo_OSNMA.h" +#include "gnss_crypto.h" +#include "osnma_helper.h" +#include "osnma_msg_receiver.h" +#include +#include + +void bm_verify_public_key(benchmark::State& state) +{ + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(CRTFILE_DEFAULT, MERKLEFILE_DEFAULT); + Osnma_Helper helper; + osnma->set_merkle_root(helper.convert_from_hex_string("A10C440F3AA62453526DB4AF76DF8D9410D35D8277397D7053C700D192702B0D")); + DSM_PKR_message dsm_pkr_message; + dsm_pkr_message.npkt = 0x01; + dsm_pkr_message.npktid = 0x2; + dsm_pkr_message.mid = 0x01; + std::vector vec = helper.convert_from_hex_string( + "7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" + "956380BAB0D2C939EC6208151040CCFFCF1FB7156178FD1255BA0AECAAA253F7" + "407B6C5DD4DF059FF8789474061301E1C34881DB7A367A913A3674300E21EAB1" + "24EF508389B7D446C3E2ECE8D459FBBD3239A794906F5B1F92469C640164FD87"); + std::copy(vec.begin(), vec.end(), dsm_pkr_message.itn.begin()); + dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); + + while (state.KeepRunning()) + { + osnma->verify_dsm_pkr(dsm_pkr_message); + } +} + +void bm_verify_tesla_key(benchmark::State& state) +{ + // osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(CRTFILE_DEFAULT, MERKLEFILE_DEFAULT); + // Osnma_Helper helper; + // osnma->d_tesla_key_verified = false; + // osnma->d_osnma_data.d_dsm_kroot_message.kroot = {0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; // Kroot, TOW 345570 GST_0 - 30 + // osnma->d_osnma_data.d_dsm_kroot_message.ks = 4; // TABLE 10 --> 128 bits + // osnma->d_osnma_data.d_dsm_kroot_message.alpha = 0x610BDF26D77B; + // osnma->d_GST_SIS = (1248 & 0x00000FFF) << 20 | (345630 & 0x000FFFFF); + // osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30) + // osnma->d_GST_Sf = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G. + // + // osnma->d_tesla_keys.insert((std::pair>(345600, {0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference. + // std::vector key = {0x2D, 0xC3, 0xA3, 0xCD, 0xB1, 0x17, 0xFA, 0xAD, 0xB8, 0x3B, 0x5F, 0x0B, 0x6F, 0xEA, 0x88, 0xEB}; // K2 + // uint32_t TOW = 345630; + // + // while (state.KeepRunning()) + // { + // osnma->verify_tesla_key(key, TOW); + // } +} + +void bm_verify_tesla_key_24h(benchmark::State& state) +{ + // TODO - copy of normal tesla verification but with 2800 steps instead of only two (max Kroot time is 1 day as per spec.) +} + +void bm_tag_verification(benchmark::State& state) +{ + // osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(CRTFILE_DEFAULT, MERKLEFILE_DEFAULT); + // Osnma_Helper helper; + // uint32_t TOW_Tag0 = 345660; + // uint32_t TOW_NavData = TOW_Tag0 - 30; + // uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30; + // uint32_t WN = 1248; + // uint32_t PRNa = 2; + // uint8_t CTR = 1; + // + // osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + // osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 + // osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; + // osnma->d_nav_data_manager->add_navigation_data( + // "000011101001011001000100000101000111010110100100100101100000000000" + // "011101101011001111101110101010000001010000011011111100000011101011" + // "011100101101011010101011011011001001110111101011110110111111001111" + // "001000011111101110011000111111110111111010000011101011111111110000" + // "110111000000100000001110110000110110001110000100001110101100010100" + // "110100010001000110001110011010110000111010000010000000000001101000" + // "000000000011100101100100010000000000000110110100110001111100000000" + // "000000100110100000000101010010100000001011000010001001100000011111" + // "110111111111000000000", + // PRNa, TOW_NavData); + // osnma->d_osnma_data.d_nma_header.nmas = 0b10; + // + // MACK_tag_and_info MTI; + // MTI.tag = static_cast(0xE37BC4F858); + // MTI.tag_info.PRN_d = 0x02; + // MTI.tag_info.ADKD = 0x00; + // MTI.tag_info.cop = 0x0F; + // Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); + // + // while (state.KeepRunning()) + // { + // osnma->verify_tag(t0); + // } +} + +void bm_kroot_verification(benchmark::State& state) +{ + // TODO - this is essentially the signature verification, maybe could implement it for comparison purposes +} + +BENCHMARK(bm_verify_public_key); +BENCHMARK(bm_verify_tesla_key); +BENCHMARK(bm_verify_tesla_key_24h); +BENCHMARK(bm_tag_verification); +BENCHMARK(bm_kroot_verification); + + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/src/tests/benchmarks/benchmark_preamble.cc b/tests/benchmarks/benchmark_preamble.cc similarity index 100% rename from src/tests/benchmarks/benchmark_preamble.cc rename to tests/benchmarks/benchmark_preamble.cc diff --git a/src/tests/benchmarks/benchmark_reed_solomon.cc b/tests/benchmarks/benchmark_reed_solomon.cc similarity index 100% rename from src/tests/benchmarks/benchmark_reed_solomon.cc rename to tests/benchmarks/benchmark_reed_solomon.cc diff --git a/src/tests/common-files/gnuplot_i.h b/tests/common-files/gnuplot_i.h similarity index 99% rename from src/tests/common-files/gnuplot_i.h rename to tests/common-files/gnuplot_i.h index 5566f59cc..783674802 100644 --- a/src/tests/common-files/gnuplot_i.h +++ b/tests/common-files/gnuplot_i.h @@ -34,7 +34,6 @@ #ifndef GNSS_SDR_GNUPLOT_I_H #define GNSS_SDR_GNUPLOT_I_H -#include #include #include // for getenv() #include // for strncpy @@ -47,7 +46,13 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include DEFINE_bool(show_plots, true, "Show plots on screen. Disable for non-interactive testing."); +#else +#include +ABSL_FLAG(bool, show_plots, true, "Show plots on screen. Disable for non-interactive testing."); +#endif #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) // defined for 32 and 64-bit environments @@ -2090,7 +2095,7 @@ inline bool Gnuplot::get_program_path() // scan list for Gnuplot program files for (std::list::const_iterator i = ls.begin(); - i != ls.end(); ++i) + i != ls.end(); ++i) { tmp = (*i) + "/" + Gnuplot::m_sGNUPlotFileName; #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) diff --git a/src/tests/common-files/observable_tests_flags.h b/tests/common-files/observable_tests_flags.h similarity index 60% rename from src/tests/common-files/observable_tests_flags.h rename to tests/common-files/observable_tests_flags.h index 444211337..a0ab470b6 100644 --- a/src/tests/common-files/observable_tests_flags.h +++ b/tests/common-files/observable_tests_flags.h @@ -17,12 +17,27 @@ #ifndef GNSS_SDR_OBSERVABLE_TESTS_FLAGS_H #define GNSS_SDR_OBSERVABLE_TESTS_FLAGS_H -#include #include +#include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +#if USE_GLOG_AND_GFLAGS DEFINE_double(skip_obs_transitory_s, 30.0, "Skip the initial observable outputs to avoid transitory results [s]"); DEFINE_bool(compute_single_diffs, false, "Compute also the single difference errors for Accumulated Carrier Phase and Carrier Doppler (requires LO synchronization between receivers)"); DEFINE_bool(compare_with_5X, false, "Compare the E5a Doppler and Carrier Phases with the E5 full bw in RINEX (expect discrepancy due to the center frequencies differences"); DEFINE_bool(duplicated_satellites_test, false, "Enable special observable test mode where the scenario contains duplicated satellite orbits"); DEFINE_string(duplicated_satellites_prns, "1,2,3,4", "List of duplicated satellites PRN pairs (i.e. 1,2,3,4 indicates that the PRNs 1,2 share the same orbit. The same applies for PRNs 3,4)"); +#else +ABSL_FLAG(double, skip_obs_transitory_s, 30.0, "Skip the initial observable outputs to avoid transitory results [s]"); +ABSL_FLAG(bool, compute_single_diffs, false, "Compute also the single difference errors for Accumulated Carrier Phase and Carrier Doppler (requires LO synchronization between receivers)"); +ABSL_FLAG(bool, compare_with_5X, false, "Compare the E5a Doppler and Carrier Phases with the E5 full bw in RINEX (expect discrepancy due to the center frequencies differences"); +ABSL_FLAG(bool, duplicated_satellites_test, false, "Enable special observable test mode where the scenario contains duplicated satellite orbits"); +ABSL_FLAG(std::string, duplicated_satellites_prns, "1,2,3,4", "List of duplicated satellites PRN pairs (i.e. 1,2,3,4 indicates that the PRNs 1,2 share the same orbit. The same applies for PRNs 3,4)"); +#endif + #endif diff --git a/src/tests/common-files/signal_generator_flags.h b/tests/common-files/signal_generator_flags.h similarity index 56% rename from src/tests/common-files/signal_generator_flags.h rename to tests/common-files/signal_generator_flags.h index c43763fd3..be2ae03ac 100644 --- a/src/tests/common-files/signal_generator_flags.h +++ b/tests/common-files/signal_generator_flags.h @@ -17,10 +17,17 @@ #ifndef GNSS_SDR_SIGNAL_GENERATOR_FLAGS_H #define GNSS_SDR_SIGNAL_GENERATOR_FLAGS_H -#include +#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +#if USE_GLOG_AND_GFLAGS DEFINE_bool(disable_generator, false, "Disable the signal generator (a external signal file must be available for the test)"); DEFINE_string(generator_binary, std::string(SW_GENERATOR_BIN), "Path of software-defined signal generator binary"); DEFINE_string(rinex_nav_file, std::string(DEFAULT_RINEX_NAV), "Input RINEX navigation file"); @@ -34,5 +41,20 @@ DEFINE_int32(test_satellite_PRN, 1, "PRN of the satellite under test (must be vi DEFINE_int32(test_satellite_PRN2, 2, "PRN of the satellite under test (must be visible during the observation time)"); DEFINE_string(test_satellite_PRN_list, "1,2,3,6,9,10,12,17,20,23,28", "List of PRN of the satellites under test (must be visible during the observation time)"); DEFINE_double(CN0_dBHz, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 [dB-Hz]"); +#else +ABSL_FLAG(bool, disable_generator, false, "Disable the signal generator (a external signal file must be available for the test)"); +ABSL_FLAG(std::string, generator_binary, std::string(SW_GENERATOR_BIN), "Path of software-defined signal generator binary"); +ABSL_FLAG(std::string, rinex_nav_file, std::string(DEFAULT_RINEX_NAV), "Input RINEX navigation file"); +ABSL_FLAG(int32_t, duration, 100, "Duration of the experiment [in seconds, max = 300]"); +ABSL_FLAG(std::string, static_position, "30.286502,120.032669,100", "Static receiver position [latitude,longitude,height]"); +ABSL_FLAG(std::string, dynamic_position, "", "Observer positions file, in .csv or .nmea format"); +ABSL_FLAG(std::string, filename_rinex_obs, "sim.16o", "Filename of output RINEX navigation file"); +ABSL_FLAG(std::string, filename_raw_data, "signal_out.bin", "Filename of output raw data file"); +ABSL_FLAG(int32_t, fs_gen_sps, 2600000, "Sampling frequency [sps]"); +ABSL_FLAG(int32_t, test_satellite_PRN, 1, "PRN of the satellite under test (must be visible during the observation time)"); +ABSL_FLAG(int32_t, test_satellite_PRN2, 2, "PRN of the satellite under test (must be visible during the observation time)"); +ABSL_FLAG(std::string, test_satellite_PRN_list, "1,2,3,6,9,10,12,17,20,23,28", "List of PRN of the satellites under test (must be visible during the observation time)"); +ABSL_FLAG(double, CN0_dBHz, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 [dB-Hz]"); +#endif #endif diff --git a/src/tests/common-files/test_flags.h b/tests/common-files/test_flags.h similarity index 68% rename from src/tests/common-files/test_flags.h rename to tests/common-files/test_flags.h index 814cf69e6..57061e5a7 100644 --- a/src/tests/common-files/test_flags.h +++ b/tests/common-files/test_flags.h @@ -17,16 +17,28 @@ #ifndef GNSS_SDR_TEST_FLAGS_H #define GNSS_SDR_TEST_FLAGS_H -#include + +#include #include + +#if USE_GLOG_AND_GFLAGS +#include #if defined GNUPLOT_EXECUTABLE DEFINE_string(gnuplot_executable, std::string(GNUPLOT_EXECUTABLE), "Gnuplot binary path"); #elif !defined GNUPLOT_EXECUTABLE DEFINE_string(gnuplot_executable, "", "Gnuplot binary path"); #endif - DEFINE_bool(plot_acq_grid, false, "Plots acquisition grid with gnuplot"); DEFINE_int32(plot_decimate, 1, "Decimate plots"); - +#else +#include +#if defined GNUPLOT_EXECUTABLE +ABSL_FLAG(std::string, gnuplot_executable, std::string(GNUPLOT_EXECUTABLE), "Gnuplot binary path"); +#elif !defined GNUPLOT_EXECUTABLE +ABSL_FLAG(std::string, gnuplot_executable, "", "Gnuplot binary path"); +#endif +ABSL_FLAG(bool, plot_acq_grid, false, "Plots acquisition grid with gnuplot"); +ABSL_FLAG(int32_t, plot_decimate, 1, "Decimate plots"); +#endif #endif diff --git a/src/tests/common-files/tracking_tests_flags.h b/tests/common-files/tracking_tests_flags.h similarity index 52% rename from src/tests/common-files/tracking_tests_flags.h rename to tests/common-files/tracking_tests_flags.h index 8bbc4701c..0027fb862 100644 --- a/src/tests/common-files/tracking_tests_flags.h +++ b/tests/common-files/tracking_tests_flags.h @@ -17,10 +17,12 @@ #ifndef GNSS_SDR_TRACKING_TESTS_FLAGS_H #define GNSS_SDR_TRACKING_TESTS_FLAGS_H -#include +#include #include #include +#if USE_GLOG_AND_GFLAGS +#include DEFINE_string(trk_test_implementation, std::string("GPS_L1_CA_DLL_PLL_Tracking"), "Tracking block implementation under test, defaults to GPS_L1_CA_DLL_PLL_Tracking"); // Input signal configuration @@ -77,6 +79,63 @@ DEFINE_bool(high_dyn, false, "Activates the code resampler and NCO generator for // Test output configuration DEFINE_bool(plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); +#else +#include +ABSL_FLAG(std::string, trk_test_implementation, std::string("GPS_L1_CA_DLL_PLL_Tracking"), "Tracking block implementation under test, defaults to GPS_L1_CA_DLL_PLL_Tracking"); +// Input signal configuration +ABSL_FLAG(bool, enable_external_signal_file, false, "Use an external signal file capture instead of the software-defined signal generator"); +ABSL_FLAG(double, external_signal_acquisition_threshold, 2.5, "Threshold for satellite acquisition when external file is used"); +ABSL_FLAG(int32_t, external_signal_acquisition_dwells, 5, "Maximum dwells count for satellite acquisition when external file is used"); +ABSL_FLAG(double, external_signal_acquisition_doppler_max_hz, 5000.0, "Doppler max for satellite acquisition when external file is used"); +ABSL_FLAG(double, external_signal_acquisition_doppler_step_hz, 125.0, "Doppler step for satellite acquisition when external file is used"); +ABSL_FLAG(bool, use_acquisition_resampler, false, "Reduce the sampling rate of the input signal for the acquisition in order to optimize the SNR and decrease the processor load"); +ABSL_FLAG(std::string, signal_file, std::string("signal_out.bin"), "Path of the external signal capture file"); +ABSL_FLAG(double, CN0_dBHz_start, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 start sweep value [dB-Hz]"); +ABSL_FLAG(double, CN0_dBHz_stop, std::numeric_limits::infinity(), "Enable noise generator and set the CN0 stop sweep value [dB-Hz]"); +ABSL_FLAG(double, CN0_dB_step, 3.0, "Noise generator CN0 sweep step value [dB]"); + +ABSL_FLAG(double, PLL_bw_hz_start, 20.0, "PLL Wide configuration start sweep value [Hz]"); +ABSL_FLAG(double, PLL_bw_hz_stop, 20.0, "PLL Wide configuration stop sweep value [Hz]"); +ABSL_FLAG(double, PLL_bw_hz_step, 5.0, "PLL Wide configuration sweep step value [Hz]"); + +ABSL_FLAG(double, DLL_bw_hz_start, 1.0, "DLL Wide configuration start sweep value [Hz]"); +ABSL_FLAG(double, DLL_bw_hz_stop, 1.0, "DLL Wide configuration stop sweep value [Hz]"); +ABSL_FLAG(double, DLL_bw_hz_step, 0.25, "DLL Wide configuration sweep step value [Hz]"); + +ABSL_FLAG(double, fll_bw_hz, 4.0, "FLL filter bandwidth [Hz]"); +ABSL_FLAG(bool, enable_fll_pull_in, false, "Enable FLL in pull-in phase"); +ABSL_FLAG(bool, enable_fll_steady_state, false, "Enable FLL in steady-state phase"); + +ABSL_FLAG(double, PLL_narrow_bw_hz, 5.0, "PLL Narrow configuration value [Hz]"); +ABSL_FLAG(double, DLL_narrow_bw_hz, 0.75, "DLL Narrow configuration value [Hz]"); + +ABSL_FLAG(double, acq_Doppler_error_hz_start, 1000.0, "Acquisition Doppler error start sweep value [Hz]"); +ABSL_FLAG(double, acq_Doppler_error_hz_stop, -1000.0, "Acquisition Doppler error stop sweep value [Hz]"); +ABSL_FLAG(double, acq_Doppler_error_hz_step, -50.0, "Acquisition Doppler error sweep step value [Hz]"); + +ABSL_FLAG(double, acq_Delay_error_chips_start, 2.0, "Acquisition Code Delay error start sweep value [Chips]"); +ABSL_FLAG(double, acq_Delay_error_chips_stop, -2.0, "Acquisition Code Delay error stop sweep value [Chips]"); +ABSL_FLAG(double, acq_Delay_error_chips_step, -0.1, "Acquisition Code Delay error sweep step value [Chips]"); + +ABSL_FLAG(double, acq_to_trk_delay_s, 0.0, "Acquisition to Tracking delay value [s]"); + + +ABSL_FLAG(int64_t, skip_samples, 0, "Skip an initial transitory in the processed signal file capture [samples]"); + +ABSL_FLAG(int32_t, plot_detail_level, 0, "Specify the desired plot detail (0,1,2): 0 - Minimum plots (default) 2 - Plot all tracking parameters"); + +ABSL_FLAG(double, skip_trk_transitory_s, 1.0, "Skip the initial tracking output signal to avoid transitory results [s]"); + +// Emulated acquisition configuration + +// Tracking configuration +ABSL_FLAG(int32_t, extend_correlation_symbols, 1, "Set the tracking coherent correlation to N symbols (up to 20 for GPS L1 C/A)"); +ABSL_FLAG(int32_t, smoother_length, 10, "Set the moving average size for the carrier phase and code phase in case of high dynamics"); +ABSL_FLAG(bool, high_dyn, false, "Activates the code resampler and NCO generator for high dynamics"); + +// Test output configuration +ABSL_FLAG(bool, plot_gps_l1_tracking_test, false, "Plots results of GpsL1CADllPllTrackingTest with gnuplot"); #endif +#endif diff --git a/src/tests/data/config_file_sample.txt b/tests/data/config_file_sample.txt similarity index 100% rename from src/tests/data/config_file_sample.txt rename to tests/data/config_file_sample.txt diff --git a/src/tests/data/gnsstk_gcc13.patch b/tests/data/gnsstk_gcc13.patch similarity index 100% rename from src/tests/data/gnsstk_gcc13.patch rename to tests/data/gnsstk_gcc13.patch diff --git a/src/tests/data/gnsstk_static13.patch b/tests/data/gnsstk_static13.patch similarity index 100% rename from src/tests/data/gnsstk_static13.patch rename to tests/data/gnsstk_static13.patch diff --git a/src/tests/data/gnsstk_static14.patch b/tests/data/gnsstk_static14.patch similarity index 100% rename from src/tests/data/gnsstk_static14.patch rename to tests/data/gnsstk_static14.patch diff --git a/src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml b/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml similarity index 100% rename from src/tests/data/rtklib_test/eph_GPS_L1CA_test1.xml rename to tests/data/rtklib_test/eph_GPS_L1CA_test1.xml diff --git a/src/tests/data/rtklib_test/obs_test1.xml b/tests/data/rtklib_test/obs_test1.xml similarity index 100% rename from src/tests/data/rtklib_test/obs_test1.xml rename to tests/data/rtklib_test/obs_test1.xml diff --git a/src/tests/single_test_main.cc b/tests/single_test_main.cc similarity index 51% rename from src/tests/single_test_main.cc rename to tests/single_test_main.cc index 5f8d52aab..27dc60c17 100644 --- a/src/tests/single_test_main.cc +++ b/tests/single_test_main.cc @@ -18,28 +18,75 @@ #include "concurrent_map.h" #include "concurrent_queue.h" +#include "gnss_sdr_flags.h" #include "gps_acq_assist.h" +#include +#include +#include +#include +#include + +#if USE_GLOG_AND_GFLAGS #include #include -#include -#include - #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } +DECLARE_string(log_dir); #endif +#else +#include +#include +#include +#include +#include +#include +#include +class TestLogSink : public absl::LogSink +{ +public: + TestLogSink() + { + if (!absl::GetFlag(FLAGS_log_dir).empty()) + { + logfile.open(absl::GetFlag(FLAGS_log_dir) + "/test.log"); + } + else + { + logfile.open(GetTempDir() + "/test.log"); + } + } + void Send(const absl::LogEntry &entry) override + { + logfile << entry.text_message_with_prefix_and_newline() << std::flush; + } + +private: + std::ofstream logfile; +}; +#endif + Concurrent_Queue global_gps_acq_assist_queue; Concurrent_Map global_gps_acq_assist_map; -DECLARE_string(log_dir); int main(int argc, char **argv) { - gflags::ParseCommandLineFlags(&argc, &argv, true); +#if USE_GLOG_AND_GFLAGS + try + { + testing::InitGoogleTest(&argc, argv); + gflags::ParseCommandLineFlags(&argc, &argv, true); + } + catch (...) + { + } // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest +#else + absl::ParseCommandLine(argc, argv); try { testing::InitGoogleTest(&argc, argv); @@ -47,7 +94,10 @@ int main(int argc, char **argv) catch (...) { } // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest - google::InitGoogleLogging(argv[0]); + absl::LogSink *testLogSink = new TestLogSink; + absl::AddLogSink(testLogSink); + absl::InitializeLog(); +#endif int res = 0; try { @@ -57,6 +107,10 @@ int main(int argc, char **argv) { LOG(WARNING) << "Unexpected catch"; } +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#else + absl::FlushLogSinks(); +#endif return res; } diff --git a/src/tests/system-tests/libs/CMakeLists.txt b/tests/system-tests/libs/CMakeLists.txt similarity index 83% rename from src/tests/system-tests/libs/CMakeLists.txt rename to tests/system-tests/libs/CMakeLists.txt index eb936a24f..01a5bfdeb 100644 --- a/src/tests/system-tests/libs/CMakeLists.txt +++ b/tests/system-tests/libs/CMakeLists.txt @@ -32,12 +32,18 @@ endif() target_link_libraries(system_testing_lib PUBLIC Armadillo::armadillo - Gflags::gflags PRIVATE Boost::headers Matio::matio ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(system_testing_lib PUBLIC Gflags::gflags) + target_compile_definitions(system_testing_lib PUBLIC -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(system_testing_lib PUBLIC absl::flags) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(system_testing_lib diff --git a/src/tests/system-tests/libs/position_test_flags.h b/tests/system-tests/libs/position_test_flags.h similarity index 55% rename from src/tests/system-tests/libs/position_test_flags.h rename to tests/system-tests/libs/position_test_flags.h index 57cc1e5dd..abff0f4a6 100644 --- a/src/tests/system-tests/libs/position_test_flags.h +++ b/tests/system-tests/libs/position_test_flags.h @@ -17,10 +17,18 @@ #ifndef GNSS_SDR_POSITION_TEST_FLAGS_H #define GNSS_SDR_POSITION_TEST_FLAGS_H -#include + +#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +#if USE_GLOG_AND_GFLAGS DEFINE_string(config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); DEFINE_bool(plot_position_test, false, "Plots results of with gnuplot"); DEFINE_bool(static_scenario, true, "Compute figures of merit for static user position (DRMS, CEP, etc..)"); @@ -35,5 +43,21 @@ DEFINE_double(precision_SEP, 15.0, "Static scenario 3D (East, North, Up) precisi DEFINE_double(dynamic_3D_position_RMSE, 10.0, "Dynamic scenario 3D (ECEF) accuracy RMSE threshold [meters]"); DEFINE_double(dynamic_3D_velocity_RMSE, 5.0, "Dynamic scenario 3D (ECEF) velocity accuracy RMSE threshold [meters/second]"); DEFINE_bool(enable_carrier_smoothing, false, "Activates carrier smoothing of pseudoranges"); +#else +ABSL_FLAG(std::string, config_file_ptest, std::string(""), "File containing the configuration parameters for the position test."); +ABSL_FLAG(bool, plot_position_test, false, "Plots results of with gnuplot"); +ABSL_FLAG(bool, static_scenario, true, "Compute figures of merit for static user position (DRMS, CEP, etc..)"); +ABSL_FLAG(bool, use_ref_motion_file, false, "Enable or disable the use of a reference file containing the true receiver position, velocity and acceleration."); +ABSL_FLAG(int32_t, ref_motion_file_type, 1, "Type of reference motion file: 1- Spirent CSV motion file"); +ABSL_FLAG(std::string, ref_motion_filename, std::string("motion.csv"), "Path and filename for the reference motion file"); +ABSL_FLAG(std::string, pvt_solver_dump_filename, std::string("PVT.dat"), "Path and filename for the PVT solver binary dump file"); +ABSL_FLAG(double, static_2D_error_m, 2.0, "Static scenario 2D (East, North) positioning error threshold [meters]"); +ABSL_FLAG(double, static_3D_error_m, 5.0, "Static scenario 3D (East, North, Up) positioning error threshold [meters]"); +ABSL_FLAG(double, accuracy_CEP, 3.0, "Static scenario 2D (East, North) accuracy Circular Error Position (CEP) threshold [meters]"); +ABSL_FLAG(double, precision_SEP, 15.0, "Static scenario 3D (East, North, Up) precision Spherical Error Position (SEP) threshold [meters]"); +ABSL_FLAG(double, dynamic_3D_position_RMSE, 10.0, "Dynamic scenario 3D (ECEF) accuracy RMSE threshold [meters]"); +ABSL_FLAG(double, dynamic_3D_velocity_RMSE, 5.0, "Dynamic scenario 3D (ECEF) velocity accuracy RMSE threshold [meters/second]"); +ABSL_FLAG(bool, enable_carrier_smoothing, false, "Activates carrier smoothing of pseudoranges"); +#endif #endif diff --git a/src/tests/system-tests/libs/rtklib_solver_dump_reader.cc b/tests/system-tests/libs/rtklib_solver_dump_reader.cc similarity index 100% rename from src/tests/system-tests/libs/rtklib_solver_dump_reader.cc rename to tests/system-tests/libs/rtklib_solver_dump_reader.cc diff --git a/src/tests/system-tests/libs/rtklib_solver_dump_reader.h b/tests/system-tests/libs/rtklib_solver_dump_reader.h similarity index 100% rename from src/tests/system-tests/libs/rtklib_solver_dump_reader.h rename to tests/system-tests/libs/rtklib_solver_dump_reader.h diff --git a/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc b/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc similarity index 99% rename from src/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc rename to tests/system-tests/libs/spirent_motion_csv_dump_reader.cc index dc88d9e7b..66a73d6df 100644 --- a/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc +++ b/tests/system-tests/libs/spirent_motion_csv_dump_reader.cc @@ -97,7 +97,7 @@ bool Spirent_Motion_Csv_Dump_Reader::read_csv_obs() line, boost::escaped_list_separator('\\', ',', '\"')); for (boost::tokenizer>::iterator i( tk.begin()); - i != tk.end(); ++i) + i != tk.end(); ++i) { try { diff --git a/src/tests/system-tests/libs/spirent_motion_csv_dump_reader.h b/tests/system-tests/libs/spirent_motion_csv_dump_reader.h similarity index 100% rename from src/tests/system-tests/libs/spirent_motion_csv_dump_reader.h rename to tests/system-tests/libs/spirent_motion_csv_dump_reader.h diff --git a/src/tests/system-tests/position_test.cc b/tests/system-tests/position_test.cc similarity index 86% rename from src/tests/system-tests/position_test.cc rename to tests/system-tests/position_test.cc index 5802aa9ca..f15fdf6aa 100644 --- a/src/tests/system-tests/position_test.cc +++ b/tests/system-tests/position_test.cc @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -48,16 +47,53 @@ #include #include #include +#include #include +#if USE_GLOG_AND_GFLAGS +#include #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } #endif +#else +#include +#include +#include +#include +#include +#include +#endif +#if USE_GLOG_AND_GFLAGS DEFINE_int32(num_channels, 11, "Number of channels"); +#else +ABSL_FLAG(int32_t, num_channels, 11, "Number of channels"); +class PositionTestLogSink : public absl::LogSink +{ +public: + PositionTestLogSink() + { + if (!absl::GetFlag(FLAGS_log_dir).empty()) + { + logfile.open(absl::GetFlag(FLAGS_log_dir) + "/position_test.log"); + } + else + { + logfile.open(GetTempDir() + "/position_test.log"); + } + } + void Send(const absl::LogEntry& entry) override + { + logfile << entry.text_message_with_prefix_and_newline() << std::flush; + } + +private: + std::ofstream logfile; +}; +#endif // For GPS NAVIGATION (L1) Concurrent_Queue global_gps_acq_assist_queue; @@ -84,11 +120,15 @@ private: std::string p5; std::string p6; +#if USE_GLOG_AND_GFLAGS const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; - +#else + const double baseband_sampling_freq = static_cast(absl::GetFlag(FLAGS_fs_gen_sps)); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif void print_results(const arma::mat& R_eb_enu) const; std::shared_ptr config; std::shared_ptr config_f; @@ -101,6 +141,7 @@ private: int PositionSystemTest::configure_generator() { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -128,6 +169,35 @@ int PositionSystemTest::configure_generator() { p6 = std::string("-CN0_dBHz=") + std::to_string(FLAGS_CN0_dBHz); } +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(std::min(absl::GetFlag(FLAGS_duration) * 10, 3000)); + if (absl::GetFlag(FLAGS_duration) > 300) + { + std::cout << "WARNING: Duration has been set to its maximum value of 300 s\n"; + } + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] + if (absl::GetFlag(FLAGS_CN0_dBHz) > 100.0) + { + p6 = std::string("-CN0_dBHz=45"); + } + else + { + p6 = std::string("-CN0_dBHz=") + std::to_string(absl::GetFlag(FLAGS_CN0_dBHz)); + } +#endif return 0; } @@ -162,7 +232,11 @@ int PositionSystemTest::generate_signal() int PositionSystemTest::configure_receiver() { +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { config = std::make_shared(); const int sampling_rate_internal = baseband_sampling_freq; @@ -182,7 +256,11 @@ int PositionSystemTest::configure_receiver() const int grid_density = 16; const float zero = 0.0; +#if USE_GLOG_AND_GFLAGS const int number_of_channels = FLAGS_num_channels; +#else + const int number_of_channels = absl::GetFlag(FLAGS_num_channels); +#endif const int in_acquisition = 1; const float threshold = 2.5; @@ -199,14 +277,22 @@ int PositionSystemTest::configure_receiver() const float early_late_space_narrow_chips = 0.1; const float pll_bw_narrow_hz = 15.0; const float dll_bw_narrow_hz = 1.5; +#if USE_GLOG_AND_GFLAGS const int extend_correlation_symbols = FLAGS_extend_correlation_symbols; // defaults to 1 - +#else + const int extend_correlation_symbols = absl::GetFlag(FLAGS_extend_correlation_symbols); // defaults to 1 +#endif const int display_rate_ms = 500; const int output_rate_ms = 100; config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_rate_internal)); // Enable automatic resampler for the acquisition, if required + +#if USE_GLOG_AND_GFLAGS if (FLAGS_use_acquisition_resampler == true) +#else + if (absl::GetFlag(FLAGS_use_acquisition_resampler) == true) +#endif { config->set_property("GNSS-SDR.use_acquisition_resampler", "true"); } @@ -305,8 +391,13 @@ int PositionSystemTest::configure_receiver() // Set Observables config->set_property("Observables.implementation", "Hybrid_Observables"); +#if USE_GLOG_AND_GFLAGS config->set_property("Observables.enable_carrier_smoothing", FLAGS_enable_carrier_smoothing ? "true" : "false"); config->set_property("Observables.smoothing_factor", std::to_string(FLAGS_carrier_smoothing_factor)); +#else + config->set_property("Observables.enable_carrier_smoothing", absl::GetFlag(FLAGS_enable_carrier_smoothing) ? "true" : "false"); + config->set_property("Observables.smoothing_factor", std::to_string(absl::GetFlag(FLAGS_carrier_smoothing_factor))); +#endif config->set_property("Observables.dump", "false"); config->set_property("Observables.dump_filename", "./observables.dat"); @@ -334,7 +425,11 @@ int PositionSystemTest::configure_receiver() } else { +#if USE_GLOG_AND_GFLAGS config_f = std::make_shared(FLAGS_config_file_ptest); +#else + config_f = std::make_shared(absl::GetFlag(FLAGS_config_file_ptest)); +#endif config = nullptr; } return 0; @@ -344,7 +439,11 @@ int PositionSystemTest::configure_receiver() int PositionSystemTest::run_receiver() { std::shared_ptr control_thread; +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { control_thread = std::make_shared(config); } @@ -472,7 +571,11 @@ void PositionSystemTest::check_results() arma::mat ref_LLH; // Geodetic coordinates (latitude, longitude, height) reference in WGS84 datum arma::vec ref_time_s; +#if USE_GLOG_AND_GFLAGS std::istringstream iss2(FLAGS_static_position); +#else + std::istringstream iss2(absl::GetFlag(FLAGS_static_position)); +#endif std::string str_aux; std::getline(iss2, str_aux, ','); double ref_lat = std::stod(str_aux); @@ -491,7 +594,11 @@ void PositionSystemTest::check_results() cart2utm(true_r_eb_e, utm_zone, ref_r_enu); Rtklib_Solver_Dump_Reader pvt_reader; +#if USE_GLOG_AND_GFLAGS pvt_reader.open_obs_file(FLAGS_pvt_solver_dump_filename); +#else + pvt_reader.open_obs_file(absl::GetFlag(FLAGS_pvt_solver_dump_filename)); +#endif int64_t n_epochs_pvt = pvt_reader.num_epochs(); R_eb_e = arma::zeros(3, n_epochs_pvt); V_eb_e = arma::zeros(3, n_epochs_pvt); @@ -525,7 +632,11 @@ void PositionSystemTest::check_results() ASSERT_FALSE(current_epoch == 0) << "PVT dump is empty"; // compute results +#if USE_GLOG_AND_GFLAGS if (FLAGS_static_scenario) +#else + if (absl::GetFlag(FLAGS_static_scenario)) +#endif { double sigma_E_2_precision = arma::var(R_eb_enu.row(0)); double sigma_N_2_precision = arma::var(R_eb_enu.row(1)); @@ -566,11 +677,17 @@ void PositionSystemTest::check_results() std::stringstream stm; std::ofstream position_test_file; +#if USE_GLOG_AND_GFLAGS if (!FLAGS_config_file_ptest.empty()) { stm << "Configuration file: " << FLAGS_config_file_ptest << '\n'; } - +#else + if (!absl::GetFlag(FLAGS_config_file_ptest).empty()) + { + stm << "Configuration file: " << absl::GetFlag(FLAGS_config_file_ptest) << '\n'; + } +#endif stm << "---- STATIC ACCURACY ----\n"; stm << "2DRMS = " << 2 * sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]\n"; stm << "DRMS = " << sqrt(sigma_E_2_accuracy + sigma_N_2_accuracy) << " [m]\n"; @@ -607,7 +724,7 @@ void PositionSystemTest::check_results() // Sanity Check double accuracy_CEP = 0.62 * sqrt(sigma_N_2_accuracy) + 0.56 * sqrt(sigma_E_2_accuracy); double precision_SEP = 0.51 * (sigma_E_2_precision + sigma_N_2_precision + sigma_U_2_precision); - +#if USE_GLOG_AND_GFLAGS EXPECT_LT(static_2D_error_m, FLAGS_static_2D_error_m); EXPECT_LT(static_3D_error_m, FLAGS_static_3D_error_m); ASSERT_LT(accuracy_CEP, FLAGS_accuracy_CEP); @@ -617,12 +734,27 @@ void PositionSystemTest::check_results() { print_results(R_eb_enu); } +#else + EXPECT_LT(static_2D_error_m, absl::GetFlag(FLAGS_static_2D_error_m)); + EXPECT_LT(static_3D_error_m, absl::GetFlag(FLAGS_static_3D_error_m)); + ASSERT_LT(accuracy_CEP, absl::GetFlag(FLAGS_accuracy_CEP)); + ASSERT_LT(precision_SEP, absl::GetFlag(FLAGS_precision_SEP)); + + if (absl::GetFlag(FLAGS_plot_position_test) == true) + { + print_results(R_eb_enu); + } +#endif } else { // dynamic position Spirent_Motion_Csv_Dump_Reader ref_reader; +#if USE_GLOG_AND_GFLAGS ref_reader.open_obs_file(FLAGS_ref_motion_filename); +#else + ref_reader.open_obs_file(absl::GetFlag(FLAGS_ref_motion_filename)); +#endif int64_t n_epochs_ref = ref_reader.num_epochs(); ref_R_eb_e = arma::zeros(3, n_epochs_ref); ref_V_eb_e = arma::zeros(3, n_epochs_ref); @@ -692,10 +824,17 @@ void PositionSystemTest::check_results() // report std::cout << "----- Position and Velocity 3D ECEF error statistics -----\n"; +#if USE_GLOG_AND_GFLAGS if (!FLAGS_config_file_ptest.empty()) { std::cout << "---- Configuration file: " << FLAGS_config_file_ptest << '\n'; } +#else + if (!absl::GetFlag(FLAGS_config_file_ptest).empty()) + { + std::cout << "---- Configuration file: " << absl::GetFlag(FLAGS_config_file_ptest) << '\n'; + } +#endif std::streamsize ss = std::cout.precision(); std::cout << std::setprecision(10) << "---- 3D ECEF Position RMSE = " << rmse_R_eb_e << ", mean = " << error_mean_R_eb_e @@ -711,14 +850,24 @@ void PositionSystemTest::check_results() << " [m/s]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_position_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + if (absl::GetFlag(FLAGS_plot_position_test) == true) + { + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (!gnuplot_executable.empty()) { Gnuplot g1("points"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -740,7 +889,11 @@ void PositionSystemTest::check_results() g1.cmd("set key box opaque"); g1.plot_xyz(X, Y, Z, "ECEF 3D error"); g1.set_legend(); +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { g1.savetops("ECEF_3d_error"); } @@ -750,7 +903,11 @@ void PositionSystemTest::check_results() } arma::vec time_vector_from_start_s = receiver_time_s - receiver_time_s(0); Gnuplot g3("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g3.showonscreen(); // window output } @@ -771,7 +928,11 @@ void PositionSystemTest::check_results() g3.set_style("lines"); g3.plot_xy(time_vector_from_start_s, error_mean, "Mean"); g3.set_legend(); +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { g3.savetops("Position_3d_error"); } @@ -781,7 +942,11 @@ void PositionSystemTest::check_results() } Gnuplot g4("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g4.showonscreen(); // window output } @@ -802,7 +967,11 @@ void PositionSystemTest::check_results() g4.set_style("lines"); g4.plot_xy(time_vector_from_start_s, error_mean_v, "Mean"); g4.set_legend(); +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { g4.savetops("Velocity_3d_error"); } @@ -813,17 +982,27 @@ void PositionSystemTest::check_results() } } - // ERROR CHECK - // todo: reduce the error tolerance or enable the option to pass the error tolerance by parameter + // ERROR CHECK + // todo: reduce the error tolerance or enable the option to pass the error tolerance by parameter + +#if USE_GLOG_AND_GFLAGS EXPECT_LT(rmse_R_eb_e, FLAGS_dynamic_3D_position_RMSE); // 3D RMS positioning error less than 10 meters EXPECT_LT(rmse_V_eb_e, FLAGS_dynamic_3D_velocity_RMSE); // 3D RMS speed error less than 5 meters/s (18 km/h) +#else + EXPECT_LT(rmse_R_eb_e, absl::GetFlag(FLAGS_dynamic_3D_position_RMSE)); // 3D RMS positioning error less than 10 meters + EXPECT_LT(rmse_V_eb_e, absl::GetFlag(FLAGS_dynamic_3D_velocity_RMSE)); // 3D RMS speed error less than 5 meters/s (18 km/h) +#endif } } void PositionSystemTest::print_results(const arma::mat& R_eb_enu) const { +#if USE_GLOG_AND_GFLAGS const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_position_test has been set to TRUE,\n"; @@ -874,7 +1053,11 @@ void PositionSystemTest::print_results(const arma::mat& R_eb_enu) const Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("points"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -895,7 +1078,11 @@ void PositionSystemTest::print_results(const arma::mat& R_eb_enu) const g1.cmd("set grid front"); g1.cmd("replot"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { g1.savetops("Position_test_2D"); g1.savetopdf("Position_test_2D", 18); @@ -907,7 +1094,11 @@ void PositionSystemTest::print_results(const arma::mat& R_eb_enu) const } Gnuplot g2("points"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g2.showonscreen(); // window output } @@ -930,7 +1121,11 @@ void PositionSystemTest::print_results(const arma::mat& R_eb_enu) const std::to_string(ninty_sas) + "\n fx(v,u) = r*cos(v)*cos(u)\n fy(v,u) = r*cos(v)*sin(u)\n fz(v) = r*sin(v) \n splot fx(v,u),fy(v,u),fz(v) title \"90%-SAS\" lt rgb \"gray\"\n"); g2.plot_xyz(east, north, up, "3D Position Fixes"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { g2.savetops("Position_test_3D"); g2.savetopdf("Position_test_3D"); @@ -951,20 +1146,33 @@ void PositionSystemTest::print_results(const arma::mat& R_eb_enu) const TEST_F(PositionSystemTest /*unused*/, Position_system_test /*unused*/) { +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { // Configure the signal generator configure_generator(); // Generate signal raw signal samples and observations RINEX file + +#if USE_GLOG_AND_GFLAGS if (!FLAGS_disable_generator) +#else + if (!absl::GetFlag(FLAGS_disable_generator)) +#endif { generate_signal(); } } else { +#if USE_GLOG_AND_GFLAGS config_filename_no_extension = FLAGS_config_file_ptest.substr(FLAGS_config_file_ptest.find_last_of("/\\") + 1); +#else + config_filename_no_extension = absl::GetFlag(FLAGS_config_file_ptest).substr(absl::GetFlag(FLAGS_config_file_ptest).find_last_of("/\\") + 1); +#endif config_filename_no_extension = config_filename_no_extension.erase(config_filename_no_extension.length() - 5); } @@ -991,8 +1199,15 @@ int main(int argc, char** argv) { } // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest +#if USE_GLOG_AND_GFLAGS gflags::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); +#else + absl::ParseCommandLine(argc, argv); + absl::LogSink* logSink = new PositionTestLogSink; + absl::AddLogSink(logSink); + absl::InitializeLog(); +#endif // Run the Tests try @@ -1003,6 +1218,10 @@ int main(int argc, char** argv) { LOG(WARNING) << "Unexpected catch"; } +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#else + absl::FlushLogSinks(); +#endif return res; } diff --git a/src/tests/system-tests/ttff.cc b/tests/system-tests/ttff.cc similarity index 74% rename from src/tests/system-tests/ttff.cc rename to tests/system-tests/ttff.cc index 55f0698cf..f26c63e88 100644 --- a/src/tests/system-tests/ttff.cc +++ b/tests/system-tests/ttff.cc @@ -21,39 +21,56 @@ #include "control_thread.h" #include "file_configuration.h" #include "gnss_flowgraph.h" +#include "gnss_sdr_make_unique.h" #include "gps_acq_assist.h" #include "in_memory_configuration.h" #include #include #include -#include -#include +#include #include #include #include #include +#include #include #include #include #include -#include -#include -#include #include +#if USE_GLOG_AND_GFLAGS +#include +#include #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } #endif +#else +#include +#include +#include +#include +#endif + +#if USE_GLOG_AND_GFLAGS DEFINE_int32(fs_in, 4000000, "Sampling rate, in Samples/s"); DEFINE_int32(max_measurement_duration, 90, "Maximum time waiting for a position fix, in seconds"); DEFINE_int32(num_measurements, 2, "Number of measurements"); DEFINE_string(device_address, "192.168.40.2", "USRP device IP address"); DEFINE_string(subdevice, "A:0", "USRP subdevice"); DEFINE_string(config_file_ttff, std::string(""), "File containing the configuration parameters for the TTFF test."); +#else +ABSL_FLAG(int32_t, fs_in, 4000000, "Sampling rate, in Samples/s"); +ABSL_FLAG(int32_t, max_measurement_duration, 90, "Maximum time waiting for a position fix, in seconds"); +ABSL_FLAG(int32_t, num_measurements, 2, "Number of measurements"); +ABSL_FLAG(std::string, device_address, "192.168.40.2", "USRP device IP address"); +ABSL_FLAG(std::string, subdevice, "A:0", "USRP subdevice"); +ABSL_FLAG(std::string, config_file_ttff, std::string(""), "File containing the configuration parameters for the TTFF test."); +#endif // For GPS NAVIGATION (L1) Concurrent_Queue global_gps_acq_assist_queue; @@ -61,13 +78,6 @@ Concurrent_Map global_gps_acq_assist_map; std::vector TTFF_v; -typedef struct -{ - long mtype; // required by SysV message - double ttff; -} ttff_msgbuf; - - class TtffTest : public ::testing::Test { public: @@ -121,8 +131,11 @@ void TtffTest::config_1() { config = std::make_shared(); +#if USE_GLOG_AND_GFLAGS config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(FLAGS_fs_in)); - +#else + config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(absl::GetFlag(FLAGS_fs_in))); +#endif // Set the assistance system parameters config->set_property("GNSS-SDR.SUPL_gps_ephemeris_server", "supl.google.com"); config->set_property("GNSS-SDR.SUPL_gps_ephemeris_port", std::to_string(7275)); @@ -137,11 +150,18 @@ void TtffTest::config_1() config->set_property("SignalSource.item_type", "cshort"); config->set_property("SignalSource.implementation", "UHD_Signal_Source"); config->set_property("SignalSource.freq", std::to_string(central_freq)); - config->set_property("SignalSource.sampling_frequency", std::to_string(FLAGS_fs_in)); config->set_property("SignalSource.gain", std::to_string(gain_dB)); +#if USE_GLOG_AND_GFLAGS + config->set_property("SignalSource.sampling_frequency", std::to_string(FLAGS_fs_in)); config->set_property("SignalSource.subdevice", FLAGS_subdevice); config->set_property("SignalSource.samples", std::to_string(FLAGS_fs_in * FLAGS_max_measurement_duration)); config->set_property("SignalSource.device_address", FLAGS_device_address); +#else + config->set_property("SignalSource.sampling_frequency", std::to_string(absl::GetFlag(FLAGS_fs_in))); + config->set_property("SignalSource.subdevice", absl::GetFlag(FLAGS_subdevice)); + config->set_property("SignalSource.samples", std::to_string(absl::GetFlag(FLAGS_fs_in) * absl::GetFlag(FLAGS_max_measurement_duration))); + config->set_property("SignalSource.device_address", absl::GetFlag(FLAGS_device_address)); +#endif // Set the Signal Conditioner config->set_property("SignalConditioner.implementation", "Signal_Conditioner"); @@ -166,13 +186,22 @@ void TtffTest::config_1() config->set_property("InputFilter.band2_error", std::to_string(band2_error)); config->set_property("InputFilter.filter_type", "bandpass"); config->set_property("InputFilter.grid_density", std::to_string(grid_density)); +#if USE_GLOG_AND_GFLAGS config->set_property("InputFilter.sampling_frequency", std::to_string(FLAGS_fs_in)); +#else + config->set_property("InputFilter.sampling_frequency", std::to_string(absl::GetFlag(FLAGS_fs_in))); +#endif config->set_property("InputFilter.IF", std::to_string(zero)); config->set_property("Resampler.implementation", "Pass_Through"); config->set_property("Resampler.dump", "false"); config->set_property("Resampler.item_type", "gr_complex"); +#if USE_GLOG_AND_GFLAGS config->set_property("Resampler.sample_freq_in", std::to_string(FLAGS_fs_in)); config->set_property("Resampler.sample_freq_out", std::to_string(FLAGS_fs_in)); +#else + config->set_property("Resampler.sample_freq_in", std::to_string(absl::GetFlag(FLAGS_fs_in))); + config->set_property("Resampler.sample_freq_out", std::to_string(absl::GetFlag(FLAGS_fs_in))); +#endif // Set the number of Channels config->set_property("Channels_1C.count", std::to_string(number_of_channels)); @@ -228,6 +257,7 @@ void TtffTest::config_1() void TtffTest::config_2() { +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ttff.empty()) { std::string path = std::string(TEST_PATH); @@ -242,50 +272,92 @@ void TtffTest::config_2() int d_sampling_rate; d_sampling_rate = config2->property("GNSS-SDR.internal_fs_sps", FLAGS_fs_in); config2->set_property("SignalSource.samples", std::to_string(d_sampling_rate * FLAGS_max_measurement_duration)); +#else + if (absl::GetFlag(FLAGS_config_file_ttff).empty()) + { + std::string path = std::string(TEST_PATH); + std::string filename = path + "../../conf/gnss-sdr_GPS_L1_USRP_X300_realtime.conf"; + config2 = std::make_shared(filename); + } + else + { + config2 = std::make_shared(absl::GetFlag(FLAGS_config_file_ttff)); + } + + int d_sampling_rate; + d_sampling_rate = config2->property("GNSS-SDR.internal_fs_sps", absl::GetFlag(FLAGS_fs_in)); + config2->set_property("SignalSource.samples", std::to_string(d_sampling_rate * absl::GetFlag(FLAGS_max_measurement_duration))); +#endif } void receive_msg() { - ttff_msgbuf msg; - ttff_msgbuf msg_stop; - msg_stop.mtype = 1; - msg_stop.ttff = -200.0; - double ttff_msg = 0.0; - int msgrcv_size = sizeof(msg.ttff); - int msqid; - int msqid_stop = -1; - key_t key = 1101; - key_t key_stop = 1102; bool leave = false; while (!leave) { - // wait for the queue to be created - while ((msqid = msgget(key, 0644)) == -1) + // wait for the queues to be created + const std::string queue_name = "gnss_sdr_ttff_message_queue"; + std::unique_ptr d_mq; + bool queue_found = false; + while (!queue_found) { + try + { + // Attempt to open the message queue + d_mq = std::make_unique(boost::interprocess::open_only, queue_name.c_str()); + queue_found = true; // Queue found + } + catch (const boost::interprocess::interprocess_exception &) + { + // Queue not found, wait and retry + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } } - if (msgrcv(msqid, &msg, msgrcv_size, 1, 0) != -1) + double received_message; + unsigned int priority; + std::size_t received_size; + // Receive a message (non-blocking) + if (d_mq->try_receive(&received_message, sizeof(received_message), received_size, priority)) { - ttff_msg = msg.ttff; - if ((ttff_msg != 0) && (ttff_msg != -1)) + // Validate the size of the received message + if (received_size == sizeof(double) && (received_message != 0) && (received_message != -1)) { - TTFF_v.push_back(ttff_msg); - LOG(INFO) << "Valid Time-To-First-Fix: " << ttff_msg << "[s]"; + TTFF_v.push_back(received_message); + LOG(INFO) << "Valid Time-To-First-Fix: " << received_message << " [s]"; // Stop the receiver - while (((msqid_stop = msgget(key_stop, 0644))) == -1) + double stop_message = -200.0; + const std::string queue_name_stop = "receiver_control_queue"; + std::unique_ptr d_mq_stop; + bool queue_found2 = false; + while (!queue_found2) { + try + { + // Attempt to open the message queue + d_mq_stop = std::make_unique(boost::interprocess::open_only, queue_name_stop.c_str()); + queue_found2 = true; // Queue found + } + catch (const boost::interprocess::interprocess_exception &) + { + // Queue not found, wait and retry + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } } - double msgsend_size = sizeof(msg_stop.ttff); - msgsnd(msqid_stop, &msg_stop, msgsend_size, IPC_NOWAIT); + d_mq_stop->send(&stop_message, sizeof(stop_message), 0); } - - if (std::abs(ttff_msg - (-1.0)) < 10 * std::numeric_limits::epsilon()) + if (received_size == sizeof(double) && std::abs(received_message - (-1.0)) < 10 * std::numeric_limits::epsilon()) { leave = true; } } + else + { + // No message available, add a small delay to prevent busy-waiting + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } } } @@ -377,7 +449,12 @@ void TtffTest::print_TTFF_report(const std::vector &ttff_v, const std::s { stm << "Disabled.\n"; } +#if USE_GLOG_AND_GFLAGS stm << "Valid measurements (" << ttff.size() << "/" << FLAGS_num_measurements << "): "; +#else + stm << "Valid measurements (" << ttff.size() << "/" << absl::GetFlag(FLAGS_num_measurements) << "): "; +#endif + for (double ttff_ : ttff) { stm << ttff_ << " "; @@ -427,12 +504,19 @@ TEST_F(TtffTest /*unused*/, ColdStart /*unused*/) config2->set_property("GNSS-SDR.SUPL_gps_enabled", "false"); config2->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "false"); config2->set_property("PVT.flag_rtcm_server", "false"); - +#if USE_GLOG_AND_GFLAGS for (int n = 0; n < FLAGS_num_measurements; n++) +#else + for (int n = 0; n < absl::GetFlag(FLAGS_num_measurements); n++) +#endif { // Create a new ControlThread object with a smart pointer std::shared_ptr control_thread; +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ttff.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ttff).empty()) +#endif { control_thread = std::make_shared(config); } @@ -441,8 +525,12 @@ TEST_F(TtffTest /*unused*/, ColdStart /*unused*/) control_thread = std::make_shared(config2); } - // record startup time + // record startup time +#if USE_GLOG_AND_GFLAGS std::cout << "Starting measurement " << num_measurements + 1 << " / " << FLAGS_num_measurements << '\n'; +#else + std::cout << "Starting measurement " << num_measurements + 1 << " / " << absl::GetFlag(FLAGS_num_measurements) << '\n'; +#endif std::chrono::time_point start; std::chrono::time_point end; start = std::chrono::system_clock::now(); @@ -470,7 +558,11 @@ TEST_F(TtffTest /*unused*/, ColdStart /*unused*/) num_measurements = num_measurements + 1; std::cout << "Just finished measurement " << num_measurements << ", which took " << ttff << " seconds.\n"; +#if USE_GLOG_AND_GFLAGS if (n < FLAGS_num_measurements - 1) +#else + if (n < absl::GetFlag(FLAGS_num_measurements) - 1) +#endif { std::random_device r; std::default_random_engine e1(r()); @@ -484,8 +576,13 @@ TEST_F(TtffTest /*unused*/, ColdStart /*unused*/) } } - // Print TTFF report + // Print TTFF report + +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ttff.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ttff).empty()) +#endif { print_TTFF_report(TTFF_v, config); } @@ -513,11 +610,19 @@ TEST_F(TtffTest /*unused*/, HotStart /*unused*/) config2->set_property("GNSS-SDR.SUPL_read_gps_assistance_xml", "true"); config2->set_property("PVT.flag_rtcm_server", "false"); +#if USE_GLOG_AND_GFLAGS for (int n = 0; n < FLAGS_num_measurements; n++) +#else + for (int n = 0; n < absl::GetFlag(FLAGS_num_measurements); n++) +#endif { // Create a new ControlThread object with a smart pointer std::shared_ptr control_thread; +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ttff.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ttff).empty()) +#endif { control_thread = std::make_shared(config); } @@ -525,8 +630,12 @@ TEST_F(TtffTest /*unused*/, HotStart /*unused*/) { control_thread = std::make_shared(config2); } - // record startup time + // record startup time +#if USE_GLOG_AND_GFLAGS std::cout << "Starting measurement " << num_measurements + 1 << " / " << FLAGS_num_measurements << '\n'; +#else + std::cout << "Starting measurement " << num_measurements + 1 << " / " << absl::GetFlag(FLAGS_num_measurements) << '\n'; +#endif std::chrono::time_point start; std::chrono::time_point end; start = std::chrono::system_clock::now(); @@ -555,7 +664,11 @@ TEST_F(TtffTest /*unused*/, HotStart /*unused*/) num_measurements = num_measurements + 1; std::cout << "Just finished measurement " << num_measurements << ", which took " << ttff << " seconds.\n"; +#if USE_GLOG_AND_GFLAGS if (n < FLAGS_num_measurements - 1) +#else + if (n < absl::GetFlag(FLAGS_num_measurements) - 1) +#endif { std::random_device r; std::default_random_engine e1(r()); @@ -569,8 +682,13 @@ TEST_F(TtffTest /*unused*/, HotStart /*unused*/) } } - // Print TTFF report + // Print TTFF report + +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ttff.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ttff).empty()) +#endif { print_TTFF_report(TTFF_v, config); } @@ -594,8 +712,12 @@ int main(int argc, char **argv) { } // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest +#if USE_GLOG_AND_GFLAGS gflags::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); +#else + absl::ParseCommandLine(argc, argv); +#endif // Start queue thread std::thread receive_msg_thread(receive_msg); @@ -611,24 +733,26 @@ int main(int argc, char **argv) } // Terminate the queue thread - key_t sysv_msg_key; - int sysv_msqid; - sysv_msg_key = 1101; - int msgflg = IPC_CREAT | 0666; - if ((sysv_msqid = msgget(sysv_msg_key, msgflg)) == -1) - { - std::cout << "GNSS-SDR can not create message queues!\n"; - return 1; - } - ttff_msgbuf msg; - msg.mtype = 1; - msg.ttff = -1; - int msgsend_size; - msgsend_size = sizeof(msg.ttff); - msgsnd(sysv_msqid, &msg, msgsend_size, IPC_NOWAIT); - receive_msg_thread.join(); - msgctl(sysv_msqid, IPC_RMID, nullptr); + const std::string queue_name = "gnss_sdr_ttff_message_queue"; + boost::interprocess::message_queue::remove(queue_name.c_str()); + // Create a new message queue + auto mq = std::make_unique( + boost::interprocess::create_only, // Create a new queue + queue_name.c_str(), // Queue name + 10, // Maximum number of messages + sizeof(double) // Maximum message size + ); + double finish = -1.0; + if (mq) + { + mq->send(&finish, sizeof(finish), 0); + } + receive_msg_thread.join(); + boost::interprocess::message_queue::remove(queue_name.c_str()); + +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return res; } diff --git a/src/tests/test_main.cc b/tests/test_main.cc similarity index 86% rename from src/tests/test_main.cc rename to tests/test_main.cc index 3769756aa..5e55b1b60 100644 --- a/src/tests/test_main.cc +++ b/tests/test_main.cc @@ -18,19 +18,59 @@ #include "concurrent_map.h" #include "concurrent_queue.h" #include "gps_acq_assist.h" +#include +#include +#include +#include +#include + +#if USE_GLOG_AND_GFLAGS #include #include -#include -#include - #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } +DECLARE_string(log_dir); +#endif +#else +#include "gnss_sdr_flags.h" +#include +#include +#include +#include +#include +#include +#include +#include + +class TestingLogSink : public absl::LogSink +{ +public: + TestingLogSink() + { + if (!absl::GetFlag(FLAGS_log_dir).empty()) + { + filename = std::string(absl::GetFlag(FLAGS_log_dir) + "/run_tests.log"); + } + else + { + filename = std::string(GetTempDir() + "/run_tests.log"); + } + logfile.open(filename); + } + void Send(const absl::LogEntry &entry) override + { + logfile << entry.text_message_with_prefix_and_newline() << std::flush; + } + +private: + std::ofstream logfile; + std::string filename; +}; #endif -DECLARE_string(log_dir); #if UNIT_TESTING_MINIMAL #include "unit-tests/arithmetic/matio_test.cc" @@ -72,6 +112,8 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/adapter/adapter_test.cc" #include "unit-tests/signal-processing-blocks/adapter/pass_through_test.cc" #include "unit-tests/signal-processing-blocks/libs/item_type_helpers_test.cc" +#include "unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc" +#include "unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc" #include "unit-tests/signal-processing-blocks/pvt/geohash_test.cc" #include "unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc" #include "unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc" @@ -91,7 +133,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc" #include "unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc" #include "unit-tests/system-parameters/galileo_e6b_reed_solomon_test.cc" -#include "unit-tests/system-parameters/glonass_gnav_crc_test.cc" +#include "unit-tests/system-parameters/galileo_ism_test.cc" #include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" #include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc" #include "unit-tests/system-parameters/has_decoding_test.cc" @@ -141,6 +183,7 @@ DECLARE_string(log_dir); #ifndef EXCLUDE_TESTS_REQUIRING_BINARIES #include "unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc" #include "unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc" +#include "unit-tests/signal-processing-blocks/osnma/osnma_test_vectors.cc" #include "unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc" #endif // #include "unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc" @@ -174,8 +217,15 @@ int main(int argc, char **argv) catch (...) { } // catch the "testing::internal::::ClassUniqueToAlwaysTrue" from gtest +#if USE_GLOG_AND_GFLAGS gflags::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); +#else + absl::ParseCommandLine(argc, argv); + absl::LogSink *testLogSink = new TestingLogSink; + absl::AddLogSink(testLogSink); + absl::InitializeLog(); +#endif try { res = RUN_ALL_TESTS(); @@ -184,6 +234,10 @@ int main(int argc, char **argv) { LOG(WARNING) << "Unexpected catch"; } +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#else + absl::FlushLogSinks(); +#endif return res; } diff --git a/src/tests/unit-tests/arithmetic/code_generation_test.cc b/tests/unit-tests/arithmetic/code_generation_test.cc similarity index 100% rename from src/tests/unit-tests/arithmetic/code_generation_test.cc rename to tests/unit-tests/arithmetic/code_generation_test.cc diff --git a/src/tests/unit-tests/arithmetic/complex_carrier_test.cc b/tests/unit-tests/arithmetic/complex_carrier_test.cc similarity index 69% rename from src/tests/unit-tests/arithmetic/complex_carrier_test.cc rename to tests/unit-tests/arithmetic/complex_carrier_test.cc index 19a4ba37c..0504b543b 100644 --- a/src/tests/unit-tests/arithmetic/complex_carrier_test.cc +++ b/tests/unit-tests/arithmetic/complex_carrier_test.cc @@ -20,16 +20,23 @@ #include #include #include +#include - +#if USE_GLOG_AND_GFLAGS DEFINE_int32(size_carrier_test, 100000, "Size of the arrays used for complex carrier testing"); - +#else +ABSL_FLAG(int32_t, size_carrier_test, 100000, "Size of the arrays used for complex carrier testing"); +#endif TEST(ComplexCarrierTest, StandardComplexImplementation) { - // Dynamic allocation creates new usable space on the program STACK - // (an area of RAM specifically allocated to the program) +// Dynamic allocation creates new usable space on the program STACK +// (an area of RAM specifically allocated to the program) +#if USE_GLOG_AND_GFLAGS auto* output = new std::complex[FLAGS_size_carrier_test]; +#else + auto* output = new std::complex[absl::GetFlag(FLAGS_size_carrier_test)]; +#endif const double _f = 2000.0; const double _fs = 2000000.0; const auto phase_step = (TWO_PI * _f) / _fs; @@ -37,8 +44,11 @@ TEST(ComplexCarrierTest, StandardComplexImplementation) std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_carrier_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_carrier_test); i++) +#endif { output[i] = std::complex(cos(phase), sin(phase)); phase += phase_step; @@ -46,18 +56,32 @@ TEST(ComplexCarrierTest, StandardComplexImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "A " << FLAGS_size_carrier_test +#else + std::cout << "A " << absl::GetFlag(FLAGS_size_carrier_test) +#endif << "-length complex carrier in standard C++ (dynamic allocation) generated in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; std::complex expected(1, 0); +#if USE_GLOG_AND_GFLAGS std::vector> mag(FLAGS_size_carrier_test); for (int i = 0; i < FLAGS_size_carrier_test; i++) +#else + std::vector> mag(absl::GetFlag(FLAGS_size_carrier_test)); + for (int i = 0; i < absl::GetFlag(FLAGS_size_carrier_test); i++) +#endif { mag[i] = output[i] * std::conj(output[i]); } delete[] output; +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_carrier_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_carrier_test); i++) +#endif { ASSERT_FLOAT_EQ(std::norm(expected), std::norm(mag[i])); } @@ -69,7 +93,12 @@ TEST(ComplexCarrierTest, StandardComplexImplementation) TEST(ComplexCarrierTest, C11ComplexImplementation) { // declaration: load data onto the program data segment + +#if USE_GLOG_AND_GFLAGS std::vector> output(FLAGS_size_carrier_test); +#else + std::vector> output(absl::GetFlag(FLAGS_size_carrier_test)); +#endif const double _f = 2000.0; const double _fs = 2000000.0; const auto phase_step = (TWO_PI * _f) / _fs; @@ -78,20 +107,34 @@ TEST(ComplexCarrierTest, C11ComplexImplementation) std::chrono::time_point start, end; start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_carrier_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_carrier_test); i++) +#endif { output[i] = std::complex(cos(phase), sin(phase)); phase += phase_step; } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "A " << FLAGS_size_carrier_test +#else + std::cout << "A " << absl::GetFlag(FLAGS_size_carrier_test) +#endif << "-length complex carrier in standard C++ (declaration) generated in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); std::complex expected(1, 0); +#if USE_GLOG_AND_GFLAGS std::vector> mag(FLAGS_size_carrier_test); for (int i = 0; i < FLAGS_size_carrier_test; i++) +#else + std::vector> mag(absl::GetFlag(FLAGS_size_carrier_test)); + for (int i = 0; i < absl::GetFlag(FLAGS_size_carrier_test); i++) +#endif { mag[i] = output[i] * std::conj(output[i]); ASSERT_FLOAT_EQ(std::norm(expected), std::norm(mag[i])); @@ -101,8 +144,11 @@ TEST(ComplexCarrierTest, C11ComplexImplementation) TEST(ComplexCarrierTest, OwnComplexImplementation) { +#if USE_GLOG_AND_GFLAGS std::vector> output(FLAGS_size_carrier_test); - +#else + std::vector> output(absl::GetFlag(FLAGS_size_carrier_test)); +#endif double _f = 2000.0; double _fs = 2000000.0; std::chrono::time_point start, end; @@ -112,18 +158,31 @@ TEST(ComplexCarrierTest, OwnComplexImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "A " << FLAGS_size_carrier_test +#else + std::cout << "A " << absl::GetFlag(FLAGS_size_carrier_test) +#endif << "-length complex carrier using fixed point generated in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; std::complex expected(1, 0); + +#if USE_GLOG_AND_GFLAGS std::vector> mag(FLAGS_size_carrier_test); for (int i = 0; i < FLAGS_size_carrier_test; i++) +#else + std::vector> mag(absl::GetFlag(FLAGS_size_carrier_test)); + for (int i = 0; i < absl::GetFlag(FLAGS_size_carrier_test); i++) +#endif { mag[i] = output[i] * std::conj(output[i]); } - +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_carrier_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_carrier_test); i++) +#endif { ASSERT_NEAR(std::norm(expected), std::norm(mag[i]), 0.0001); } diff --git a/src/tests/unit-tests/arithmetic/conjugate_test.cc b/tests/unit-tests/arithmetic/conjugate_test.cc similarity index 67% rename from src/tests/unit-tests/arithmetic/conjugate_test.cc rename to tests/unit-tests/arithmetic/conjugate_test.cc index 1fadedfed..2a72656f1 100644 --- a/src/tests/unit-tests/arithmetic/conjugate_test.cc +++ b/tests/unit-tests/arithmetic/conjugate_test.cc @@ -23,26 +23,42 @@ #include #include +#if USE_GLOG_AND_GFLAGS DEFINE_int32(size_conjugate_test, 100000, "Size of the arrays used for conjugate testing"); +#else +ABSL_FLAG(int32_t, size_conjugate_test, 100000, "Size of the arrays used for conjugate testing"); +#endif TEST(ConjugateTest, StandardCComplexImplementation) { +#if USE_GLOG_AND_GFLAGS auto* input = new std::complex[FLAGS_size_conjugate_test]; auto* output = new std::complex[FLAGS_size_conjugate_test]; std::fill_n(input, FLAGS_size_conjugate_test, std::complex(0.0, 0.0)); - +#else + auto* input = new std::complex[absl::GetFlag(FLAGS_size_conjugate_test)]; + auto* output = new std::complex[absl::GetFlag(FLAGS_size_conjugate_test)]; + std::fill_n(input, absl::GetFlag(FLAGS_size_conjugate_test), std::complex(0.0, 0.0)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_conjugate_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_conjugate_test); i++) +#endif { output[i] = std::conj(input[i]); } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Conjugate of a " << FLAGS_size_conjugate_test +#else + std::cout << "Conjugate of a " << absl::GetFlag(FLAGS_size_conjugate_test) +#endif << "-length complex float vector in standard C finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; @@ -54,8 +70,13 @@ TEST(ConjugateTest, StandardCComplexImplementation) TEST(ConjugateTest, C11ComplexImplementation) { +#if USE_GLOG_AND_GFLAGS const std::vector> input(FLAGS_size_conjugate_test); std::vector> output(FLAGS_size_conjugate_test); +#else + const std::vector> input(absl::GetFlag(FLAGS_size_conjugate_test)); + std::vector> output(absl::GetFlag(FLAGS_size_conjugate_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); int pos = 0; @@ -65,7 +86,11 @@ TEST(ConjugateTest, C11ComplexImplementation) } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Conjugate of a " << FLAGS_size_conjugate_test +#else + std::cout << "Conjugate of a " << absl::GetFlag(FLAGS_size_conjugate_test) +#endif << " complex vector (C++11-style) finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -82,9 +107,13 @@ TEST(ConjugateTest, C11ComplexImplementation) TEST(ConjugateTest, ArmadilloComplexImplementation) { +#if USE_GLOG_AND_GFLAGS arma::cx_fvec input(FLAGS_size_conjugate_test, arma::fill::zeros); arma::cx_fvec output(FLAGS_size_conjugate_test); - +#else + arma::cx_fvec input(absl::GetFlag(FLAGS_size_conjugate_test), arma::fill::zeros); + arma::cx_fvec output(absl::GetFlag(FLAGS_size_conjugate_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); @@ -92,7 +121,12 @@ TEST(ConjugateTest, ArmadilloComplexImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "Conjugate of a " << FLAGS_size_conjugate_test +#else + std::cout << "Conjugate of a " << absl::GetFlag(FLAGS_size_conjugate_test) +#endif << "-length complex float Armadillo vector finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -101,18 +135,29 @@ TEST(ConjugateTest, ArmadilloComplexImplementation) TEST(ConjugateTest, VolkComplexImplementation) { +#if USE_GLOG_AND_GFLAGS auto* input = static_cast*>(volk_gnsssdr_malloc(FLAGS_size_conjugate_test * sizeof(std::complex), volk_gnsssdr_get_alignment())); auto* output = static_cast*>(volk_gnsssdr_malloc(FLAGS_size_conjugate_test * sizeof(std::complex), volk_gnsssdr_get_alignment())); std::fill_n(input, FLAGS_size_conjugate_test, std::complex(0.0, 0.0)); - +#else + auto* input = static_cast*>(volk_gnsssdr_malloc(absl::GetFlag(FLAGS_size_conjugate_test) * sizeof(std::complex), volk_gnsssdr_get_alignment())); + auto* output = static_cast*>(volk_gnsssdr_malloc(absl::GetFlag(FLAGS_size_conjugate_test) * sizeof(std::complex), volk_gnsssdr_get_alignment())); + std::fill_n(input, absl::GetFlag(FLAGS_size_conjugate_test), std::complex(0.0, 0.0)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - +#if USE_GLOG_AND_GFLAGS volk_32fc_conjugate_32fc(output, input, FLAGS_size_conjugate_test); - +#else + volk_32fc_conjugate_32fc(output, input, absl::GetFlag(FLAGS_size_conjugate_test)); +#endif end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Conjugate of a " << FLAGS_size_conjugate_test +#else + std::cout << "Conjugate of a " << absl::GetFlag(FLAGS_size_conjugate_test) +#endif << "-length complex float vector using VOLK finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -123,17 +168,27 @@ TEST(ConjugateTest, VolkComplexImplementation) TEST(ConjugateTest, VolkComplexImplementationAlloc) { +#if USE_GLOG_AND_GFLAGS volk_gnsssdr::vector> input(FLAGS_size_conjugate_test, std::complex(0.0, 0.0)); volk_gnsssdr::vector> output(FLAGS_size_conjugate_test); - +#else + volk_gnsssdr::vector> input(absl::GetFlag(FLAGS_size_conjugate_test), std::complex(0.0, 0.0)); + volk_gnsssdr::vector> output(absl::GetFlag(FLAGS_size_conjugate_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - +#if USE_GLOG_AND_GFLAGS volk_32fc_conjugate_32fc(output.data(), input.data(), FLAGS_size_conjugate_test); - +#else + volk_32fc_conjugate_32fc(output.data(), input.data(), absl::GetFlag(FLAGS_size_conjugate_test)); +#endif end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Conjugate of a " << FLAGS_size_conjugate_test +#else + std::cout << "Conjugate of a " << absl::GetFlag(FLAGS_size_conjugate_test) +#endif << "-length complex float vector using VOLK ALLOC finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); diff --git a/src/tests/unit-tests/arithmetic/fft_length_test.cc b/tests/unit-tests/arithmetic/fft_length_test.cc similarity index 82% rename from src/tests/unit-tests/arithmetic/fft_length_test.cc rename to tests/unit-tests/arithmetic/fft_length_test.cc index 8ad39a141..fb937de89 100644 --- a/src/tests/unit-tests/arithmetic/fft_length_test.cc +++ b/tests/unit-tests/arithmetic/fft_length_test.cc @@ -24,9 +24,13 @@ #include #include - +#if USE_GLOG_AND_GFLAGS DEFINE_int32(fft_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); DEFINE_bool(plot_fft_length_test, false, "Plots results of FFTLengthTest with gnuplot"); +#else +ABSL_FLAG(int32_t, fft_iterations_test, 1000, "Number of averaged iterations in FFT length timing test"); +ABSL_FLAG(bool, plot_fft_length_test, false, "Plots results of FFTLengthTest with gnuplot"); +#endif // Note from FFTW documentation: the standard FFTW distribution works most efficiently for arrays whose // size can be factored into small primes (2, 3, 5, and 7), and otherwise it uses a slower general-purpose routine. @@ -63,13 +67,21 @@ TEST(FFTLengthTest, MeasureExecutionTime) std::generate_n(d_fft->get_inbuf(), d_fft_size, gen); start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS for (int k = 0; k < FLAGS_fft_iterations_test; k++) +#else + for (int k = 0; k < absl::GetFlag(FLAGS_fft_iterations_test); k++) +#endif { d_fft->execute(); } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS double exec_time = elapsed_seconds.count() / static_cast(FLAGS_fft_iterations_test); +#else + double exec_time = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_fft_iterations_test)); +#endif execution_times.push_back(exec_time * 1e3); std::cout << "FFT execution time for length=" << d_fft_size << " : " << exec_time << " [s]\n"; @@ -79,10 +91,15 @@ TEST(FFTLengthTest, MeasureExecutionTime) execution_times_powers_of_two.push_back(exec_time / 1e-3); } }); - +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_fft_length_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + if (absl::GetFlag(FLAGS_plot_fft_length_test) == true) + { + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_fft_length_test has been set to TRUE,\n"; @@ -99,7 +116,11 @@ TEST(FFTLengthTest, MeasureExecutionTime) Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -111,13 +132,21 @@ TEST(FFTLengthTest, MeasureExecutionTime) g1.set_grid(); g1.set_xlabel("FFT length"); g1.set_ylabel("Execution time [ms]"); +#if USE_GLOG_AND_GFLAGS g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); +#else + g1.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(absl::GetFlag(FLAGS_fft_iterations_test)) + " iterations)"); +#endif g1.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g1.savetops("FFT_execution_times_extended"); g1.savetopdf("FFT_execution_times_extended", 18); Gnuplot g2("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g2.showonscreen(); // window output } @@ -130,11 +159,20 @@ TEST(FFTLengthTest, MeasureExecutionTime) g2.set_xlabel("FFT length"); g2.set_ylabel("Execution time [ms]"); g2.set_xrange(0, 16384); +#if USE_GLOG_AND_GFLAGS g2.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(FLAGS_fft_iterations_test) + " iterations)"); +#else + g2.plot_xy(fft_sizes_v, execution_times, "FFT execution time (averaged over " + std::to_string(absl::GetFlag(FLAGS_fft_iterations_test)) + " iterations)"); +#endif + g2.set_style("points").plot_xy(powers_of_two, execution_times_powers_of_two, "Power of 2"); g2.savetops("FFT_execution_times"); g2.savetopdf("FFT_execution_times", 18); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g2.showonscreen(); // window output } diff --git a/src/tests/unit-tests/arithmetic/fft_speed_test.cc b/tests/unit-tests/arithmetic/fft_speed_test.cc similarity index 78% rename from src/tests/unit-tests/arithmetic/fft_speed_test.cc rename to tests/unit-tests/arithmetic/fft_speed_test.cc index 2fa477b81..e2282f2ed 100644 --- a/src/tests/unit-tests/arithmetic/fft_speed_test.cc +++ b/tests/unit-tests/arithmetic/fft_speed_test.cc @@ -22,7 +22,11 @@ #include #include +#if USE_GLOG_AND_GFLAGS DEFINE_int32(fft_speed_iterations_test, 100, "Number of averaged iterations in FFT length timing test"); +#else +ABSL_FLAG(int32_t, fft_speed_iterations_test, 100, "Number of averaged iterations in FFT length timing test"); +#endif TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) { @@ -33,8 +37,7 @@ TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) unsigned int fft_sizes[19] = {16, 25, 32, 45, 64, 95, 128, 195, 256, 325, 512, 785, 1024, 1503, 2048, 3127, 4096, 6349, 8192}; double d_execution_time; EXPECT_NO_THROW( - for (unsigned int fft_size - : fft_sizes) { + for (unsigned int fft_size : fft_sizes) { d_fft_size = fft_size; auto d_gr_fft = gnss_fft_fwd_make_unique(d_fft_size); arma::arma_rng::set_seed_random(); @@ -43,23 +46,39 @@ TEST(FFTSpeedTest, ArmadilloVSGNURadioExecutionTime) std::copy_n(d_arma_fft.memptr(), d_fft_size, d_gr_fft->get_inbuf()); start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS for (int k = 0; k < FLAGS_fft_speed_iterations_test; k++) +#else + for (int k = 0; k < absl::GetFlag(FLAGS_fft_speed_iterations_test); k++) +#endif { d_gr_fft->execute(); } end = std::chrono::system_clock::now(); elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS d_execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_speed_iterations_test); +#else + d_execution_time = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_fft_speed_iterations_test)); +#endif std::cout << "GNU Radio FFT execution time for length = " << d_fft_size << " : " << d_execution_time * 1e6 << " [us]\n"; start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS for (int k = 0; k < FLAGS_fft_speed_iterations_test; k++) +#else + for (int k = 0; k < absl::GetFlag(FLAGS_fft_speed_iterations_test); k++) +#endif { d_arma_fft_result = arma::fft(d_arma_fft); } end = std::chrono::system_clock::now(); elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS d_execution_time = elapsed_seconds.count() / static_cast(FLAGS_fft_speed_iterations_test); +#else + d_execution_time = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_fft_speed_iterations_test)); +#endif std::cout << "Armadillo FFT execution time for length = " << d_fft_size << " : " << d_execution_time * 1e6 << " [us]\n"; }); } diff --git a/src/tests/unit-tests/arithmetic/magnitude_squared_test.cc b/tests/unit-tests/arithmetic/magnitude_squared_test.cc similarity index 68% rename from src/tests/unit-tests/arithmetic/magnitude_squared_test.cc rename to tests/unit-tests/arithmetic/magnitude_squared_test.cc index 3611733f3..3287b51e2 100644 --- a/src/tests/unit-tests/arithmetic/magnitude_squared_test.cc +++ b/tests/unit-tests/arithmetic/magnitude_squared_test.cc @@ -24,29 +24,49 @@ #include #include +#if USE_GLOG_AND_GFLAGS DEFINE_int32(size_magnitude_test, 100000, "Size of the arrays used for magnitude testing"); - +#else +ABSL_FLAG(int32_t, size_magnitude_test, 100000, "Size of the arrays used for magnitude testing"); +#endif TEST(MagnitudeSquaredTest, StandardCComplexImplementation) { +#if USE_GLOG_AND_GFLAGS auto* input = new std::complex[FLAGS_size_magnitude_test]; auto* output = new float[FLAGS_size_magnitude_test]; +#else + auto* input = new std::complex[absl::GetFlag(FLAGS_size_magnitude_test)]; + auto* output = new float[absl::GetFlag(FLAGS_size_magnitude_test)]; +#endif unsigned int number = 0; +#if USE_GLOG_AND_GFLAGS for (number = 0; number < static_cast(FLAGS_size_magnitude_test); number++) +#else + for (number = 0; number < static_cast(absl::GetFlag(FLAGS_size_magnitude_test)); number++) +#endif { input[number] = std::complex(0.0, 0.0); } std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - +#if USE_GLOG_AND_GFLAGS for (number = 0; number < static_cast(FLAGS_size_magnitude_test); number++) +#else + for (number = 0; number < static_cast(absl::GetFlag(FLAGS_size_magnitude_test)); number++) +#endif { output[number] = (input[number].real() * input[number].real()) + (input[number].imag() * input[number].imag()); } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "The squared magnitude of a " << FLAGS_size_magnitude_test +#else + std::cout << "The squared magnitude of a " << absl::GetFlag(FLAGS_size_magnitude_test) +#endif << "-length complex vector in standard C computed in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; delete[] input; @@ -57,8 +77,13 @@ TEST(MagnitudeSquaredTest, StandardCComplexImplementation) TEST(MagnitudeSquaredTest, C11ComplexImplementation) { +#if USE_GLOG_AND_GFLAGS const std::vector> input(FLAGS_size_magnitude_test); std::vector output(FLAGS_size_magnitude_test); +#else + const std::vector> input(absl::GetFlag(FLAGS_size_magnitude_test)); + std::vector output(absl::GetFlag(FLAGS_size_magnitude_test)); +#endif int pos = 0; std::chrono::time_point start, end; start = std::chrono::system_clock::now(); @@ -70,7 +95,12 @@ TEST(MagnitudeSquaredTest, C11ComplexImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "The squared magnitude of a " << FLAGS_size_magnitude_test +#else + std::cout << "The squared magnitude of a " << absl::GetFlag(FLAGS_size_magnitude_test) +#endif << " complex vector (C++11-style) finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -87,8 +117,13 @@ TEST(MagnitudeSquaredTest, C11ComplexImplementation) TEST(MagnitudeSquaredTest, ArmadilloComplexImplementation) { +#if USE_GLOG_AND_GFLAGS arma::cx_fvec input(FLAGS_size_magnitude_test, arma::fill::zeros); arma::fvec output(FLAGS_size_magnitude_test); +#else + arma::cx_fvec input(absl::GetFlag(FLAGS_size_magnitude_test), arma::fill::zeros); + arma::fvec output(absl::GetFlag(FLAGS_size_magnitude_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); @@ -96,7 +131,12 @@ TEST(MagnitudeSquaredTest, ArmadilloComplexImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "The squared magnitude of a " << FLAGS_size_magnitude_test +#else + std::cout << "The squared magnitude of a " << absl::GetFlag(FLAGS_size_magnitude_test) +#endif << "-length vector using Armadillo computed in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -105,17 +145,31 @@ TEST(MagnitudeSquaredTest, ArmadilloComplexImplementation) TEST(MagnitudeSquaredTest, VolkComplexImplementation) { +#if USE_GLOG_AND_GFLAGS auto* input = static_cast*>(volk_gnsssdr_malloc(FLAGS_size_magnitude_test * sizeof(std::complex), volk_gnsssdr_get_alignment())); std::fill_n(input, FLAGS_size_magnitude_test, std::complex(0.0, 0.0)); auto* output = static_cast(volk_gnsssdr_malloc(FLAGS_size_magnitude_test * sizeof(float), volk_gnsssdr_get_alignment())); +#else + auto* input = static_cast*>(volk_gnsssdr_malloc(absl::GetFlag(FLAGS_size_magnitude_test) * sizeof(std::complex), volk_gnsssdr_get_alignment())); + std::fill_n(input, absl::GetFlag(FLAGS_size_magnitude_test), std::complex(0.0, 0.0)); + auto* output = static_cast(volk_gnsssdr_malloc(absl::GetFlag(FLAGS_size_magnitude_test) * sizeof(float), volk_gnsssdr_get_alignment())); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS volk_32fc_magnitude_squared_32f(output, input, static_cast(FLAGS_size_magnitude_test)); - +#else + volk_32fc_magnitude_squared_32f(output, input, static_cast(absl::GetFlag(FLAGS_size_magnitude_test))); +#endif end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "The squared magnitude of a " << FLAGS_size_magnitude_test +#else + std::cout << "The squared magnitude of a " << absl::GetFlag(FLAGS_size_magnitude_test) +#endif << "-length vector using VOLK computed in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; volk_gnsssdr_free(input); @@ -126,18 +180,30 @@ TEST(MagnitudeSquaredTest, VolkComplexImplementation) TEST(MagnitudeSquaredTest, VolkComplexImplementationAlloc) { +#if USE_GLOG_AND_GFLAGS volk_gnsssdr::vector> input(FLAGS_size_magnitude_test); // or: input(FLAGS_size_magnitude_test, std::complex(0.0, 0.0)); std::fill_n(input.begin(), FLAGS_size_magnitude_test, std::complex(0.0, 0.0)); volk_gnsssdr::vector output(FLAGS_size_magnitude_test); +#else + volk_gnsssdr::vector> input(absl::GetFlag(FLAGS_size_magnitude_test)); + std::fill_n(input.begin(), absl::GetFlag(FLAGS_size_magnitude_test), std::complex(0.0, 0.0)); + volk_gnsssdr::vector output(absl::GetFlag(FLAGS_size_magnitude_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - +#if USE_GLOG_AND_GFLAGS volk_32fc_magnitude_squared_32f(output.data(), input.data(), static_cast(FLAGS_size_magnitude_test)); - +#else + volk_32fc_magnitude_squared_32f(output.data(), input.data(), static_cast(absl::GetFlag(FLAGS_size_magnitude_test))); +#endif end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "The squared magnitude of a " << FLAGS_size_magnitude_test +#else + std::cout << "The squared magnitude of a " << absl::GetFlag(FLAGS_size_magnitude_test) +#endif << "-length vector using VOLK ALLOC computed in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); diff --git a/src/tests/unit-tests/arithmetic/matio_test.cc b/tests/unit-tests/arithmetic/matio_test.cc similarity index 99% rename from src/tests/unit-tests/arithmetic/matio_test.cc rename to tests/unit-tests/arithmetic/matio_test.cc index 1b1bb3a22..4ff9290dd 100644 --- a/src/tests/unit-tests/arithmetic/matio_test.cc +++ b/tests/unit-tests/arithmetic/matio_test.cc @@ -131,6 +131,7 @@ TEST(MatioTest, WriteAndReadGrComplex) auto *x_read_real = reinterpret_cast(x_read_st->Re); auto *x_read_imag = reinterpret_cast(x_read_st->Im); std::vector x_v_read; + x_v_read.reserve(size); for (unsigned int k = 0; k < size; k++) { x_v_read.emplace_back(x_read_real[k], x_read_imag[k]); diff --git a/src/tests/unit-tests/arithmetic/multiply_test.cc b/tests/unit-tests/arithmetic/multiply_test.cc similarity index 65% rename from src/tests/unit-tests/arithmetic/multiply_test.cc rename to tests/unit-tests/arithmetic/multiply_test.cc index bb47dac58..cc0f7acd6 100644 --- a/src/tests/unit-tests/arithmetic/multiply_test.cc +++ b/tests/unit-tests/arithmetic/multiply_test.cc @@ -24,31 +24,51 @@ #include #include +#if USE_GLOG_AND_GFLAGS DEFINE_int32(size_multiply_test, 100000, "Size of the arrays used for multiply testing"); - +#else +ABSL_FLAG(int32_t, size_multiply_test, 100000, "Size of the arrays used for multiply testing"); +#endif TEST(MultiplyTest, StandardCDoubleImplementation) { +#if USE_GLOG_AND_GFLAGS auto* input = new double[FLAGS_size_multiply_test]; auto* output = new double[FLAGS_size_multiply_test]; std::fill_n(input, FLAGS_size_multiply_test, 0.0); +#else + auto* input = new double[absl::GetFlag(FLAGS_size_multiply_test)]; + auto* output = new double[absl::GetFlag(FLAGS_size_multiply_test)]; + std::fill_n(input, absl::GetFlag(FLAGS_size_multiply_test), 0.0); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_multiply_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_multiply_test); i++) +#endif { output[i] = input[i] * input[i]; } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Element-wise multiplication of " << FLAGS_size_multiply_test +#else + std::cout << "Element-wise multiplication of " << absl::GetFlag(FLAGS_size_multiply_test) +#endif << " doubles in standard C finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; double acc = 0.0; double expected = 0.0; +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_multiply_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_multiply_test); i++) +#endif { acc += output[i]; } @@ -61,9 +81,13 @@ TEST(MultiplyTest, StandardCDoubleImplementation) TEST(MultiplyTest, ArmadilloImplementation) { +#if USE_GLOG_AND_GFLAGS arma::vec input(FLAGS_size_multiply_test, arma::fill::zeros); arma::vec output(FLAGS_size_multiply_test); - +#else + arma::vec input(absl::GetFlag(FLAGS_size_multiply_test), arma::fill::zeros); + arma::vec output(absl::GetFlag(FLAGS_size_multiply_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); @@ -71,7 +95,11 @@ TEST(MultiplyTest, ArmadilloImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Element-wise multiplication of " << FLAGS_size_multiply_test +#else + std::cout << "Element-wise multiplication of " << absl::GetFlag(FLAGS_size_multiply_test) +#endif << "-length double Armadillo vectors finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -81,26 +109,44 @@ TEST(MultiplyTest, ArmadilloImplementation) TEST(MultiplyTest, StandardCComplexImplementation) { +#if USE_GLOG_AND_GFLAGS auto* input = new std::complex[FLAGS_size_multiply_test]; auto* output = new std::complex[FLAGS_size_multiply_test]; std::fill_n(input, FLAGS_size_multiply_test, std::complex(0.0, 0.0)); +#else + auto* input = new std::complex[absl::GetFlag(FLAGS_size_multiply_test)]; + auto* output = new std::complex[absl::GetFlag(FLAGS_size_multiply_test)]; + std::fill_n(input, absl::GetFlag(FLAGS_size_multiply_test), std::complex(0.0, 0.0)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_multiply_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_multiply_test); i++) +#endif { output[i] = input[i] * input[i]; } end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Element-wise multiplication of " << FLAGS_size_multiply_test +#else + std::cout << "Element-wise multiplication of " << absl::GetFlag(FLAGS_size_multiply_test) +#endif << " complex in standard C finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; std::complex expected(0.0, 0.0); std::complex result(0.0, 0.0); +#if USE_GLOG_AND_GFLAGS for (int i = 0; i < FLAGS_size_multiply_test; i++) +#else + for (int i = 0; i < absl::GetFlag(FLAGS_size_multiply_test); i++) +#endif { result += output[i]; } @@ -113,8 +159,13 @@ TEST(MultiplyTest, StandardCComplexImplementation) TEST(MultiplyTest, C11ComplexImplementation) { +#if USE_GLOG_AND_GFLAGS const std::vector> input(FLAGS_size_multiply_test); std::vector> output(FLAGS_size_multiply_test); +#else + const std::vector> input(absl::GetFlag(FLAGS_size_multiply_test)); + std::vector> output(absl::GetFlag(FLAGS_size_multiply_test)); +#endif int pos = 0; std::chrono::time_point start, end; start = std::chrono::system_clock::now(); @@ -127,7 +178,11 @@ TEST(MultiplyTest, C11ComplexImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Element-wise multiplication of " << FLAGS_size_multiply_test +#else + std::cout << "Element-wise multiplication of " << absl::GetFlag(FLAGS_size_multiply_test) +#endif << " complex vector (C++11-style) finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -140,8 +195,13 @@ TEST(MultiplyTest, C11ComplexImplementation) TEST(MultiplyTest, ArmadilloComplexImplementation) { +#if USE_GLOG_AND_GFLAGS arma::cx_fvec input(FLAGS_size_multiply_test, arma::fill::zeros); arma::cx_fvec output(FLAGS_size_multiply_test); +#else + arma::cx_fvec input(absl::GetFlag(FLAGS_size_multiply_test), arma::fill::zeros); + arma::cx_fvec output(absl::GetFlag(FLAGS_size_multiply_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); @@ -150,7 +210,12 @@ TEST(MultiplyTest, ArmadilloComplexImplementation) end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "Element-wise multiplication of " << FLAGS_size_multiply_test +#else + std::cout << "Element-wise multiplication of " << absl::GetFlag(FLAGS_size_multiply_test) +#endif << "-length complex float Armadillo vectors finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); @@ -160,30 +225,55 @@ TEST(MultiplyTest, ArmadilloComplexImplementation) TEST(MultiplyTest, VolkComplexImplementation) { +#if USE_GLOG_AND_GFLAGS auto* input = static_cast*>(volk_gnsssdr_malloc(FLAGS_size_multiply_test * sizeof(std::complex), volk_gnsssdr_get_alignment())); auto* output = static_cast*>(volk_gnsssdr_malloc(FLAGS_size_multiply_test * sizeof(std::complex), volk_gnsssdr_get_alignment())); std::fill_n(input, FLAGS_size_multiply_test, std::complex(0.0, 0.0)); +#else + auto* input = static_cast*>(volk_gnsssdr_malloc(absl::GetFlag(FLAGS_size_multiply_test) * sizeof(std::complex), volk_gnsssdr_get_alignment())); + auto* output = static_cast*>(volk_gnsssdr_malloc(absl::GetFlag(FLAGS_size_multiply_test) * sizeof(std::complex), volk_gnsssdr_get_alignment())); + std::fill_n(input, absl::GetFlag(FLAGS_size_multiply_test), std::complex(0.0, 0.0)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS volk_32fc_x2_multiply_32fc(output, input, input, FLAGS_size_multiply_test); +#else + volk_32fc_x2_multiply_32fc(output, input, input, absl::GetFlag(FLAGS_size_multiply_test)); +#endif end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS std::cout << "Element-wise multiplication of " << FLAGS_size_multiply_test +#else + std::cout << "Element-wise multiplication of " << absl::GetFlag(FLAGS_size_multiply_test) +#endif << "-length complex float vector using VOLK finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); +#if USE_GLOG_AND_GFLAGS auto* mag = static_cast(volk_gnsssdr_malloc(FLAGS_size_multiply_test * sizeof(float), volk_gnsssdr_get_alignment())); volk_32fc_magnitude_32f(mag, output, FLAGS_size_multiply_test); +#else + auto* mag = static_cast(volk_gnsssdr_malloc(absl::GetFlag(FLAGS_size_multiply_test) * sizeof(float), volk_gnsssdr_get_alignment())); + volk_32fc_magnitude_32f(mag, output, absl::GetFlag(FLAGS_size_multiply_test)); +#endif auto* result = new float(0.0); + +#if USE_GLOG_AND_GFLAGS volk_32f_accumulator_s32f(result, mag, FLAGS_size_multiply_test); +#else + volk_32f_accumulator_s32f(result, mag, absl::GetFlag(FLAGS_size_multiply_test)); +#endif + // Comparing floating-point numbers is tricky. // Due to round-off errors, it is very unlikely that two floating-points will match exactly. - // See https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#floating-point-comparison + // See https://google.github.io/googletest/reference/assertions.html#floating-point float expected = 0.0; ASSERT_FLOAT_EQ(expected, result[0]); volk_gnsssdr_free(input); @@ -194,28 +284,52 @@ TEST(MultiplyTest, VolkComplexImplementation) TEST(MultiplyTest, VolkComplexImplementationAlloc) { +#if USE_GLOG_AND_GFLAGS volk_gnsssdr::vector> input(FLAGS_size_multiply_test, std::complex(0.0, 0.0)); volk_gnsssdr::vector> output(FLAGS_size_multiply_test); - +#else + volk_gnsssdr::vector> input(absl::GetFlag(FLAGS_size_multiply_test), std::complex(0.0, 0.0)); + volk_gnsssdr::vector> output(absl::GetFlag(FLAGS_size_multiply_test)); +#endif std::chrono::time_point start, end; start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS volk_32fc_x2_multiply_32fc(output.data(), input.data(), input.data(), FLAGS_size_multiply_test); +#else + volk_32fc_x2_multiply_32fc(output.data(), input.data(), input.data(), absl::GetFlag(FLAGS_size_multiply_test)); +#endif end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; + +#if USE_GLOG_AND_GFLAGS std::cout << "Element-wise multiplication of " << FLAGS_size_multiply_test +#else + std::cout << "Element-wise multiplication of " << absl::GetFlag(FLAGS_size_multiply_test) +#endif << "-length complex float vector using VOLK ALLOC finished in " << elapsed_seconds.count() * 1e6 << " microseconds\n"; ASSERT_LE(0, elapsed_seconds.count() * 1e6); + +#if USE_GLOG_AND_GFLAGS volk_gnsssdr::vector mag(FLAGS_size_multiply_test); volk_32fc_magnitude_32f(mag.data(), output.data(), FLAGS_size_multiply_test); +#else + volk_gnsssdr::vector mag(absl::GetFlag(FLAGS_size_multiply_test)); + volk_32fc_magnitude_32f(mag.data(), output.data(), absl::GetFlag(FLAGS_size_multiply_test)); +#endif auto* result = new float(0.0); + +#if USE_GLOG_AND_GFLAGS volk_32f_accumulator_s32f(result, mag.data(), FLAGS_size_multiply_test); +#else + volk_32f_accumulator_s32f(result, mag.data(), absl::GetFlag(FLAGS_size_multiply_test)); +#endif // Comparing floating-point numbers is tricky. // Due to round-off errors, it is very unlikely that two floating-points will match exactly. - // See https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#floating-point-comparison + // See https://google.github.io/googletest/reference/assertions.html#floating-point float expected = 0.0; ASSERT_FLOAT_EQ(expected, result[0]); } diff --git a/src/tests/unit-tests/arithmetic/preamble_correlator_test.cc b/tests/unit-tests/arithmetic/preamble_correlator_test.cc similarity index 100% rename from src/tests/unit-tests/arithmetic/preamble_correlator_test.cc rename to tests/unit-tests/arithmetic/preamble_correlator_test.cc diff --git a/src/tests/unit-tests/control-plane/control_thread_test.cc b/tests/unit-tests/control-plane/control_thread_test.cc similarity index 86% rename from src/tests/unit-tests/control-plane/control_thread_test.cc rename to tests/unit-tests/control-plane/control_thread_test.cc index c43756128..8ad0100e5 100644 --- a/src/tests/unit-tests/control-plane/control_thread_test.cc +++ b/tests/unit-tests/control-plane/control_thread_test.cc @@ -21,58 +21,72 @@ #include "command_event.h" #include "concurrent_queue.h" #include "control_thread.h" +#include "gnss_sdr_filesystem.h" #include "gnss_sdr_make_unique.h" #include "in_memory_configuration.h" #include #include +#include #include -#include -#include #include #include #include #include #include -#include -#include -#include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#include +#else +#include +#endif class ControlThreadTest : public ::testing::Test { public: static int stop_receiver(); - typedef struct - { - long mtype; // required by SysV message - double message; - } message_buffer; }; int ControlThreadTest::stop_receiver() { - message_buffer msg_stop; - msg_stop.mtype = 1; - msg_stop.message = -200.0; - int msqid_stop = -1; - int msgsend_size = sizeof(msg_stop.message); - key_t key_stop = 1102; - - // wait for the receiver control queue to be created - while (((msqid_stop = msgget(key_stop, 0644))) == -1) + const std::string queue_name = "receiver_control_queue"; + std::unique_ptr d_mq; + try { + bool queue_found = false; + + while (!queue_found) + { + try + { + // Attempt to open the message queue + d_mq = std::make_unique(boost::interprocess::open_only, queue_name.c_str()); + queue_found = true; // Queue found + } + catch (const boost::interprocess::interprocess_exception&) + { + // Queue not found, wait and retry + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + + double stop_message = -200.0; + + // Wait for a couple of seconds before sending + std::this_thread::sleep_for(std::chrono::seconds(2)); + // Send the double value + d_mq->send(&stop_message, sizeof(stop_message), 0); // Priority 0 + return 0; + } + catch (const boost::interprocess::interprocess_exception& e) + { + std::cerr << "Failed to send stop message: " << e.what() << std::endl; + return -1; } - - // wait for a couple of seconds - std::this_thread::sleep_for(std::chrono::seconds(2)); - - // Stop the receiver - msgsnd(msqid_stop, &msg_stop, msgsend_size, IPC_NOWAIT); - - return 0; } @@ -107,6 +121,8 @@ TEST_F(ControlThreadTest /*unused*/, InstantiateRunControlMessages /*unused*/) config->set_property("PVT.item_type", "gr_complex"); config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); + ASSERT_TRUE(fs::exists(file)); + std::shared_ptr control_thread = std::make_shared(config); std::shared_ptr> control_queue = std::make_shared>(); @@ -166,6 +182,8 @@ TEST_F(ControlThreadTest /*unused*/, InstantiateRunControlMessages2 /*unused*/) config->set_property("PVT.item_type", "gr_complex"); config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); + ASSERT_TRUE(fs::exists(file)); + auto control_thread2 = std::make_unique(config); std::shared_ptr> control_queue2 = std::make_shared>(); @@ -228,6 +246,8 @@ TEST_F(ControlThreadTest /*unused*/, StopReceiverProgrammatically /*unused*/) config->set_property("PVT.item_type", "gr_complex"); config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); + ASSERT_TRUE(fs::exists(file)); + std::shared_ptr control_thread = std::make_shared(config); std::shared_ptr> control_queue = std::make_shared>(); control_thread->set_control_queue(control_queue); diff --git a/src/tests/unit-tests/control-plane/file_configuration_test.cc b/tests/unit-tests/control-plane/file_configuration_test.cc similarity index 100% rename from src/tests/unit-tests/control-plane/file_configuration_test.cc rename to tests/unit-tests/control-plane/file_configuration_test.cc diff --git a/src/tests/unit-tests/control-plane/gnss_block_factory_test.cc b/tests/unit-tests/control-plane/gnss_block_factory_test.cc similarity index 100% rename from src/tests/unit-tests/control-plane/gnss_block_factory_test.cc rename to tests/unit-tests/control-plane/gnss_block_factory_test.cc diff --git a/src/tests/unit-tests/control-plane/gnss_flowgraph_test.cc b/tests/unit-tests/control-plane/gnss_flowgraph_test.cc similarity index 100% rename from src/tests/unit-tests/control-plane/gnss_flowgraph_test.cc rename to tests/unit-tests/control-plane/gnss_flowgraph_test.cc diff --git a/src/tests/unit-tests/control-plane/in_memory_configuration_test.cc b/tests/unit-tests/control-plane/in_memory_configuration_test.cc similarity index 100% rename from src/tests/unit-tests/control-plane/in_memory_configuration_test.cc rename to tests/unit-tests/control-plane/in_memory_configuration_test.cc diff --git a/src/tests/unit-tests/control-plane/protobuf_test.cc b/tests/unit-tests/control-plane/protobuf_test.cc similarity index 100% rename from src/tests/unit-tests/control-plane/protobuf_test.cc rename to tests/unit-tests/control-plane/protobuf_test.cc diff --git a/src/tests/unit-tests/control-plane/string_converter_test.cc b/tests/unit-tests/control-plane/string_converter_test.cc similarity index 100% rename from src/tests/unit-tests/control-plane/string_converter_test.cc rename to tests/unit-tests/control-plane/string_converter_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc similarity index 81% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc index 327ffade0..4c5d37ea6 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/acq_performance_test.cc @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include @@ -55,6 +57,7 @@ namespace wht = boost; namespace wht = std; #endif +#if USE_GLOG_AND_GFLAGS DEFINE_string(config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test."); DEFINE_string(acq_test_input_file, std::string(""), "File containing raw signal data, must be in int8_t format. The signal generator will not be used."); DEFINE_string(acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition"), "Acquisition block implementation under test. Alternatives: GPS_L1_CA_PCPS_Acquisition, GPS_L1_CA_PCPS_Acquisition_Fine_Doppler, Galileo_E1_PCPS_Ambiguous_Acquisition, GLONASS_L1_CA_PCPS_Acquisition, GLONASS_L2_CA_PCPS_Acquisition, GPS_L2_M_PCPS_Acquisition, Galileo_E5a_Pcps_Acquisition, GPS_L5i_PCPS_Acquisition"); @@ -86,8 +89,41 @@ DEFINE_int32(acq_test_fake_PRN, 33, "PRN number of a non-present satellite"); DEFINE_int32(acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)"); DEFINE_bool(plot_acq_test, false, "Plots results with gnuplot, if available"); DEFINE_int32(acq_test_skiphead, 0, "Number of samples to skip in the input file"); +#else +ABSL_FLAG(std::string, config_file_ptest, std::string(""), "File containing alternative configuration parameters for the acquisition performance test."); +ABSL_FLAG(std::string, acq_test_input_file, std::string(""), "File containing raw signal data, must be in int8_t format. The signal generator will not be used."); +ABSL_FLAG(std::string, acq_test_implementation, std::string("GPS_L1_CA_PCPS_Acquisition"), "Acquisition block implementation under test. Alternatives: GPS_L1_CA_PCPS_Acquisition, GPS_L1_CA_PCPS_Acquisition_Fine_Doppler, Galileo_E1_PCPS_Ambiguous_Acquisition, GLONASS_L1_CA_PCPS_Acquisition, GLONASS_L2_CA_PCPS_Acquisition, GPS_L2_M_PCPS_Acquisition, Galileo_E5a_Pcps_Acquisition, GPS_L5i_PCPS_Acquisition"); -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +ABSL_FLAG(int32_t, acq_test_doppler_max, 5000, "Maximum Doppler, in Hz"); +ABSL_FLAG(int32_t, acq_test_doppler_step, 125, "Doppler step, in Hz."); +ABSL_FLAG(int32_t, acq_test_coherent_time_ms, 1, "Acquisition coherent time, in ms"); +ABSL_FLAG(int32_t, acq_test_max_dwells, 1, "Number of non-coherent integrations."); +ABSL_FLAG(bool, acq_test_bit_transition_flag, false, "Bit transition flag."); +ABSL_FLAG(bool, acq_test_make_two_steps, false, "Perform second step in a thinner grid."); +ABSL_FLAG(int32_t, acq_test_second_nbins, 4, "If --acq_test_make_two_steps is set to true, this parameter sets the number of bins done in the acquisition refinement stage."); +ABSL_FLAG(int32_t, acq_test_second_doppler_step, 10, "If --acq_test_make_two_steps is set to true, this parameter sets the Doppler step applied in the acquisition refinement stage, in Hz."); + +ABSL_FLAG(int32_t, acq_test_signal_duration_s, 2, "Generated signal duration, in s"); +ABSL_FLAG(int32_t, acq_test_num_meas, 0, "Number of measurements per run. 0 means the complete file."); +ABSL_FLAG(double, acq_test_cn0_init, 30.0, "Initial CN0, in dBHz."); +ABSL_FLAG(double, acq_test_cn0_final, 45.0, "Final CN0, in dBHz."); +ABSL_FLAG(double, acq_test_cn0_step, 3.0, "CN0 step, in dB."); + +ABSL_FLAG(double, acq_test_threshold_init, 3.0, "Initial acquisition threshold"); +ABSL_FLAG(double, acq_test_threshold_final, 4.0, "Final acquisition threshold"); +ABSL_FLAG(double, acq_test_threshold_step, 0.5, "Acquisition threshold step"); + +ABSL_FLAG(double, acq_test_pfa_init, 1e-5, "Set initial threshold via probability of false alarm. Disable with -1.0"); + +ABSL_FLAG(int32_t, acq_test_PRN, 1, "PRN number of a present satellite"); +ABSL_FLAG(int32_t, acq_test_fake_PRN, 33, "PRN number of a non-present satellite"); + +ABSL_FLAG(int32_t, acq_test_iterations, 1, "Number of iterations (same signal, different noise realization)"); +ABSL_FLAG(bool, plot_acq_test, false, "Plots results with gnuplot, if available"); +ABSL_FLAG(int32_t, acq_test_skiphead, 0, "Number of samples to skip in the input file"); +#endif + +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class AcqPerfTest_msg_rx; using AcqPerfTest_msg_rx_sptr = gnss_shared_ptr; @@ -160,9 +196,15 @@ protected: config = std::make_shared(); item_size = sizeof(gr_complex); gnss_synchro = Gnss_Synchro(); +#if USE_GLOG_AND_GFLAGS doppler_max = static_cast(FLAGS_acq_test_doppler_max); doppler_step = static_cast(FLAGS_acq_test_doppler_step); +#else + doppler_max = static_cast(absl::GetFlag(FLAGS_acq_test_doppler_max)); + doppler_step = static_cast(absl::GetFlag(FLAGS_acq_test_doppler_step)); +#endif stop = false; +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_input_file.empty()) { cn0_vector.push_back(FLAGS_acq_test_cn0_init); @@ -173,6 +215,18 @@ protected: aux = aux + FLAGS_acq_test_cn0_step; } } +#else + if (absl::GetFlag(FLAGS_acq_test_input_file).empty()) + { + cn0_vector.push_back(absl::GetFlag(FLAGS_acq_test_cn0_init)); + double aux = absl::GetFlag(FLAGS_acq_test_cn0_init) + absl::GetFlag(FLAGS_acq_test_cn0_step); + while (aux <= absl::GetFlag(FLAGS_acq_test_cn0_final)) + { + cn0_vector.push_back(aux); + aux = aux + absl::GetFlag(FLAGS_acq_test_cn0_step); + } + } +#endif else { cn0_vector = {0.0}; @@ -182,14 +236,22 @@ protected: { signal_id = "1C"; system_id = 'G'; +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif min_integration_ms = 1; } else if (implementation == "GPS_L1_CA_PCPS_Acquisition_Fine_Doppler") { signal_id = "1C"; system_id = 'G'; +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif min_integration_ms = 1; } else if (implementation == "Galileo_E1_PCPS_Ambiguous_Acquisition") @@ -197,40 +259,65 @@ protected: signal_id = "1B"; system_id = 'E'; min_integration_ms = 4; +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_coherent_time_ms == 1) +#else + if (absl::GetFlag(FLAGS_acq_test_coherent_time_ms) == 1) +#endif { coherent_integration_time_ms = 4; } else { +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif } } else if (implementation == "GLONASS_L1_CA_PCPS_Acquisition") { signal_id = "1G"; system_id = 'R'; +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif min_integration_ms = 1; } else if (implementation == "GLONASS_L2_CA_PCPS_Acquisition") { signal_id = "2G"; system_id = 'R'; +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif min_integration_ms = 1; } else if (implementation == "GPS_L2_M_PCPS_Acquisition") { signal_id = "2S"; system_id = 'G'; +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_coherent_time_ms == 1) +#else + if (absl::GetFlag(FLAGS_acq_test_coherent_time_ms) == 1) +#endif + { coherent_integration_time_ms = 20; } else { +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif } min_integration_ms = 20; } @@ -238,25 +325,37 @@ protected: { signal_id = "5X"; system_id = 'E'; +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif min_integration_ms = 1; } else if (implementation == "GPS_L5i_PCPS_Acquisition") { signal_id = "L5"; system_id = 'G'; +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif } else { signal_id = "1C"; system_id = 'G'; +#if USE_GLOG_AND_GFLAGS coherent_integration_time_ms = FLAGS_acq_test_coherent_time_ms; +#else + coherent_integration_time_ms = absl::GetFlag(FLAGS_acq_test_coherent_time_ms); +#endif min_integration_ms = 1; } init(); - +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_pfa_init > 0.0) { pfa_vector.push_back(FLAGS_acq_test_pfa_init); @@ -279,11 +378,36 @@ protected: aux = aux + static_cast(FLAGS_acq_test_threshold_step); } } +#else + if (absl::GetFlag(FLAGS_acq_test_pfa_init) > 0.0) + { + pfa_vector.push_back(absl::GetFlag(FLAGS_acq_test_pfa_init)); + float aux = 1.0; + while ((absl::GetFlag(FLAGS_acq_test_pfa_init) * std::pow(10, aux)) < 1) + { + pfa_vector.push_back(absl::GetFlag(FLAGS_acq_test_pfa_init) * std::pow(10, aux)); + aux = aux + 1.0; + } + pfa_vector.push_back(0.999); + } + else + { + auto aux = static_cast(absl::GetFlag(FLAGS_acq_test_threshold_init)); + pfa_vector.push_back(aux); + aux = aux + static_cast(absl::GetFlag(FLAGS_acq_test_threshold_step)); + while (aux <= static_cast(absl::GetFlag(FLAGS_acq_test_threshold_final))) + { + pfa_vector.push_back(aux); + aux = aux + static_cast(absl::GetFlag(FLAGS_acq_test_threshold_step)); + } + } +#endif num_thresholds = pfa_vector.size(); // the gnss simulator does not dump the trk observables for the last 100 ms of generated signal int aux2; +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_bit_transition_flag) { aux2 = floor((generated_signal_duration_s * ms_per_s - 100) / (FLAGS_acq_test_coherent_time_ms * 2.0) - 1); @@ -300,7 +424,24 @@ protected: { num_of_measurements = static_cast(aux2); } - +#else + if (absl::GetFlag(FLAGS_acq_test_bit_transition_flag)) + { + aux2 = floor((generated_signal_duration_s * ms_per_s - 100) / (absl::GetFlag(FLAGS_acq_test_coherent_time_ms) * 2.0) - 1); + } + else + { + aux2 = floor((generated_signal_duration_s * ms_per_s - 100) / (absl::GetFlag(FLAGS_acq_test_coherent_time_ms) * absl::GetFlag(FLAGS_acq_test_max_dwells)) - 1); + } + if ((absl::GetFlag(FLAGS_acq_test_num_meas) > 0) && (absl::GetFlag(FLAGS_acq_test_num_meas) < aux2)) + { + num_of_measurements = static_cast(absl::GetFlag(FLAGS_acq_test_num_meas)); + } + else + { + num_of_measurements = static_cast(aux2); + } +#endif Pd.resize(cn0_vector.size()); for (int i = 0; i < static_cast(cn0_vector.size()); i++) { @@ -323,7 +464,12 @@ protected: std::vector cn0_vector; std::vector pfa_vector; +#if USE_GLOG_AND_GFLAGS int N_iterations = FLAGS_acq_test_iterations; +#else + int N_iterations = absl::GetFlag(FLAGS_acq_test_iterations); +#endif + void init(); int configure_generator(double cn0); @@ -353,19 +499,31 @@ protected: int message; std::thread ch_thread; - +#if USE_GLOG_AND_GFLAGS std::string implementation = FLAGS_acq_test_implementation; - const double baseband_sampling_freq = static_cast(FLAGS_fs_gen_sps); +#else + std::string implementation = absl::GetFlag(FLAGS_acq_test_implementation); + const double baseband_sampling_freq = static_cast(absl::GetFlag(FLAGS_fs_gen_sps)); +#endif + int coherent_integration_time_ms; const int in_acquisition = 1; const int dump_channel = 0; +#if USE_GLOG_AND_GFLAGS int generated_signal_duration_s = FLAGS_acq_test_signal_duration_s; +#else + int generated_signal_duration_s = absl::GetFlag(FLAGS_acq_test_signal_duration_s); +#endif unsigned int num_of_measurements; unsigned int measurement_counter = 0; +#if USE_GLOG_AND_GFLAGS unsigned int observed_satellite = FLAGS_acq_test_PRN; +#else + unsigned int observed_satellite = absl::GetFlag(FLAGS_acq_test_PRN); +#endif std::string path_str = "./acq-perf-test"; int num_thresholds; @@ -388,8 +546,13 @@ private: std::string p5; std::string p6; +#if USE_GLOG_AND_GFLAGS std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; +#else + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif char system_id; double compute_stdev_precision(const std::vector& vec); @@ -449,6 +612,7 @@ void AcquisitionPerformanceTest::stop_queue() int AcquisitionPerformanceTest::configure_generator(double cn0) { // Configure signal generator +#if USE_GLOG_AND_GFLAGS generator_binary = FLAGS_generator_binary; p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; @@ -464,6 +628,24 @@ int AcquisitionPerformanceTest::configure_generator(double cn0) p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] p6 = std::string("-CN0_dBHz=") + std::to_string(cn0); +#else + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(std::min(generated_signal_duration_s * 10, 3000)); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] + p6 = std::string("-CN0_dBHz=") + std::to_string(cn0); +#endif + return 0; } @@ -498,7 +680,11 @@ int AcquisitionPerformanceTest::generate_signal() int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsigned int iter) { +#if USE_GLOG_AND_GFLAGS if (FLAGS_config_file_ptest.empty()) +#else + if (absl::GetFlag(FLAGS_config_file_ptest).empty()) +#endif { config = std::make_shared(); const int sampling_rate_internal = baseband_sampling_freq; @@ -514,13 +700,23 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign config->set_property("Acquisition.threshold", std::to_string(pfa)); // if (FLAGS_acq_test_pfa_init > 0.0) config->supersede_property("Acquisition.pfa", std::to_string(pfa)); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_pfa_init > 0.0) +#else + if (absl::GetFlag(FLAGS_acq_test_pfa_init) > 0.0) +#endif { config->supersede_property("Acquisition.pfa", std::to_string(pfa)); } config->set_property("Acquisition.coherent_integration_time_ms", std::to_string(coherent_integration_time_ms)); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_bit_transition_flag) +#else + if (absl::GetFlag(FLAGS_acq_test_bit_transition_flag)) +#endif { config->set_property("Acquisition.bit_transition_flag", "true"); } @@ -528,18 +724,30 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign { config->set_property("Acquisition.bit_transition_flag", "false"); } - +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_acq_test_max_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_acq_test_max_dwells))); +#endif config->set_property("Acquisition.repeat_satellite", "true"); config->set_property("Acquisition.blocking", "true"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_make_two_steps) { config->set_property("Acquisition.make_two_steps", "true"); config->set_property("Acquisition.second_nbins", std::to_string(FLAGS_acq_test_second_nbins)); config->set_property("Acquisition.second_doppler_step", std::to_string(FLAGS_acq_test_second_doppler_step)); } +#else + if (absl::GetFlag(FLAGS_acq_test_make_two_steps)) + { + config->set_property("Acquisition.make_two_steps", "true"); + config->set_property("Acquisition.second_nbins", std::to_string(absl::GetFlag(FLAGS_acq_test_second_nbins))); + config->set_property("Acquisition.second_doppler_step", std::to_string(absl::GetFlag(FLAGS_acq_test_second_doppler_step))); + } +#endif else { config->set_property("Acquisition.make_two_steps", "false"); @@ -557,7 +765,11 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign } else { +#if USE_GLOG_AND_GFLAGS config_f = std::make_shared(FLAGS_config_file_ptest); +#else + config_f = std::make_shared(absl::GetFlag(FLAGS_config_file_ptest)); +#endif config = nullptr; } return 0; @@ -567,13 +779,21 @@ int AcquisitionPerformanceTest::configure_receiver(double cn0, float pfa, unsign int AcquisitionPerformanceTest::run_receiver() { std::string file; +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_input_file.empty()) +#else + if (absl::GetFlag(FLAGS_acq_test_input_file).empty()) +#endif { file = "./" + filename_raw_data; } else { +#if USE_GLOG_AND_GFLAGS file = FLAGS_acq_test_input_file; +#else + file = absl::GetFlag(FLAGS_acq_test_input_file); +#endif } const char* file_name = file.c_str(); gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); @@ -582,7 +802,11 @@ int AcquisitionPerformanceTest::run_receiver() top_block = gr::make_top_block("Acquisition test"); auto msg_rx = AcqPerfTest_msg_rx_make(channel_internal_queue); +#if USE_GLOG_AND_GFLAGS gr::blocks::skiphead::sptr skiphead = gr::blocks::skiphead::make(sizeof(gr_complex), FLAGS_acq_test_skiphead); +#else + gr::blocks::skiphead::sptr skiphead = gr::blocks::skiphead::make(sizeof(gr_complex), absl::GetFlag(FLAGS_acq_test_skiphead)); +#endif queue = std::make_shared>(); gnss_synchro = Gnss_Synchro(); @@ -681,9 +905,15 @@ int AcquisitionPerformanceTest::count_executions(const std::string& basename, un void AcquisitionPerformanceTest::plot_results() { +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + if (absl::GetFlag(FLAGS_plot_acq_test) == true) + { + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE,\n"; @@ -700,7 +930,11 @@ void AcquisitionPerformanceTest::plot_results() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -736,7 +970,11 @@ void AcquisitionPerformanceTest::plot_results() g1.savetopdf("ROC", 18); Gnuplot g2("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g2.showonscreen(); // window output } @@ -798,8 +1036,11 @@ TEST_F(AcquisitionPerformanceTest, ROC) std::vector meas_Pd_; std::vector meas_Pd_correct_; std::vector meas_Pfa_; - +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_input_file.empty()) +#else + if (absl::GetFlag(FLAGS_acq_test_input_file).empty()) +#endif { std::cout << "Execution for CN0 = " << it << " dB-Hz\n"; } @@ -807,7 +1048,11 @@ TEST_F(AcquisitionPerformanceTest, ROC) // Do N_iterations of the experiment for (int pfa_iter = 0; pfa_iter < static_cast(pfa_vector.size()); pfa_iter++) { +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_pfa_init > 0.0) +#else + if (absl::GetFlag(FLAGS_acq_test_pfa_init) > 0.0) +#endif { std::cout << "Setting threshold for Pfa = " << pfa_vector[pfa_iter] << '\n'; } @@ -816,16 +1061,25 @@ TEST_F(AcquisitionPerformanceTest, ROC) std::cout << "Setting threshold to " << pfa_vector[pfa_iter] << '\n'; } - // Configure the signal generator + // Configure the signal generator + +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_input_file.empty()) +#else + if (absl::GetFlag(FLAGS_acq_test_input_file).empty()) +#endif { configure_generator(it); } for (int iter = 0; iter < N_iterations; iter++) { - // Generate signal raw signal samples and observations RINEX file +// Generate signal raw signal samples and observations RINEX file +#if USE_GLOG_AND_GFLAGS if (FLAGS_acq_test_input_file.empty()) +#else + if (absl::GetFlag(FLAGS_acq_test_input_file).empty()) +#endif { generate_signal(); } @@ -834,11 +1088,19 @@ TEST_F(AcquisitionPerformanceTest, ROC) { if (k == 0) { +#if USE_GLOG_AND_GFLAGS observed_satellite = FLAGS_acq_test_PRN; +#else + observed_satellite = absl::GetFlag(FLAGS_acq_test_PRN); +#endif } else { +#if USE_GLOG_AND_GFLAGS observed_satellite = FLAGS_acq_test_fake_PRN; +#else + observed_satellite = absl::GetFlag(FLAGS_acq_test_fake_PRN); +#endif } init(); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b1i_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b1i_pcps_acquisition_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b1i_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/beidou_b1i_pcps_acquisition_test.cc index 9e577e096..7e14fb453 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b1i_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b1i_pcps_acquisition_test.cc @@ -29,7 +29,6 @@ #include "in_memory_configuration.h" #include "test_flags.h" #include -#include #include #include #include @@ -39,6 +38,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -57,7 +62,7 @@ namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class BeidouB1iPcpsAcquisitionTest_msg_rx; using BeidouB1iPcpsAcquisitionTest_msg_rx_sptr = std::shared_ptr; @@ -139,7 +144,7 @@ protected: gr::top_block_sptr top_block; std::shared_ptr config; - Gnss_Synchro gnss_synchro{}; + Gnss_Synchro gnss_synchro; size_t item_size; unsigned int doppler_max; unsigned int doppler_step; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc index bb99b7f07..2b492e52f 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/beidou_b3i_pcps_acquisition_test.cc @@ -29,7 +29,6 @@ #include "in_memory_configuration.h" #include "test_flags.h" #include -#include #include #include #include @@ -39,6 +38,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -56,7 +61,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class BeidouB3iPcpsAcquisitionTest_msg_rx; using BeidouB3iPcpsAcquisitionTest_msg_rx_sptr = std::shared_ptr; @@ -138,7 +143,7 @@ protected: gr::top_block_sptr top_block; std::shared_ptr config; - Gnss_Synchro gnss_synchro{}; + Gnss_Synchro gnss_synchro; size_t item_size; unsigned int doppler_max; unsigned int doppler_step; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc index e28db3b6c..09fac757e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc @@ -53,7 +53,7 @@ namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test_msg_rx; using GalileoE1Pcps8msAmbiguousAcquisitionGSoC2013Test_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc index 103778f60..b15bb3a90 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc2013_test.cc @@ -49,7 +49,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test_msg_rx; using GalileoE1PcpsAmbiguousAcquisitionGSoC2013Test_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc index 1a3886d81..3eda7db73 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc @@ -59,7 +59,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx; using GalileoE1PcpsAmbiguousAcquisitionGSoCTest_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc similarity index 96% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc index 0d964e826..5acb03b32 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test.cc @@ -31,7 +31,6 @@ #include "in_memory_configuration.h" #include "test_flags.h" #include -#include #include #include #include @@ -59,7 +58,7 @@ namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE1PcpsAmbiguousAcquisitionTest_msg_rx; using GalileoE1PcpsAmbiguousAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; @@ -162,7 +161,11 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::init() config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); config->set_property("Acquisition_1B.item_type", "gr_complex"); config->set_property("Acquisition_1B.coherent_integration_time_ms", "4"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { config->set_property("Acquisition_1B.dump", "true"); } @@ -198,7 +201,11 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() std::vector* samples = &acq_dump.samples; std::vector>* mag = &acq_dump.mag; +#if USE_GLOG_AND_GFLAGS const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE,\n"; @@ -216,7 +223,11 @@ void GalileoE1PcpsAmbiguousAcquisitionTest::plot_grid() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("lines"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -291,7 +302,11 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { std::string data_str = "./tmp-acq-gal1"; if (fs::exists(data_str)) @@ -368,7 +383,11 @@ TEST_F(GalileoE1PcpsAmbiguousAcquisitionTest, ValidationOfResults) EXPECT_LE(doppler_error_hz, 166) << "Doppler error exceeds the expected value: 166 Hz = 2/(3*integration period)"; EXPECT_LT(delay_error_chips, 0.175) << "Delay error exceeds the expected value: 0.175 chips"; +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { plot_grid(); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc index 714810fd7..4d68363f8 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc @@ -29,7 +29,6 @@ #include "in_memory_configuration.h" #include "test_flags.h" #include -#include #include #include #include @@ -38,6 +37,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #ifdef GR_GREATER_38 #include #else @@ -62,7 +67,7 @@ class GalileoE1PcpsAmbiguousAcquisitionTestFpga : public ::testing::Test { public: bool acquire_signal(); - std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga"; + std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_FPGA"; std::vector gnss_synchro_vec; const int32_t TEST_ACQ_SKIP_SAMPLES = 1024; @@ -316,7 +321,7 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal() // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal @@ -392,7 +397,7 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal() void GalileoE1PcpsAmbiguousAcquisitionTestFpga::init() { config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition_Fpga"); + config->set_property("Acquisition.implementation", "Galileo_E1_PCPS_Ambiguous_Acquisition_FPGA"); config->set_property("Acquisition.threshold", "0.00001"); config->set_property("Acquisition.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition.doppler_step", std::to_string(doppler_step)); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc index db50b891d..78457f584 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_cccwsr_ambiguous_acquisition_gsoc2013_test.cc @@ -52,7 +52,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE1PcpsCccwsrAmbiguousAcquisitionTest_msg_rx; using GalileoE1PcpsCccwsrAmbiguousAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc index 5204b859b..b61d6846c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_quicksync_ambiguous_acquisition_gsoc2014_test.cc @@ -27,18 +27,23 @@ #include "in_memory_configuration.h" #include "signal_generator.h" #include "signal_generator_c.h" -#include #include #include #include #include #include #include +#include #include #include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif #if HAS_GENERIC_LAMBDA #else #include @@ -54,11 +59,15 @@ namespace wht = boost; namespace wht = std; #endif +#if USE_GLOG_AND_GFLAGS DEFINE_double(e1_value_threshold, 0.3, "Value of the threshold for the acquisition"); DEFINE_int32(e1_value_CN0_dB_0, 50, "Value for the CN0_dB_0 in channel 0"); +#else +ABSL_FLAG(double, e1_value_threshold, 0.3, "Value of the threshold for the acquisition"); +ABSL_FLAG(int32_t, e1_value_CN0_dB_0, 50, "Value for the CN0_dB_0 in channel 0"); +#endif - -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test_msg_rx; using GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test_msg_rx_sptr = gnss_shared_ptr; @@ -297,7 +306,7 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_2() /*Unset this flag to eliminates data logging for the Validation of results probabilities test*/ - dump_test_results = true; + dump_test_results = false; num_of_realizations = 100; @@ -313,7 +322,11 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_2() config->set_property("SignalSource.system_0", "E"); config->set_property("SignalSource.PRN_0", "10"); +#if USE_GLOG_AND_GFLAGS config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_e1_value_CN0_dB_0)); +#else + config->set_property("SignalSource.CN0_dB_0", std::to_string(absl::GetFlag(FLAGS_e1_value_CN0_dB_0))); +#endif config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz)); config->set_property("SignalSource.delay_chips_0", @@ -366,7 +379,11 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_2() std::to_string(integration_time_ms)); config->set_property("Acquisition_1B.max_dwells", "1"); config->set_property("Acquisition_1B.bit_transition_flag", "false"); +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition_1B.threshold", std::to_string(FLAGS_e1_value_threshold)); +#else + config->set_property("Acquisition_1B.threshold", std::to_string(absl::GetFlag(FLAGS_e1_value_threshold))); +#endif config->set_property("Acquisition_1B.doppler_max", "10000"); config->set_property("Acquisition_1B.doppler_step", "125"); config->set_property("Acquisition_1B.folding_factor", "2"); @@ -403,7 +420,11 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test::config_3() config->set_property("SignalSource.system_0", "E"); config->set_property("SignalSource.PRN_0", "10"); +#if USE_GLOG_AND_GFLAGS config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_e1_value_CN0_dB_0)); +#else + config->set_property("SignalSource.CN0_dB_0", std::to_string(absl::GetFlag(FLAGS_e1_value_CN0_dB_0))); +#endif config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz)); config->set_property("SignalSource.delay_chips_0", @@ -861,12 +882,20 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul { std::stringstream filenamepd; filenamepd.str(""); - filenamepd << "../data/test_statistics_" << gnss_synchro.System + filenamepd << "./test_statistics_" << gnss_synchro.System << "_" << gnss_synchro.Signal << "_sat_" +#if USE_GLOG_AND_GFLAGS << gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_e1_value_CN0_dB_0 << "_dBHz.csv"; - +#else + << gnss_synchro.PRN << "CN0_dB_0_" << absl::GetFlag(FLAGS_e1_value_CN0_dB_0) << "_dBHz.csv"; +#endif pdpfafile.open(filenamepd.str().c_str(), std::ios::app | std::ios::out); + +#if USE_GLOG_AND_GFLAGS pdpfafile << FLAGS_e1_value_threshold << "," << Pd << "," << Pfa_p << "," << Pmd << '\n'; +#else + pdpfafile << absl::GetFlag(FLAGS_e1_value_threshold) << "," << Pd << "," << Pfa_p << "," << Pmd << '\n'; +#endif pdpfafile.close(); } } @@ -879,12 +908,20 @@ TEST_F(GalileoE1PcpsQuickSyncAmbiguousAcquisitionGSoC2014Test, ValidationOfResul { std::stringstream filenamepf; filenamepf.str(""); - filenamepf << "../data/test_statistics_" << gnss_synchro.System + filenamepf << "./test_statistics_" << gnss_synchro.System << "_" << gnss_synchro.Signal << "_sat_" +#if USE_GLOG_AND_GFLAGS << gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_e1_value_CN0_dB_0 << "_dBHz.csv"; - +#else + << gnss_synchro.PRN << "CN0_dB_0_" << absl::GetFlag(FLAGS_e1_value_CN0_dB_0) << "_dBHz.csv"; +#endif pdpfafile.open(filenamepf.str().c_str(), std::ios::app | std::ios::out); + +#if USE_GLOG_AND_GFLAGS pdpfafile << FLAGS_e1_value_threshold << "," << Pfa_a << '\n'; +#else + pdpfafile << absl::GetFlag(FLAGS_e1_value_threshold) << "," << Pfa_a << '\n'; +#endif pdpfafile.close(); } } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc index 093121afa..c252c0dbe 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_tong_ambiguous_acquisition_gsoc2013_test.cc @@ -53,7 +53,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test_msg_rx; using GalileoE1PcpsTongAmbiguousAcquisitionGSoC2013Test_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc index 33d60383e..6e1e3d8db 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5a_pcps_acquisition_gsoc2014_gensource_test.cc @@ -49,7 +49,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE5aPcpsAcquisitionGSoC2014GensourceTest_msg_rx; using GalileoE5aPcpsAcquisitionGSoC2014GensourceTest_msg_rx_sptr = gnss_shared_ptr; @@ -243,7 +243,7 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::config_1() config->set_property("SignalSource.BW_BB", "0.97"); config->set_property("SignalSource.dump", "false"); - config->set_property("SignalSource.dump_filename", "../data/signal_source.dat"); + config->set_property("SignalSource.dump_filename", "./signal_source.dat"); config->set_property("InputFilter.implementation", "Fir_Filter"); config->set_property("InputFilter.input_item_type", "gr_complex"); @@ -277,7 +277,7 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::config_1() config->set_property("Acquisition_5X.doppler_step", "250"); config->set_property("Acquisition_5X.bit_transition_flag", "false"); config->set_property("Acquisition_5X.dump", "false"); - config->set_property("SignalSource.dump_filename", "../data/acquisition.dat"); + config->set_property("SignalSource.dump_filename", "./acquisition.dat"); } @@ -313,7 +313,7 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::config_2() config->set_property("Acquisition_5X.doppler_step", "250"); config->set_property("Acquisition_5X.bit_transition_flag", "false"); config->set_property("Acquisition_5X.dump", "false"); - config->set_property("SignalSource.dump_filename", "../data/acquisition.dat"); + config->set_property("SignalSource.dump_filename", "./acquisition.dat"); } @@ -393,7 +393,7 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::config_3() config->set_property("SignalSource.BW_BB", "0.97"); config->set_property("SignalSource.dump", "false"); - config->set_property("SignalSource.dump_filename", "../data/signal_source.dat"); + config->set_property("SignalSource.dump_filename", "./signal_source.dat"); config->set_property("InputFilter.implementation", "Fir_Filter"); config->set_property("InputFilter.input_item_type", "gr_complex"); @@ -424,7 +424,7 @@ void GalileoE5aPcpsAcquisitionGSoC2014GensourceTest::config_3() config->set_property("Acquisition_5X.doppler_step", "250"); config->set_property("Acquisition_5X.bit_transition_flag", "false"); config->set_property("Acquisition_5X.dump", "false"); - config->set_property("SignalSource.dump_filename", "../data/acquisition.dat"); + config->set_property("SignalSource.dump_filename", "./acquisition.dat"); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5b_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5b_pcps_acquisition_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5b_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5b_pcps_acquisition_test.cc index c74b99d29..b596a6f3c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5b_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e5b_pcps_acquisition_test.cc @@ -55,7 +55,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE5bPcpsAcquisitionTest_msg_rx; using GalileoE5bPcpsAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; @@ -200,7 +200,7 @@ void GalileoE5bPcpsAcquisitionTest::init() config->set_property("SignalSource.data_flag", "false"); config->set_property("SignalSource.BW_BB", "0.97"); config->set_property("SignalSource.dump", "false"); - config->set_property("SignalSource.dump_filename", "../data/signal_source.dat"); + config->set_property("SignalSource.dump_filename", "./signal_source.dat"); config->set_property("InputFilter.implementation", "Fir_Filter"); config->set_property("InputFilter.input_item_type", "gr_complex"); config->set_property("InputFilter.output_item_type", "gr_complex"); @@ -222,7 +222,7 @@ void GalileoE5bPcpsAcquisitionTest::init() config->set_property("Acquisition_7X.implementation", "Galileo_E5b_PCPS_Acquisition"); config->set_property("Acquisition_7X.item_type", "gr_complex"); config->set_property("Acquisition_7X.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition_7X.dump", "true"); + config->set_property("Acquisition_7X.dump", "false"); config->set_property("Acquisition_7X.dump_filename", "./acquisition"); config->set_property("Acquisition_7X.threshold", "0.001"); config->set_property("Acquisition_7X.doppler_max", "10000"); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e6_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e6_pcps_acquisition_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e6_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/galileo_e6_pcps_acquisition_test.cc index 497ced58f..13fd07893 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e6_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e6_pcps_acquisition_test.cc @@ -55,7 +55,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GalileoE6PcpsAcquisitionTest_msg_rx; using GalileoE6PcpsAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; @@ -200,7 +200,7 @@ void GalileoE6PcpsAcquisitionTest::init() config->set_property("SignalSource.data_flag", "false"); config->set_property("SignalSource.BW_BB", "0.97"); config->set_property("SignalSource.dump", "false"); - config->set_property("SignalSource.dump_filename", "../data/signal_source.dat"); + config->set_property("SignalSource.dump_filename", "./signal_source.dat"); config->set_property("InputFilter.implementation", "Fir_Filter"); config->set_property("InputFilter.input_item_type", "gr_complex"); config->set_property("InputFilter.output_item_type", "gr_complex"); @@ -222,7 +222,7 @@ void GalileoE6PcpsAcquisitionTest::init() config->set_property("Acquisition_E6.implementation", "Galileo_E6_PCPS_Acquisition"); config->set_property("Acquisition_E6.item_type", "gr_complex"); config->set_property("Acquisition_E6.coherent_integration_time_ms", std::to_string(integration_time_ms)); - config->set_property("Acquisition_E6.dump", "true"); + config->set_property("Acquisition_E6.dump", "false"); config->set_property("Acquisition_E6.dump_filename", "./acquisition"); config->set_property("Acquisition_E6.pfa", "0.01"); config->set_property("Acquisition_E6.doppler_max", "10000"); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc index b23c989bf..5e146c9f2 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_gsoc2017_test.cc @@ -54,7 +54,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx; using GlonassL1CaPcpsAcquisitionGSoC2017Test_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc index 2495623e1..7bd987a41 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l1_ca_pcps_acquisition_test.cc @@ -48,7 +48,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GlonassL1CaPcpsAcquisitionTest_msg_rx; using GlonassL1CaPcpsAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc index 4f205422d..3775d845e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/glonass_l2_ca_pcps_acquisition_test.cc @@ -52,7 +52,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GlonassL2CaPcpsAcquisitionTest_msg_rx; using GlonassL2CaPcpsAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc index 70015c2d5..e8d340d27 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_gsoc2013_test.cc @@ -54,7 +54,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx; using GpsL1CaPcpsAcquisitionGSoC2013Test_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc index 76056cb3b..9cb9537d1 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test.cc @@ -28,7 +28,6 @@ #include "gps_l1_ca_pcps_acquisition.h" #include "in_memory_configuration.h" #include "test_flags.h" -#include #include #include #include @@ -39,6 +38,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -56,7 +61,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CaPcpsAcquisitionTest_msg_rx; using GpsL1CaPcpsAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; @@ -132,7 +137,7 @@ protected: gr::top_block_sptr top_block; std::shared_ptr config; - Gnss_Synchro gnss_synchro{}; + Gnss_Synchro gnss_synchro; size_t item_size; unsigned int doppler_max{5000}; unsigned int doppler_step{100}; @@ -150,7 +155,12 @@ void GpsL1CaPcpsAcquisitionTest::init() config->set_property("Acquisition_1C.implementation", "GPS_L1_CA_PCPS_Acquisition"); config->set_property("Acquisition_1C.item_type", "gr_complex"); config->set_property("Acquisition_1C.coherent_integration_time_ms", "1"); + +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { config->set_property("Acquisition_1C.dump", "true"); } @@ -185,8 +195,12 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() const std::vector *doppler = &acq_dump.doppler; std::vector *samples = &acq_dump.samples; std::vector > *mag = &acq_dump.mag; - +#if USE_GLOG_AND_GFLAGS const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif + if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE,\n"; @@ -204,7 +218,11 @@ void GpsL1CaPcpsAcquisitionTest::plot_grid() const Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("lines"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -286,7 +304,11 @@ TEST_F(GpsL1CaPcpsAcquisitionTest /*unused*/, ValidationOfResults /*unused*/) init(); +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { std::string data_str = "./tmp-acq-gps1"; if (fs::exists(data_str)) @@ -354,7 +376,11 @@ TEST_F(GpsL1CaPcpsAcquisitionTest /*unused*/, ValidationOfResults /*unused*/) EXPECT_LE(doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)"; EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { plot_grid(); } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc index 60db2ec9b..47ddc54aa 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc @@ -29,7 +29,6 @@ #include "in_memory_configuration.h" #include "test_flags.h" #include -#include #include #include #include // for abs, pow, floor @@ -37,6 +36,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + #ifdef GR_GREATER_38 #include #else @@ -61,7 +66,7 @@ class GpsL1CaPcpsAcquisitionTestFpga : public ::testing::Test { public: bool acquire_signal(); - std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_Fpga"; + std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking_FPGA"; std::vector gnss_synchro_vec; const int32_t TEST_ACQ_SKIP_SAMPLES = 1024; @@ -315,7 +320,7 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal() // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal @@ -391,7 +396,7 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal() void GpsL1CaPcpsAcquisitionTestFpga::init() { config->set_property("GNSS-SDR.internal_fs_sps", "4000000"); - config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition_Fpga"); + config->set_property("Acquisition.implementation", "GPS_L1_CA_PCPS_Acquisition_FPGA"); config->set_property("Acquisition.threshold", "0.00001"); config->set_property("Acquisition.doppler_max", std::to_string(doppler_max)); config->set_property("Acquisition.doppler_step", std::to_string(doppler_step)); diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc index 40f735c05..5be8d6998 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc @@ -51,7 +51,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CaPcpsOpenClAcquisitionGSoC2013Test_msg_rx; using GpsL1CaPcpsOpenClAcquisitionGSoC2013Test_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc index 92a8e19ff..ed92fae66 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_quicksync_acquisition_gsoc2014_test.cc @@ -25,7 +25,6 @@ #include "in_memory_configuration.h" #include "signal_generator.h" #include "signal_generator_c.h" -#include #include #include #include @@ -33,9 +32,15 @@ #include #include #include +#include #include #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif #if HAS_GENERIC_LAMBDA #else #include @@ -51,11 +56,15 @@ namespace wht = boost; namespace wht = std; #endif +#if USE_GLOG_AND_GFLAGS DEFINE_double(value_threshold, 1, "Value of the threshold for the acquisition"); DEFINE_int32(value_CN0_dB_0, 44, "Value for the CN0_dB_0 in channel 0"); +#else +ABSL_FLAG(double, value_threshold, 1, "Value of the threshold for the acquisition"); +ABSL_FLAG(int32_t, value_CN0_dB_0, 44, "Value for the CN0_dB_0 in channel 0"); +#endif - -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test_msg_rx; using GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test_msg_rx_sptr = gnss_shared_ptr; @@ -304,7 +313,11 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_2() config->set_property("SignalSource.system_0", "G"); config->set_property("SignalSource.PRN_0", "10"); +#if USE_GLOG_AND_GFLAGS config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_value_CN0_dB_0)); +#else + config->set_property("SignalSource.CN0_dB_0", std::to_string(absl::GetFlag(FLAGS_value_CN0_dB_0))); +#endif config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz)); config->set_property("SignalSource.delay_chips_0", std::to_string(expected_delay_chips)); @@ -354,7 +367,11 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_2() config->set_property("Acquisition_1C.coherent_integration_time_ms", std::to_string(integration_time_ms)); config->set_property("Acquisition_1C.max_dwells", "1"); +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition_1C.threshold", std::to_string(FLAGS_value_threshold)); +#else + config->set_property("Acquisition_1C.threshold", std::to_string(absl::GetFlag(FLAGS_value_threshold))); +#endif config->set_property("Acquisition_1C.doppler_max", "10000"); config->set_property("Acquisition_1C.doppler_step", "100"); config->set_property("Acquisition_1C.bit_transition_flag", "false"); @@ -379,7 +396,7 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_3() /*Unset this flag to eliminates data logging for the Validation of results probabilities test*/ - dump_test_results = true; + dump_test_results = false; num_of_realizations = 1; @@ -395,7 +412,11 @@ void GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test::config_3() config->set_property("SignalSource.system_0", "G"); config->set_property("SignalSource.PRN_0", "10"); +#if USE_GLOG_AND_GFLAGS config->set_property("SignalSource.CN0_dB_0", std::to_string(FLAGS_value_CN0_dB_0)); +#else + config->set_property("SignalSource.CN0_dB_0", std::to_string(absl::GetFlag(FLAGS_value_CN0_dB_0))); +#endif config->set_property("SignalSource.doppler_Hz_0", std::to_string(expected_doppler_hz)); config->set_property("SignalSource.delay_chips_0", std::to_string(expected_delay_chips)); @@ -828,12 +849,21 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsProbabili { std::stringstream filenamepd; filenamepd.str(""); - filenamepd << "../data/test_statistics_" << gnss_synchro.System + filenamepd << "./test_statistics_" << gnss_synchro.System << "_" << gnss_synchro.Signal << "_sat_" +#if USE_GLOG_AND_GFLAGS << gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_value_CN0_dB_0 << "_dBHz.csv"; +#else + << gnss_synchro.PRN << "CN0_dB_0_" << absl::GetFlag(FLAGS_value_CN0_dB_0) << "_dBHz.csv"; +#endif pdpfafile.open(filenamepd.str().c_str(), std::ios::app | std::ios::out); + +#if USE_GLOG_AND_GFLAGS pdpfafile << FLAGS_value_threshold << "," << Pd << "," << Pfa_p << "," << Pmd << '\n'; +#else + pdpfafile << absl::GetFlag(FLAGS_value_threshold) << "," << Pd << "," << Pfa_p << "," << Pmd << '\n'; +#endif pdpfafile.close(); } } @@ -846,12 +876,20 @@ TEST_F(GpsL1CaPcpsQuickSyncAcquisitionGSoC2014Test, ValidationOfResultsProbabili { std::stringstream filenamepf; filenamepf.str(""); - filenamepf << "../data/test_statistics_" << gnss_synchro.System + filenamepf << "./test_statistics_" << gnss_synchro.System << "_" << gnss_synchro.Signal << "_sat_" +#if USE_GLOG_AND_GFLAGS << gnss_synchro.PRN << "CN0_dB_0_" << FLAGS_value_CN0_dB_0 << "_dBHz.csv"; - +#else + << gnss_synchro.PRN << "CN0_dB_0_" << absl::GetFlag(FLAGS_value_CN0_dB_0) << "_dBHz.csv"; +#endif pdpfafile.open(filenamepf.str().c_str(), std::ios::app | std::ios::out); + +#if USE_GLOG_AND_GFLAGS pdpfafile << FLAGS_value_threshold << "," << Pfa_a << '\n'; +#else + pdpfafile << absl::GetFlag(FLAGS_value_threshold) << "," << Pfa_a << '\n'; +#endif pdpfafile.close(); } } diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc index 20e737c94..ab856b48e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_tong_acquisition_gsoc2013_test.cc @@ -53,7 +53,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CaPcpsTongAcquisitionGSoC2013Test_msg_rx; using GpsL1CaPcpsTongAcquisitionGSoC2013Test_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc similarity index 96% rename from src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc rename to tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc index a2d87201d..270cfe91a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc +++ b/tests/unit-tests/signal-processing-blocks/acquisition/gps_l2_m_pcps_acquisition_test.cc @@ -57,7 +57,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL2MPcpsAcquisitionTest_msg_rx; using GpsL2MPcpsAcquisitionTest_msg_rx_sptr = gnss_shared_ptr; @@ -160,7 +160,11 @@ void GpsL2MPcpsAcquisitionTest::init() config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(sampling_frequency_hz)); config->set_property("Acquisition_2S.implementation", "GPS_L2_M_PCPS_Acquisition"); config->set_property("Acquisition_2S.item_type", "gr_complex"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { config->set_property("Acquisition_2S.dump", "true"); } @@ -195,7 +199,11 @@ void GpsL2MPcpsAcquisitionTest::plot_grid() std::vector *samples = &acq_dump.samples; std::vector> *mag = &acq_dump.mag; +#if USE_GLOG_AND_GFLAGS const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_acq_grid has been set to TRUE,\n"; @@ -213,7 +221,11 @@ void GpsL2MPcpsAcquisitionTest::plot_grid() Gnuplot::set_GNUPlotPath(gnuplot_path); Gnuplot g1("impulses"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -290,7 +302,11 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) double expected_delay_samples = 1; // 2004; double expected_doppler_hz = 1200; // 3000; +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { std::string data_str = "./tmp-acq-gps2"; if (fs::exists(data_str)) @@ -372,7 +388,11 @@ TEST_F(GpsL2MPcpsAcquisitionTest, ValidationOfResults) EXPECT_LE(doppler_error_hz, 200) << "Doppler error exceeds the expected value: 2/(3*integration period)"; EXPECT_LT(delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips"; +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_acq_grid == true) +#else + if (absl::GetFlag(FLAGS_plot_acq_grid) == true) +#endif { plot_grid(); } diff --git a/src/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc b/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc rename to tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc index f4c6aaa44..6aa9d5358 100644 --- a/src/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc +++ b/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc b/tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc rename to tests/unit-tests/signal-processing-blocks/adapter/pass_through_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc b/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc similarity index 97% rename from src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc rename to tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc index 97b27f51c..9bebac3a9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc +++ b/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc @@ -14,7 +14,6 @@ * ----------------------------------------------------------------------------- */ -#include #include #include #include @@ -40,13 +39,24 @@ #include +#if USE_GLOG_AND_GFLAGS +#include DEFINE_int32(filter_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#else +#include +ABSL_FLAG(int32_t, filter_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#endif + class FirFilterTest : public ::testing::Test { protected: FirFilterTest() : item_size(sizeof(gr_complex)), +#if USE_GLOG_AND_GFLAGS nsamples(FLAGS_filter_test_nsamples) +#else + nsamples(absl::GetFlag(FLAGS_filter_test_nsamples)) +#endif { queue = std::make_shared>(); config = std::make_shared(); diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc b/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc rename to tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc index 1c77dc929..79cc01136 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc +++ b/tests/unit-tests/signal-processing-blocks/filter/notch_filter_lite_test.cc @@ -14,7 +14,6 @@ * ----------------------------------------------------------------------------- */ -#include #include #include #include @@ -38,14 +37,24 @@ #include #include - +#if USE_GLOG_AND_GFLAGS +#include DEFINE_int32(notch_filter_lite_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#else +#include +ABSL_FLAG(int32_t, notch_filter_lite_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#endif + class NotchFilterLiteTest : public ::testing::Test { protected: NotchFilterLiteTest() : item_size(sizeof(gr_complex)), +#if USE_GLOG_AND_GFLAGS nsamples(FLAGS_notch_filter_lite_test_nsamples) +#else + nsamples(absl::GetFlag(FLAGS_notch_filter_lite_test_nsamples)) +#endif { queue = std::make_shared>(); config = std::make_shared(); diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc b/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc rename to tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc index cf4cde035..17be01cc4 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc +++ b/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc @@ -14,7 +14,6 @@ * ----------------------------------------------------------------------------- */ -#include #include #include #include @@ -38,14 +37,23 @@ #include #include - +#if USE_GLOG_AND_GFLAGS +#include DEFINE_int32(notch_filter_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#else +#include +ABSL_FLAG(int32_t, notch_filter_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#endif class NotchFilterTest : public ::testing::Test { protected: NotchFilterTest() : item_size(sizeof(gr_complex)), +#if USE_GLOG_AND_GFLAGS nsamples(FLAGS_notch_filter_test_nsamples) +#else + nsamples(absl::GetFlag(FLAGS_notch_filter_test_nsamples)) +#endif { queue = std::make_shared>(); config = std::make_shared(); diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc b/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc rename to tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc index 4cb3c5c43..b99e17655 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc +++ b/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc @@ -14,7 +14,6 @@ * ----------------------------------------------------------------------------- */ -#include #include #include #include @@ -38,14 +37,23 @@ #include #include - +#if USE_GLOG_AND_GFLAGS +#include DEFINE_int32(pb_filter_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#else +#include +ABSL_FLAG(int32_t, pb_filter_test_nsamples, 1000000, "Number of samples to filter in the tests (max: 2147483647)"); +#endif class PulseBlankingFilterTest : public ::testing::Test { protected: PulseBlankingFilterTest() : item_size(sizeof(gr_complex)), +#if USE_GLOG_AND_GFLAGS nsamples(FLAGS_pb_filter_test_nsamples) +#else + nsamples(absl::GetFlag(FLAGS_pb_filter_test_nsamples)) +#endif { queue = std::make_shared>(); config = std::make_shared(); diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt b/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt similarity index 88% rename from src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt rename to tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt index 53545ef44..54d27bcc3 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt +++ b/tests/unit-tests/signal-processing-blocks/libs/CMakeLists.txt @@ -37,20 +37,25 @@ endif() target_link_libraries(signal_processing_testing_lib PUBLIC Armadillo::armadillo - Gflags::gflags Gnuradio::runtime Gnuradio::pmt PRIVATE Boost::headers Matio::matio - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(signal_processing_testing_lib PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(signal_processing_testing_lib PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(signal_processing_testing_lib PRIVATE absl::flags absl::log) +endif() + target_include_directories(signal_processing_testing_lib PUBLIC ${GNSSSDR_SOURCE_DIR}/src/core/interfaces INTERFACE - ${GNSSSDR_SOURCE_DIR}/src/tests/common-files + ${GNSSSDR_SOURCE_DIR}/tests/common-files ) if(USE_GENERIC_LAMBDAS) diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc b/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc rename to tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h b/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h rename to tests/unit-tests/signal-processing-blocks/libs/acquisition_dump_reader.h diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc b/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc rename to tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc index c8701e41d..fb8697898 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc +++ b/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.cc @@ -17,10 +17,17 @@ */ #include "acquisition_msg_rx.h" -#include -#include #include #include + +#if USE_GLOG_AND_GFLAGS +#include +#include +#else +#include +#include +#endif + #if HAS_GENERIC_LAMBDA #else #include diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h b/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h similarity index 95% rename from src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h rename to tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h index 50d54c2e7..fc50fb353 100644 --- a/src/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h +++ b/tests/unit-tests/signal-processing-blocks/libs/acquisition_msg_rx.h @@ -25,7 +25,7 @@ #include -// ######## GNURADIO ACQUISITION BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO ACQUISITION BLOCK MESSAGE RECEIVER ######### class Acquisition_msg_rx; using Acquisition_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/item_type_helpers_test.cc b/tests/unit-tests/signal-processing-blocks/libs/item_type_helpers_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/item_type_helpers_test.cc rename to tests/unit-tests/signal-processing-blocks/libs/item_type_helpers_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc b/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc rename to tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h b/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h rename to tests/unit-tests/signal-processing-blocks/libs/observables_dump_reader.h diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc b/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc rename to tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h b/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h rename to tests/unit-tests/signal-processing-blocks/libs/tlm_dump_reader.h diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc b/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc rename to tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h b/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h rename to tests/unit-tests/signal-processing-blocks/libs/tracking_dump_reader.h diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc b/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc rename to tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h b/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h rename to tests/unit-tests/signal-processing-blocks/libs/tracking_true_obs_reader.h diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc b/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc rename to tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h b/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h rename to tests/unit-tests/signal-processing-blocks/libs/true_observables_reader.h diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc b/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc similarity index 93% rename from src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc rename to tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc index 9cb2337d4..46c9c444b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc +++ b/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test.cc @@ -100,7 +100,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER FOR TRACKING MESSAGES ######### class HybridObservablesTest_msg_rx; using HybridObservablesTest_msg_rx_sptr = gnss_shared_ptr; @@ -164,7 +164,7 @@ HybridObservablesTest_msg_rx::~HybridObservablesTest_msg_rx() = default; // ########################################################### -// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TLM MESSAGES ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER FOR TLM MESSAGES ######### class HybridObservablesTest_tlm_msg_rx; @@ -252,12 +252,18 @@ public: std::string p3; std::string p4; std::string p5; + +#if USE_GLOG_AND_GFLAGS std::string implementation = FLAGS_trk_test_implementation; - const int baseband_sampling_freq = FLAGS_fs_gen_sps; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; +#else + std::string implementation = absl::GetFlag(FLAGS_trk_test_implementation); + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif int configure_generator(); int generate_signal(); @@ -340,6 +346,7 @@ public: int HybridObservablesTest::configure_generator() { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -355,6 +362,24 @@ int HybridObservablesTest::configure_generator() p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#endif + return 0; } @@ -395,8 +420,12 @@ bool HybridObservablesTest::acquire_signal() tmp_gnss_synchro.Channel_ID = 0; config = std::make_shared(); config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); - // Enable automatic resampler for the acquisition, if required +// Enable automatic resampler for the acquisition, if required +#if USE_GLOG_AND_GFLAGS if (FLAGS_use_acquisition_resampler == true) +#else + if (absl::GetFlag(FLAGS_use_acquisition_resampler) == true) +#endif { config->set_property("GNSS-SDR.use_acquisition_resampler", "true"); } @@ -418,8 +447,11 @@ bool HybridObservablesTest::acquire_signal() std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L1 CA"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); - // acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking") @@ -430,7 +462,11 @@ bool HybridObservablesTest::acquire_signal() std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E1B"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else if (implementation == "GPS_L2_M_DLL_PLL_Tracking") @@ -441,7 +477,11 @@ bool HybridObservablesTest::acquire_signal() std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L2CM"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_b") @@ -453,7 +493,11 @@ bool HybridObservablesTest::acquire_signal() tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E5a"; config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif config->set_property("Acquisition.CAF_window_hz", "0"); // **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is deactivated. Recommended value 3000 Hz config->set_property("Acquisition.Zero_padding", "0"); // **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. config->set_property("Acquisition.bit_transition_flag", "false"); @@ -468,7 +512,11 @@ bool HybridObservablesTest::acquire_signal() std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E5a"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else if (implementation == "GPS_L5_DLL_PLL_Tracking") @@ -479,7 +527,11 @@ bool HybridObservablesTest::acquire_signal() std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L5I"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else @@ -490,27 +542,43 @@ bool HybridObservablesTest::acquire_signal() acquisition->set_gnss_synchro(&tmp_gnss_synchro); acquisition->set_channel(0); +#if USE_GLOG_AND_GFLAGS acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz)); acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz)); acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); +#else + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_max_hz))); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_step_hz))); + acquisition->set_threshold(config->property("Acquisition.threshold", absl::GetFlag(FLAGS_external_signal_acquisition_threshold))); +#endif acquisition->init(); acquisition->set_local_code(); acquisition->set_state(1); // Ensure that acquisition starts at the first sample acquisition->connect(top_block_acq); gr::blocks::file_source::sptr file_source; +#if USE_GLOG_AND_GFLAGS std::string file = FLAGS_signal_file; +#else + std::string file = absl::GetFlag(FLAGS_signal_file); +#endif const char* file_name = file.c_str(); file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); +#if USE_GLOG_AND_GFLAGS file_source->seek(2 * FLAGS_skip_samples, 0); // skip head. ibyte, two bytes per complex sample +#else + file_source->seek(2 * absl::GetFlag(FLAGS_skip_samples), 0); // skip head. ibyte, two bytes per complex sample +#endif gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); - // gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); - // top_block_acq->connect(head_samples, 0, acquisition->get_left_block(), 0); - top_block_acq->connect(file_source, 0, gr_interleaved_char_to_complex, 0); // Enable automatic resampler for the acquisition, if required + +#if USE_GLOG_AND_GFLAGS if (FLAGS_use_acquisition_resampler == true) +#else + if (absl::GetFlag(FLAGS_use_acquisition_resampler) == true) +#endif { // create acquisition resamplers if required double resampler_ratio = 1.0; @@ -636,7 +704,11 @@ bool HybridObservablesTest::acquire_signal() top_block_acq->run(); if (start_msg == true) { +#if USE_GLOG_AND_GFLAGS std::cout << "Reading external signal file: " << FLAGS_signal_file << '\n'; +#else + std::cout << "Reading external signal file: " << absl::GetFlag(FLAGS_signal_file) << '\n'; +#endif std::cout << "Searching for " << System_and_Signal << " Satellites...\n"; std::cout << "["; start_msg = false; @@ -655,7 +727,11 @@ bool HybridObservablesTest::acquire_signal() std::cout << " . "; } top_block_acq->stop(); +#if USE_GLOG_AND_GFLAGS file_source->seek(2 * FLAGS_skip_samples, 0); // skip head. ibyte, two bytes per complex sample +#else + file_source->seek(2 * absl::GetFlag(FLAGS_skip_samples), 0); // skip head. ibyte, two bytes per complex sample +#endif std::cout.flush(); } std::cout << "]\n"; @@ -712,9 +788,15 @@ void HybridObservablesTest::configure_receiver( config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); +#if USE_GLOG_AND_GFLAGS config->set_property("Tracking.fll_bw_hz", std::to_string(FLAGS_fll_bw_hz)); config->set_property("Tracking.enable_fll_pull_in", FLAGS_enable_fll_pull_in ? "true" : "false"); config->set_property("Tracking.enable_fll_steady_state", FLAGS_enable_fll_steady_state ? "true" : "false"); +#else + config->set_property("Tracking.fll_bw_hz", std::to_string(absl::GetFlag(FLAGS_fll_bw_hz))); + config->set_property("Tracking.enable_fll_pull_in", absl::GetFlag(FLAGS_enable_fll_pull_in) ? "true" : "false"); + config->set_property("Tracking.enable_fll_steady_state", absl::GetFlag(FLAGS_enable_fll_steady_state) ? "true" : "false"); +#endif config->set_property("Tracking.smoother_length", std::to_string(smoother_length)); config->set_property("Tracking.dump", "true"); config->set_property("Tracking.dump_filename", "./tracking_ch_"); @@ -877,7 +959,12 @@ void HybridObservablesTest::check_results_carrier_phase( std::cout.precision(ss); // plots + +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Accumulated Carrier phase error [cycles]"); @@ -968,7 +1055,12 @@ void HybridObservablesTest::check_results_carrier_phase_double_diff( std::cout.precision(ss); // plots + +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Carrier Phase error [Cycles]"); @@ -1061,8 +1153,12 @@ void HybridObservablesTest::check_results_carrier_doppler_double_diff( << " [Hz]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Carrier Doppler error [Hz]"); @@ -1147,7 +1243,11 @@ void HybridObservablesTest::check_results_carrier_doppler( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Carrier Doppler error [Hz]"); @@ -1282,7 +1382,11 @@ void HybridObservablesTest::check_results_duplicated_satellite( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Carrier Doppler error [Hz]"); @@ -1341,8 +1445,12 @@ void HybridObservablesTest::check_results_duplicated_satellite( << " [Cycles]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Carrier Phase error [Cycles]"); @@ -1401,7 +1509,12 @@ void HybridObservablesTest::check_results_duplicated_satellite( std::cout.precision(ss); // plots + +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Pseudorange error [m]"); @@ -1526,8 +1639,12 @@ void HybridObservablesTest::check_results_code_pseudorange( << " [meters]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Pseudorange error [m]"); @@ -1568,7 +1685,11 @@ bool HybridObservablesTest::ReadRinexObs(std::vector* obs_vec, Gnss_S // Open and read reference RINEX observables file try { +#if USE_GLOG_AND_GFLAGS gnsstk::Rinex3ObsStream r_ref(FLAGS_filename_rinex_obs); +#else + gnsstk::Rinex3ObsStream r_ref(absl::GetFlag(FLAGS_filename_rinex_obs)); +#endif r_ref.exceptions(std::ios::failbit); gnsstk::Rinex3ObsData r_ref_data; gnsstk::Rinex3ObsHeader r_ref_header; @@ -1695,7 +1816,7 @@ bool HybridObservablesTest::ReadRinexObs(std::vector* obs_vec, Gnss_S } } } // end while - } // End of 'try' block + } // End of 'try' block catch (const gnsstk::FFStreamError& e) { std::cout << e; @@ -1727,7 +1848,12 @@ TEST_F(HybridObservablesTest, ValidationOfResults) configure_generator(); // Generate signal raw signal samples and observations RINEX file + +#if USE_GLOG_AND_GFLAGS if (FLAGS_disable_generator == false) +#else + if (absl::GetFlag(FLAGS_disable_generator) == false) +#endif { generate_signal(); } @@ -1736,7 +1862,12 @@ TEST_F(HybridObservablesTest, ValidationOfResults) std::chrono::duration elapsed_seconds(0); // use generator or use an external capture file + +#if USE_GLOG_AND_GFLAGS if (FLAGS_enable_external_signal_file) +#else + if (absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { // create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters ASSERT_EQ(acquire_signal(), true); @@ -1747,8 +1878,11 @@ TEST_F(HybridObservablesTest, ValidationOfResults) tmp_gnss_synchro.System = 'G'; std::string signal = "1C"; signal.copy(tmp_gnss_synchro.Signal, 2, 0); - +#if USE_GLOG_AND_GFLAGS std::istringstream ss(FLAGS_test_satellite_PRN_list); +#else + std::istringstream ss(absl::GetFlag(FLAGS_test_satellite_PRN_list)); +#endif std::string token; while (std::getline(ss, token, ',')) @@ -1758,6 +1892,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) } } +#if USE_GLOG_AND_GFLAGS configure_receiver(FLAGS_PLL_bw_hz_start, FLAGS_DLL_bw_hz_start, FLAGS_PLL_narrow_bw_hz, @@ -1765,11 +1900,25 @@ TEST_F(HybridObservablesTest, ValidationOfResults) FLAGS_extend_correlation_symbols, FLAGS_smoother_length, FLAGS_high_dyn); +#else + configure_receiver(absl::GetFlag(FLAGS_PLL_bw_hz_start), + absl::GetFlag(FLAGS_DLL_bw_hz_start), + absl::GetFlag(FLAGS_PLL_narrow_bw_hz), + absl::GetFlag(FLAGS_DLL_narrow_bw_hz), + absl::GetFlag(FLAGS_extend_correlation_symbols), + absl::GetFlag(FLAGS_smoother_length), + absl::GetFlag(FLAGS_high_dyn)); +#endif for (auto& n : gnss_synchro_vec) { // setup the signal synchronization, simulating an acquisition + +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { // based on true observables metadata (for custom sdr generator) // open true observables log file written by the simulator or based on provided RINEX obs @@ -1873,6 +2022,7 @@ TEST_F(HybridObservablesTest, ValidationOfResults) ASSERT_NO_THROW({ std::string file; +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { file = "./" + filename_raw_data; @@ -1881,6 +2031,16 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { file = FLAGS_signal_file; } +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + file = "./" + filename_raw_data; + } + else + { + file = absl::GetFlag(FLAGS_signal_file); + } +#endif const char* file_name = file.c_str(); gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); @@ -1900,7 +2060,11 @@ TEST_F(HybridObservablesTest, ValidationOfResults) // connect sample counter and timmer to the last channel in observables block (extra channel) top_block_tlm->connect(samp_counter, 0, observables->get_left_block(), tracking_ch_vec.size()); +#if USE_GLOG_AND_GFLAGS file_source->seek(2 * FLAGS_skip_samples, 0); // skip head. ibyte, two bytes per complex sample +#else + file_source->seek(2 * absl::GetFlag(FLAGS_skip_samples), 0); // skip head. ibyte, two bytes per complex sample +#endif }) << "Failure connecting the blocks."; for (auto& n : tracking_ch_vec) @@ -1918,8 +2082,11 @@ TEST_F(HybridObservablesTest, ValidationOfResults) // check results // Matrices for storing columnwise true GPS time, Range, Doppler and Carrier phase std::vector true_obs_vec; - +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { // load the true values True_Observables_Reader true_observables; @@ -1963,7 +2130,11 @@ TEST_F(HybridObservablesTest, ValidationOfResults) } else { +#if USE_GLOG_AND_GFLAGS if (!FLAGS_duplicated_satellites_test) +#else + if (!absl::GetFlag(FLAGS_duplicated_satellites_test)) +#endif { ASSERT_EQ(ReadRinexObs(&true_obs_vec, gnss_synchro_master), true) << "Failure reading RINEX file"; @@ -2018,8 +2189,12 @@ TEST_F(HybridObservablesTest, ValidationOfResults) } } - // Cut measurement initial transitory of the measurements +// Cut measurement initial transitory of the measurements +#if USE_GLOG_AND_GFLAGS double initial_transitory_s = FLAGS_skip_obs_transitory_s; +#else + double initial_transitory_s = absl::GetFlag(FLAGS_skip_obs_transitory_s); +#endif for (unsigned int n = 0; n < measured_obs_vec.size(); n++) { index = arma::find(measured_obs_vec.at(n).col(0) >= (measured_obs_vec.at(n)(0, 0) + initial_transitory_s), 1, "first"); @@ -2027,8 +2202,11 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { measured_obs_vec.at(n).shed_rows(0, index(0)); } - +#if USE_GLOG_AND_GFLAGS if (!FLAGS_duplicated_satellites_test) +#else + if (!absl::GetFlag(FLAGS_duplicated_satellites_test)) +#endif { index = arma::find(measured_obs_vec.at(n).col(0) >= true_obs_vec.at(n)(0, 0), 1, "first"); if ((!index.empty()) and (index(0) > 0)) @@ -2038,11 +2216,19 @@ TEST_F(HybridObservablesTest, ValidationOfResults) } } +#if USE_GLOG_AND_GFLAGS if (FLAGS_duplicated_satellites_test) +#else + if (absl::GetFlag(FLAGS_duplicated_satellites_test)) +#endif { // special test mode for duplicated satellites std::vector prn_pairs; +#if USE_GLOG_AND_GFLAGS std::stringstream ss(FLAGS_duplicated_satellites_prns); +#else + std::stringstream ss(absl::GetFlag(FLAGS_duplicated_satellites_prns)); +#endif unsigned int i; while (ss >> i) { @@ -2190,9 +2376,13 @@ TEST_F(HybridObservablesTest, ValidationOfResults) measured_obs_vec.at(n), measured_obs_vec.at(min_pr_ch_id), "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); - // Do not compare E5a with E5 RINEX due to the Doppler frequency discrepancy caused by the different center frequencies - // E5a_fc=1176.45e6, E5b_fc=1207.14e6, E5_fc=1191.795e6; +// Do not compare E5a with E5 RINEX due to the Doppler frequency discrepancy caused by the different center frequencies +// E5a_fc=1176.45e6, E5b_fc=1207.14e6, E5_fc=1191.795e6; +#if USE_GLOG_AND_GFLAGS if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or FLAGS_compare_with_5X) +#else + if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or absl::GetFlag(FLAGS_compare_with_5X)) +#endif { check_results_carrier_phase_double_diff(true_obs_vec.at(n), true_obs_vec.at(min_pr_ch_id), @@ -2215,7 +2405,11 @@ TEST_F(HybridObservablesTest, ValidationOfResults) { std::cout << "[CH " << std::to_string(n) << "] PRN " << std::to_string(gnss_synchro_vec.at(n).PRN) << " is the reference satellite\n"; } +#if USE_GLOG_AND_GFLAGS if (FLAGS_compute_single_diffs) +#else + if (absl::GetFlag(FLAGS_compute_single_diffs)) +#endif { check_results_carrier_phase(true_obs_vec.at(n), true_TOW_ch_s, diff --git a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc b/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc similarity index 93% rename from src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc rename to tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc index 492b5d1fc..f16c45004 100644 --- a/src/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc +++ b/tests/unit-tests/signal-processing-blocks/observables/hybrid_observables_test_fpga.cc @@ -224,12 +224,17 @@ public: std::string p3; std::string p4; std::string p5; +#if USE_GLOG_AND_GFLAGS std::string implementation = FLAGS_trk_test_implementation; - const int baseband_sampling_freq = FLAGS_fs_gen_sps; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; +#else + std::string implementation = absl::GetFlag(FLAGS_trk_test_implementation); + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif int configure_generator(); int generate_signal(); @@ -310,6 +315,7 @@ public: int HybridObservablesTestFpga::configure_generator() { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -325,6 +331,24 @@ int HybridObservablesTestFpga::configure_generator() p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#endif + return 0; } @@ -422,12 +446,15 @@ void* handler_DMA_obs_test(void* arguments) return nullptr; } - // ************************************************************************* - // Open input file - // ************************************************************************* + // ************************************************************************* + // Open input file + // ************************************************************************* +#if USE_GLOG_AND_GFLAGS uint32_t skip_samples = static_cast(FLAGS_skip_samples); - +#else + uint32_t skip_samples = static_cast(absl::GetFlag(FLAGS_skip_samples)); +#endif if (skip_samples + skip_used_samples > 0) { try @@ -601,18 +628,21 @@ bool HybridObservablesTestFpga::acquire_signal() std::string signal; struct DMA_handler_args_obs_test args; struct acquisition_handler_args_obs_test args_acq; - +#if USE_GLOG_AND_GFLAGS std::string file = FLAGS_signal_file; +#else + std::string file = absl::GetFlag(FLAGS_signal_file); +#endif args.file = file; // DMA file configuration // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "1C"; @@ -624,7 +654,7 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "1B"; @@ -636,7 +666,7 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "5X"; @@ -648,7 +678,7 @@ bool HybridObservablesTestFpga::acquire_signal() args.freq_band = 1; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "L5"; @@ -669,11 +699,17 @@ bool HybridObservablesTestFpga::acquire_signal() acquisition->set_gnss_synchro(&tmp_gnss_synchro); acquisition->set_channel_fsm(channel_fsm_); acquisition->set_channel(0); +#if USE_GLOG_AND_GFLAGS acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz)); acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz)); acquisition->set_doppler_center(0); acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); - +#else + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_max_hz))); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_step_hz))); + acquisition->set_doppler_center(0); + acquisition->set_threshold(config->property("Acquisition.threshold", absl::GetFlag(FLAGS_external_signal_acquisition_threshold))); +#endif std::chrono::time_point start, end; std::chrono::duration elapsed_seconds; start = std::chrono::system_clock::now(); @@ -696,19 +732,19 @@ bool HybridObservablesTestFpga::acquire_signal() // number of samples that the DMA has to transfer unsigned int nsamples_to_transfer; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); } - else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_FPGA") == 0)) { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); } @@ -726,7 +762,7 @@ bool HybridObservablesTestFpga::acquire_signal() acquisition->init(); acquisition->set_local_code(); - if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")) + if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA")) { // Skip the first TEST_OBS_SKIP_SAMPLES samples args.skip_used_samples = 0; @@ -760,7 +796,11 @@ bool HybridObservablesTestFpga::acquire_signal() if (start_msg == true) { +#if USE_GLOG_AND_GFLAGS std::cout << "Reading external signal file: " << FLAGS_signal_file << '\n'; +#else + std::cout << "Reading external signal file: " << absl::GetFlag(FLAGS_signal_file) << '\n'; +#endif std::cout << "Searching for " << System_and_Signal << " Satellites...\n"; std::cout << "["; start_msg = false; @@ -850,9 +890,15 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); +#if USE_GLOG_AND_GFLAGS config->set_property("Tracking.fll_bw_hz", std::to_string(FLAGS_fll_bw_hz)); config->set_property("Tracking.enable_fll_pull_in", FLAGS_enable_fll_pull_in ? "true" : "false"); config->set_property("Tracking.enable_fll_steady_state", FLAGS_enable_fll_steady_state ? "true" : "false"); +#else + config->set_property("Tracking.fll_bw_hz", std::to_string(absl::GetFlag(FLAGS_fll_bw_hz))); + config->set_property("Tracking.enable_fll_pull_in", absl::GetFlag(FLAGS_enable_fll_pull_in) ? "true" : "false"); + config->set_property("Tracking.enable_fll_steady_state", absl::GetFlag(FLAGS_enable_fll_steady_state) ? "true" : "false"); +#endif config->set_property("Tracking.smoother_length", std::to_string(smoother_length)); config->set_property("Tracking.dump", "true"); config->set_property("Tracking.dump_filename", "./tracking_ch_"); @@ -864,7 +910,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); std::string System_and_Signal; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { gnss_synchro_master.System = 'G'; std::string signal = "1C"; @@ -877,7 +923,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("TelemetryDecoder.implementation", "GPS_L1_CA_Telemetry_Decoder"); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { gnss_synchro_master.System = 'E'; std::string signal = "1B"; @@ -893,7 +939,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("TelemetryDecoder.implementation", "Galileo_E1B_Telemetry_Decoder"); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") // or implementation.compare("Galileo_E5a_DLL_PLL_Tracking_b") == 0) { gnss_synchro_master.System = 'E'; std::string signal = "5X"; @@ -907,7 +953,7 @@ void HybridObservablesTestFpga::configure_receiver( config->set_property("TelemetryDecoder.implementation", "Galileo_E5a_Telemetry_Decoder"); } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { gnss_synchro_master.System = 'G'; std::string signal = "L5"; @@ -995,7 +1041,11 @@ void HybridObservablesTestFpga::check_results_carrier_phase( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Accumulated Carrier phase error [cycles]"); @@ -1084,7 +1134,11 @@ void HybridObservablesTestFpga::check_results_carrier_phase_double_diff( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Carrier Phase error [Cycles]"); @@ -1171,8 +1225,12 @@ void HybridObservablesTestFpga::check_results_carrier_doppler_double_diff( << " [Hz]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Carrier Doppler error [Hz]"); @@ -1250,7 +1308,11 @@ void HybridObservablesTestFpga::check_results_carrier_doppler( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Carrier Doppler error [Hz]"); @@ -1384,7 +1446,11 @@ void HybridObservablesTestFpga::check_results_duplicated_satellite( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Carrier Doppler error [Hz]"); @@ -1444,7 +1510,11 @@ void HybridObservablesTestFpga::check_results_duplicated_satellite( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Carrier Phase error [Cycles]"); @@ -1503,7 +1573,11 @@ void HybridObservablesTestFpga::check_results_duplicated_satellite( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Pseudorange error [m]"); @@ -1627,8 +1701,12 @@ void HybridObservablesTestFpga::check_results_code_pseudorange( << " [meters]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Pseudorange error [m]"); @@ -1661,7 +1739,11 @@ bool HybridObservablesTestFpga::ReadRinexObs(std::vector* obs_vec, Gn // Open and read reference RINEX observables file try { +#if USE_GLOG_AND_GFLAGS gnsstk::Rinex3ObsStream r_ref(FLAGS_filename_rinex_obs); +#else + gnsstk::Rinex3ObsStream r_ref(absl::GetFlag(FLAGS_filename_rinex_obs)); +#endif r_ref.exceptions(std::ios::failbit); gnsstk::Rinex3ObsData r_ref_data; gnsstk::Rinex3ObsHeader r_ref_header; @@ -1789,7 +1871,7 @@ bool HybridObservablesTestFpga::ReadRinexObs(std::vector* obs_vec, Gn } } } // end while - } // End of 'try' block + } // End of 'try' block catch (const gnsstk::FFStreamError& e) { @@ -1828,7 +1910,11 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) configure_generator(); // Generate signal raw signal samples and observations RINEX file +#if USE_GLOG_AND_GFLAGS if (FLAGS_disable_generator == false) +#else + if (absl::GetFlag(FLAGS_disable_generator) == false) +#endif { generate_signal(); } @@ -1836,8 +1922,12 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); - // use generator or use an external capture file +// use generator or use an external capture file +#if USE_GLOG_AND_GFLAGS if (FLAGS_enable_external_signal_file) +#else + if (absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { // create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters ASSERT_EQ(acquire_signal(), true); @@ -1849,7 +1939,11 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) std::string signal = "1C"; signal.copy(tmp_gnss_synchro.Signal, 2, 0); +#if USE_GLOG_AND_GFLAGS std::istringstream ss(FLAGS_test_satellite_PRN_list); +#else + std::istringstream ss(absl::GetFlag(FLAGS_test_satellite_PRN_list)); +#endif std::string token; while (std::getline(ss, token, ',')) @@ -1858,7 +1952,7 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) gnss_synchro_vec.push_back(tmp_gnss_synchro); } } - +#if USE_GLOG_AND_GFLAGS configure_receiver(FLAGS_PLL_bw_hz_start, FLAGS_DLL_bw_hz_start, FLAGS_PLL_narrow_bw_hz, @@ -1866,11 +1960,24 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) FLAGS_extend_correlation_symbols, FLAGS_smoother_length, FLAGS_high_dyn); +#else + configure_receiver(absl::GetFlag(FLAGS_PLL_bw_hz_start), + absl::GetFlag(FLAGS_DLL_bw_hz_start), + absl::GetFlag(FLAGS_PLL_narrow_bw_hz), + absl::GetFlag(FLAGS_DLL_narrow_bw_hz), + absl::GetFlag(FLAGS_extend_correlation_symbols), + absl::GetFlag(FLAGS_smoother_length), + absl::GetFlag(FLAGS_high_dyn)); +#endif for (auto& n : gnss_synchro_vec) { // setup the signal synchronization, simulating an acquisition +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { // based on true observables metadata (for custom sdr generator) // open true observables log file written by the simulator or based on provided RINEX obs @@ -1924,22 +2031,22 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR; // reset the HW to clear the sample counters: the acquisition constructor generates a reset - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1; } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1; @@ -2011,6 +2118,7 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) std::string file; ASSERT_NO_THROW({ +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { file = "./" + filename_raw_data; @@ -2019,6 +2127,16 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) { file = FLAGS_signal_file; } +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + file = "./" + filename_raw_data; + } + else + { + file = absl::GetFlag(FLAGS_signal_file); + } +#endif int observable_interval_ms = 20; double fs = static_cast(config->property("GNSS-SDR.internal_fs_sps", 0)); @@ -2051,7 +2169,12 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) usleep(1000000); args.file = file; +#if USE_GLOG_AND_GFLAGS args.nsamples_tx = baseband_sampling_freq * FLAGS_duration; +#else + args.nsamples_tx = baseband_sampling_freq * absl::GetFlag(FLAGS_duration); +#endif + args.skip_used_samples = 0; if (pthread_create(&thread_DMA, nullptr, handler_DMA_obs_test, reinterpret_cast(&args)) < 0) @@ -2087,8 +2210,11 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) // check results // Matrices for storing columnwise true GPS time, Range, Doppler and Carrier phase std::vector true_obs_vec; - +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { // load the true values True_Observables_Reader true_observables; @@ -2132,7 +2258,11 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) } else { +#if USE_GLOG_AND_GFLAGS if (!FLAGS_duplicated_satellites_test) +#else + if (!absl::GetFlag(FLAGS_duplicated_satellites_test)) +#endif { ASSERT_EQ(ReadRinexObs(&true_obs_vec, gnss_synchro_master), true) << "Failure reading RINEX file"; @@ -2188,8 +2318,12 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) } } - // Cut measurement initial transitory of the measurements +// Cut measurement initial transitory of the measurements +#if USE_GLOG_AND_GFLAGS double initial_transitory_s = FLAGS_skip_obs_transitory_s; +#else + double initial_transitory_s = absl::GetFlag(FLAGS_skip_obs_transitory_s); +#endif for (unsigned int n = 0; n < measured_obs_vec.size(); n++) { index = arma::find(measured_obs_vec.at(n).col(0) >= (measured_obs_vec.at(n)(0, 0) + initial_transitory_s), 1, "first"); @@ -2197,8 +2331,11 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) { measured_obs_vec.at(n).shed_rows(0, index(0)); } - +#if USE_GLOG_AND_GFLAGS if (!FLAGS_duplicated_satellites_test) +#else + if (!absl::GetFlag(FLAGS_duplicated_satellites_test)) +#endif { index = arma::find(measured_obs_vec.at(n).col(0) >= true_obs_vec.at(n)(0, 0), 1, "first"); if ((!index.empty()) and (index(0) > 0)) @@ -2207,12 +2344,19 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) } } } - +#if USE_GLOG_AND_GFLAGS if (FLAGS_duplicated_satellites_test) +#else + if (absl::GetFlag(FLAGS_duplicated_satellites_test)) +#endif { // special test mode for duplicated satellites std::vector prn_pairs; +#if USE_GLOG_AND_GFLAGS std::stringstream ss(FLAGS_duplicated_satellites_prns); +#else + std::stringstream ss(absl::GetFlag(FLAGS_duplicated_satellites_prns)); +#endif unsigned int i; while (ss >> i) { @@ -2363,7 +2507,11 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) "[CH " + std::to_string(n) + "] PRN " + std::to_string(gnss_synchro_vec.at(n).PRN) + " "); // Do not compare E5a with E5 RINEX due to the Doppler frequency discrepancy caused by the different center frequencies // E5a_fc=1176.45e6, E5b_fc=1207.14e6, E5_fc=1191.795e6; +#if USE_GLOG_AND_GFLAGS if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or FLAGS_compare_with_5X) +#else + if (strcmp("5X\0", gnss_synchro_vec.at(n).Signal) != 0 or absl::GetFlag(FLAGS_compare_with_5X)) +#endif { check_results_carrier_phase_double_diff(true_obs_vec.at(n), true_obs_vec.at(min_pr_ch_id), @@ -2386,7 +2534,11 @@ TEST_F(HybridObservablesTestFpga, ValidationOfResults) { std::cout << "[CH " << std::to_string(n) << "] PRN " << std::to_string(gnss_synchro_vec.at(n).PRN) << " is the reference satellite\n"; } +#if USE_GLOG_AND_GFLAGS if (FLAGS_compute_single_diffs) +#else + if (absl::GetFlag(FLAGS_compute_single_diffs)) +#endif { check_results_carrier_phase(true_obs_vec.at(n), true_TOW_ch_s, diff --git a/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc b/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc new file mode 100644 index 000000000..58dcc3f2f --- /dev/null +++ b/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc @@ -0,0 +1,347 @@ +/*! + * \file gnss_crypto_test.cc + * \brief Tests for the Gnss_Crypto class. + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "gnss_crypto.h" +#include "gnss_sdr_filesystem.h" +#include "gnss_sdr_make_unique.h" +#include +#include +#include +#include + +class GnssCryptoTest : public ::testing::Test +{ +}; + + +TEST(GnssCryptoTest, VerifyPubKeyImport) +{ + auto d_crypto = std::make_unique(); + // Input taken from RG 1.3 A7.1 + // compressed ECDSA P-256 format + std::vector publicKey = { + 0x03, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, + 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, + 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, + 0x79, 0x80, 0xEA}; + + ASSERT_FALSE(d_crypto->have_public_key()); + + d_crypto->set_public_key(publicKey); + + ASSERT_TRUE(d_crypto->have_public_key()); +} + + +TEST(GnssCryptoTest, VerifyPublicKeyStorage) +{ + const std::string f1("./osnma_test_file1.pem"); + const std::string f2("./osnma_test_file2.pem"); + const std::string f3("./osnma_test_file3.pem"); + + // Input taken from RG 1.3 A7.1 + // compressed ECDSA P-256 format + std::vector publicKey = { + 0x03, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, + 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, + 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, + 0x79, 0x80, 0xEA}; + + auto d_crypto = std::make_unique(); + ASSERT_FALSE(d_crypto->have_public_key()); + ASSERT_TRUE(d_crypto->get_public_key_type() == "Unknown"); + d_crypto->set_public_key(publicKey); + ASSERT_TRUE(d_crypto->have_public_key()); + ASSERT_TRUE(d_crypto->store_public_key(f1)); + + auto d_crypto2 = std::make_unique(f1, ""); + ASSERT_TRUE(d_crypto2->have_public_key()); + ASSERT_TRUE(d_crypto2->get_public_key_type() == "ECDSA P-256"); + ASSERT_TRUE(d_crypto2->store_public_key(f2)); + + std::ifstream t(f1); + std::string content_file((std::istreambuf_iterator(t)), std::istreambuf_iterator()); + + std::ifstream t2(f2); + std::string content_file2((std::istreambuf_iterator(t2)), std::istreambuf_iterator()); + + ASSERT_EQ(content_file, content_file2); + + // P-521 Public key in compressed X format + std::vector publicKey_P521 = { + 0x03, 0x00, 0x28, 0x35, 0xBB, 0xE9, 0x24, 0x59, 0x4E, 0xF0, + 0xE3, 0xA2, 0xDB, 0xC0, 0x49, 0x30, 0x60, 0x7C, 0x61, 0x90, + 0xE4, 0x03, 0xE0, 0xC7, 0xB8, 0xC2, 0x62, 0x37, 0xF7, 0x58, + 0x56, 0xBE, 0x63, 0x5C, 0x97, 0xF7, 0x53, 0x64, 0x7E, 0xE1, + 0x0C, 0x07, 0xD3, 0x97, 0x8D, 0x58, 0x46, 0xFD, 0x6E, 0x06, + 0x44, 0x01, 0xA7, 0xAA, 0xC4, 0x95, 0x13, 0x5D, 0xC9, 0x77, + 0x26, 0xE9, 0xF8, 0x72, 0x0C, 0xD3, 0x88}; + + d_crypto->set_public_key(publicKey_P521); + ASSERT_TRUE(d_crypto->have_public_key()); + ASSERT_TRUE(d_crypto->get_public_key_type() == "ECDSA P-521"); + ASSERT_TRUE(d_crypto->store_public_key(f3)); + + auto d_crypto3 = std::make_unique(f3, ""); + ASSERT_TRUE(d_crypto3->have_public_key()); + ASSERT_TRUE(d_crypto3->get_public_key_type() == "ECDSA P-521"); + + std::vector wrong_publicKey = { + 0x03, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, + 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, + 0x63, 0xFF, 0xA0}; + + auto d_crypto4 = std::make_unique(); + d_crypto4->set_public_key(wrong_publicKey); + ASSERT_FALSE(d_crypto4->have_public_key()); + ASSERT_TRUE(d_crypto4->get_public_key_type() == "Unknown"); + + errorlib::error_code ec; + ASSERT_TRUE(fs::remove(fs::path(f1), ec)); + ASSERT_TRUE(fs::remove(fs::path(f2), ec)); + ASSERT_TRUE(fs::remove(fs::path(f3), ec)); +} + + +TEST(GnssCryptoTest, TestComputeSHA_256) +{ + auto d_crypto = std::make_unique(); + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world + + std::vector expected_output = { + 0x18, 0x94, 0xA1, 0x9C, 0x85, 0xBA, 0x15, 0x3A, 0xCB, 0xF7, + 0x43, 0xAC, 0x4E, 0x43, 0xFC, 0x00, 0x4C, 0x89, 0x16, 0x04, + 0xB2, 0x6F, 0x8C, 0x69, 0xE1, 0xE8, 0x3E, 0xA2, 0xAF, 0xC7, + 0xC4, 0x8F}; + + std::vector output = d_crypto->compute_SHA_256(message); + + ASSERT_EQ(expected_output, output); +} + + +TEST(GnssCryptoTest, TestComputeSHA3_256) +{ + auto d_crypto = std::make_unique(); + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world + + std::vector expected_output = { + 0xCC, 0xB8, 0xF9, 0x23, 0x5F, 0x4A, 0x93, 0x2C, 0xA0, 0xAB, + 0xBB, 0x2C, 0x24, 0x36, 0x72, 0x5E, 0x2E, 0x8D, 0xC7, 0x5B, + 0x99, 0xE7, 0xF6, 0xC4, 0x50, 0x5B, 0x2A, 0x93, 0x6E, 0xB6, + 0x3B, 0x3F}; + + std::vector output = d_crypto->compute_SHA3_256(message); + + ASSERT_EQ(expected_output, output); +} + + +// Unit test for computeHMAC_SHA_256 function. +TEST(GnssCryptoTest, TestComputeHMACSHA256) +{ + auto d_crypto = std::make_unique(); + + std::vector key = { + 0x24, 0x24, 0x3B, 0x76, 0xF9, 0x14, 0xB1, 0xA7, + 0x7D, 0x48, 0xE7, 0xF1, 0x48, 0x0C, 0xC2, 0x98, + 0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3, + 0xB4, 0xD4, 0xDB, 0x31, 0xEE, 0x96, 0xAB, 0xFA}; + + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world + + std::vector expected_output = { + 0xC3, 0x51, 0xF6, 0xFD, 0xDD, 0xC9, 0x8B, 0x41, + 0xD6, 0xF4, 0x77, 0x6D, 0xAC, 0xE8, 0xE0, 0x14, + 0xB2, 0x7A, 0xCC, 0x22, 0x00, 0xAA, 0xD2, 0x37, + 0xD0, 0x79, 0x06, 0x12, 0x83, 0x40, 0xB7, 0xA6}; + + std::vector output = d_crypto->compute_HMAC_SHA_256(key, message); + + ASSERT_EQ(expected_output, output); +} + + +TEST(GnssCryptoTest, TestComputeHMACSHA256_m0) +{ + // key and message generated from RG A.6.5.1 + auto d_crypto = std::make_unique(); + + // RG K4 @ 345690 + std::vector key = { + 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, + 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; + + // m0 + std::vector message = { + 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, + 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, + 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, + 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, + 0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, + 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, + 0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0, + 0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00, + 0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, + 0xF7, 0xFC, 0x00}; + + std::vector expected_output = { + 0xE3, 0x7B, 0xC4, 0xF8, 0x58, 0xAE, 0x1E, 0x5C, + 0xFD, 0xC4, 0x6F, 0x05, 0x4B, 0x1F, 0x47, 0xB9, + 0xD2, 0xEA, 0x61, 0xE1, 0xEF, 0x09, 0x11, 0x5C, + 0xFE, 0x70, 0x68, 0x52, 0xBF, 0xF2, 0x3A, 0x83}; + + std::vector output = d_crypto->compute_HMAC_SHA_256(key, message); + + ASSERT_EQ(expected_output, output); +} + + +TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) +{ + // key and message generated from RG A.6.5.2 + auto d_crypto = std::make_unique(); + + // RG K4 @ 345690 + std::vector key = { + 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, + 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; + + std::vector message = { + 0x02, 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x03, 0xBF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x44, 0x92, + 0x38, 0x22, 0x78, 0x97, 0xFD, 0xEF, 0xF9, 0x30, + 0x40}; + + std::vector expected_output = { + 0x7B, 0xB2, 0x38, 0xC8, 0x83, 0xC0, 0x6A, 0x2B, + 0x50, 0x8F, 0xE6, 0x3F, 0xB7, 0xF4, 0xF5, 0x4D, + 0x44, 0xAB, 0xEE, 0x4D, 0xCE, 0xB9, 0x3D, 0xCF, + 0x65, 0xCB, 0x3A, 0x5B, 0x81, 0x4A, 0x34, 0xE9}; + + std::vector output = d_crypto->compute_HMAC_SHA_256(key, message); + + ASSERT_EQ(expected_output, output); +} + + +TEST(GnssCryptoTest, TestComputeCMAC_AES) +{ + // Tests vectors from https://datatracker.ietf.org/doc/html/rfc4493#appendix-A + auto d_crypto = std::make_unique(); + + std::vector key = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; + + std::vector message{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A}; + + std::vector expected_output = { + 0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44, + 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C}; + + std::vector output = d_crypto->compute_CMAC_AES(key, message); + + ASSERT_EQ(expected_output, output); +} + + +TEST(GnssCryptoTest, VerifySignatureP256) +{ + auto d_crypto = std::make_unique(); + + // RG example - import crt certificate + std::vector message = { + 0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, + 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, + 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; + + // ECDSA P-256 signature, raw format + std::vector signature = { + 0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, + 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, + 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, + 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, + 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, + 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, + 0x28, 0xC1, 0x77, 0xFB}; + + // Input taken from RG 1.3 A7.1 + // compressed ECDSA P-256 format + std::vector publicKey = { + 0x03, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, + 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, + 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, + 0x79, 0x80, 0xEA}; + + d_crypto->set_public_key(publicKey); + ASSERT_TRUE(d_crypto->verify_signature_ecdsa_p256(message, signature)); + + std::vector wrong_signature = std::move(signature); + wrong_signature[1] = 1; + ASSERT_FALSE(d_crypto->verify_signature_ecdsa_p256(message, wrong_signature)); +} + + +TEST(GnssCryptoTest, VerifySignatureP521) +{ + std::unique_ptr d_crypto = std::make_unique(); + + // Message to be verified + std::vector message = { + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // "Hello world\n" + + // Public key in compressed X format + std::vector publicKey = { + 0x03, 0x00, 0x28, 0x35, 0xBB, 0xE9, 0x24, 0x59, 0x4E, 0xF0, + 0xE3, 0xA2, 0xDB, 0xC0, 0x49, 0x30, 0x60, 0x7C, 0x61, 0x90, + 0xE4, 0x03, 0xE0, 0xC7, 0xB8, 0xC2, 0x62, 0x37, 0xF7, 0x58, + 0x56, 0xBE, 0x63, 0x5C, 0x97, 0xF7, 0x53, 0x64, 0x7E, 0xE1, + 0x0C, 0x07, 0xD3, 0x97, 0x8D, 0x58, 0x46, 0xFD, 0x6E, 0x06, + 0x44, 0x01, 0xA7, 0xAA, 0xC4, 0x95, 0x13, 0x5D, 0xC9, 0x77, + 0x26, 0xE9, 0xF8, 0x72, 0x0C, 0xD3, 0x88}; + + // ECDSA P-521 signature, raw format + std::vector signature = { + 0x01, 0x5C, 0x23, 0xC0, 0xBE, 0xAD, 0x1E, 0x44, 0x60, 0xD4, + 0xE0, 0x81, 0x38, 0xF2, 0xBA, 0xF5, 0xB5, 0x37, 0x5A, 0x34, + 0xB5, 0xCA, 0x6B, 0xC8, 0x0F, 0xCD, 0x75, 0x1D, 0x5E, 0xC0, + 0x8A, 0xD3, 0xD7, 0x79, 0xA7, 0xC1, 0xB8, 0xA2, 0xC6, 0xEA, + 0x5A, 0x7D, 0x60, 0x66, 0x50, 0x97, 0x37, 0x6C, 0xF9, 0x0A, + 0xF6, 0x3D, 0x77, 0x9A, 0xE2, 0x19, 0xF7, 0xF9, 0xDD, 0x52, + 0xC4, 0x0F, 0x98, 0xAA, 0xA2, 0xA4, 0x01, 0xC9, 0x41, 0x0B, + 0xD0, 0x25, 0xDD, 0xC9, 0x7C, 0x3F, 0x70, 0x32, 0x23, 0xCF, + 0xFE, 0x37, 0x67, 0x3A, 0xBC, 0x0B, 0x76, 0x16, 0x82, 0x83, + 0x27, 0x3D, 0x1D, 0x19, 0x15, 0x78, 0x08, 0x2B, 0xD4, 0xA7, + 0xC2, 0x0F, 0x11, 0xF4, 0xDD, 0xE5, 0x5A, 0x5D, 0x04, 0x8D, + 0x6D, 0x5E, 0xC4, 0x1F, 0x54, 0x44, 0xA9, 0x13, 0x34, 0x71, + 0x0F, 0xF7, 0x57, 0x9A, 0x9F, 0x2E, 0xF4, 0x97, 0x7D, 0xAE, + 0x28, 0xEF}; + + d_crypto->set_public_key(publicKey); + ASSERT_TRUE(d_crypto->verify_signature_ecdsa_p521(message, signature)); + + std::vector wrong_signature = std::move(signature); + wrong_signature[1] = 1; + ASSERT_FALSE(d_crypto->verify_signature_ecdsa_p521(message, wrong_signature)); +} diff --git a/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc b/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc new file mode 100644 index 000000000..3031a399a --- /dev/null +++ b/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc @@ -0,0 +1,303 @@ +/*! + * \file osmna_msg_receiver_test.cc + * \brief Tests for the osnma_msg_receiver class. + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "Galileo_OSNMA.h" +#include "gnss_crypto.h" +#include "osnma_helper.h" +#include "osnma_msg_receiver.h" +#include +#include +#include +#include +#include +#include +#include + +#if USE_GLOG_AND_GFLAGS +#include // for LOG +#else +#include +#endif + +class OsnmaMsgReceiverTest : public ::testing::Test +{ +protected: + Osnma_Helper helper; + osnma_msg_receiver_sptr osnma; + OSNMA_msg osnma_msg{}; + std::array nma_position_filled; + uint32_t d_GST_SIS{}; + uint32_t TOW{}; + uint32_t WN{}; + std::tm GST_START_EPOCH = {0, 0, 0, 22, 8 - 1, 1999 - 1900, 0, 0, 0, 0, 0}; // months start with 0 and years since 1900 in std::tm + const uint32_t LEAP_SECONDS = 0; // tried with 13 + 5, which is the official count, but won't parse correctly + void set_time(std::tm& input); + + void SetUp() override + { + // std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; // conf. 1 + std::tm input_time = {0, 0, 0, 27, 7 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; // conf. 2 + set_time(input_time); + osnma = osnma_msg_receiver_make(CRTFILE_DEFAULT, MERKLEFILE_DEFAULT); + } +}; + + +TEST_F(OsnmaMsgReceiverTest, ComputeMerkleRoot) +{ + // input data taken from Receiver Guidelines v1.3, A.7 + // Arrange + std::vector computed_merkle_root; + std::vector expected_merkle_root = helper.convert_from_hex_string("A10C440F3AA62453526DB4AF76DF8D9410D35D8277397D7053C700D192702B0D"); + DSM_PKR_message dsm_pkr_message; + dsm_pkr_message.npkt = 0x01; + dsm_pkr_message.npktid = 0x2; + dsm_pkr_message.mid = 0x01; + std::vector base_leaf = helper.convert_from_hex_string("120303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); + + // ITN + std::vector vec = helper.convert_from_hex_string( + "7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" + "956380BAB0D2C939EC6208151040CCFFCF1FB7156178FD1255BA0AECAAA253F7" + "407B6C5DD4DF059FF8789474061301E1C34881DB7A367A913A3674300E21EAB1" + "24EF508389B7D446C3E2ECE8D459FBBD3239A794906F5B1F92469C640164FD87"); + std::copy(vec.begin(), vec.end(), dsm_pkr_message.itn.begin()); + dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); + + // Act + computed_merkle_root = osnma->compute_merkle_root(dsm_pkr_message, base_leaf); + + // Assert + ASSERT_EQ(computed_merkle_root, expected_merkle_root); +} + + +TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf) +{ + // input data taken from Receiver Guidelines v1.3, A.7 + // Arrange + std::vector expected_base_leaf = helper.convert_from_hex_string("120303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); + DSM_PKR_message dsm_pkr_message; + dsm_pkr_message.npkt = 0x01; + dsm_pkr_message.npktid = 0x2; + dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); + + // Act + std::vector computed_base_leaf = osnma->get_merkle_tree_leaves(dsm_pkr_message); + + // Assert + ASSERT_EQ(computed_base_leaf, expected_base_leaf); +} + + +TEST_F(OsnmaMsgReceiverTest, VerifyPublicKey) +{ + // Input data taken from Receiver Guidelines v1.3, A.7 + // Arrange + osnma->d_crypto->set_merkle_root(helper.convert_from_hex_string("A10C440F3AA62453526DB4AF76DF8D9410D35D8277397D7053C700D192702B0D")); + DSM_PKR_message dsm_pkr_message; + dsm_pkr_message.npkt = 0x01; + dsm_pkr_message.npktid = 0x2; + dsm_pkr_message.mid = 0x01; + std::vector vec = helper.convert_from_hex_string( + "7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" + "956380BAB0D2C939EC6208151040CCFFCF1FB7156178FD1255BA0AECAAA253F7" + "407B6C5DD4DF059FF8789474061301E1C34881DB7A367A913A3674300E21EAB1" + "24EF508389B7D446C3E2ECE8D459FBBD3239A794906F5B1F92469C640164FD87"); + std::copy(vec.begin(), vec.end(), dsm_pkr_message.itn.begin()); + dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); + + // Act + bool result = osnma->verify_dsm_pkr(dsm_pkr_message); // TODO - refactor method so that output is more than a boolean. + + // Assert + ASSERT_TRUE(result); +} + + +TEST_F(OsnmaMsgReceiverTest, BuildTagMessageM0) +{ + // input data taken from Receiver Guidelines v1.3, A.6.5.1 + // Arrange + std::vector expected_message = { + 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, + 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, + 0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, + 0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0, 0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00, + 0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, 0xF7, 0xFC, 0x00}; + + uint32_t TOW_Tag0 = 345660; + uint32_t TOW_NavData = TOW_Tag0 - 30; + uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30; + uint32_t WN = 1248; + uint32_t PRNa = 2; + uint8_t CTR = 1; + + osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDB, 0xBC, 0x73}; // K4 + osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; + osnma->d_nav_data_manager->add_navigation_data( + "000011101001011001000100000101000111010110100100100101100000000000" + "011101101011001111101110101010000001010000011011111100000011101011" + "011100101101011010101011011011001001110111101011110110111111001111" + "001000011111101110011000111111110111111010000011101011111111110000" + "110111000000100000001110110000110110001110000100001110101100010100" + "110100010001000110001110011010110000111010000010000000000001101000" + "000000000011100101100100010000000000000110110100110001111100000000" + "000000100110100000000101010010100000001011000010001001100000011111" + "110111111111000000000", + PRNa, TOW_NavData); + osnma->d_osnma_data.d_nma_header.nmas = 0b10; + + MACK_tag_and_info MTI; + MTI.tag = static_cast(0xE37BC4F858); + MTI.tag_info.PRN_d = 0x02; + MTI.tag_info.ADKD = 0x00; + MTI.tag_info.cop = 0x0F; + Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); + + // Act + auto computed_message = osnma->build_message(t0); + + // Assert + ASSERT_TRUE(computed_message == expected_message); +} + + +TEST_F(OsnmaMsgReceiverTest, TagVerification) +{ + // input data taken from Receiver Guidelines v1.3, A.6.5.1 + // Arrange + // Tag0 + uint32_t TOW_Tag0 = 345660; + uint32_t TOW_NavData = TOW_Tag0 - 30; + uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30; + uint32_t WN = 1248; + uint32_t PRNa = 2; + uint8_t CTR = 1; + + osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 + osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; + osnma->d_nav_data_manager->add_navigation_data( + "000011101001011001000100000101000111010110100100100101100000000000" + "011101101011001111101110101010000001010000011011111100000011101011" + "011100101101011010101011011011001001110111101011110110111111001111" + "001000011111101110011000111111110111111010000011101011111111110000" + "110111000000100000001110110000110110001110000100001110101100010100" + "110100010001000110001110011010110000111010000010000000000001101000" + "000000000011100101100100010000000000000110110100110001111100000000" + "000000100110100000000101010010100000001011000010001001100000011111" + "110111111111000000000", + PRNa, TOW_NavData); + osnma->d_osnma_data.d_nma_header.nmas = 0b10; + + MACK_tag_and_info MTI; + MTI.tag = static_cast(0xE37BC4F858); + MTI.tag_info.PRN_d = 0x02; + MTI.tag_info.ADKD = 0x00; + MTI.tag_info.cop = 0x0F; + Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); + + // Act + bool result_tag0 = osnma->verify_tag(t0); + + // Assert + + // Tag3 + uint32_t TOW_Key_Tag3 = TOW_Tag0 + 30; + WN = 1248; + PRNa = 2; + CTR = 3; + + osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + osnma->d_tesla_keys[TOW_Key_Tag3] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 + osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; + osnma->d_nav_data_manager->add_navigation_data( + "111111111111111111111111111111110000000000000000000000010001001001001000" + "111000001000100111100010010111111111011110111111111001001100000100000", + PRNa, TOW_NavData); + osnma->d_osnma_data.d_nma_header.nmas = 0b10; + + MTI.tag = static_cast(0x7BB238C883); + MTI.tag_info.PRN_d = 0x02; + MTI.tag_info.ADKD = 0x04; + MTI.tag_info.cop = 0x0F; + Tag t3(MTI, TOW_Tag0, WN, PRNa, CTR); + + bool result_tag3 = osnma->verify_tag(t3); + + ASSERT_TRUE(result_tag0 && result_tag3); +} + + +TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) +{ + // input data taken from Receiver Guidelines v1.3, A.5.2 + // Arrange + osnma->d_tesla_key_verified = false; + osnma->d_osnma_data.d_dsm_kroot_message.kroot = {0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; // Kroot, TOW 345570 GST_0 - 30 + osnma->d_osnma_data.d_dsm_kroot_message.ks = 4; // TABLE 10 --> 128 bits + osnma->d_osnma_data.d_dsm_kroot_message.alpha = 0x610BDF26D77B; + osnma->d_GST_SIS = (1248 & 0x00000FFF) << 20 | (345630 & 0x000FFFFF); + osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30) + osnma->d_GST_Sf = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G. + + osnma->d_tesla_keys.insert((std::pair>(345600, {0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference. + std::vector key = {0x2D, 0xC3, 0xA3, 0xCD, 0xB1, 0x17, 0xFA, 0xAD, 0xB8, 0x3B, 0x5F, 0x0B, 0x6F, 0xEA, 0x88, 0xEB}; // K2 + uint32_t TOW = 345630; + + // Act + bool result = osnma->verify_tesla_key(key, TOW); // TODO - refactor so that output is not a boolean. Or use last_verified_tesla_key? + + // Assert + ASSERT_TRUE(result); +} + + +/** + * @brief Sets the time based on the given input. + * + * This function calculates the week number (WN) and time of week (TOW) + * based on the input time and the GST_START_EPOCH. It then stores the + * calculated values in the WN and TOW member variables. Finally, it + * combines the WN and TOW into a single 32-bit value and stores it in + * the d_GST_SIS member variable. + * + * @param input The input time as a tm struct. + */ +void OsnmaMsgReceiverTest::set_time(std::tm& input) +{ + auto epoch_time_point = std::chrono::system_clock::from_time_t(mktime(&GST_START_EPOCH)); + auto input_time_point = std::chrono::system_clock::from_time_t(mktime(&input)); + + // Get the duration from epoch in seconds + auto duration_sec = std::chrono::duration_cast(input_time_point - epoch_time_point); + + // Calculate the week number (WN) and time of week (TOW) + uint32_t sec_in_week = 7 * 24 * 60 * 60; + uint32_t week_number = duration_sec.count() / sec_in_week; + uint32_t time_of_week = duration_sec.count() % sec_in_week; + this->WN = week_number; + this->TOW = time_of_week + LEAP_SECONDS; + // Return the week number and time of week as a pair + + // TODO: d_GST_SIS or d_receiver_time? doubt + // I am assuming that local realisation of receiver is identical to SIS GST time coming from W5 or W0 + this->d_GST_SIS = (this->WN & 0x00000FFF) << 20 | (this->TOW & 0x000FFFFF); +} diff --git a/tests/unit-tests/signal-processing-blocks/osnma/osnma_test_vectors.cc b/tests/unit-tests/signal-processing-blocks/osnma/osnma_test_vectors.cc new file mode 100644 index 000000000..7ac04d3c7 --- /dev/null +++ b/tests/unit-tests/signal-processing-blocks/osnma/osnma_test_vectors.cc @@ -0,0 +1,671 @@ +/*! + * \file osmna_test_vectors.cc + * \brief Tests for the osnma_msg_receiver class. + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "gnss_crypto.h" +#include "osnma_msg_receiver.h" +#include +#include +#include +#include +#include + +#if USE_GLOG_AND_GFLAGS +#include // for LOG +#else +#include +#endif + +struct TestVector +{ + int svId; + int numNavBits; + std::vector navBits; +}; + + +class OsnmaTestVectors : public ::testing::Test +{ +protected: + std::vector parseNavBits(const std::string& hex); + std::vector readTestVectorsFromFile(const std::string& filename); + std::string bytes_to_str(const std::vector& bytes); + std::vector extract_page_bytes(const TestVector& tv, int byte_index, int num_bytes); + bool feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_object, std::vector> testVectors, std::vector startTimesFiles); + void set_time(std::tm& input); + void SetUp() override + { + } + + uint32_t d_GST_SIS{}; + uint32_t TOW{}; + uint32_t WN{}; + std::tm GST_START_EPOCH = {0, 0, 0, 22, 8 - 1, 1999 - 1900, 0, 0, 0, 0, 0}; // months start with 0 and years since 1900 in std::tm + const uint32_t LEAP_SECONDS = 0; + const int SIZE_PAGE_BYTES{240 / 8}; // total bytes of a page + const int SIZE_SUBFRAME_PAGES{15}; // number of pages of a subframe + const int DURATION_SUBFRAME{30}; // duration of a subframe, in seconds// 13 + 5; + + bool d_flag_NPK{false}; // flag for NPK, new MT will be set when the new Kroot is received. +}; + +TEST_F(OsnmaTestVectors, NominalTestConf1) +{ + // Arrange + std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_1/PublicKey/OSNMA_PublicKey_20230803105952_newPKID_1.crt"; + std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_1/MerkleTree/OSNMA_MerkleTree_20230803105953_newPKID_1.xml"; + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); + + std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::vector input_times = {input_time}; + + std::vector testVector = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/configuration_1/16_AUG_2023_GST_05_00_01.csv"); + if (testVector.empty()) + { + ASSERT_TRUE(false); + } + std::vector> testVectors = {testVector}; + + // Act + bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times); + ASSERT_TRUE(result); + + // Assert + LOG(INFO) << "Successful tags count= " << osnma->d_count_successful_tags; + LOG(INFO) << "Failed tags count= " << osnma->d_count_failed_tags; + LOG(INFO) << "Unverified tags count= " << osnma->d_tags_awaiting_verify.size(); + LOG(INFO) << "Failed Kroot count= " << osnma->d_count_failed_Kroot; + LOG(INFO) << "Failed PK count= " << osnma->d_count_failed_pubKey; + LOG(INFO) << "Failed MACSEQ count= " << osnma->d_count_failed_macseq; + ASSERT_EQ(osnma->d_count_failed_tags, 0); + ASSERT_EQ(osnma->d_count_failed_Kroot, 0); + ASSERT_EQ(osnma->d_count_failed_pubKey, 0); + ASSERT_EQ(osnma->d_count_failed_macseq, 0); +} + +TEST_F(OsnmaTestVectors, NominalTestConf2) +{ + // Arrange + std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20230720113300_newPKID_2.crt"; // conf. 2 + std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20230720113300_newPKID_2.xml"; + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); + + std::tm input_time = {0, 0, 0, 27, 7 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; // conf. 2 + std::vector input_times = {input_time}; + + std::vector testVector = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/configuration_2/27_JUL_2023_GST_00_00_01.csv"); + if (testVector.empty()) + { + ASSERT_TRUE(false); + } + std::vector> testVectors = {testVector}; + + // Act + bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times); + ASSERT_TRUE(result); + + // Assert + LOG(INFO) << "Successful tags count= " << osnma->d_count_successful_tags; + LOG(INFO) << "Failed tags count= " << osnma->d_count_failed_tags; + LOG(INFO) << "Unverified tags count= " << osnma->d_tags_awaiting_verify.size(); + LOG(INFO) << "Failed Kroot count= " << osnma->d_count_failed_Kroot; + LOG(INFO) << "Failed PK count= " << osnma->d_count_failed_pubKey; + LOG(INFO) << "Failed MACSEQ count= " << osnma->d_count_failed_macseq; + ASSERT_EQ(osnma->d_count_failed_tags, 0); + ASSERT_EQ(osnma->d_count_failed_Kroot, 0); + ASSERT_EQ(osnma->d_count_failed_pubKey, 0); + ASSERT_EQ(osnma->d_count_failed_macseq, 0); +} + +TEST_F(OsnmaTestVectors, PublicKeyRenewal) +{ + // Arrange + std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20231007041500_PKID_7.crt"; + std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007041500_PKID_7.xml"; + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); + + std::tm input_time_step1 = {0, 45, 2, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step2 = {0, 45, 3, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step3 = {0, 45, 4, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::vector input_times = {input_time_step1, input_time_step2, input_time_step3}; + + std::vector testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/npk_step1/07_OCT_2023_GST_02_45_01.csv"); + std::vector testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/npk_step2/07_OCT_2023_GST_03_45_01.csv"); + std::vector testVectors_step3 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/npk_step3/07_OCT_2023_GST_04_45_01.csv"); + if (testVectors_step1.empty() || testVectors_step2.empty() || testVectors_step3.empty()) + { + ASSERT_TRUE(false); + } + std::vector> testVectors = {testVectors_step1, testVectors_step2, testVectors_step3}; + + // Act + d_flag_NPK = true; + bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times); + ASSERT_TRUE(result); + + // Assert + LOG(INFO) << "Successful tags count= " << osnma->d_count_successful_tags; + LOG(INFO) << "Failed tags count= " << osnma->d_count_failed_tags; + LOG(INFO) << "Unverified tags count= " << osnma->d_tags_awaiting_verify.size(); + LOG(INFO) << "Failed Kroot count= " << osnma->d_count_failed_Kroot; + LOG(INFO) << "Failed PK count= " << osnma->d_count_failed_pubKey; + LOG(INFO) << "Failed MACSEQ count= " << osnma->d_count_failed_macseq; + ASSERT_EQ(osnma->d_count_failed_tags, 0); + ASSERT_EQ(osnma->d_count_failed_Kroot, 0); + ASSERT_EQ(osnma->d_count_failed_pubKey, 0); + ASSERT_EQ(osnma->d_count_failed_macseq, 0); +} + +TEST_F(OsnmaTestVectors, PublicKeyRevocation) +{ + // Arrange + std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20231007081500_PKID_8.crt"; + std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007081500_PKID_8.xml"; + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); + + std::tm input_time_step1 = {0, 45, 7, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step2 = {0, 30, 9, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step3 = {0, 30, 10, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::vector input_times = {input_time_step1, input_time_step2, input_time_step3}; + + std::vector testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/pkrev_step1/07_OCT_2023_GST_07_45_01.csv"); + std::vector testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/pkrev_step2/07_OCT_2023_GST_09_30_01.csv"); + std::vector testVectors_step3 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/pkrev_step3/07_OCT_2023_GST_10_30_01.csv"); + if (testVectors_step1.empty() || testVectors_step2.empty() || testVectors_step3.empty()) + { + ASSERT_TRUE(false); + } + std::vector> testVectors = {testVectors_step1, testVectors_step2, testVectors_step3}; + + // Act + bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times); + ASSERT_TRUE(result); + + // Assert + LOG(INFO) << "Successful tags count= " << osnma->d_count_successful_tags; + LOG(INFO) << "Failed tags count= " << osnma->d_count_failed_tags; + LOG(INFO) << "Unverified tags count= " << osnma->d_tags_awaiting_verify.size(); + LOG(INFO) << "Failed Kroot count= " << osnma->d_count_failed_Kroot; + LOG(INFO) << "Failed PK count= " << osnma->d_count_failed_pubKey; + LOG(INFO) << "Failed MACSEQ count= " << osnma->d_count_failed_macseq; + ASSERT_EQ(osnma->d_count_failed_tags, 0); + ASSERT_EQ(osnma->d_count_failed_Kroot, 0); + ASSERT_EQ(osnma->d_count_failed_pubKey, 0); + ASSERT_EQ(osnma->d_count_failed_macseq, 0); +} + +TEST_F(OsnmaTestVectors, ChainRenewal) +{ + // Arrange + std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20231007041500_PKID_7.crt"; + std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007041500_PKID_7.xml"; + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); + + std::tm input_time_step1 = {0, 45, 16, 6, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step2 = {0, 30, 18, 6, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::vector input_times = {input_time_step1, input_time_step2}; + + std::vector testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/eoc_step1/06_OCT_2023_GST_16_45_01.csv"); + std::vector testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/eoc_step2/06_OCT_2023_GST_18_30_01.csv"); + if (testVectors_step1.empty() || testVectors_step2.empty()) + { + ASSERT_TRUE(false); + } + std::vector> testVectors = {testVectors_step1, testVectors_step2}; + + // Act + bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times); + ASSERT_TRUE(result); + + // Assert + LOG(INFO) << "Successful tags count= " << osnma->d_count_successful_tags; + LOG(INFO) << "Failed tags count= " << osnma->d_count_failed_tags; + LOG(INFO) << "Unverified tags count= " << osnma->d_tags_awaiting_verify.size(); + LOG(INFO) << "Failed Kroot count= " << osnma->d_count_failed_Kroot; + LOG(INFO) << "Failed PK count= " << osnma->d_count_failed_pubKey; + LOG(INFO) << "Failed MACSEQ count= " << osnma->d_count_failed_macseq; + ASSERT_EQ(osnma->d_count_failed_tags, 0); + ASSERT_EQ(osnma->d_count_failed_Kroot, 0); + ASSERT_EQ(osnma->d_count_failed_pubKey, 0); + ASSERT_EQ(osnma->d_count_failed_macseq, 0); +} + +TEST_F(OsnmaTestVectors, ChainRevocation) +{ + // Arrange + std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20231007041500_PKID_7.crt"; + std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007041500_PKID_7.xml"; + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); + + std::tm input_time_step1 = {0, 45, 21, 6, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step2 = {0, 30, 23, 6, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step3 = {0, 30, 00, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + + std::vector input_times = {input_time_step1, input_time_step2, input_time_step3}; + + std::vector testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/crev_step1/06_OCT_2023_GST_21_45_01.csv"); + std::vector testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/crev_step2/06_OCT_2023_GST_23_30_01.csv"); + std::vector testVectors_step3 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/crev_step3/07_OCT_2023_GST_00_30_01.csv"); + if (testVectors_step1.empty() || testVectors_step2.empty() || testVectors_step3.empty()) + { + ASSERT_TRUE(false); + } + std::vector> testVectors = {testVectors_step1, testVectors_step2, testVectors_step3}; + + // Act + bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times); + ASSERT_TRUE(result); + + // Assert + LOG(INFO) << "Successful tags count= " << osnma->d_count_successful_tags; + LOG(INFO) << "Failed tags count= " << osnma->d_count_failed_tags; + LOG(INFO) << "Unverified tags count= " << osnma->d_tags_awaiting_verify.size(); + LOG(INFO) << "Failed Kroot count= " << osnma->d_count_failed_Kroot; + LOG(INFO) << "Failed PK count= " << osnma->d_count_failed_pubKey; + LOG(INFO) << "Failed MACSEQ count= " << osnma->d_count_failed_macseq; + ASSERT_EQ(osnma->d_count_failed_tags, 0); + ASSERT_EQ(osnma->d_count_failed_Kroot, 0); + ASSERT_EQ(osnma->d_count_failed_pubKey, 0); + ASSERT_EQ(osnma->d_count_failed_macseq, 0); +} + +TEST_F(OsnmaTestVectors, AlertMessage) +{ + // Arrange + std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_3/PublicKey/OSNMA_PublicKey_20231007201500_PKID_1.crt"; + std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_3/MerkleTree/OSNMA_MerkleTree_20231007201500_PKID_1.xml"; + osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); + + std::tm input_time_step1 = {0, 45, 18, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::tm input_time_step2 = {0, 45, 19, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; + std::vector input_times = {input_time_step1, input_time_step2}; + + std::vector testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/oam_step1/07_OCT_2023_GST_18_45_01.csv"); + std::vector testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/oam_step2/07_OCT_2023_GST_19_45_01.csv"); + if (testVectors_step1.empty() || testVectors_step2.empty()) + { + ASSERT_TRUE(false); + } + std::vector> testVectors = {testVectors_step1, testVectors_step2}; + + // Act + bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times); + ASSERT_TRUE(result); + + // Assert + LOG(INFO) << "Successful tags count= " << osnma->d_count_successful_tags; + LOG(INFO) << "Failed tags count= " << osnma->d_count_failed_tags; + LOG(INFO) << "Unverified tags count= " << osnma->d_tags_awaiting_verify.size(); + LOG(INFO) << "Failed Kroot count= " << osnma->d_count_failed_Kroot; + LOG(INFO) << "Failed PK count= " << osnma->d_count_failed_pubKey; + LOG(INFO) << "Failed MACSEQ count= " << osnma->d_count_failed_macseq; + ASSERT_EQ(osnma->d_count_failed_tags, 0); + ASSERT_EQ(osnma->d_count_failed_Kroot, 0); + ASSERT_EQ(osnma->d_count_failed_pubKey, 0); + ASSERT_EQ(osnma->d_count_failed_macseq, 0); +} + +// Auxiliary functions for the OsnmaTestVectorsSimulation test fixture. +// Essentially, they perform same work as the telemetry decoder block, but adapted to the osnma-test-vector files. +bool OsnmaTestVectors::feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_object, std::vector> testVectors, std::vector startTimesFiles) +{ + bool end_of_hex_stream; + int offset_byte{0}; + int byte_index{0}; // index containing the last byte position of the hex stream that was retrieved. Takes advantage that all TVs have same size + + const int DUMMY_PAGE{63}; + bool flag_dummy_page{false}; + // Act + // loop over all bytes of data. Note: all TestVectors have same amount of data. + // if needed, add global flags so that particular logic may be done at certain points in between files + for (size_t test_step = 0; test_step < testVectors.size(); test_step++) + { + // set variables for each file + end_of_hex_stream = false; + offset_byte = 0; + byte_index = 0; + set_time(startTimesFiles[test_step]); + std::cout << "OsnmaTestVectorsSimulation:" + << " d_GST_SIS= " << d_GST_SIS + << ", TOW=" << TOW + << ", WN=" << WN << std::endl; + + if (test_step == 1 && d_flag_NPK == true) + { + // step 2: this simulates the osnma connecting to the GSC server and downloading the Merkle tree of the next public key + osnma_object->read_merkle_xml( + std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007081500_PKID_8.xml"); + } + + while (!end_of_hex_stream) + { + // loop over all SVs, extract a subframe + for (const TestVector& tv : testVectors[test_step]) + { // loop over all SVs, extract a subframe + std::cout << "OsnmaTestVectorsSimulation: SVID (PRN_a) " << tv.svId << std::endl; + auto osnmaMsg_sptr = std::make_shared(); + std::array hkroot{}; + std::array mack{}; + byte_index = offset_byte; // reset byte_index to the offset position for the next test vector. Offset is updated at the end of each Subframe (every 30 s or 450 Bytes) + std::map> words_for_OSNMA; // structure containing and + + for (int idx = 0; idx < SIZE_SUBFRAME_PAGES; ++idx) // extract all pages of a subframe + { + // extract bytes of complete page (odd+even) -- extract SIZE_PAGE from tv.navBits, starting from byte_index + std::vector page_bytes = extract_page_bytes(tv, byte_index, SIZE_PAGE_BYTES); + if (page_bytes.empty()) + { + std::cout << "OsnmaTestVectorsSimulation: end of TestVectors \n" + << "byte_index=" << byte_index << " expected= " << 432000 / 8 << std::endl; + end_of_hex_stream = true; + break; + } + // convert them to bitset representation using bytes_to_string + std::string page_bits = bytes_to_str(page_bytes); + // Extract the 40 OSNMA bits starting from the 18th bit + std::string even_page = page_bits.substr(0, page_bits.size() / 2); + std::string odd_page = page_bits.substr(page_bits.size() / 2); + if (even_page.size() < 120 || odd_page.size() < 120) + { + std::cout << "OsnmaTestVectorsSimulation: error parsing pages" << std::endl; + } + bool even_odd_OK = even_page[0] == '0' && odd_page[0] == '1'; + bool page_type_OK = even_page[1] == '0' && odd_page[1] == '0'; + bool tail_bits_OK = even_page.substr(even_page.size() - 6) == "000000" && odd_page.substr(odd_page.size() - 6) == "000000"; + if (!even_odd_OK || !page_type_OK || !tail_bits_OK) + std::cerr << "OsnmaTestVectorsSimulation: error parsing pages." << std::endl; + + std::bitset<112> data_k(even_page.substr(2, 112)); + std::bitset<16> data_j(odd_page.substr(2, 16)); + std::bitset<112> shifted_data_k = data_k; + uint8_t word_type = static_cast((shifted_data_k >>= 106).to_ulong()); // word type is the first 6 bits of the word + // std::cout << "OsnmaTestVectorsSimulation: received Word " << static_cast(word_type) << std::endl; + if ((word_type >= 1 && word_type <= 5) || word_type == 6 || word_type == 10) + { + // store raw word + std::bitset<128> data_combined(data_k.to_string() + data_j.to_string()); + words_for_OSNMA[word_type] = data_combined; + } + if (word_type == DUMMY_PAGE) + flag_dummy_page = true; + + // place it into osnma object. + std::bitset<40> osnmaBits(odd_page.substr(18, 40)); + + // Extract bits for hkroot and mack + std::bitset<8> hkrootBits(osnmaBits.to_string().substr(0, 8)); + std::bitset<32> mackBits(osnmaBits.to_string().substr(8, 32)); + hkroot[idx] = static_cast(hkrootBits.to_ulong()); + mack[idx] = static_cast(mackBits.to_ulong()); + + byte_index += SIZE_PAGE_BYTES; + } + + // std::cout << "----------" << std::endl; + if (end_of_hex_stream) + break; + if (flag_dummy_page) + { + flag_dummy_page = false; + continue; // skip this SV + } + + // Fill osnma object + osnmaMsg_sptr->hkroot = hkroot; + osnmaMsg_sptr->mack = mack; + + osnmaMsg_sptr->TOW_sf0 = d_GST_SIS & 0x000FFFFF; + osnmaMsg_sptr->WN_sf0 = (d_GST_SIS & 0xFFF00000) >> 20; + osnmaMsg_sptr->PRN = tv.svId; // PRNa + + // TODO - refactor this logic, currently it is split + // check if words_for_OSNMA 1--> 5 words_for_OSNMA are received => fill EphClockStatus data vector + bool ephClockStatusWordsReceived = true; + for (int i = 1; i <= 5; ++i) + { + if (words_for_OSNMA.find(i) == words_for_OSNMA.end()) + { + ephClockStatusWordsReceived = false; + std::cerr << "OsnmaTestVectorsSimulation: error parsing words_for_OSNMA 1->5. " + "Word " + << i << " should be received for each subframe but was not." << std::endl; + } + } + // extract bits as needed by osnma block + if (ephClockStatusWordsReceived) + { + // Define the starting position and length of bits to extract for each word + std::map> extractionParams = { + {1, {6, 120}}, + {2, {6, 120}}, + {3, {6, 122}}, + {4, {6, 120}}, + {5, {6, 67}}, + }; + + // Fill NavData bits -- Iterate over the extraction parameters + std::string nav_data_ADKD_0_12 = ""; + for (const auto& param : extractionParams) + { + uint8_t wordKey = param.first; + uint8_t start = param.second.first; + uint8_t length = param.second.second; + + // Extract the required bits and fill osnma block + nav_data_ADKD_0_12 += words_for_OSNMA[wordKey].to_string().substr(start, length); + } + // send to osnma block + bool check_size_is_ok = nav_data_ADKD_0_12.size() == 549; + if (check_size_is_ok) + { + std::cout << "Galileo OSNMA: sending ADKD=0/12 navData, PRN_d (" << tv.svId << ") " + << "TOW_sf=" << osnmaMsg_sptr->TOW_sf0 << std::endl; + const auto tmp_obj_osnma = std::make_shared>( // < PRNd , navDataBits, TOW_Sosf> + tv.svId, + nav_data_ADKD_0_12, + osnmaMsg_sptr->TOW_sf0); + // LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast(tv.svId) << ", TOW=" << static_cast(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_0_12; + osnma_object->msg_handler_osnma(pmt::make_any(tmp_obj_osnma)); + } + } + + // check w6 && w10 is received => fill TimingData data vector + bool timingWordsReceived = words_for_OSNMA.find(6) != words_for_OSNMA.end() && + words_for_OSNMA.find(10) != words_for_OSNMA.end(); + // extract bits as needed by osnma block + if (timingWordsReceived) + { + // Define the starting position and length of bits to extract for each word + std::map> extractionParams = { + {6, {6, 99}}, + {10, {86, 42}}}; + + std::string nav_data_ADKD_4 = ""; + // Fill NavData bits -- Iterate over the extraction parameters + for (const auto& param : extractionParams) + { + uint8_t wordKey = param.first; + uint8_t start = param.second.first; + uint8_t length = param.second.second; + + // Extract the required bits and fill osnma block + nav_data_ADKD_4 += words_for_OSNMA[wordKey].to_string().substr(start, length); + } + // send to osnma block + bool check_size_is_ok = nav_data_ADKD_4.size() == 141; + if (check_size_is_ok) + { + std::cout << "Galileo OSNMA: sending ADKD=04 navData, PRN_d (" << tv.svId << ") " + << "TOW_sf=" << osnmaMsg_sptr->TOW_sf0 << std::endl; + const auto tmp_obj_osnma = std::make_shared>( // < PRNd , navDataBits, TOW_Sosf> + tv.svId, + nav_data_ADKD_4, + osnmaMsg_sptr->TOW_sf0); + // LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast(tv.svId) << ", TOW=" << static_cast(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_4; + osnma_object->msg_handler_osnma(pmt::make_any(tmp_obj_osnma)); + } + } + + // Call the handler, as if it came from telemetry decoder block + auto temp_obj = pmt::make_any(osnmaMsg_sptr); + + osnma_object->msg_handler_osnma(temp_obj); // osnma entry point + } + if (!end_of_hex_stream) + { + offset_byte = byte_index; // update offset for the next subframe + d_GST_SIS += DURATION_SUBFRAME; + TOW = d_GST_SIS & 0x000FFFFF; + WN = (d_GST_SIS & 0xFFF00000) >> 20; + std::cout << "OsnmaTestVectorsSimulation:" + << " d_GST_SIS= " << d_GST_SIS + << ", TOW=" << TOW + << ", WN=" << WN << std::endl; + } + } + if (end_of_hex_stream) + continue; + } + return true; +} + +std::vector OsnmaTestVectors::readTestVectorsFromFile(const std::string& filename) +{ + std::ifstream file(filename); + std::vector testVectors; + if (!file.is_open()) + { + std::cerr << "Error reading the file \"" << filename << "\" \n"; + return testVectors; + } + + std::string line; + std::getline(file, line); + if (line != "SVID,NumNavBits,NavBitsHEX\r") + { + std::cerr << "Error parsing first line" + << "\n"; + } + + while (std::getline(file, line)) + { + std::stringstream ss(line); + TestVector tv; + + std::string val; + + std::getline(ss, val, ','); + tv.svId = std::stoi(val); + + std::getline(ss, val, ','); + tv.numNavBits = std::stoi(val); + + std::getline(ss, val, ','); + tv.navBits = OsnmaTestVectors::parseNavBits(val); + + testVectors.push_back(tv); + } + + return testVectors; +} + +std::vector OsnmaTestVectors::parseNavBits(const std::string& hexadecimal) +{ + std::vector bytes; + + for (unsigned int i = 0; i < hexadecimal.length() - 1; i += 2) + { + std::string byteString = hexadecimal.substr(i, 2); + uint8_t byte = static_cast(strtol(byteString.c_str(), nullptr, 16)); + bytes.push_back(byte); + } + return bytes; +} + +std::string OsnmaTestVectors::bytes_to_str(const std::vector& bytes) +{ + std::string bit_string; + bit_string.reserve(bytes.size() * 8); + for (const auto& byte : bytes) + { + std::bitset<8> bits(byte); + bit_string += bits.to_string(); + } + return bit_string; +} + +/** + * @brief Extracts a range of bytes from a TestVector's navBits vector. + * + * This function extracts a extracts the bytes of complete page (odd+even) + * from the navBits vector of a TestVector object. + * + * + * @param tv The TestVector object from which to extract bytes. + * @param byte_index The index of the first byte to extract. + * @param num_bytes The number of bytes to extract. + * @return A vector containing the extracted bytes, or an empty vector if extraction is not possible. + */ +std::vector OsnmaTestVectors::extract_page_bytes(const TestVector& tv, int byte_index, int num_bytes) +{ + // Ensure we don't go beyond the end of tv.navBits + int num_bytes_to_extract = std::min(num_bytes, static_cast(tv.navBits.size() - byte_index)); + + // If byte_index is beyond the end of tv.navBits, return an empty vector + if (num_bytes_to_extract <= 0) + { + return std::vector(); + } + + // Use std::next to get an iterator to the range to extract + std::vector extracted_bytes(tv.navBits.begin() + byte_index, tv.navBits.begin() + byte_index + num_bytes_to_extract); + + return extracted_bytes; +} + +/** + * @brief Sets the time based on the given input. + * + * This function calculates the week number (WN) and time of week (TOW) + * based on the input time and the GST_START_EPOCH. It then stores the + * calculated values in the WN and TOW member variables. Finally, it + * combines the WN and TOW into a single 32-bit value and stores it in + * the d_GST_SIS member variable. + * \post WN, TOW and GST_SIS are set up based on the input time. + * + * @param input The input time as a tm struct. + */ +void OsnmaTestVectors::set_time(std::tm& input) +{ + auto epoch_time_point = std::chrono::system_clock::from_time_t(mktime(&GST_START_EPOCH)); + auto input_time_point = std::chrono::system_clock::from_time_t(mktime(&input)); + + // Get the duration from epoch in seconds + auto duration_sec = std::chrono::duration_cast(input_time_point - epoch_time_point); + + // Calculate the week number (WN) and time of week (TOW) + uint32_t sec_in_week = 7 * 24 * 60 * 60; + uint32_t week_number = duration_sec.count() / sec_in_week; + uint32_t time_of_week = duration_sec.count() % sec_in_week; + this->WN = week_number; + this->TOW = time_of_week + LEAP_SECONDS; + // Return the week number and time of week as a pair + + // TODO: d_GST_SIS or d_receiver_time? doubt + // I am assuming that local realisation of receiver is identical to SIS GST time coming from W5 or W0 + this->d_GST_SIS = (this->WN & 0x00000FFF) << 20 | (this->TOW & 0x000FFFFF); +} diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/geohash_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/geohash_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/pvt/geohash_test.cc rename to tests/unit-tests/signal-processing-blocks/pvt/geohash_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc rename to tests/unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc rename to tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc rename to tests/unit-tests/signal-processing-blocks/pvt/rtcm_printer_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc rename to tests/unit-tests/signal-processing-blocks/pvt/rtcm_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc rename to tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc index fe2aa27af..cebd4615c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc +++ b/tests/unit-tests/signal-processing-blocks/pvt/rtklib_solver_test.cc @@ -398,8 +398,8 @@ TEST(RTKLibSolverTest, test1) { std::map::const_iterator gps_eph_iter; for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.cbegin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); - gps_eph_iter++) + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.cend(); + gps_eph_iter++) { std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << '\n'; std::shared_ptr tmp_obj = std::make_shared(gps_eph_iter->second); diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc b/tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc rename to tests/unit-tests/signal-processing-blocks/pvt/serdes_monitor_pvt_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc b/tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc rename to tests/unit-tests/signal-processing-blocks/resampler/direct_resampler_conditioner_cc_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc b/tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc rename to tests/unit-tests/signal-processing-blocks/resampler/mmse_resampler_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc b/tests/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc rename to tests/unit-tests/signal-processing-blocks/sources/file_signal_source_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc b/tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc rename to tests/unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc b/tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc rename to tests/unit-tests/signal-processing-blocks/sources/unpack_2bit_samples_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc b/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc rename to tests/unit-tests/signal-processing-blocks/telemetry_decoder/galileo_fnav_inav_decoder_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc b/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc similarity index 91% rename from src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc rename to tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc index 3155a3ab8..16bb39763 100644 --- a/src/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc +++ b/tests/unit-tests/signal-processing-blocks/telemetry_decoder/gps_l1_ca_telemetry_decoder_test.cc @@ -60,7 +60,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TRACKING MESSAGES ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER FOR TRACKING MESSAGES ######### class GpsL1CADllPllTelemetryDecoderTest_msg_rx; using GpsL1CADllPllTelemetryDecoderTest_msg_rx_sptr = gnss_shared_ptr; @@ -120,7 +120,7 @@ GpsL1CADllPllTelemetryDecoderTest_msg_rx::~GpsL1CADllPllTelemetryDecoderTest_msg // ########################################################### -// ######## GNURADIO BLOCK MESSAGE RECEVER FOR TLM MESSAGES ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER FOR TLM MESSAGES ######### class GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx; using GpsL1CADllPllTelemetryDecoderTest_tlm_msg_rx_sptr = std::shared_ptr; @@ -186,11 +186,15 @@ public: std::string p4; std::string p5; +#if USE_GLOG_AND_GFLAGS const int baseband_sampling_freq = FLAGS_fs_gen_sps; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; - +#else + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif int configure_generator(); int generate_signal(); void check_results(arma::vec& true_time_s, @@ -218,6 +222,7 @@ public: int GpsL1CATelemetryDecoderTest::configure_generator() { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -233,6 +238,24 @@ int GpsL1CATelemetryDecoderTest::configure_generator() p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#endif + return 0; } @@ -268,8 +291,11 @@ void GpsL1CATelemetryDecoderTest::configure_receiver() gnss_synchro.System = 'G'; std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); +#if USE_GLOG_AND_GFLAGS gnss_synchro.PRN = FLAGS_test_satellite_PRN; - +#else + gnss_synchro.PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); // Set Tracking @@ -340,7 +366,11 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) configure_generator(); // Generate signal raw signal samples and observations RINEX file +#if USE_GLOG_AND_GFLAGS if (FLAGS_disable_generator == false) +#else + if (absl::GetFlag(FLAGS_disable_generator) == false) +#endif { generate_signal(); } @@ -352,7 +382,11 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) // open true observables log file written by the simulator Tracking_True_Obs_Reader true_obs_data; +#if USE_GLOG_AND_GFLAGS int test_satellite_PRN = FLAGS_test_satellite_PRN; +#else + int test_satellite_PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif std::cout << "Testing satellite PRN=" << test_satellite_PRN << '\n'; std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/bayesian_estimation_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc similarity index 90% rename from src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc index 34c4894d7..620729691 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_real_codes_test.cc @@ -18,18 +18,25 @@ #include "GPS_L1_CA.h" #include "cpu_multicorrelator_real_codes.h" #include "gps_sdr_signal_replica.h" -#include #include #include #include #include #include +#include #include #include - +#if USE_GLOG_AND_GFLAGS +#include DEFINE_int32(cpu_multicorrelator_real_codes_iterations_test, 100, "Number of averaged iterations in CPU multicorrelator test timing test"); DEFINE_int32(cpu_multicorrelator_real_codes_max_threads_test, 12, "Number of maximum concurrent correlators in CPU multicorrelator test timing test"); +#else +#include +ABSL_FLAG(int32_t, cpu_multicorrelator_real_codes_iterations_test, 100, "Number of averaged iterations in CPU multicorrelator test timing test"); +ABSL_FLAG(int32_t, cpu_multicorrelator_real_codes_max_threads_test, 12, "Number of maximum concurrent correlators in CPU multicorrelator test timing test"); +#endif + void run_correlator_cpu_real_codes(Cpu_Multicorrelator_Real_Codes* correlator, float d_rem_carrier_phase_rad, @@ -39,7 +46,11 @@ void run_correlator_cpu_real_codes(Cpu_Multicorrelator_Real_Codes* correlator, float d_rem_code_phase_chips, int correlation_size) { +#if USE_GLOG_AND_GFLAGS for (int k = 0; k < FLAGS_cpu_multicorrelator_real_codes_iterations_test; k++) +#else + for (int k = 0; k < absl::GetFlag(FLAGS_cpu_multicorrelator_real_codes_iterations_test); k++) +#endif { correlator->Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad, d_carrier_phase_step_rad, @@ -56,7 +67,11 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTime) std::chrono::time_point start; std::chrono::time_point end; std::chrono::duration elapsed_seconds(0); +#if USE_GLOG_AND_GFLAGS int max_threads = FLAGS_cpu_multicorrelator_real_codes_max_threads_test; +#else + int max_threads = absl::GetFlag(FLAGS_cpu_multicorrelator_real_codes_max_threads_test); +#endif std::vector thread_pool; std::vector correlator_pool(max_threads); unsigned int correlation_sizes[3] = {2048, 4096, 8192}; @@ -94,7 +109,7 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTime) // local code resampler on GPU // generate local reference (1 sample per chip) gps_l1_ca_code_gen_float(own::span(d_ca_code, static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(float)), 1, 0); - // generate inut signal + // generate input signal std::random_device r; std::default_random_engine e1(r()); std::uniform_real_distribution uniform_dist(0, 1); @@ -143,7 +158,11 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTime) thread_pool.clear(); end = std::chrono::system_clock::now(); elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(FLAGS_cpu_multicorrelator_real_codes_iterations_test); +#else + execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_cpu_multicorrelator_real_codes_iterations_test)); +#endif std::cout << "CPU Multicorrelator (real codes) execution time for length=" << correlation_sizes[correlation_sizes_idx] << " : " << execution_times[correlation_sizes_idx] << " [s]\n"; } @@ -166,7 +185,11 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTimeAlloc) std::chrono::time_point start; std::chrono::time_point end; std::chrono::duration elapsed_seconds(0); +#if USE_GLOG_AND_GFLAGS int max_threads = FLAGS_cpu_multicorrelator_real_codes_max_threads_test; +#else + int max_threads = absl::GetFlag(FLAGS_cpu_multicorrelator_real_codes_max_threads_test); +#endif std::vector thread_pool; std::vector correlator_pool(max_threads); unsigned int correlation_sizes[3] = {2048, 4096, 8192}; @@ -192,7 +215,7 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTimeAlloc) // local code resampler on GPU // generate local reference (1 sample per chip) gps_l1_ca_code_gen_float(d_ca_code, 1, 0); - // generate inut signal + // generate input signal std::random_device r; std::default_random_engine e1(r()); std::uniform_real_distribution uniform_dist(0, 1); @@ -241,7 +264,11 @@ TEST(CpuMulticorrelatorRealCodesTest, MeasureExecutionTimeAlloc) thread_pool.clear(); end = std::chrono::system_clock::now(); elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(FLAGS_cpu_multicorrelator_real_codes_iterations_test); +#else + execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_cpu_multicorrelator_real_codes_iterations_test)); +#endif std::cout << "CPU Multicorrelator (real codes) execution time for length=" << correlation_sizes[correlation_sizes_idx] << " : " << execution_times[correlation_sizes_idx] << " [s]\n"; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc similarity index 90% rename from src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc index 339205f43..19c9cb23d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/cpu_multicorrelator_test.cc @@ -18,7 +18,6 @@ #include "GPS_L1_CA.h" #include "cpu_multicorrelator.h" #include "gps_sdr_signal_replica.h" -#include #include #include #include @@ -27,9 +26,13 @@ #include #include - +#if USE_GLOG_AND_GFLAGS DEFINE_int32(cpu_multicorrelator_iterations_test, 100, "Number of averaged iterations in CPU multicorrelator test timing test"); DEFINE_int32(cpu_multicorrelator_max_threads_test, 12, "Number of maximum concurrent correlators in CPU multicorrelator test timing test"); +#else +ABSL_FLAG(int32_t, cpu_multicorrelator_iterations_test, 100, "Number of averaged iterations in CPU multicorrelator test timing test"); +ABSL_FLAG(int32_t, cpu_multicorrelator_max_threads_test, 12, "Number of maximum concurrent correlators in CPU multicorrelator test timing test"); +#endif void run_correlator_cpu(Cpu_Multicorrelator* correlator, float d_rem_carrier_phase_rad, @@ -38,7 +41,11 @@ void run_correlator_cpu(Cpu_Multicorrelator* correlator, float d_rem_code_phase_chips, int correlation_size) { +#if USE_GLOG_AND_GFLAGS for (int k = 0; k < FLAGS_cpu_multicorrelator_iterations_test; k++) +#else + for (int k = 0; k < absl::GetFlag(FLAGS_cpu_multicorrelator_iterations_test); k++) +#endif { correlator->Carrier_wipeoff_multicorrelator_resampler(d_rem_carrier_phase_rad, d_carrier_phase_step_rad, @@ -53,7 +60,11 @@ TEST(CpuMulticorrelatorTest, MeasureExecutionTime) { std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); +#if USE_GLOG_AND_GFLAGS int max_threads = FLAGS_cpu_multicorrelator_max_threads_test; +#else + int max_threads = absl::GetFlag(FLAGS_cpu_multicorrelator_max_threads_test); +#endif std::vector thread_pool; std::vector correlator_pool(max_threads); unsigned int correlation_sizes[3] = {2048, 4096, 8192}; @@ -91,7 +102,7 @@ TEST(CpuMulticorrelatorTest, MeasureExecutionTime) // local code resampler on GPU // generate local reference (1 sample per chip) gps_l1_ca_code_gen_complex(own::span(d_ca_code, static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS) * sizeof(gr_complex)), 1, 0); - // generate inut signal + // generate input signal std::random_device r; std::default_random_engine e1(r()); std::uniform_real_distribution uniform_dist(0, 1); @@ -138,7 +149,11 @@ TEST(CpuMulticorrelatorTest, MeasureExecutionTime) thread_pool.clear(); end = std::chrono::system_clock::now(); elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(FLAGS_cpu_multicorrelator_iterations_test); +#else + execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_cpu_multicorrelator_iterations_test)); +#endif std::cout << "CPU Multicorrelator execution time for length=" << correlation_sizes[correlation_sizes_idx] << " : " << execution_times[correlation_sizes_idx] << " [s]\n"; } @@ -160,7 +175,11 @@ TEST(CpuMulticorrelatorTest, MeasureExecutionTimeAlloc) { std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); +#if USE_GLOG_AND_GFLAGS int max_threads = FLAGS_cpu_multicorrelator_max_threads_test; +#else + int max_threads = absl::GetFlag(FLAGS_cpu_multicorrelator_max_threads_test); +#endif std::vector thread_pool; std::vector correlator_pool(max_threads); unsigned int correlation_sizes[3] = {2048, 4096, 8192}; @@ -189,7 +208,7 @@ TEST(CpuMulticorrelatorTest, MeasureExecutionTimeAlloc) // local code resampler on GPU // generate local reference (1 sample per chip) gps_l1_ca_code_gen_complex(d_ca_code, 1, 0); - // generate inut signal + // generate input signal std::random_device r; std::default_random_engine e1(r()); std::uniform_real_distribution uniform_dist(0, 1); @@ -236,7 +255,11 @@ TEST(CpuMulticorrelatorTest, MeasureExecutionTimeAlloc) thread_pool.clear(); end = std::chrono::system_clock::now(); elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(FLAGS_cpu_multicorrelator_iterations_test); +#else + execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_cpu_multicorrelator_iterations_test)); +#endif std::cout << "CPU Multicorrelator execution time for length=" << correlation_sizes[correlation_sizes_idx] << " : " << execution_times[correlation_sizes_idx] << " [s]\n"; } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/cubature_filter_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/cubature_filter_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/tracking/cubature_filter_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/cubature_filter_test.cc index 2c78fa743..ff73bd1c4 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/cubature_filter_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/cubature_filter_test.cc @@ -25,7 +25,7 @@ class TransitionModel : public ModelFunction { public: - explicit TransitionModel(const arma::mat& kf_F) : coeff_mat(kf_F){}; + explicit TransitionModel(const arma::mat& kf_F) : coeff_mat(kf_F) {}; arma::vec operator()(const arma::vec& input) override { return coeff_mat * input; }; private: @@ -35,7 +35,7 @@ private: class MeasurementModel : public ModelFunction { public: - explicit MeasurementModel(const arma::mat& kf_H) : coeff_mat(kf_H){}; + explicit MeasurementModel(const arma::mat& kf_H) : coeff_mat(kf_H) {}; arma::vec operator()(const arma::vec& input) override { return coeff_mat * input; }; private: diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/discriminator_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc index 0519b3de3..bd4e74d7e 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/galileo_e1_dll_pll_veml_tracking_test.cc @@ -53,7 +53,7 @@ protected: gr::top_block_sptr top_block; std::shared_ptr factory; std::shared_ptr config; - Gnss_Synchro gnss_synchro{}; + Gnss_Synchro gnss_synchro; size_t item_size; int message{0}; bool stop{false}; @@ -72,7 +72,7 @@ void GalileoE1DllPllVemlTrackingInternalTest::init() config->set_property("Tracking_1B.implementation", "Galileo_E1_DLL_PLL_VEML_Tracking"); config->set_property("Tracking_1B.item_type", "gr_complex"); config->set_property("Tracking_1B.dump", "false"); - config->set_property("Tracking_1B.dump_filename", "../data/veml_tracking_ch_"); + config->set_property("Tracking_1B.dump_filename", "./veml_tracking_ch_"); config->set_property("Tracking_1B.early_late_space_chips", "0.15"); config->set_property("Tracking_1B.very_early_late_space_chips", "0.6"); config->set_property("Tracking_1B.pll_bw_hz", "30.0"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc index 9d17f703a..f13a498bd 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5a_tracking_test.cc @@ -78,7 +78,7 @@ void GalileoE5aTrackingTest::init() config->set_property("Tracking_5X.implementation", "Galileo_E5a_DLL_PLL_Tracking"); config->set_property("Tracking_5X.item_type", "gr_complex"); config->set_property("Tracking_5X.dump", "false"); - config->set_property("Tracking_5X.dump_filename", "../data/e5a_tracking_ch_"); + config->set_property("Tracking_5X.dump_filename", "./e5a_tracking_ch_"); config->set_property("Tracking_5X.early_late_space_chips", "0.5"); config->set_property("Tracking_5X.order", "2"); config->set_property("Tracking_5X.pll_bw_hz", "20.0"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc index 4e69dae2a..8536ece4f 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/galileo_e5b_dll_pll_tracking_test.cc @@ -79,7 +79,7 @@ void GalileoE5bTrackingTest::init() config->set_property("Tracking_7X.implementation", "Galileo_E5b_DLL_PLL_Tracking"); config->set_property("Tracking_7X.item_type", "gr_complex"); config->set_property("Tracking_7X.dump", "false"); - config->set_property("Tracking_7X.dump_filename", "../data/e5b_tracking"); + config->set_property("Tracking_7X.dump_filename", "./e5b_tracking"); config->set_property("Tracking_7X.early_late_space_chips", "0.5"); config->set_property("Tracking_7X.order", "2"); config->set_property("Tracking_7X.pll_bw_hz", "20.0"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc index 33770b758..55bfbb3e7 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_c_aid_tracking_test.cc @@ -42,7 +42,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GlonassL1CaDllPllCAidTrackingTest_msg_rx; using GlonassL1CaDllPllCAidTrackingTest_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc similarity index 99% rename from src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc index 001628c2f..17ddbfe44 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/glonass_l1_ca_dll_pll_tracking_test.cc @@ -48,7 +48,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GlonassL1CaDllPllTrackingTest_msg_rx; using GlonassL1CaDllPllTrackingTest_msg_rx_sptr = gnss_shared_ptr; diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc similarity index 86% rename from src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc index 87af5fe45..a50f07e35 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test.cc @@ -61,7 +61,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CADllPllTrackingTest_msg_rx; using GpsL1CADllPllTrackingTest_msg_rx_sptr = gnss_shared_ptr; @@ -138,10 +138,15 @@ public: std::string p6; std::string implementation = "GPS_L1_CA_DLL_PLL_Tracking"; +#if USE_GLOG_AND_GFLAGS const int baseband_sampling_freq = FLAGS_fs_gen_sps; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; +#else + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif int configure_generator(double CN0_dBHz, int file_idx); int generate_signal(); @@ -193,6 +198,7 @@ public: int GpsL1CADllPllTrackingTest::configure_generator(double CN0_dBHz, int file_idx) { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -209,6 +215,25 @@ int GpsL1CADllPllTrackingTest::configure_generator(double CN0_dBHz, int file_idx p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data) + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] + p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 +#endif + return 0; } @@ -249,7 +274,12 @@ void GpsL1CADllPllTrackingTest::configure_receiver( gnss_synchro.System = 'G'; std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); + +#if USE_GLOG_AND_GFLAGS gnss_synchro.PRN = FLAGS_test_satellite_PRN; +#else + gnss_synchro.PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif config = std::make_shared(); config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); @@ -464,6 +494,7 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) // *********************************************************** // ***** STEP 2: Tracking configuration parameters sweep ***** // *********************************************************** +#if USE_GLOG_AND_GFLAGS if (FLAGS_PLL_bw_hz_start == FLAGS_PLL_bw_hz_stop) { if (FLAGS_DLL_bw_hz_start == FLAGS_DLL_bw_hz_stop) @@ -491,25 +522,70 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) DLL_wide_bw_values.push_back(FLAGS_DLL_bw_hz_start); } } +#else + if (absl::GetFlag(FLAGS_PLL_bw_hz_start) == absl::GetFlag(FLAGS_PLL_bw_hz_stop)) + { + if (absl::GetFlag(FLAGS_DLL_bw_hz_start) == absl::GetFlag(FLAGS_DLL_bw_hz_stop)) + { + // NO PLL/DLL BW sweep + PLL_wide_bw_values.push_back(absl::GetFlag(FLAGS_PLL_bw_hz_start)); + DLL_wide_bw_values.push_back(absl::GetFlag(FLAGS_DLL_bw_hz_start)); + } + else + { + // DLL BW Sweep + for (double dll_bw = absl::GetFlag(FLAGS_DLL_bw_hz_start); dll_bw >= absl::GetFlag(FLAGS_DLL_bw_hz_stop); dll_bw = dll_bw - absl::GetFlag(FLAGS_DLL_bw_hz_step)) + { + PLL_wide_bw_values.push_back(absl::GetFlag(FLAGS_PLL_bw_hz_start)); + DLL_wide_bw_values.push_back(dll_bw); + } + } + } + else + { + // PLL BW Sweep + for (double pll_bw = absl::GetFlag(FLAGS_PLL_bw_hz_start); pll_bw >= absl::GetFlag(FLAGS_PLL_bw_hz_stop); pll_bw = pll_bw - absl::GetFlag(FLAGS_PLL_bw_hz_step)) + { + PLL_wide_bw_values.push_back(pll_bw); + DLL_wide_bw_values.push_back(absl::GetFlag(FLAGS_DLL_bw_hz_start)); + } + } +#endif // ********************************************* // ***** STEP 3: Generate the input signal ***** // ********************************************* std::vector cno_vector; +#if USE_GLOG_AND_GFLAGS if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) { generator_CN0_values.push_back(FLAGS_CN0_dBHz_start); } +#else + if (absl::GetFlag(FLAGS_CN0_dBHz_start) == absl::GetFlag(FLAGS_CN0_dBHz_stop)) + { + generator_CN0_values.push_back(absl::GetFlag(FLAGS_CN0_dBHz_start)); + } +#endif else { +#if USE_GLOG_AND_GFLAGS for (double cn0 = FLAGS_CN0_dBHz_start; cn0 > FLAGS_CN0_dBHz_stop; cn0 = cn0 - FLAGS_CN0_dB_step) +#else + for (double cn0 = absl::GetFlag(FLAGS_CN0_dBHz_start); cn0 > absl::GetFlag(FLAGS_CN0_dBHz_stop); cn0 = cn0 - absl::GetFlag(FLAGS_CN0_dB_step)) +#endif { generator_CN0_values.push_back(cn0); } } - // use generator or use an external capture file + // use generator or use an external capture file + +#if USE_GLOG_AND_GFLAGS if (FLAGS_enable_external_signal_file) +#else + if (absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { // todo: create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters } @@ -520,7 +596,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) // Configure the signal generator configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); // Generate signal raw signal samples and observations RINEX file +#if USE_GLOG_AND_GFLAGS if (FLAGS_disable_generator == false) +#else + if (absl::GetFlag(FLAGS_disable_generator) == false) +#endif { generate_signal(); } @@ -561,17 +641,29 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) configure_receiver(PLL_wide_bw_values.at(config_idx), DLL_wide_bw_values.at(config_idx), +#if USE_GLOG_AND_GFLAGS FLAGS_PLL_narrow_bw_hz, FLAGS_DLL_narrow_bw_hz, FLAGS_extend_correlation_symbols); +#else + absl::GetFlag(FLAGS_PLL_narrow_bw_hz), + absl::GetFlag(FLAGS_DLL_narrow_bw_hz), + absl::GetFlag(FLAGS_extend_correlation_symbols)); +#endif for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { // ****************************************************************************************** // ***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** // ****************************************************************************************** +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { test_satellite_PRN = FLAGS_test_satellite_PRN; +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + test_satellite_PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); true_obs_file.append(".dat"); @@ -580,7 +672,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) // load acquisition data based on the first epoch of the true observations ASSERT_EQ(true_obs_data.read_binary_obs(), true) << "Failure reading true tracking dump file.\n" +#if USE_GLOG_AND_GFLAGS << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + +#else + << "Maybe sat PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + +#endif " is not available?"; std::cout << "Testing satellite PRN=" << test_satellite_PRN << '\n'; std::cout << "Initial Doppler [Hz]=" << true_obs_data.doppler_l1_hz << " Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << '\n'; @@ -694,10 +790,14 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) promptQ_sweep.push_back(promptQ); CN0_dBHz_sweep.push_back(CN0_dBHz); - // *********************************************************** - // ***** STEP 6: Compare with true values (if available) ***** - // *********************************************************** +// *********************************************************** +// ***** STEP 6: Compare with true values (if available) ***** +// *********************************************************** +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { std::vector doppler_error_hz; std::vector code_phase_error_chips; @@ -726,8 +826,12 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) true_tow_s(epoch_counter) = true_obs_data.tow; epoch_counter++; } - // Align initial measurements and cut the tracking pull-in transitory +// Align initial measurements and cut the tracking pull-in transitory +#if USE_GLOG_AND_GFLAGS double pull_in_offset_s = FLAGS_skip_trk_transitory_s; +#else + double pull_in_offset_s = absl::GetFlag(FLAGS_skip_trk_transitory_s); +#endif arma::uvec initial_meas_point = arma::find(trk_timestamp_s >= (true_timestamp_s(0) + pull_in_offset_s), 1, "first"); if (!initial_meas_point.empty() and tracking_last_msg != 3) @@ -782,8 +886,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } } } // CN0 LOOP - +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { mean_doppler_error_sweep.push_back(mean_doppler_error); std_dev_doppler_error_sweep.push_back(std_dev_doppler_error); @@ -801,12 +908,18 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) generator_CN0_values_sweep_copy.push_back(valid_CN0_values); } - // ******************************** - // ***** STEP 7: Plot results ***** - // ******************************** +// ******************************** +// ***** STEP 7: Plot results ***** +// ******************************** +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_gps_l1_tracking_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + if (absl::GetFlag(FLAGS_plot_gps_l1_tracking_test) == true) + { + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE,\n"; @@ -821,14 +934,26 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) fs::path dir = p.parent_path(); const std::string& gnuplot_path = dir.native(); Gnuplot::set_GNUPlotPath(gnuplot_path); +#if USE_GLOG_AND_GFLAGS auto decimate = static_cast(FLAGS_plot_decimate); if (FLAGS_plot_detail_level >= 2) +#else + auto decimate = static_cast(absl::GetFlag(FLAGS_plot_decimate)); + + if (absl::GetFlag(FLAGS_plot_detail_level) >= 2) +#endif + { for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { Gnuplot g1("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif + { g1.showonscreen(); // window output } @@ -836,7 +961,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { g1.disablescreen(); } +#if USE_GLOG_AND_GFLAGS g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g1.set_grid(); g1.set_xlabel("Time [s]"); g1.set_ylabel("Correlators' output"); @@ -849,7 +978,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g1.savetopdf("Correlators_outputs" + std::to_string(generator_CN0_values.at(current_cn0_idx)), 18); } Gnuplot g2("points"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g2.showonscreen(); // window output } @@ -862,7 +995,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values.size(); current_cn0_idx++) { g2.reset_plot(); +#if USE_GLOG_AND_GFLAGS g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz" + "GPS L1 C/A (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g2.set_grid(); g2.set_xlabel("Inphase"); g2.set_ylabel("Quadrature"); @@ -874,7 +1011,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g2.savetopdf("Constellation", 18); Gnuplot g3("linespoints"); +#if USE_GLOG_AND_GFLAGS g3.set_title("GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g3.set_title("GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g3.set_grid(); g3.set_xlabel("Time [s]"); g3.set_ylabel("Reported CN0 [dB-Hz]"); @@ -887,7 +1028,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g3.set_legend(); g3.savetops("CN0_output"); g3.savetopdf("CN0_output", 18); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g3.showonscreen(); // window output } @@ -897,13 +1042,22 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } } - // PLOT ERROR FIGURES (only if it is used the signal generator) +// PLOT ERROR FIGURES (only if it is used the signal generator) +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { if (FLAGS_plot_detail_level >= 1) { Gnuplot g5("points"); if (FLAGS_show_plots) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + if (absl::GetFlag(FLAGS_plot_detail_level) >= 1) + { + Gnuplot g5("points"); + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g5.showonscreen(); // window output } @@ -911,7 +1065,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { g5.disablescreen(); } +#if USE_GLOG_AND_GFLAGS g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g5.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g5.set_grid(); g5.set_xlabel("Time [s]"); g5.set_ylabel("Code delay error [Chips]"); @@ -937,7 +1095,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g5.savetopdf("Code_error_chips", 18); Gnuplot g5b("points"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g5b.showonscreen(); // window output } @@ -945,7 +1107,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { g5b.disablescreen(); } +#if USE_GLOG_AND_GFLAGS g5b.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g5b.set_title("Code delay error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g5b.set_grid(); g5b.set_xlabel("Time [s]"); g5b.set_ylabel("Code delay error [meters]"); @@ -971,7 +1137,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g5b.savetopdf("Code_error_meters", 18); Gnuplot g6("points"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g6.showonscreen(); // window output } @@ -979,7 +1149,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { g6.disablescreen(); } +#if USE_GLOG_AND_GFLAGS g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g6.set_title("Accumulated carrier phase error, PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g6.set_grid(); g6.set_xlabel("Time [s]"); g6.set_ylabel("Accumulated carrier phase error [Cycles]"); @@ -1005,7 +1179,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g6.savetopdf("Acc_carrier_phase_error_cycles", 18); Gnuplot g4("points"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g4.showonscreen(); // window output } @@ -1018,7 +1196,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) for (unsigned int current_cn0_idx = 0; current_cn0_idx < generator_CN0_values_sweep_copy.at(config_idx).size(); current_cn0_idx++) { g4.reset_plot(); +#if USE_GLOG_AND_GFLAGS g4.set_title("Dopper error" + std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz], PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g4.set_title("Dopper error" + std::to_string(static_cast(round(generator_CN0_values_sweep_copy.at(config_idx).at(current_cn0_idx)))) + "[dB-Hz], PLL/DLL BW: " + std::to_string(PLL_wide_bw_values.at(config_idx)) + "," + std::to_string(DLL_wide_bw_values.at(config_idx)) + " Hz (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g4.set_grid(); // g4.cmd("set key box opaque"); g4.set_xlabel("Time [s]"); @@ -1051,7 +1233,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) } } +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_gps_l1_tracking_test == true) +#else + if (absl::GetFlag(FLAGS_plot_gps_l1_tracking_test) == true) +#endif { std::cout << "Plotting performance metrics...\n"; try @@ -1060,7 +1246,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { // plot metrics Gnuplot g7("linespoints"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g7.showonscreen(); // window output } @@ -1068,7 +1258,12 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) { g7.disablescreen(); } + +#if USE_GLOG_AND_GFLAGS g7.set_title("Doppler error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g7.set_title("Doppler error metrics (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g7.set_grid(); g7.set_xlabel("CN0 [dB-Hz]"); g7.set_ylabel("Doppler error [Hz]"); @@ -1093,7 +1288,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g7.savetopdf("Doppler_error_metrics", 18); Gnuplot g8("linespoints"); +#if USE_GLOG_AND_GFLAGS g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g8.set_title("Accumulated carrier phase error metrics (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g8.set_grid(); g8.set_xlabel("CN0 [dB-Hz]"); g8.set_ylabel("Accumulated Carrier Phase error [Cycles]"); @@ -1117,7 +1316,11 @@ TEST_F(GpsL1CADllPllTrackingTest, ValidationOfResults) g8.savetopdf("Carrier_error_metrics", 18); Gnuplot g9("linespoints"); +#if USE_GLOG_AND_GFLAGS g9.set_title("Code Phase error metrics (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g9.set_title("Code Phase error metrics (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g9.set_grid(); g9.set_xlabel("CN0 [dB-Hz]"); g9.set_ylabel("Code Phase error [Chips]"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc b/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc similarity index 93% rename from src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc rename to tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc index 81ca1df0c..e1717b44b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_dll_pll_tracking_test_fpga.cc @@ -29,8 +29,6 @@ #include "tracking_true_obs_reader.h" #include #include // to test the FPGA we have to create a simultaneous task to send the samples using the DMA and stop the test -#include -#include #include #include #include @@ -46,6 +44,14 @@ #include #include #include + +#if USE_GLOG_AND_GFLAGS +#include +#include +#else +#include +#include +#endif #if HAS_GENERIC_LAMBDA #else #include @@ -155,7 +161,7 @@ void sending_thread(const gr::top_block_sptr &top_block, const char *file_name) } -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CADllPllTrackingTestFpga_msg_rx; using GpsL1CADllPllTrackingTestFpga_msg_rx_sptr = gnss_shared_ptr; @@ -232,11 +238,15 @@ public: std::string p4; std::string p5; +#if USE_GLOG_AND_GFLAGS const int baseband_sampling_freq = FLAGS_fs_gen_sps; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; - +#else + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif int configure_generator(); int generate_signal(); void check_results_doppler(arma::vec &true_time_s, arma::vec &true_value, @@ -266,7 +276,8 @@ public: int GpsL1CADllPllTrackingTestFpga::configure_generator() { - // Configure signal generator +// Configure signal generator +#if USE_GLOG_AND_GFLAGS generator_binary = FLAGS_generator_binary; p1 = std::string("-rinex_nav_file=") + FLAGS_rinex_nav_file; @@ -281,6 +292,23 @@ int GpsL1CADllPllTrackingTestFpga::configure_generator() p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#else + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#endif + return 0; } @@ -317,13 +345,17 @@ void GpsL1CADllPllTrackingTestFpga::configure_receiver() gnss_synchro.System = 'G'; std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); +#if USE_GLOG_AND_GFLAGS gnss_synchro.PRN = FLAGS_test_satellite_PRN; +#else + gnss_synchro.PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); // Set Tracking config->set_property("Tracking_1C.implementation", - "GPS_L1_CA_DLL_PLL_Tracking_Fpga"); + "GPS_L1_CA_DLL_PLL_Tracking_FPGA"); config->set_property("Tracking_1C.item_type", "cshort"); config->set_property("Tracking_1C.dump", "true"); config->set_property("Tracking_1C.dump_filename", "./tracking_ch_"); @@ -464,7 +496,11 @@ TEST_F(GpsL1CADllPllTrackingTestFpga, ValidationOfResultsFpga) // open true observables log file written by the simulator Tracking_True_Obs_Reader true_obs_data; +#if USE_GLOG_AND_GFLAGS int test_satellite_PRN = FLAGS_test_satellite_PRN; +#else + int test_satellite_PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif std::cout << "Testing satellite PRN=" << test_satellite_PRN << '\n'; std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_gaussian_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_gaussian_tracking_test.cc similarity index 88% rename from src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_gaussian_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_gaussian_tracking_test.cc index fbd1b2d0f..0e5d64c73 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_gaussian_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/gps_l1_ca_gaussian_tracking_test.cc @@ -60,10 +60,13 @@ namespace wht = boost; namespace wht = std; #endif +#if USE_GLOG_AND_GFLAGS DEFINE_bool(plot_gps_l1_gaussian_tracking_test, false, "Plots results of GpsL1CAGaussianTrackingTest with gnuplot"); +#else +ABSL_FLAG(bool, plot_gps_l1_gaussian_tracking_test, false, "Plots results of GpsL1CAGaussianTrackingTest with gnuplot"); +#endif - -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL1CAGaussianTrackingTest_msg_rx; @@ -139,10 +142,15 @@ public: std::string implementation = "GPS_L1_CA_Gaussian_Tracking"; +#if USE_GLOG_AND_GFLAGS const int baseband_sampling_freq = FLAGS_fs_gen_sps; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_filename_raw_data; +#else + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_filename_raw_data); +#endif int configure_generator(); int generate_signal(); @@ -181,6 +189,7 @@ public: int GpsL1CAGaussianTrackingTest::configure_generator() { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -196,6 +205,24 @@ int GpsL1CAGaussianTrackingTest::configure_generator() p3 = std::string("-rinex_obs_file=") + FLAGS_filename_rinex_obs; // RINEX 2.10 observation file output p4 = std::string("-sig_out_file=") + FLAGS_filename_raw_data; // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_filename_raw_data); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] +#endif + return 0; } @@ -231,16 +258,27 @@ void GpsL1CAGaussianTrackingTest::configure_receiver() gnss_synchro.System = 'G'; std::string signal = "1C"; signal.copy(gnss_synchro.Signal, 2, 0); +#if USE_GLOG_AND_GFLAGS gnss_synchro.PRN = FLAGS_test_satellite_PRN; +#else + gnss_synchro.PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); // Set Tracking config->set_property("Tracking_1C.implementation", implementation); config->set_property("Tracking_1C.item_type", "gr_complex"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_dll_bw_hz != 0.0) { config->set_property("Tracking_1C.dll_bw_hz", std::to_string(FLAGS_dll_bw_hz)); } +#else + if (absl::GetFlag(FLAGS_dll_bw_hz) != 0.0) + { + config->set_property("Tracking_1C.dll_bw_hz", std::to_string(absl::GetFlag(FLAGS_dll_bw_hz))); + } +#endif else { config->set_property("Tracking_1C.dll_bw_hz", "2.0"); @@ -376,18 +414,28 @@ TEST_F(GpsL1CAGaussianTrackingTest, ValidationOfResults) configure_generator(); // Generate signal raw signal samples and observations RINEX file +#if USE_GLOG_AND_GFLAGS if (FLAGS_disable_generator == false) { generate_signal(); } - +#else + if (absl::GetFlag(FLAGS_disable_generator) == false) + { + generate_signal(); + } +#endif std::chrono::time_point start, end; configure_receiver(); // open true observables log file written by the simulator Tracking_True_Obs_Reader true_obs_data; +#if USE_GLOG_AND_GFLAGS int test_satellite_PRN = FLAGS_test_satellite_PRN; +#else + int test_satellite_PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif std::cout << "Testing satellite PRN=" << test_satellite_PRN << '\n'; std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); @@ -404,7 +452,11 @@ TEST_F(GpsL1CAGaussianTrackingTest, ValidationOfResults) // load acquisition data based on the first epoch of the true observations ASSERT_EQ(true_obs_data.read_binary_obs(), true) << "Failure reading true tracking dump file.\n" +#if USE_GLOG_AND_GFLAGS << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + +#else + << "Maybe sat PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + +#endif " is not available?"; // restart the epoch counter @@ -522,10 +574,15 @@ TEST_F(GpsL1CAGaussianTrackingTest, ValidationOfResults) std::chrono::duration elapsed_seconds = end - start; std::cout << "Signal tracking completed in " << elapsed_seconds.count() << " seconds.\n"; - +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_gps_l1_gaussian_tracking_test == true) { const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + if (absl::GetFlag(FLAGS_plot_gps_l1_gaussian_tracking_test) == true) + { + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag plot_gps_l1_tracking_test has been set to TRUE,\n"; @@ -549,18 +606,30 @@ TEST_F(GpsL1CAGaussianTrackingTest, ValidationOfResults) t = t + GPS_L1_CA_CODE_PERIOD_S; } Gnuplot g1("linespoints"); +#if USE_GLOG_AND_GFLAGS g1.set_title("GPS L1 C/A signal tracking correlators' output (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g1.set_title("GPS L1 C/A signal tracking correlators' output (satellite PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g1.set_grid(); g1.set_xlabel("Time [s]"); g1.set_ylabel("Correlators' output"); g1.cmd("set key box opaque"); +#if USE_GLOG_AND_GFLAGS auto decimate = static_cast(FLAGS_plot_decimate); +#else + auto decimate = static_cast(absl::GetFlag(FLAGS_plot_decimate)); +#endif g1.plot_xy(timevec, prompt, "Prompt", decimate); g1.plot_xy(timevec, early, "Early", decimate); g1.plot_xy(timevec, late, "Late", decimate); g1.savetops("Correlators_outputs"); g1.savetopdf("Correlators_outputs", 18); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g1.showonscreen(); // window output } @@ -570,7 +639,11 @@ TEST_F(GpsL1CAGaussianTrackingTest, ValidationOfResults) } Gnuplot g2("points"); +#if USE_GLOG_AND_GFLAGS g2.set_title("Constellation diagram (satellite PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); +#else + g2.set_title("Constellation diagram (satellite PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); +#endif g2.set_grid(); g2.set_xlabel("Inphase"); g2.set_ylabel("Quadrature"); @@ -578,7 +651,11 @@ TEST_F(GpsL1CAGaussianTrackingTest, ValidationOfResults) g2.plot_xy(promptI, promptQ); g2.savetops("Constellation"); g2.savetopdf("Constellation", 18); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g2.showonscreen(); // window output } diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc similarity index 98% rename from src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc index 43c32314a..ffa0b1fba 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/gps_l2_m_dll_pll_tracking_test.cc @@ -48,7 +48,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class GpsL2MDllPllTrackingTest_msg_rx; using GpsL2MDllPllTrackingTest_msg_rx_sptr = gnss_shared_ptr; @@ -144,7 +144,7 @@ void GpsL2MDllPllTrackingTest::init() config->set_property("GNSS-SDR.internal_fs_sps", "5000000"); config->set_property("Tracking_2S.item_type", "gr_complex"); config->set_property("Tracking_2S.dump", "false"); - config->set_property("Tracking_2S.dump_filename", "../data/L2m_tracking_ch_"); + config->set_property("Tracking_2S.dump_filename", "./L2m_tracking_ch_"); config->set_property("Tracking_2S.implementation", "GPS_L2_M_DLL_PLL_Tracking"); config->set_property("Tracking_2S.early_late_space_chips", "0.5"); config->set_property("Tracking_2S.order", "2"); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc similarity index 89% rename from src/tests/unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc index d8749dc39..91eacd660 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/gpu_multicorrelator_test.cc @@ -20,14 +20,19 @@ #include "gps_sdr_signal_replica.h" #include #include +#include #include #include #include #include - +#if USE_GLOG_AND_GFLAGS DEFINE_int32(gpu_multicorrelator_iterations_test, 1000, "Number of averaged iterations in GPU multicorrelator test timing test"); DEFINE_int32(gpu_multicorrelator_max_threads_test, 12, "Number of maximum concurrent correlators in GPU multicorrelator test timing test"); +#else +ABSL_FLAG(int32_t, gpu_multicorrelator_iterations_test, 1000, "Number of averaged iterations in GPU multicorrelator test timing test"); +ABSL_FLAG(int32_t, gpu_multicorrelator_max_threads_test, 12, "Number of maximum concurrent correlators in GPU multicorrelator test timing test"); +#endif void run_correlator_gpu(cuda_multicorrelator* correlator, float d_rem_carrier_phase_rad, @@ -37,7 +42,11 @@ void run_correlator_gpu(cuda_multicorrelator* correlator, int correlation_size, int d_n_correlator_taps) { +#if USE_GLOG_AND_GFLAGS for (int k = 0; k < FLAGS_cpu_multicorrelator_iterations_test; k++) +#else + for (int k = 0; k < absl::GetFlag(FLAGS_cpu_multicorrelator_iterations_test); k++) +#endif { correlator->Carrier_wipeoff_multicorrelator_resampler_cuda(d_rem_carrier_phase_rad, d_carrier_phase_step_rad, @@ -53,7 +62,11 @@ TEST(GpuMulticorrelatorTest, MeasureExecutionTime) { std::chrono::time_point start, end; std::chrono::duration elapsed_seconds(0); +#if USE_GLOG_AND_GFLAGS int max_threads = FLAGS_gpu_multicorrelator_max_threads_test; +#else + int max_threads = absl::GetFlag(FLAGS_gpu_multicorrelator_max_threads_test); +#endif std::vector thread_pool; cuda_multicorrelator* correlator_pool[max_threads]; unsigned int correlation_sizes[3] = {2048, 4096, 8192}; @@ -83,7 +96,7 @@ TEST(GpuMulticorrelatorTest, MeasureExecutionTime) // local code resampler on GPU // generate local reference (1 sample per chip) gps_l1_ca_code_gen_complex(own::span(d_ca_code, static_cast(GPS_L1_CA_CODE_LENGTH_CHIPS)), 1, 0); - // generate inut signal + // generate input signal for (int n = 0; n < 2 * d_vector_length; n++) { in_gpu[n] = std::complex(static_cast(rand()) / static_cast(RAND_MAX), static_cast(rand()) / static_cast(RAND_MAX)); @@ -133,7 +146,11 @@ TEST(GpuMulticorrelatorTest, MeasureExecutionTime) thread_pool.clear(); end = std::chrono::system_clock::now(); elapsed_seconds = end - start; +#if USE_GLOG_AND_GFLAGS execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(FLAGS_gpu_multicorrelator_iterations_test); +#else + execution_times[correlation_sizes_idx] = elapsed_seconds.count() / static_cast(absl::GetFlag(FLAGS_gpu_multicorrelator_iterations_test)); +#endif std::cout << "GPU Multicorrelator execution time for length=" << correlation_sizes[correlation_sizes_idx] << " : " << execution_times[correlation_sizes_idx] << " [s]\n"; } }); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/tracking_loop_filter_test.cc diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc similarity index 79% rename from src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc index 5f1265edd..b13b91fbe 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test.cc @@ -74,7 +74,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO TRACKING BLOCK MESSAGE RECEIVER ######### class TrackingPullInTest_msg_rx; using TrackingPullInTest_msg_rx_sptr = gnss_shared_ptr; @@ -161,12 +161,18 @@ public: std::string p4; std::string p5; std::string p6; + +#if USE_GLOG_AND_GFLAGS std::string implementation = FLAGS_trk_test_implementation; - const int baseband_sampling_freq = FLAGS_fs_gen_sps; - std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_signal_file; +#else + std::string implementation = absl::GetFlag(FLAGS_trk_test_implementation); + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_signal_file); +#endif std::map doppler_measurements_map; std::map code_delay_measurements_map; @@ -229,6 +235,7 @@ public: int TrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx) { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -245,6 +252,24 @@ int TrackingPullInTest::configure_generator(double CN0_dBHz, int file_idx) p4 = std::string("-sig_out_file=") + FLAGS_signal_file + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_signal_file) + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] + p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 +#endif return 0; } @@ -291,7 +316,11 @@ void TrackingPullInTest::configure_receiver( config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); +#if USE_GLOG_AND_GFLAGS gnss_synchro.PRN = FLAGS_test_satellite_PRN; +#else + gnss_synchro.PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif gnss_synchro.Channel_ID = 0; config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); @@ -383,8 +412,12 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) config = std::make_shared(); config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); - // Enable automatic resampler for the acquisition, if required +// Enable automatic resampler for the acquisition, if required +#if USE_GLOG_AND_GFLAGS if (FLAGS_use_acquisition_resampler == true) +#else + if (absl::GetFlag(FLAGS_use_acquisition_resampler) == true) +#endif { config->set_property("GNSS-SDR.use_acquisition_resampler", "true"); } @@ -406,7 +439,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L1 CA"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif // acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } @@ -418,7 +455,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E1B"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else if (implementation == "GPS_L2_M_DLL_PLL_Tracking") @@ -429,7 +470,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L2CM"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_b") @@ -441,7 +486,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E5a"; config->set_property("Acquisition_5X.coherent_integration_time_ms", "1"); +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif config->set_property("Acquisition.CAF_window_hz", "0"); // **Only for E5a** Resolves doppler ambiguity averaging the specified BW in the winner code delay. If set to 0 CAF filter is deactivated. Recommended value 3000 Hz config->set_property("Acquisition.Zero_padding", "0"); // **Only for E5a** Avoids power loss and doppler ambiguity in bit transitions by correlating one code with twice the input data length, ensuring that at least one full code is present without transitions. If set to 1 it is ON, if set to 0 it is OFF. config->set_property("Acquisition.bit_transition_flag", "false"); @@ -456,7 +505,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "Galileo E5a"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else if (implementation == "GPS_L5_DLL_PLL_Tracking") @@ -467,7 +520,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::memcpy(static_cast(tmp_gnss_synchro.Signal), str, 3); // copy string into synchro char array: 2 char + null tmp_gnss_synchro.PRN = SV_ID; System_and_Signal = "GPS L5I"; +#if USE_GLOG_AND_GFLAGS config->set_property("Acquisition.max_dwells", std::to_string(FLAGS_external_signal_acquisition_dwells)); +#else + config->set_property("Acquisition.max_dwells", std::to_string(absl::GetFlag(FLAGS_external_signal_acquisition_dwells))); +#endif acquisition = std::make_shared(config.get(), "Acquisition", 1, 0); } else @@ -478,26 +535,44 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) acquisition->set_gnss_synchro(&tmp_gnss_synchro); acquisition->set_channel(0); +#if USE_GLOG_AND_GFLAGS acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz)); acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz)); acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); +#else + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_max_hz))); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_step_hz))); + acquisition->set_threshold(config->property("Acquisition.threshold", absl::GetFlag(FLAGS_external_signal_acquisition_threshold))); +#endif acquisition->init(); acquisition->set_local_code(); acquisition->set_state(1); // Ensure that acquisition starts at the first sample acquisition->connect(top_block_acq); gr::blocks::file_source::sptr file_source; +#if USE_GLOG_AND_GFLAGS std::string file = FLAGS_signal_file; +#else + std::string file = absl::GetFlag(FLAGS_signal_file); +#endif const char* file_name = file.c_str(); file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); +#if USE_GLOG_AND_GFLAGS file_source->seek(2 * FLAGS_skip_samples, SEEK_SET); // skip head. ibyte, two bytes per complex sample +#else + file_source->seek(2 * absl::GetFlag(FLAGS_skip_samples), SEEK_SET); // skip head. ibyte, two bytes per complex sample +#endif gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); // gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); top_block_acq->connect(file_source, 0, gr_interleaved_char_to_complex, 0); - // Enable automatic resampler for the acquisition, if required +// Enable automatic resampler for the acquisition, if required +#if USE_GLOG_AND_GFLAGS if (FLAGS_use_acquisition_resampler == true) +#else + if (absl::GetFlag(FLAGS_use_acquisition_resampler) == true) +#endif { // create acquisition resamplers if required double resampler_ratio = 1.0; @@ -625,7 +700,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) top_block_acq->run(); if (start_msg == true) { +#if USE_GLOG_AND_GFLAGS std::cout << "Reading external signal file: " << FLAGS_signal_file << '\n'; +#else + std::cout << "Reading external signal file: " << absl::GetFlag(FLAGS_signal_file) << '\n'; +#endif std::cout << "Searching for " << System_and_Signal << " Satellites...\n"; std::cout << "["; start_msg = false; @@ -646,7 +725,11 @@ bool TrackingPullInTest::acquire_signal(int SV_ID) std::cout << " . "; } top_block_acq->stop(); +#if USE_GLOG_AND_GFLAGS file_source->seek(2 * FLAGS_skip_samples, SEEK_SET); // skip head. ibyte, two bytes per complex sample +#else + file_source->seek(2 * absl::GetFlag(FLAGS_skip_samples), SEEK_SET); // skip head. ibyte, two bytes per complex sample +#endif std::cout.flush(); } std::cout << "]\n"; @@ -672,16 +755,23 @@ TEST_F(TrackingPullInTest, ValidationOfResults) // ************************************************* // ***** STEP 1: Prepare the parameters sweep ****** // ************************************************* - std::vector - acq_doppler_error_hz_values; + std::vector acq_doppler_error_hz_values; std::vector> acq_delay_error_chips_values; // vector of vector - +#if USE_GLOG_AND_GFLAGS for (double doppler_hz = FLAGS_acq_Doppler_error_hz_start; doppler_hz >= FLAGS_acq_Doppler_error_hz_stop; doppler_hz = doppler_hz + FLAGS_acq_Doppler_error_hz_step) +#else + for (double doppler_hz = absl::GetFlag(FLAGS_acq_Doppler_error_hz_start); doppler_hz >= absl::GetFlag(FLAGS_acq_Doppler_error_hz_stop); doppler_hz = doppler_hz + absl::GetFlag(FLAGS_acq_Doppler_error_hz_step)) +#endif + { acq_doppler_error_hz_values.push_back(doppler_hz); std::vector tmp_vector; - // Code Delay Sweep +// Code Delay Sweep +#if USE_GLOG_AND_GFLAGS for (double code_delay_chips = FLAGS_acq_Delay_error_chips_start; code_delay_chips >= FLAGS_acq_Delay_error_chips_stop; code_delay_chips = code_delay_chips + FLAGS_acq_Delay_error_chips_step) +#else + for (double code_delay_chips = absl::GetFlag(FLAGS_acq_Delay_error_chips_start); code_delay_chips >= absl::GetFlag(FLAGS_acq_Delay_error_chips_stop); code_delay_chips = code_delay_chips + absl::GetFlag(FLAGS_acq_Delay_error_chips_step)) +#endif { tmp_vector.push_back(code_delay_chips); } @@ -692,12 +782,17 @@ TEST_F(TrackingPullInTest, ValidationOfResults) // ***** STEP 2: Generate the input signal (if required) ***** // *********************************************************** std::vector generator_CN0_values; +#if USE_GLOG_AND_GFLAGS if (FLAGS_enable_external_signal_file) +#else + if (absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { generator_CN0_values.push_back(999); // an external input signal capture is selected, no CN0 information available } else { +#if USE_GLOG_AND_GFLAGS if (FLAGS_CN0_dBHz_start == FLAGS_CN0_dBHz_stop) { generator_CN0_values.push_back(FLAGS_CN0_dBHz_start); @@ -709,15 +804,39 @@ TEST_F(TrackingPullInTest, ValidationOfResults) generator_CN0_values.push_back(cn0); } } +#else + if (absl::GetFlag(FLAGS_CN0_dBHz_start) == absl::GetFlag(FLAGS_CN0_dBHz_stop)) + { + generator_CN0_values.push_back(absl::GetFlag(FLAGS_CN0_dBHz_start)); + } + else + { + for (double cn0 = absl::GetFlag(FLAGS_CN0_dBHz_start); cn0 > absl::GetFlag(FLAGS_CN0_dBHz_stop); cn0 = cn0 - absl::GetFlag(FLAGS_CN0_dB_step)) + { + generator_CN0_values.push_back(cn0); + } + } +#endif } - // use generator or use an external capture file + // use generator or use an external capture file + +#if USE_GLOG_AND_GFLAGS if (FLAGS_enable_external_signal_file) +#else + if (absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { +#if USE_GLOG_AND_GFLAGS // create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters ASSERT_EQ(acquire_signal(FLAGS_test_satellite_PRN), true); bool found_satellite = doppler_measurements_map.find(FLAGS_test_satellite_PRN) != doppler_measurements_map.end(); EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << FLAGS_test_satellite_PRN << " is not acquired"; +#else + ASSERT_EQ(acquire_signal(absl::GetFlag(FLAGS_test_satellite_PRN)), true); + bool found_satellite = doppler_measurements_map.find(absl::GetFlag(FLAGS_test_satellite_PRN)) != doppler_measurements_map.end(); + EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << absl::GetFlag(FLAGS_test_satellite_PRN) << " is not acquired"; +#endif if (!found_satellite) { return; @@ -730,18 +849,30 @@ TEST_F(TrackingPullInTest, ValidationOfResults) // Configure the signal generator configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); // Generate signal raw signal samples and observations RINEX file +#if USE_GLOG_AND_GFLAGS if (FLAGS_disable_generator == false) +#else + if (absl::GetFlag(FLAGS_disable_generator) == false) +#endif { generate_signal(); } } } +#if USE_GLOG_AND_GFLAGS configure_receiver(FLAGS_PLL_bw_hz_start, FLAGS_DLL_bw_hz_start, FLAGS_PLL_narrow_bw_hz, FLAGS_DLL_narrow_bw_hz, FLAGS_extend_correlation_symbols); +#else + configure_receiver(absl::GetFlag(FLAGS_PLL_bw_hz_start), + absl::GetFlag(FLAGS_DLL_bw_hz_start), + absl::GetFlag(FLAGS_PLL_narrow_bw_hz), + absl::GetFlag(FLAGS_DLL_narrow_bw_hz), + absl::GetFlag(FLAGS_extend_correlation_symbols)); +#endif // ****************************************************************************************** // ***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** @@ -752,9 +883,15 @@ TEST_F(TrackingPullInTest, ValidationOfResults) uint64_t acq_samplestamp_samples = 0; Tracking_True_Obs_Reader true_obs_data; +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { test_satellite_PRN = FLAGS_test_satellite_PRN; +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + test_satellite_PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); true_obs_file.append(".dat"); @@ -763,7 +900,11 @@ TEST_F(TrackingPullInTest, ValidationOfResults) // load acquisition data based on the first epoch of the true observations ASSERT_EQ(true_obs_data.read_binary_obs(), true) << "Failure reading true tracking dump file.\n" +#if USE_GLOG_AND_GFLAGS << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + +#else + << "Maybe sat PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + +#endif " is not available?"; std::cout << "Testing satellite PRN=" << test_satellite_PRN << '\n'; std::cout << "True Initial Doppler " << true_obs_data.doppler_l1_hz << " [Hz], true Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << "[Chips]\n"; @@ -773,17 +914,30 @@ TEST_F(TrackingPullInTest, ValidationOfResults) } else { +#if USE_GLOG_AND_GFLAGS true_acq_doppler_hz = doppler_measurements_map.find(FLAGS_test_satellite_PRN)->second; true_acq_delay_samples = code_delay_measurements_map.find(FLAGS_test_satellite_PRN)->second; +#else + true_acq_doppler_hz = doppler_measurements_map.find(absl::GetFlag(FLAGS_test_satellite_PRN))->second; + true_acq_delay_samples = code_delay_measurements_map.find(absl::GetFlag(FLAGS_test_satellite_PRN))->second; +#endif acq_samplestamp_samples = 0; std::cout << "Estimated Initial Doppler " << true_acq_doppler_hz << " [Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]" +#if USE_GLOG_AND_GFLAGS << " Acquisition SampleStamp is " << acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second << '\n'; +#else + << " Acquisition SampleStamp is " << acq_samplestamp_map.find(absl::GetFlag(FLAGS_test_satellite_PRN))->second << '\n'; +#endif } // create the msg queue for valve queue = std::make_shared>(); +#if USE_GLOG_AND_GFLAGS long long int acq_to_trk_delay_samples = ceil(static_cast(FLAGS_fs_gen_sps) * FLAGS_acq_to_trk_delay_s); +#else + long long int acq_to_trk_delay_samples = ceil(static_cast(absl::GetFlag(FLAGS_fs_gen_sps)) * absl::GetFlag(FLAGS_acq_to_trk_delay_s)); +#endif auto resetable_valve_ = gnss_sdr_make_valve(sizeof(gr_complex), acq_to_trk_delay_samples, queue.get(), false); // CN0 LOOP @@ -822,19 +976,31 @@ TEST_F(TrackingPullInTest, ValidationOfResults) std::string file; ASSERT_NO_THROW({ +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { file = "./" + filename_raw_data + std::to_string(current_cn0_idx); } else { +#if USE_GLOG_AND_GFLAGS file = FLAGS_signal_file; +#else + file = absl::GetFlag(FLAGS_signal_file); +#endif } const char* file_name = file.c_str(); gr::blocks::file_source::sptr file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name, false); gr::blocks::interleaved_char_to_complex::sptr gr_interleaved_char_to_complex = gr::blocks::interleaved_char_to_complex::make(); gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); +#if USE_GLOG_AND_GFLAGS gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * FLAGS_duration); +#else + gr::blocks::head::sptr head_samples = gr::blocks::head::make(sizeof(gr_complex), baseband_sampling_freq * absl::GetFlag(FLAGS_duration)); +#endif top_block_trk->connect(file_source, 0, gr_interleaved_char_to_complex, 0); top_block_trk->connect(gr_interleaved_char_to_complex, 0, head_samples, 0); if (acq_to_trk_delay_samples > 0) @@ -848,7 +1014,11 @@ TEST_F(TrackingPullInTest, ValidationOfResults) } top_block_trk->connect(tracking->get_right_block(), 0, sink, 0); top_block_trk->msg_connect(tracking->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); +#if USE_GLOG_AND_GFLAGS file_source->seek(2 * FLAGS_skip_samples, 0); // skip head. ibyte, two bytes per complex sample +#else + file_source->seek(2 * absl::GetFlag(FLAGS_skip_samples), 0); // skip head. ibyte, two bytes per complex sample +#endif }) << "Failure connecting the blocks of tracking test."; // ******************************************************************** @@ -860,7 +1030,11 @@ TEST_F(TrackingPullInTest, ValidationOfResults) { EXPECT_NO_THROW({ start = std::chrono::system_clock::now(); +#if USE_GLOG_AND_GFLAGS std::cout << "--- SIMULATING A PULL-IN DELAY OF " << FLAGS_acq_to_trk_delay_s << " SECONDS ---\n"; +#else + std::cout << "--- SIMULATING A PULL-IN DELAY OF " << absl::GetFlag(FLAGS_acq_to_trk_delay_s) << " SECONDS ---\n"; +#endif top_block_trk->start(); std::cout << " Waiting for valve...\n"; // wait the valve message indicating the circulation of the amount of samples of the delay @@ -889,10 +1063,14 @@ TEST_F(TrackingPullInTest, ValidationOfResults) pull_in_results_v.push_back(msg_rx->rx_message != 3); // save last asynchronous tracking message in order to detect a loss of lock - // ******************************** - // ***** STEP 7: Plot results ***** - // ******************************** +// ******************************** +// ***** STEP 7: Plot results ***** +// ******************************** +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_plot_detail_level) >= 2 and absl::GetFlag(FLAGS_show_plots)) +#endif { // load the measured values Tracking_Dump_Reader trk_dump; @@ -937,8 +1115,11 @@ TEST_F(TrackingPullInTest, ValidationOfResults) Doppler.push_back(trk_dump.carrier_doppler_hz); epoch_counter++; } - +#if USE_GLOG_AND_GFLAGS const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag show_plots has been set to TRUE,\n"; @@ -953,6 +1134,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) fs::path dir = p.parent_path(); const std::string& gnuplot_path = dir.native(); Gnuplot::set_GNUPlotPath(gnuplot_path); +#if USE_GLOG_AND_GFLAGS auto decimate = static_cast(FLAGS_plot_decimate); if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots) @@ -967,6 +1149,22 @@ TEST_F(TrackingPullInTest, ValidationOfResults) { g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } +#else + auto decimate = static_cast(absl::GetFlag(FLAGS_plot_decimate)); + + if (absl::GetFlag(FLAGS_plot_detail_level) >= 2 and absl::GetFlag(FLAGS_show_plots)) + { + Gnuplot g1("linespoints"); + g1.showonscreen(); // window output + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g1.set_grid(); g1.set_xlabel("Time [s]"); @@ -985,6 +1183,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) Gnuplot g2("points"); g2.showonscreen(); // window output +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); @@ -993,7 +1192,16 @@ TEST_F(TrackingPullInTest, ValidationOfResults) { g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } - +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g2.set_grid(); g2.set_xlabel("Inphase"); g2.set_ylabel("Quadrature"); @@ -1002,6 +1210,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) g2.savetops("Constellation"); Gnuplot g3("linespoints"); +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { g3.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); @@ -1010,6 +1219,16 @@ TEST_F(TrackingPullInTest, ValidationOfResults) { g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g3.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g3.set_grid(); g3.set_xlabel("Time [s]"); g3.set_ylabel("Reported CN0 [dB-Hz]"); @@ -1024,6 +1243,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) g3.showonscreen(); // window output Gnuplot g4("linespoints"); +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { g4.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); @@ -1032,6 +1252,16 @@ TEST_F(TrackingPullInTest, ValidationOfResults) { g4.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g4.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g4.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g4.set_grid(); g4.set_xlabel("Time [s]"); g4.set_ylabel("Estimated Doppler [Hz]"); @@ -1052,8 +1282,8 @@ TEST_F(TrackingPullInTest, ValidationOfResults) } } } // end plot - } // end acquisition Delay errors loop - } // end acquisition Doppler errors loop + } // end acquisition Delay errors loop + } // end acquisition Doppler errors loop pull_in_results_v_v.push_back(pull_in_results_v); } // end CN0 LOOP @@ -1075,7 +1305,11 @@ TEST_F(TrackingPullInTest, ValidationOfResults) pull_in_result_mesh = pull_in_results_v_v.at(current_cn0_idx); // plot grid Gnuplot g4("points palette pointsize 2 pointtype 7"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g4.showonscreen(); // window output } @@ -1087,6 +1321,7 @@ TEST_F(TrackingPullInTest, ValidationOfResults) g4.cmd("set key off"); g4.cmd("set view map"); std::string title; +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz]."); @@ -1095,7 +1330,16 @@ TEST_F(TrackingPullInTest, ValidationOfResults) { title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } - +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz]."); + } + else + { + title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g4.set_title(title); g4.set_grid(); g4.set_xlabel("Acquisition Doppler error [Hz]"); @@ -1105,7 +1349,11 @@ TEST_F(TrackingPullInTest, ValidationOfResults) code_delay_error_mesh, pull_in_result_mesh); g4.set_legend(); +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx))))); g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))), 12); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc b/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc similarity index 80% rename from src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc rename to tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc index dedfcb658..77f062395 100644 --- a/src/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc +++ b/tests/unit-tests/signal-processing-blocks/tracking/tracking_pull-in_test_fpga.cc @@ -73,7 +73,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO TRACKING BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO TRACKING BLOCK MESSAGE RECEIVER ######### class TrackingPullInTest_msg_rx_Fpga; using TrackingPullInTest_msg_rx_Fpga_sptr = gnss_shared_ptr; @@ -201,10 +201,15 @@ void* handler_DMA_trk_pull_in_test(void* arguments) return nullptr; } - // ************************************************************************* - // Open input file - // ************************************************************************* + // ************************************************************************* + // Open input file + // ************************************************************************* + +#if USE_GLOG_AND_GFLAGS uint32_t skip_samples = static_cast(FLAGS_skip_samples); +#else + uint32_t skip_samples = static_cast(absl::GetFlag(FLAGS_skip_samples)); +#endif if (skip_samples + skip_used_samples > 0) { @@ -328,12 +333,17 @@ public: std::string p4; std::string p5; std::string p6; +#if USE_GLOG_AND_GFLAGS std::string implementation = FLAGS_trk_test_implementation; - const int baseband_sampling_freq = FLAGS_fs_gen_sps; std::string filename_rinex_obs = FLAGS_filename_rinex_obs; std::string filename_raw_data = FLAGS_signal_file; - +#else + std::string implementation = absl::GetFlag(FLAGS_trk_test_implementation); + const int baseband_sampling_freq = absl::GetFlag(FLAGS_fs_gen_sps); + std::string filename_rinex_obs = absl::GetFlag(FLAGS_filename_rinex_obs); + std::string filename_raw_data = absl::GetFlag(FLAGS_signal_file); +#endif std::map doppler_measurements_map; std::map code_delay_measurements_map; std::map acq_samplestamp_map; @@ -391,6 +401,7 @@ public: int TrackingPullInTestFpga::configure_generator(double CN0_dBHz, int file_idx) { +#if USE_GLOG_AND_GFLAGS // Configure signal generator generator_binary = FLAGS_generator_binary; @@ -407,6 +418,25 @@ int TrackingPullInTestFpga::configure_generator(double CN0_dBHz, int file_idx) p4 = std::string("-sig_out_file=") + FLAGS_signal_file + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 +#else + // Configure signal generator + generator_binary = absl::GetFlag(FLAGS_generator_binary); + + p1 = std::string("-rinex_nav_file=") + absl::GetFlag(FLAGS_rinex_nav_file); + if (absl::GetFlag(FLAGS_dynamic_position).empty()) + { + p2 = std::string("-static_position=") + absl::GetFlag(FLAGS_static_position) + std::string(",") + std::to_string(absl::GetFlag(FLAGS_duration) * 10); + } + else + { + p2 = std::string("-obs_pos_file=") + std::string(absl::GetFlag(FLAGS_dynamic_position)); + } + p3 = std::string("-rinex_obs_file=") + absl::GetFlag(FLAGS_filename_rinex_obs); // RINEX 2.10 observation file output + p4 = std::string("-sig_out_file=") + absl::GetFlag(FLAGS_signal_file) + std::to_string(file_idx); // Baseband signal output file. Will be stored in int8_t IQ multiplexed samples + p5 = std::string("-sampling_freq=") + std::to_string(baseband_sampling_freq); // Baseband sampling frequency [MSps] + p6 = std::string("-CN0_dBHz=") + std::to_string(CN0_dBHz); // Signal generator CN0 +#endif + return 0; } @@ -497,12 +527,16 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("Tracking.extend_correlation_symbols", std::to_string(extend_correlation_symbols)); config->set_property("Tracking.pll_bw_narrow_hz", std::to_string(PLL_narrow_bw_hz)); config->set_property("Tracking.dll_bw_narrow_hz", std::to_string(DLL_narrow_bw_hz)); +#if USE_GLOG_AND_GFLAGS gnss_synchro.PRN = FLAGS_test_satellite_PRN; +#else + gnss_synchro.PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif gnss_synchro.Channel_ID = 0; config->set_property("GNSS-SDR.internal_fs_sps", std::to_string(baseband_sampling_freq)); std::string System_and_Signal; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { gnss_synchro.System = 'G'; std::string signal = "1C"; @@ -511,7 +545,7 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("Tracking.early_late_space_chips", "0.5"); config->set_property("Tracking.early_late_space_narrow_chips", "0.5"); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { gnss_synchro.System = 'E'; std::string signal = "1B"; @@ -523,7 +557,7 @@ void TrackingPullInTestFpga::configure_receiver( config->set_property("Tracking.very_early_late_space_narrow_chips", "0.6"); config->set_property("Tracking.track_pilot", "true"); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga" or implementation == "Galileo_E5a_DLL_PLL_Tracking_b_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA" or implementation == "Galileo_E5a_DLL_PLL_Tracking_b_Fpga") { gnss_synchro.System = 'E'; std::string signal = "5X"; @@ -531,13 +565,13 @@ void TrackingPullInTestFpga::configure_receiver( signal.copy(gnss_synchro.Signal, 2, 0); if (implementation == "Galileo_E5a_DLL_PLL_Tracking_b") { - config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking_Fpga")); + config->supersede_property("Tracking.implementation", std::string("Galileo_E5a_DLL_PLL_Tracking_FPGA")); } config->set_property("Tracking.early_late_space_chips", "0.5"); config->set_property("Tracking.track_pilot", "true"); config->set_property("Tracking.order", "2"); } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { gnss_synchro.System = 'G'; std::string signal = "L5"; @@ -590,17 +624,21 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) struct DMA_handler_args_trk_pull_in_test args; struct acquisition_handler_args_trk_pull_in_test args_acq; +#if USE_GLOG_AND_GFLAGS std::string file = FLAGS_signal_file; +#else + std::string file = absl::GetFlag(FLAGS_signal_file); +#endif args.file = file; // DMA file configuration // instantiate the FPGA switch and set the // switch position to DMA. std::shared_ptr switch_fpga; - switch_fpga = std::make_shared("/dev/uio1"); + switch_fpga = std::make_shared(); switch_fpga->set_switch_position(0); // set switch position to DMA // create the correspondign acquisition block according to the desired tracking signal - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "1C"; @@ -612,7 +650,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "1B"; @@ -624,7 +662,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 0; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'E'; signal = "5X"; @@ -636,7 +674,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) args.freq_band = 1; // frequency band on which the DMA has to transfer the samples } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { tmp_gnss_synchro.System = 'G'; signal = "L5"; @@ -657,11 +695,17 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) acquisition->set_gnss_synchro(&tmp_gnss_synchro); acquisition->set_channel_fsm(channel_fsm_); acquisition->set_channel(0); +#if USE_GLOG_AND_GFLAGS acquisition->set_doppler_max(config->property("Acquisition.doppler_max", FLAGS_external_signal_acquisition_doppler_max_hz)); acquisition->set_doppler_step(config->property("Acquisition.doppler_step", FLAGS_external_signal_acquisition_doppler_step_hz)); acquisition->set_doppler_center(0); acquisition->set_threshold(config->property("Acquisition.threshold", FLAGS_external_signal_acquisition_threshold)); - +#else + acquisition->set_doppler_max(config->property("Acquisition.doppler_max", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_max_hz))); + acquisition->set_doppler_step(config->property("Acquisition.doppler_step", absl::GetFlag(FLAGS_external_signal_acquisition_doppler_step_hz))); + acquisition->set_doppler_center(0); + acquisition->set_threshold(config->property("Acquisition.threshold", absl::GetFlag(FLAGS_external_signal_acquisition_threshold))); +#endif std::chrono::time_point start, end; std::chrono::duration elapsed_seconds; start = std::chrono::system_clock::now(); @@ -688,19 +732,19 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) // number of samples that the DMA has to transfer unsigned int nsamples_to_transfer; - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L1_CA_CODE_RATE_CPS / GPS_L1_CA_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E1_CODE_CHIP_RATE_CPS / GALILEO_E1_B_CODE_LENGTH_CHIPS))); } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GALILEO_E5A_CODE_CHIP_RATE_CPS / GALILEO_E5A_CODE_LENGTH_CHIPS))); } - else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_Fpga") == 0)) + else // (if (implementation.compare("GPS_L5_DLL_PLL_Tracking_FPGA") == 0)) { nsamples_to_transfer = static_cast(std::round(static_cast(baseband_sampling_freq) / (GPS_L5I_CODE_RATE_CPS / GPS_L5I_CODE_LENGTH_CHIPS))); } @@ -718,7 +762,7 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) acquisition->init(); acquisition->set_local_code(); - if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga")) + if ((implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") or (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA")) { // Configure the DMA to send TEST_TRK_PULL_IN_TEST_SKIP_SAMPLES in order to initialize the internal // states of the downsampling filter in the FPGA @@ -755,7 +799,11 @@ bool TrackingPullInTestFpga::acquire_signal(int SV_ID) if (start_msg == true) { +#if USE_GLOG_AND_GFLAGS std::cout << "Reading external signal file: " << FLAGS_signal_file << '\n'; +#else + std::cout << "Reading external signal file: " << absl::GetFlag(FLAGS_signal_file) << '\n'; +#endif std::cout << "Searching for " << System_and_Signal << " Satellites...\n"; std::cout << "["; start_msg = false; @@ -824,13 +872,20 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) std::vector acq_doppler_error_hz_values; std::vector> acq_delay_error_chips_values; // vector of vector - +#if USE_GLOG_AND_GFLAGS for (double doppler_hz = FLAGS_acq_Doppler_error_hz_start; doppler_hz >= FLAGS_acq_Doppler_error_hz_stop; doppler_hz = doppler_hz + FLAGS_acq_Doppler_error_hz_step) +#else + for (double doppler_hz = absl::GetFlag(FLAGS_acq_Doppler_error_hz_start); doppler_hz >= absl::GetFlag(FLAGS_acq_Doppler_error_hz_stop); doppler_hz = doppler_hz + absl::GetFlag(FLAGS_acq_Doppler_error_hz_step)) +#endif { acq_doppler_error_hz_values.push_back(doppler_hz); std::vector tmp_vector; // Code Delay Sweep +#if USE_GLOG_AND_GFLAGS for (double code_delay_chips = FLAGS_acq_Delay_error_chips_start; code_delay_chips >= FLAGS_acq_Delay_error_chips_stop; code_delay_chips = code_delay_chips + FLAGS_acq_Delay_error_chips_step) +#else + for (double code_delay_chips = absl::GetFlag(FLAGS_acq_Delay_error_chips_start); code_delay_chips >= absl::GetFlag(FLAGS_acq_Delay_error_chips_stop); code_delay_chips = code_delay_chips + absl::GetFlag(FLAGS_acq_Delay_error_chips_step)) +#endif { tmp_vector.push_back(code_delay_chips); } @@ -841,6 +896,7 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) // ***** STEP 2: Generate the input signal (if required) ***** // *********************************************************** std::vector generator_CN0_values; +#if USE_GLOG_AND_GFLAGS if (FLAGS_enable_external_signal_file) { generator_CN0_values.push_back(999); // an external input signal capture is selected, no CN0 information available @@ -859,14 +915,44 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) } } } +#else + if (absl::GetFlag(FLAGS_enable_external_signal_file)) + { + generator_CN0_values.push_back(999); // an external input signal capture is selected, no CN0 information available + } + else + { + if (absl::GetFlag(FLAGS_CN0_dBHz_start) == absl::GetFlag(FLAGS_CN0_dBHz_stop)) + { + generator_CN0_values.push_back(absl::GetFlag(FLAGS_CN0_dBHz_start)); + } + else + { + for (double cn0 = absl::GetFlag(FLAGS_CN0_dBHz_start); cn0 > absl::GetFlag(FLAGS_CN0_dBHz_stop); cn0 = cn0 - absl::GetFlag(FLAGS_CN0_dB_step)) + { + generator_CN0_values.push_back(cn0); + } + } + } +#endif - // use generator or use an external capture file + // use generator or use an external capture file + +#if USE_GLOG_AND_GFLAGS if (FLAGS_enable_external_signal_file) { // create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters ASSERT_EQ(acquire_signal(FLAGS_test_satellite_PRN), true); bool found_satellite = doppler_measurements_map.find(FLAGS_test_satellite_PRN) != doppler_measurements_map.end(); EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << FLAGS_test_satellite_PRN << " is not acquired"; +#else + if (absl::GetFlag(FLAGS_enable_external_signal_file)) + { + // create and configure an acquisition block and perform an acquisition to obtain the synchronization parameters + ASSERT_EQ(acquire_signal(absl::GetFlag(FLAGS_test_satellite_PRN)), true); + bool found_satellite = doppler_measurements_map.find(absl::GetFlag(FLAGS_test_satellite_PRN)) != doppler_measurements_map.end(); + EXPECT_TRUE(found_satellite) << "Error: satellite SV: " << absl::GetFlag(FLAGS_test_satellite_PRN) << " is not acquired"; +#endif if (!found_satellite) { return; @@ -879,18 +965,30 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) // Configure the signal generator configure_generator(generator_CN0_values.at(current_cn0_idx), current_cn0_idx); // Generate signal raw signal samples and observations RINEX file + +#if USE_GLOG_AND_GFLAGS if (FLAGS_disable_generator == false) +#else + if (absl::GetFlag(FLAGS_disable_generator) == false) +#endif { generate_signal(); } } } - +#if USE_GLOG_AND_GFLAGS configure_receiver(FLAGS_PLL_bw_hz_start, FLAGS_DLL_bw_hz_start, FLAGS_PLL_narrow_bw_hz, FLAGS_DLL_narrow_bw_hz, FLAGS_extend_correlation_symbols); +#else + configure_receiver(absl::GetFlag(FLAGS_PLL_bw_hz_start), + absl::GetFlag(FLAGS_DLL_bw_hz_start), + absl::GetFlag(FLAGS_PLL_narrow_bw_hz), + absl::GetFlag(FLAGS_DLL_narrow_bw_hz), + absl::GetFlag(FLAGS_extend_correlation_symbols)); +#endif // ****************************************************************************************** // ***** Obtain the initial signal sinchronization parameters (emulating an acquisition) **** @@ -901,9 +999,15 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) uint64_t acq_samplestamp_samples = 0; Tracking_True_Obs_Reader true_obs_data; +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { test_satellite_PRN = FLAGS_test_satellite_PRN; +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + test_satellite_PRN = absl::GetFlag(FLAGS_test_satellite_PRN); +#endif std::string true_obs_file = std::string("./gps_l1_ca_obs_prn"); true_obs_file.append(std::to_string(test_satellite_PRN)); true_obs_file.append(".dat"); @@ -912,7 +1016,11 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) // load acquisition data based on the first epoch of the true observations ASSERT_EQ(true_obs_data.read_binary_obs(), true) << "Failure reading true tracking dump file.\n" +#if USE_GLOG_AND_GFLAGS << "Maybe sat PRN #" + std::to_string(FLAGS_test_satellite_PRN) + +#else + << "Maybe sat PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + +#endif " is not available?"; std::cout << "Testing satellite PRN=" << test_satellite_PRN << '\n'; std::cout << "True Initial Doppler " << true_obs_data.doppler_l1_hz << " [Hz], true Initial code delay [Chips]=" << true_obs_data.prn_delay_chips << "[Chips]\n"; @@ -922,16 +1030,29 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) } else { +#if USE_GLOG_AND_GFLAGS true_acq_doppler_hz = doppler_measurements_map.find(FLAGS_test_satellite_PRN)->second; true_acq_delay_samples = code_delay_measurements_map.find(FLAGS_test_satellite_PRN)->second; acq_samplestamp_samples = acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second; +#else + true_acq_doppler_hz = doppler_measurements_map.find(absl::GetFlag(FLAGS_test_satellite_PRN))->second; + true_acq_delay_samples = code_delay_measurements_map.find(absl::GetFlag(FLAGS_test_satellite_PRN))->second; + acq_samplestamp_samples = acq_samplestamp_map.find(absl::GetFlag(FLAGS_test_satellite_PRN))->second; +#endif std::cout << "Estimated Initial Doppler " << true_acq_doppler_hz << " [Hz], estimated Initial code delay " << true_acq_delay_samples << " [Samples]" +#if USE_GLOG_AND_GFLAGS << " Acquisition SampleStamp is " << acq_samplestamp_map.find(FLAGS_test_satellite_PRN)->second << '\n'; +#else + << " Acquisition SampleStamp is " << acq_samplestamp_map.find(absl::GetFlag(FLAGS_test_satellite_PRN))->second << '\n'; +#endif } - +#if USE_GLOG_AND_GFLAGS int64_t acq_to_trk_delay_samples = ceil(static_cast(FLAGS_fs_gen_sps) * FLAGS_acq_to_trk_delay_s); +#else + int64_t acq_to_trk_delay_samples = ceil(static_cast(absl::GetFlag(FLAGS_fs_gen_sps)) * absl::GetFlag(FLAGS_acq_to_trk_delay_s)); +#endif // set the scaling factor args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR; @@ -958,22 +1079,22 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) std::shared_ptr acquisition; // reset the HW to clear the sample counters: the acquisition constructor generates a reset - if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_Fpga") + if (implementation == "GPS_L1_CA_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_Fpga") + else if (implementation == "Galileo_E1_DLL_PLL_VEML_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 0; } - else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_Fpga") + else if (implementation == "Galileo_E5a_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1; } - else if (implementation == "GPS_L5_DLL_PLL_Tracking_Fpga") + else if (implementation == "GPS_L5_DLL_PLL_Tracking_FPGA") { acquisition = std::make_shared(config.get(), "Acquisition", 0, 0); args.freq_band = 1; @@ -1006,13 +1127,21 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) std::string file; ASSERT_NO_THROW({ +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { file = "./" + filename_raw_data + std::to_string(current_cn0_idx); } else { +#if USE_GLOG_AND_GFLAGS file = FLAGS_signal_file; +#else + file = absl::GetFlag(FLAGS_signal_file); +#endif } gr::blocks::null_sink::sptr sink = gr::blocks::null_sink::make(sizeof(Gnss_Synchro)); @@ -1034,8 +1163,11 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) if (acq_to_trk_delay_samples > 0) { +#if USE_GLOG_AND_GFLAGS std::cout << "--- SIMULATING A PULL-IN DELAY OF " << FLAGS_acq_to_trk_delay_s << " SECONDS ---\n"; - +#else + std::cout << "--- SIMULATING A PULL-IN DELAY OF " << absl::GetFlag(FLAGS_acq_to_trk_delay_s) << " SECONDS ---\n"; +#endif args.file = file; args.nsamples_tx = acq_to_trk_delay_samples; // 150 s for now but will be all file @@ -1053,8 +1185,11 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) std::cout << " Waiting flowgraph..\n"; args.file = file; +#if USE_GLOG_AND_GFLAGS args.nsamples_tx = baseband_sampling_freq * FLAGS_duration; - +#else + args.nsamples_tx = baseband_sampling_freq * absl::GetFlag(FLAGS_duration); +#endif args.skip_used_samples = acq_to_trk_delay_samples; if (pthread_create(&thread_DMA, nullptr, handler_DMA_trk_pull_in_test, reinterpret_cast(&args)) < 0) @@ -1082,7 +1217,12 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) // ******************************** // ***** STEP 7: Plot results ***** // ******************************** + +#if USE_GLOG_AND_GFLAGS if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_plot_detail_level) >= 2 and absl::GetFlag(FLAGS_show_plots)) +#endif { // load the measured values Tracking_Dump_Reader trk_dump; @@ -1127,8 +1267,11 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) Doppler.push_back(trk_dump.carrier_doppler_hz); epoch_counter++; } - +#if USE_GLOG_AND_GFLAGS const std::string gnuplot_executable(FLAGS_gnuplot_executable); +#else + const std::string gnuplot_executable(absl::GetFlag(FLAGS_gnuplot_executable)); +#endif if (gnuplot_executable.empty()) { std::cout << "WARNING: Although the flag show_plots has been set to TRUE,\n"; @@ -1143,6 +1286,7 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) fs::path dir = p.parent_path(); const std::string& gnuplot_path = dir.native(); Gnuplot::set_GNUPlotPath(gnuplot_path); +#if USE_GLOG_AND_GFLAGS auto decimate = static_cast(FLAGS_plot_decimate); if (FLAGS_plot_detail_level >= 2 and FLAGS_show_plots) @@ -1157,7 +1301,22 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) { g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } +#else + auto decimate = static_cast(absl::GetFlag(FLAGS_plot_decimate)); + if (absl::GetFlag(FLAGS_plot_detail_level) >= 2 and absl::GetFlag(FLAGS_show_plots)) + { + Gnuplot g1("linespoints"); + g1.showonscreen(); // window output + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g1.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, " + "PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g1.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g1.set_grid(); g1.set_xlabel("Time [s]"); g1.set_ylabel("Correlators' output"); @@ -1175,6 +1334,7 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) Gnuplot g2("points"); g2.showonscreen(); // window output +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); @@ -1183,7 +1343,16 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) { g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } - +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g2.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz Constellation " + "PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g2.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips], PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g2.set_grid(); g2.set_xlabel("Inphase"); g2.set_ylabel("Quadrature"); @@ -1192,6 +1361,7 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) g2.savetops("Constellation"); Gnuplot g3("linespoints"); +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { g3.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); @@ -1200,6 +1370,16 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) { g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g3.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g3.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g3.set_grid(); g3.set_xlabel("Time [s]"); g3.set_ylabel("Reported CN0 [dB-Hz]"); @@ -1214,6 +1394,7 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) g3.showonscreen(); // window output Gnuplot g4("linespoints"); +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { g4.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); @@ -1222,6 +1403,16 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) { g4.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + g4.set_title(std::to_string(generator_CN0_values.at(current_cn0_idx)) + " dB-Hz, GPS L1 C/A tracking CN0 output (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } + else + { + g4.set_title("D_e=" + std::to_string(acq_doppler_error_hz_values.at(current_acq_doppler_error_idx)) + " [Hz] " + "T_e= " + std::to_string(acq_delay_error_chips_values.at(current_acq_doppler_error_idx).at(current_acq_code_error_idx)) + " [Chips] PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g4.set_grid(); g4.set_xlabel("Time [s]"); g4.set_ylabel("Estimated Doppler [Hz]"); @@ -1242,8 +1433,8 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) } } } // end plot - } // end acquisition Delay errors loop - } // end acquisition Doppler errors loop + } // end acquisition Delay errors loop + } // end acquisition Doppler errors loop pull_in_results_v_v.push_back(pull_in_results_v); } // end CN0 LOOP @@ -1265,7 +1456,11 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) pull_in_result_mesh = pull_in_results_v_v.at(current_cn0_idx); // plot grid Gnuplot g4("points palette pointsize 2 pointtype 7"); +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { g4.showonscreen(); // window output } @@ -1277,6 +1472,7 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) g4.cmd("set key off"); g4.cmd("set view map"); std::string title; +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) { title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz]."); @@ -1285,7 +1481,16 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) { title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(FLAGS_PLL_bw_hz_start) + "," + std::to_string(FLAGS_DLL_bw_hz_start) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(FLAGS_test_satellite_PRN) + ")"); } - +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) + { + title = std::string("Tracking Pull-in result grid at CN0:" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))) + " [dB-Hz], PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz]."); + } + else + { + title = std::string("Tracking Pull-in result grid, PLL/DLL BW: " + std::to_string(absl::GetFlag(FLAGS_PLL_bw_hz_start)) + "," + std::to_string(absl::GetFlag(FLAGS_DLL_bw_hz_start)) + " [Hz], GPS L1 C/A (PRN #" + std::to_string(absl::GetFlag(FLAGS_test_satellite_PRN)) + ")"); + } +#endif g4.set_title(title); g4.set_grid(); g4.set_xlabel("Acquisition Doppler error [Hz]"); @@ -1295,7 +1500,11 @@ TEST_F(TrackingPullInTestFpga, ValidationOfResults) code_delay_error_mesh, pull_in_result_mesh); g4.set_legend(); +#if USE_GLOG_AND_GFLAGS if (!FLAGS_enable_external_signal_file) +#else + if (!absl::GetFlag(FLAGS_enable_external_signal_file)) +#endif { g4.savetops("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx))))); g4.savetopdf("trk_pull_in_grid_" + std::to_string(static_cast(round(generator_CN0_values.at(current_cn0_idx)))), 12); diff --git a/src/tests/unit-tests/signal-processing-blocks/tracking/unscented_filter_test.cc b/tests/unit-tests/signal-processing-blocks/tracking/unscented_filter_test.cc similarity index 100% rename from src/tests/unit-tests/signal-processing-blocks/tracking/unscented_filter_test.cc rename to tests/unit-tests/signal-processing-blocks/tracking/unscented_filter_test.cc diff --git a/src/tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc b/tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc similarity index 100% rename from src/tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc rename to tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc diff --git a/src/tests/unit-tests/system-parameters/galileo_e6b_reed_solomon_test.cc b/tests/unit-tests/system-parameters/galileo_e6b_reed_solomon_test.cc similarity index 100% rename from src/tests/unit-tests/system-parameters/galileo_e6b_reed_solomon_test.cc rename to tests/unit-tests/system-parameters/galileo_e6b_reed_solomon_test.cc diff --git a/tests/unit-tests/system-parameters/galileo_ism_test.cc b/tests/unit-tests/system-parameters/galileo_ism_test.cc new file mode 100644 index 000000000..131022720 --- /dev/null +++ b/tests/unit-tests/system-parameters/galileo_ism_test.cc @@ -0,0 +1,35 @@ +/*! + * \file galileo_ism_test.cc + * \brief Tests for Galileo Integrity Support Message + * \author Carles Fernandez-Prades, 2024. cfernandez(at)cttc.es + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "galileo_ism.h" +#include + +TEST(GalileoISMTest, CRC) +{ + // Example from ANNEX G Galileo ICD + Galileo_ISM gal_ism{}; + std::bitset<128> input{"01011000001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010110010111101001101011010101111"}; + bool result = gal_ism.check_ism_crc(input); + EXPECT_TRUE(result); + // Check if it can be used twice + bool result2 = gal_ism.check_ism_crc(input); + EXPECT_TRUE(result2); + // Check if it fails + input.set(127); + bool result3 = gal_ism.check_ism_crc(input); + EXPECT_TRUE(!result3); +} \ No newline at end of file diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc b/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc similarity index 100% rename from src/tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc rename to tests/unit-tests/system-parameters/glonass_gnav_crc_test.cc diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc similarity index 100% rename from src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc rename to tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc b/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc similarity index 100% rename from src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc rename to tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc diff --git a/src/tests/unit-tests/system-parameters/has_decoding_test.cc b/tests/unit-tests/system-parameters/has_decoding_test.cc similarity index 96% rename from src/tests/unit-tests/system-parameters/has_decoding_test.cc rename to tests/unit-tests/system-parameters/has_decoding_test.cc index 593ce79de..7dc0c95a5 100644 --- a/src/tests/unit-tests/system-parameters/has_decoding_test.cc +++ b/tests/unit-tests/system-parameters/has_decoding_test.cc @@ -20,7 +20,6 @@ #include "galileo_has_page.h" #include "gnss_sdr_make_unique.h" #include "has_simple_printer.h" -#include #include #include #include @@ -34,9 +33,15 @@ // Usage: // ./run_tests --gtest_filter=HAS_Test.Decoder -// ./run_tests --gtest_filter=HAS_Test.Decoder --has_data_test_file=../data/HAS_Messages_sample/encoded/Sample_HAS_Pages_Encoded_20210713_08.txt --start_page_test_file=70 +// ./run_tests --gtest_filter=HAS_Test.Decoder --has_data_test_file=./HAS_Messages_sample/encoded/Sample_HAS_Pages_Encoded_20210713_08.txt --start_page_test_file=70 + +#if USE_GLOG_AND_GFLAGS DEFINE_string(has_data_test_file, std::string(""), "File containing encoded HAS pages (format: [time sat_id HAS_page_in_hex] in each line)"); DEFINE_int32(start_page_test_file, 0, "Starting page in case of reading HAS pages from a file"); +#else +ABSL_FLAG(std::string, has_data_test_file, std::string(""), "File containing encoded HAS pages (format: [time sat_id HAS_page_in_hex] in each line)"); +ABSL_FLAG(int32_t, start_page_test_file, 0, "Starting page in case of reading HAS pages from a file"); +#endif #if PMT_USES_BOOST_ANY namespace wht = boost; @@ -44,7 +49,7 @@ namespace wht = boost; namespace wht = std; #endif -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class HasDecoderTester; using HasDecoderTester_sptr = gnss_shared_ptr; @@ -212,7 +217,11 @@ private: TEST(HAS_Test, Decoder) { Read_Encoded_Pages read_pages{}; +#if USE_GLOG_AND_GFLAGS EXPECT_TRUE(read_pages.read_data(FLAGS_has_data_test_file)); +#else + EXPECT_TRUE(read_pages.read_data(absl::GetFlag(FLAGS_has_data_test_file))); +#endif auto gal_e6_has_rx_ = galileo_e6_has_msg_receiver_make(); auto has_tester = HasDecoderTester_make(); std::unique_ptr has_simple_printer = nullptr; @@ -224,10 +233,17 @@ TEST(HAS_Test, Decoder) if (!known_data) { has_simple_printer = std::make_unique(); +#if USE_GLOG_AND_GFLAGS if (static_cast(FLAGS_start_page_test_file) < read_pages.get_number_pages()) { init = FLAGS_start_page_test_file; } +#else + if (static_cast(absl::GetFlag(FLAGS_start_page_test_file)) < read_pages.get_number_pages()) + { + init = absl::GetFlag(FLAGS_start_page_test_file); + } +#endif else { std::cerr << "The flag --start_page_test_file is set beyond the total number of pages in the file (" << read_pages.get_number_pages() << "), ignoring it.\n"; diff --git a/src/utils/CMakeLists.txt b/utils/CMakeLists.txt similarity index 100% rename from src/utils/CMakeLists.txt rename to utils/CMakeLists.txt diff --git a/src/utils/front-end-cal/CMakeLists.txt b/utils/front-end-cal/CMakeLists.txt similarity index 81% rename from src/utils/front-end-cal/CMakeLists.txt rename to utils/front-end-cal/CMakeLists.txt index 14e55ca99..1dd300b1f 100644 --- a/src/utils/front-end-cal/CMakeLists.txt +++ b/utils/front-end-cal/CMakeLists.txt @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2010-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2010-2025 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause @@ -30,12 +30,17 @@ target_link_libraries(front_end_cal_lib core_libs PRIVATE Boost::headers - Gflags::gflags - Glog::glog Gnuradio::blocks Gnuradio::runtime ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(front_end_cal_lib PRIVATE Gflags::gflags Glog::glog) + target_compile_definitions(front_end_cal_lib PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(front_end_cal_lib PRIVATE absl::flags absl::log) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(front_end_cal_lib @@ -59,9 +64,15 @@ target_link_libraries(front-end-cal front_end_cal_lib gnss_sdr_flags Boost::headers - Glog::glog ) +if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(front-end-cal PRIVATE Glog::glog) + target_compile_definitions(front-end-cal PRIVATE -DUSE_GLOG_AND_GFLAGS=1) +else() + target_link_libraries(front-end-cal PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize absl::log_sink absl::log_sink_registry) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(front-end-cal PRIVATE -DGNURADIO_USES_STD_POINTERS=1 @@ -102,6 +113,9 @@ if(PMT_USES_BOOST_ANY) ) endif() +include(XcodeRemoveWarningDuplicates) +xcode_remove_warning_duplicates(front-end-cal) + if(ENABLE_STRIP) set_target_properties(front-end-cal PROPERTIES LINK_FLAGS "-s") endif() @@ -126,11 +140,7 @@ install(TARGETS front-end-cal ) find_program(GZIP gzip - /bin - /usr/bin - /usr/local/bin - /opt/local/bin - /sbin + ${GNSSSDR_BIN_PATHS} ) if(NOT GZIP_NOTFOUND) diff --git a/src/utils/front-end-cal/front_end_cal.cc b/utils/front-end-cal/front_end_cal.cc similarity index 96% rename from src/utils/front-end-cal/front_end_cal.cc rename to utils/front-end-cal/front_end_cal.cc index 9c527d10e..e74a8556e 100644 --- a/src/utils/front-end-cal/front_end_cal.cc +++ b/utils/front-end-cal/front_end_cal.cc @@ -26,7 +26,6 @@ #include "gps_iono.h" #include "gps_utc_model.h" #include -#include #include // for min #include #include // for operator<< @@ -34,6 +33,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + extern Concurrent_Map global_gps_ephemeris_map; extern Concurrent_Map global_gps_iono_map; extern Concurrent_Map global_gps_utc_model_map; @@ -51,8 +56,8 @@ bool FrontEndCal::read_assistance_from_XML() { std::map::iterator gps_eph_iter; for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end(); - gps_eph_iter++) + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end(); + gps_eph_iter++) { std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << '\n'; LOG(INFO) << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first; @@ -129,8 +134,8 @@ int FrontEndCal::Get_SUPL_Assist() { std::map::iterator gps_eph_iter; for (gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin(); - gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end(); - gps_eph_iter++) + gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end(); + gps_eph_iter++) { LOG(INFO) << "SUPL: Received Ephemeris for GPS SV " << gps_eph_iter->first; std::cout << "SUPL: Received Ephemeris for GPS SV " << gps_eph_iter->first << '\n'; @@ -158,8 +163,8 @@ int FrontEndCal::Get_SUPL_Assist() { std::map::iterator gps_alm_iter; for (gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.begin(); - gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.end(); - gps_alm_iter++) + gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.end(); + gps_alm_iter++) { LOG(INFO) << "SUPL: Received Almanac for GPS SV " << gps_alm_iter->first; std::cout << "SUPL: Received Almanac for GPS SV " << gps_alm_iter->first << '\n'; @@ -194,8 +199,8 @@ int FrontEndCal::Get_SUPL_Assist() { std::map::iterator gps_acq_iter; for (gps_acq_iter = supl_client_acquisition_.gps_acq_map.begin(); - gps_acq_iter != supl_client_acquisition_.gps_acq_map.end(); - gps_acq_iter++) + gps_acq_iter != supl_client_acquisition_.gps_acq_map.end(); + gps_acq_iter++) { LOG(INFO) << "SUPL: Received Acquisition assistance for GPS SV " << gps_acq_iter->first; std::cout << "SUPL: Received Acquisition assistance for GPS SV " << gps_acq_iter->first << '\n'; diff --git a/src/utils/front-end-cal/front_end_cal.h b/utils/front-end-cal/front_end_cal.h similarity index 100% rename from src/utils/front-end-cal/front_end_cal.h rename to utils/front-end-cal/front_end_cal.h diff --git a/src/utils/front-end-cal/main.cc b/utils/front-end-cal/main.cc similarity index 91% rename from src/utils/front-end-cal/main.cc rename to utils/front-end-cal/main.cc index 972e4a21e..f78e0f4a6 100644 --- a/src/utils/front-end-cal/main.cc +++ b/utils/front-end-cal/main.cc @@ -40,8 +40,6 @@ #include // for bad_any_cast #include #include -#include -#include #include // for block #include #include @@ -70,6 +68,23 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif + #if HAS_GENERIC_LAMBDA #else #include @@ -81,14 +96,39 @@ namespace wht = boost; namespace wht = std; #endif +#if USE_GLOG_AND_GFLAGS #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } #endif - DECLARE_string(log_dir); +#else +class FrontEndCalLogSink : public absl::LogSink +{ +public: + FrontEndCalLogSink() + { + if (!absl::GetFlag(FLAGS_log_dir).empty()) + { + logfile.open(absl::GetFlag(FLAGS_log_dir) + "/front_end_cal.log"); + } + else + { + logfile.open(GetTempDir() + "/front_end_cal.log"); + } + } + void Send(const absl::LogEntry& entry) override + { + logfile << entry.text_message_with_prefix_and_newline() << std::flush; + } + +private: + std::ofstream logfile; +}; +std::string FrontEndCalVersionString() { return std::string(FRONT_END_CAL_VERSION) + "\n"; } +#endif Concurrent_Map global_gps_ephemeris_map; Concurrent_Map global_gps_iono_map; @@ -100,9 +140,9 @@ Concurrent_Queue global_gps_acq_assist_queue; bool stop; Concurrent_Queue channel_internal_queue; std::vector gnss_sync_vector; -Gnss_Synchro gnss_synchro{}; +Gnss_Synchro gnss_synchro; -// ######## GNURADIO BLOCK MESSAGE RECEVER ######### +// ######## GNURADIO BLOCK MESSAGE RECEIVER ######### class FrontEndCal_msg_rx; using FrontEndCal_msg_rx_sptr = gnss_shared_ptr; @@ -277,10 +317,17 @@ int main(int argc, char** argv) "This program comes with ABSOLUTELY NO WARRANTY;\n" + "See COPYING file to see a copy of the General Public License\n \n"); +#if USE_GLOG_AND_GFLAGS gflags::SetUsageMessage(intro_help); google::SetVersionString(FRONT_END_CAL_VERSION); gflags::ParseCommandLineFlags(&argc, &argv, true); - +#else + absl::FlagsUsageConfig empty_config; + empty_config.version_string = &FrontEndCalVersionString; + absl::SetFlagsUsageConfig(empty_config); + absl::SetProgramUsageMessage(intro_help); + absl::ParseCommandLine(argc, argv); +#endif std::cout << "Initializing... Please wait.\n"; } catch (const std::exception& e) @@ -289,8 +336,16 @@ int main(int argc, char** argv) std::cout << "front-end-cal program ended.\n"; return 1; } + +#if USE_GLOG_AND_GFLAGS google::InitGoogleLogging(argv[0]); if (FLAGS_log_dir.empty()) +#else + absl::LogSink* fecLogSink = new FrontEndCalLogSink; + absl::AddLogSink(fecLogSink); + absl::InitializeLog(); + if (absl::GetFlag(FLAGS_log_dir).empty()) +#endif { std::cout << "Logging will be done at " << "/tmp" @@ -302,29 +357,49 @@ int main(int argc, char** argv) { try { +#if USE_GLOG_AND_GFLAGS const fs::path p(FLAGS_log_dir); +#else + const fs::path p(absl::GetFlag(FLAGS_log_dir)); +#endif if (!fs::exists(p)) { std::cout << "The path " +#if USE_GLOG_AND_GFLAGS << FLAGS_log_dir +#else + << absl::GetFlag(FLAGS_log_dir) +#endif << " does not exist, attempting to create it" << '\n'; errorlib::error_code ec; if (!fs::create_directory(p, ec)) { +#if USE_GLOG_AND_GFLAGS std::cerr << "Could not create the " << FLAGS_log_dir << " folder. Front-end-cal program ended.\n"; gflags::ShutDownCommandLineFlags(); +#else + std::cerr << "Could not create the " << absl::GetFlag(FLAGS_log_dir) << " folder. Front-end-cal program ended.\n"; +#endif return 1; } } std::cout << "Logging with be done at " +#if USE_GLOG_AND_GFLAGS << FLAGS_log_dir << '\n'; +#else + << absl::GetFlag(FLAGS_log_dir) << '\n'; +#endif } catch (const std::exception& e) { std::cerr << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS std::cerr << "Could not create the " << FLAGS_log_dir << " folder. Front-end-cal program ended.\n"; gflags::ShutDownCommandLineFlags(); +#else + std::cerr << "Could not create the " << absl::GetFlag(FLAGS_log_dir) << " folder. Front-end-cal program ended.\n"; +#endif return 1; } } @@ -335,7 +410,11 @@ int main(int argc, char** argv) FrontEndCal front_end_cal; // 1. Load configuration parameters from config file +#if USE_GLOG_AND_GFLAGS std::shared_ptr configuration = std::make_shared(FLAGS_config_file); +#else + std::shared_ptr configuration = std::make_shared(absl::GetFlag(FLAGS_config_file)); +#endif front_end_cal.set_configuration(configuration); // 2. Get SUPL information from server: Ephemeris record, assistance info and TOW @@ -541,7 +620,9 @@ int main(int argc, char** argv) else { std::cout << "Unable to get Ephemeris SUPL assistance. TOW is unknown!\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif std::cout << "GNSS-SDR Front-end calibration program ended.\n"; return 0; } @@ -549,7 +630,9 @@ int main(int argc, char** argv) catch (const boost::exception& e) { std::cout << "Exception in getting Global ephemeris map\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif std::cout << "GNSS-SDR Front-end calibration program ended.\n"; return 0; } @@ -568,7 +651,9 @@ int main(int argc, char** argv) if (doppler_measurements_map.empty()) { std::cout << "Sorry, no GPS satellites detected in the front-end capture, please check the antenna setup...\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif std::cout << "GNSS-SDR Front-end calibration program ended.\n"; return 0; } @@ -673,17 +758,22 @@ int main(int argc, char** argv) catch (const std::exception& e) { std::cerr << "Exception: " << e.what(); +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } catch (...) { std::cerr << "Unknown error\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } - +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif std::cout << "GNSS-SDR Front-end calibration program ended.\n"; return 0; } diff --git a/src/utils/matlab/dll_pll_veml_plot_sample.m b/utils/matlab/dll_pll_veml_plot_sample.m similarity index 100% rename from src/utils/matlab/dll_pll_veml_plot_sample.m rename to utils/matlab/dll_pll_veml_plot_sample.m diff --git a/src/utils/matlab/gps_l1_ca_kf_plot_sample.m b/utils/matlab/gps_l1_ca_kf_plot_sample.m similarity index 100% rename from src/utils/matlab/gps_l1_ca_kf_plot_sample.m rename to utils/matlab/gps_l1_ca_kf_plot_sample.m diff --git a/src/utils/matlab/gps_l1_ca_pvt_plot_sample_agilent_cap2.m b/utils/matlab/gps_l1_ca_pvt_plot_sample_agilent_cap2.m similarity index 100% rename from src/utils/matlab/gps_l1_ca_pvt_plot_sample_agilent_cap2.m rename to utils/matlab/gps_l1_ca_pvt_plot_sample_agilent_cap2.m diff --git a/src/utils/matlab/gps_l1_ca_pvt_raw_plot_sample.m b/utils/matlab/gps_l1_ca_pvt_raw_plot_sample.m similarity index 100% rename from src/utils/matlab/gps_l1_ca_pvt_raw_plot_sample.m rename to utils/matlab/gps_l1_ca_pvt_raw_plot_sample.m diff --git a/src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m b/utils/matlab/gps_l1_ca_telemetry_plot_sample.m similarity index 100% rename from src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m rename to utils/matlab/gps_l1_ca_telemetry_plot_sample.m diff --git a/src/utils/matlab/help_script1.m b/utils/matlab/help_script1.m similarity index 100% rename from src/utils/matlab/help_script1.m rename to utils/matlab/help_script1.m diff --git a/src/utils/matlab/help_script2.m b/utils/matlab/help_script2.m similarity index 100% rename from src/utils/matlab/help_script2.m rename to utils/matlab/help_script2.m diff --git a/src/utils/matlab/hybrid_observables_plot_sample.m b/utils/matlab/hybrid_observables_plot_sample.m similarity index 100% rename from src/utils/matlab/hybrid_observables_plot_sample.m rename to utils/matlab/hybrid_observables_plot_sample.m diff --git a/src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m b/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m similarity index 100% rename from src/utils/matlab/libs/dll_pll_veml_read_tracking_dump.m rename to utils/matlab/libs/dll_pll_veml_read_tracking_dump.m diff --git a/src/utils/matlab/libs/geoFunctions/cart2geo.m b/utils/matlab/libs/geoFunctions/cart2geo.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/cart2geo.m rename to utils/matlab/libs/geoFunctions/cart2geo.m diff --git a/src/utils/matlab/libs/geoFunctions/cart2utm.m b/utils/matlab/libs/geoFunctions/cart2utm.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/cart2utm.m rename to utils/matlab/libs/geoFunctions/cart2utm.m diff --git a/src/utils/matlab/libs/geoFunctions/check_t.m b/utils/matlab/libs/geoFunctions/check_t.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/check_t.m rename to utils/matlab/libs/geoFunctions/check_t.m diff --git a/src/utils/matlab/libs/geoFunctions/clksin.m b/utils/matlab/libs/geoFunctions/clksin.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/clksin.m rename to utils/matlab/libs/geoFunctions/clksin.m diff --git a/src/utils/matlab/libs/geoFunctions/clsin.m b/utils/matlab/libs/geoFunctions/clsin.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/clsin.m rename to utils/matlab/libs/geoFunctions/clsin.m diff --git a/src/utils/matlab/libs/geoFunctions/deg2dms.m b/utils/matlab/libs/geoFunctions/deg2dms.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/deg2dms.m rename to utils/matlab/libs/geoFunctions/deg2dms.m diff --git a/src/utils/matlab/libs/geoFunctions/dms2deg.m b/utils/matlab/libs/geoFunctions/dms2deg.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/dms2deg.m rename to utils/matlab/libs/geoFunctions/dms2deg.m diff --git a/src/utils/matlab/libs/geoFunctions/dms2mat.m b/utils/matlab/libs/geoFunctions/dms2mat.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/dms2mat.m rename to utils/matlab/libs/geoFunctions/dms2mat.m diff --git a/src/utils/matlab/libs/geoFunctions/e_r_corr.m b/utils/matlab/libs/geoFunctions/e_r_corr.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/e_r_corr.m rename to utils/matlab/libs/geoFunctions/e_r_corr.m diff --git a/src/utils/matlab/libs/geoFunctions/findUtmZone.m b/utils/matlab/libs/geoFunctions/findUtmZone.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/findUtmZone.m rename to utils/matlab/libs/geoFunctions/findUtmZone.m diff --git a/src/utils/matlab/libs/geoFunctions/geo2cart.m b/utils/matlab/libs/geoFunctions/geo2cart.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/geo2cart.m rename to utils/matlab/libs/geoFunctions/geo2cart.m diff --git a/src/utils/matlab/libs/geoFunctions/leastSquarePos.m b/utils/matlab/libs/geoFunctions/leastSquarePos.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/leastSquarePos.m rename to utils/matlab/libs/geoFunctions/leastSquarePos.m diff --git a/src/utils/matlab/libs/geoFunctions/mat2dms.m b/utils/matlab/libs/geoFunctions/mat2dms.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/mat2dms.m rename to utils/matlab/libs/geoFunctions/mat2dms.m diff --git a/src/utils/matlab/libs/geoFunctions/roundn.m b/utils/matlab/libs/geoFunctions/roundn.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/roundn.m rename to utils/matlab/libs/geoFunctions/roundn.m diff --git a/src/utils/matlab/libs/geoFunctions/satpos.m b/utils/matlab/libs/geoFunctions/satpos.m similarity index 99% rename from src/utils/matlab/libs/geoFunctions/satpos.m rename to utils/matlab/libs/geoFunctions/satpos.m index b65004b52..7af0f24c9 100644 --- a/src/utils/matlab/libs/geoFunctions/satpos.m +++ b/utils/matlab/libs/geoFunctions/satpos.m @@ -30,7 +30,7 @@ function [satPositions, satClkCorr] = satpos(transmitTime, prnList, ... %% Initialize constants =================================================== numOfSatellites = size(prnList, 2); -% GPS constatns +% GPS constants gpsPi = 3.1415926535898; % Pi used in the GPS coordinate % system diff --git a/src/utils/matlab/libs/geoFunctions/togeod.m b/utils/matlab/libs/geoFunctions/togeod.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/togeod.m rename to utils/matlab/libs/geoFunctions/togeod.m diff --git a/src/utils/matlab/libs/geoFunctions/topocent.m b/utils/matlab/libs/geoFunctions/topocent.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/topocent.m rename to utils/matlab/libs/geoFunctions/topocent.m diff --git a/src/utils/matlab/libs/geoFunctions/tropo.m b/utils/matlab/libs/geoFunctions/tropo.m similarity index 100% rename from src/utils/matlab/libs/geoFunctions/tropo.m rename to utils/matlab/libs/geoFunctions/tropo.m diff --git a/src/utils/matlab/libs/gps_l1_ca_dll_pll_read_tracking_dump.m b/utils/matlab/libs/gps_l1_ca_dll_pll_read_tracking_dump.m similarity index 100% rename from src/utils/matlab/libs/gps_l1_ca_dll_pll_read_tracking_dump.m rename to utils/matlab/libs/gps_l1_ca_dll_pll_read_tracking_dump.m diff --git a/src/utils/matlab/libs/gps_l1_ca_kf_read_tracking_dump.m b/utils/matlab/libs/gps_l1_ca_kf_read_tracking_dump.m similarity index 100% rename from src/utils/matlab/libs/gps_l1_ca_kf_read_tracking_dump.m rename to utils/matlab/libs/gps_l1_ca_kf_read_tracking_dump.m diff --git a/src/utils/matlab/libs/gps_l1_ca_pvt_read_pvt_dump.m b/utils/matlab/libs/gps_l1_ca_pvt_read_pvt_dump.m similarity index 100% rename from src/utils/matlab/libs/gps_l1_ca_pvt_read_pvt_dump.m rename to utils/matlab/libs/gps_l1_ca_pvt_read_pvt_dump.m diff --git a/src/utils/matlab/libs/gps_l1_ca_read_pvt_raw_dump.m b/utils/matlab/libs/gps_l1_ca_read_pvt_raw_dump.m similarity index 100% rename from src/utils/matlab/libs/gps_l1_ca_read_pvt_raw_dump.m rename to utils/matlab/libs/gps_l1_ca_read_pvt_raw_dump.m diff --git a/src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m b/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m similarity index 100% rename from src/utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m rename to utils/matlab/libs/gps_l1_ca_read_telemetry_dump.m diff --git a/src/utils/matlab/libs/plotKalman.m b/utils/matlab/libs/plotKalman.m similarity index 100% rename from src/utils/matlab/libs/plotKalman.m rename to utils/matlab/libs/plotKalman.m diff --git a/src/utils/matlab/libs/plotNavigation.m b/utils/matlab/libs/plotNavigation.m similarity index 100% rename from src/utils/matlab/libs/plotNavigation.m rename to utils/matlab/libs/plotNavigation.m diff --git a/src/utils/matlab/libs/plotTracking.m b/utils/matlab/libs/plotTracking.m similarity index 100% rename from src/utils/matlab/libs/plotTracking.m rename to utils/matlab/libs/plotTracking.m diff --git a/src/utils/matlab/libs/plotVEMLTracking.m b/utils/matlab/libs/plotVEMLTracking.m similarity index 100% rename from src/utils/matlab/libs/plotVEMLTracking.m rename to utils/matlab/libs/plotVEMLTracking.m diff --git a/src/utils/matlab/libs/quantize_signal.m b/utils/matlab/libs/quantize_signal.m similarity index 100% rename from src/utils/matlab/libs/quantize_signal.m rename to utils/matlab/libs/quantize_signal.m diff --git a/src/utils/matlab/libs/read_complex_binary.m b/utils/matlab/libs/read_complex_binary.m similarity index 100% rename from src/utils/matlab/libs/read_complex_binary.m rename to utils/matlab/libs/read_complex_binary.m diff --git a/src/utils/matlab/libs/read_complex_char_binary.m b/utils/matlab/libs/read_complex_char_binary.m similarity index 100% rename from src/utils/matlab/libs/read_complex_char_binary.m rename to utils/matlab/libs/read_complex_char_binary.m diff --git a/src/utils/matlab/libs/read_complex_short_binary.m b/utils/matlab/libs/read_complex_short_binary.m similarity index 100% rename from src/utils/matlab/libs/read_complex_short_binary.m rename to utils/matlab/libs/read_complex_short_binary.m diff --git a/src/utils/matlab/libs/read_hybrid_observables_dump.m b/utils/matlab/libs/read_hybrid_observables_dump.m similarity index 100% rename from src/utils/matlab/libs/read_hybrid_observables_dump.m rename to utils/matlab/libs/read_hybrid_observables_dump.m diff --git a/src/utils/matlab/libs/read_true_sim_observables_dump.m b/utils/matlab/libs/read_true_sim_observables_dump.m similarity index 100% rename from src/utils/matlab/libs/read_true_sim_observables_dump.m rename to utils/matlab/libs/read_true_sim_observables_dump.m diff --git a/src/utils/matlab/plotTrackingE5a.m b/utils/matlab/plotTrackingE5a.m similarity index 100% rename from src/utils/matlab/plotTrackingE5a.m rename to utils/matlab/plotTrackingE5a.m diff --git a/src/utils/matlab/plot_acq_grid.m b/utils/matlab/plot_acq_grid.m similarity index 100% rename from src/utils/matlab/plot_acq_grid.m rename to utils/matlab/plot_acq_grid.m diff --git a/src/utils/matlab/plot_acq_grid_gsoc.m b/utils/matlab/plot_acq_grid_gsoc.m similarity index 100% rename from src/utils/matlab/plot_acq_grid_gsoc.m rename to utils/matlab/plot_acq_grid_gsoc.m diff --git a/src/utils/matlab/plot_acq_grid_gsoc_e5.m b/utils/matlab/plot_acq_grid_gsoc_e5.m similarity index 100% rename from src/utils/matlab/plot_acq_grid_gsoc_e5.m rename to utils/matlab/plot_acq_grid_gsoc_e5.m diff --git a/src/utils/matlab/plot_acq_grid_gsoc_glonass.m b/utils/matlab/plot_acq_grid_gsoc_glonass.m similarity index 100% rename from src/utils/matlab/plot_acq_grid_gsoc_glonass.m rename to utils/matlab/plot_acq_grid_gsoc_glonass.m diff --git a/src/utils/matlab/plot_tracking_quality_indicators.m b/utils/matlab/plot_tracking_quality_indicators.m similarity index 100% rename from src/utils/matlab/plot_tracking_quality_indicators.m rename to utils/matlab/plot_tracking_quality_indicators.m diff --git a/src/utils/nav-listener/CMakeLists.txt b/utils/nav-listener/CMakeLists.txt similarity index 71% rename from src/utils/nav-listener/CMakeLists.txt rename to utils/nav-listener/CMakeLists.txt index 048a862f4..ea9c5d36e 100644 --- a/src/utils/nav-listener/CMakeLists.txt +++ b/utils/nav-listener/CMakeLists.txt @@ -4,7 +4,7 @@ # SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause -cmake_minimum_required(VERSION 3.9...3.23) +cmake_minimum_required(VERSION 3.9...3.30) project(nav-msg-listener CXX) set(CMAKE_CXX_STANDARD 11) @@ -39,3 +39,19 @@ target_include_directories(navmsg_lib add_executable(nav_msg_listener ${NAVLISTENER_SOURCE_DIR}/main.cc) target_link_libraries(nav_msg_listener PUBLIC navmsg_lib) + +install(TARGETS nav_msg_listener + RUNTIME DESTINATION bin + COMPONENT "nav_msg_listener" +) + +if(NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY + ) + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake + ) +endif() diff --git a/src/utils/nav-listener/README.md b/utils/nav-listener/README.md similarity index 94% rename from src/utils/nav-listener/README.md rename to utils/nav-listener/README.md index 147e9717f..4bd90658e 100644 --- a/src/utils/nav-listener/README.md +++ b/utils/nav-listener/README.md @@ -17,7 +17,7 @@ as a example on how to retrieve data using the `nav_message.proto` file. # Build the software This software requires [Boost](https://www.boost.org/) and -[Protocol Buffers](https://developers.google.com/protocol-buffers). +[Protocol Buffers](https://protobuf.dev/). In a terminal, type: @@ -27,6 +27,18 @@ $ cmake .. $ make ``` +Optionally, you can install it: + +``` +$ sudo make install +``` + +and uninstall it later with: + +``` +$ sudo make uninstall +``` + ## Usage In order to tell GNSS-SDR to generate those messages, you need to include the diff --git a/utils/nav-listener/cmake/cmake_uninstall.cmake.in b/utils/nav-listener/cmake/cmake_uninstall.cmake.in new file mode 100644 index 000000000..fc57491c4 --- /dev/null +++ b/utils/nav-listener/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,35 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif() + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + if(CMAKE_VERSION VERSION_LESS 3.17) + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + else() + execute_process( + COMMAND @CMAKE_COMMAND@ -E rm "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + endif() + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif() + else() + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif() +endforeach() diff --git a/src/utils/nav-listener/main.cc b/utils/nav-listener/main.cc similarity index 83% rename from src/utils/nav-listener/main.cc rename to utils/nav-listener/main.cc index 6fee013f7..f2b789497 100644 --- a/src/utils/nav-listener/main.cc +++ b/utils/nav-listener/main.cc @@ -31,6 +31,7 @@ int main(int argc, char *argv[]) unsigned short port = boost::lexical_cast(argv[1]); Nav_Msg_Udp_Listener udp_listener(port); + std::cout << "Listening on port " << static_cast(port) << ", press Control+C to exit ...\n"; while (true) { @@ -45,9 +46,15 @@ int main(int argc, char *argv[]) } } } + catch (boost::bad_lexical_cast &) + { + std::cerr << "Error: the argument " << argv[1] << " is not a valid port number.\n"; + return 1; + } catch (std::exception &e) { std::cerr << e.what() << '\n'; + return 1; } return 0; diff --git a/src/utils/nav-listener/nav_message.proto b/utils/nav-listener/nav_message.proto similarity index 100% rename from src/utils/nav-listener/nav_message.proto rename to utils/nav-listener/nav_message.proto diff --git a/utils/nav-listener/nav_msg_udp_listener.cc b/utils/nav-listener/nav_msg_udp_listener.cc new file mode 100644 index 000000000..65debea37 --- /dev/null +++ b/utils/nav-listener/nav_msg_udp_listener.cc @@ -0,0 +1,85 @@ +/*! + * \file nav_msg_udp_listener.cc + * \author Carles Fernandez-Prades, 2021. cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: BSD-3-Clause + * + * ----------------------------------------------------------------------------- + */ + +#include "nav_msg_udp_listener.h" +#include +#include +#include + +Nav_Msg_Udp_Listener::Nav_Msg_Udp_Listener(unsigned short port) + : socket{io_service}, endpoint{boost::asio::ip::udp::v4(), port}, connected_socket(true) +{ + socket.open(endpoint.protocol(), error); // Open socket + if (error) + { + std::cerr << "Error opening socket: " << error.message() << '\n'; + connected_socket = false; + } + if (connected_socket) + { + socket.bind(endpoint, error); // Bind the socket to the given local endpoint. + if (error) + { + std::cerr << "Error binding socket: " << error.message() << '\n'; + connected_socket = false; + } + } +} + + +/* + * Blocking call to read nav_message from UDP port + * return true if message parsed successfully, false ow + */ +bool Nav_Msg_Udp_Listener::receive_and_parse_nav_message(gnss_sdr::navMsg &message) +{ + if (connected_socket) + { + char buff[8192]; // Buffer for storing the received data. + + // This call will block until one or more bytes of data has been received. + int bytes = socket.receive(boost::asio::buffer(buff)); + + std::string data(&buff[0], bytes); + // Deserialize a stock of Nav_Msg objects from the binary string. + return message.ParseFromString(data); + } + return false; +} + + +/* + * Prints navigation message content + * param[in] message nav message to be printed + */ +void Nav_Msg_Udp_Listener::print_message(gnss_sdr::navMsg &message) const +{ + if (connected_socket) + { + std::string system = message.system(); + std::string signal = message.signal(); + int prn = message.prn(); + int tow_at_current_symbol_ms = message.tow_at_current_symbol_ms(); + std::string nav_message = message.nav_message(); + + std::cout << "\nNew data received:\n"; + std::cout << "System: " << system << '\n'; + std::cout << "Signal: " << signal << '\n'; + std::cout << "PRN: " << prn << '\n'; + std::cout << "TOW of last symbol [ms]: " + << tow_at_current_symbol_ms << '\n'; + std::cout << "Nav message: " << nav_message << "\n\n"; + } +} diff --git a/src/utils/nav-listener/nav_msg_udp_listener.h b/utils/nav-listener/nav_msg_udp_listener.h similarity index 97% rename from src/utils/nav-listener/nav_msg_udp_listener.h rename to utils/nav-listener/nav_msg_udp_listener.h index c16654f40..6f70a042e 100644 --- a/src/utils/nav-listener/nav_msg_udp_listener.h +++ b/utils/nav-listener/nav_msg_udp_listener.h @@ -31,6 +31,7 @@ private: boost::asio::ip::udp::socket socket; boost::system::error_code error; boost::asio::ip::udp::endpoint endpoint; + bool connected_socket; }; #endif diff --git a/src/utils/python/dll_pll_veml_plot_sample.py b/utils/python/dll_pll_veml_plot_sample.py similarity index 100% rename from src/utils/python/dll_pll_veml_plot_sample.py rename to utils/python/dll_pll_veml_plot_sample.py diff --git a/src/utils/python/gps_l1_ca_kf_plot_sample.py b/utils/python/gps_l1_ca_kf_plot_sample.py similarity index 100% rename from src/utils/python/gps_l1_ca_kf_plot_sample.py rename to utils/python/gps_l1_ca_kf_plot_sample.py diff --git a/src/utils/python/gps_l1_ca_pvt_raw_plot_sample.py b/utils/python/gps_l1_ca_pvt_raw_plot_sample.py similarity index 100% rename from src/utils/python/gps_l1_ca_pvt_raw_plot_sample.py rename to utils/python/gps_l1_ca_pvt_raw_plot_sample.py diff --git a/src/utils/python/gps_l1_ca_telemetry_plot_sample.py b/utils/python/gps_l1_ca_telemetry_plot_sample.py similarity index 100% rename from src/utils/python/gps_l1_ca_telemetry_plot_sample.py rename to utils/python/gps_l1_ca_telemetry_plot_sample.py diff --git a/src/utils/python/hybrid_observables_plot_sample.py b/utils/python/hybrid_observables_plot_sample.py similarity index 100% rename from src/utils/python/hybrid_observables_plot_sample.py rename to utils/python/hybrid_observables_plot_sample.py diff --git a/src/utils/python/lib/dll_pll_veml_read_tracking_dump.py b/utils/python/lib/dll_pll_veml_read_tracking_dump.py similarity index 100% rename from src/utils/python/lib/dll_pll_veml_read_tracking_dump.py rename to utils/python/lib/dll_pll_veml_read_tracking_dump.py diff --git a/src/utils/python/lib/gps_l1_ca_kf_read_tracking_dump.py b/utils/python/lib/gps_l1_ca_kf_read_tracking_dump.py similarity index 100% rename from src/utils/python/lib/gps_l1_ca_kf_read_tracking_dump.py rename to utils/python/lib/gps_l1_ca_kf_read_tracking_dump.py diff --git a/src/utils/python/lib/gps_l1_ca_read_pvt_dump.py b/utils/python/lib/gps_l1_ca_read_pvt_dump.py similarity index 100% rename from src/utils/python/lib/gps_l1_ca_read_pvt_dump.py rename to utils/python/lib/gps_l1_ca_read_pvt_dump.py diff --git a/src/utils/python/lib/gps_l1_ca_read_telemetry_dump.py b/utils/python/lib/gps_l1_ca_read_telemetry_dump.py similarity index 100% rename from src/utils/python/lib/gps_l1_ca_read_telemetry_dump.py rename to utils/python/lib/gps_l1_ca_read_telemetry_dump.py diff --git a/src/utils/python/lib/plotKalman.py b/utils/python/lib/plotKalman.py similarity index 100% rename from src/utils/python/lib/plotKalman.py rename to utils/python/lib/plotKalman.py diff --git a/src/utils/python/lib/plotNavigation.py b/utils/python/lib/plotNavigation.py similarity index 100% rename from src/utils/python/lib/plotNavigation.py rename to utils/python/lib/plotNavigation.py diff --git a/src/utils/python/lib/plotPosition.py b/utils/python/lib/plotPosition.py similarity index 100% rename from src/utils/python/lib/plotPosition.py rename to utils/python/lib/plotPosition.py diff --git a/src/utils/python/lib/plotTracking.py b/utils/python/lib/plotTracking.py similarity index 100% rename from src/utils/python/lib/plotTracking.py rename to utils/python/lib/plotTracking.py diff --git a/src/utils/python/lib/plotVEMLTracking.py b/utils/python/lib/plotVEMLTracking.py similarity index 100% rename from src/utils/python/lib/plotVEMLTracking.py rename to utils/python/lib/plotVEMLTracking.py diff --git a/src/utils/python/lib/read_hybrid_observables_dump.py b/utils/python/lib/read_hybrid_observables_dump.py similarity index 100% rename from src/utils/python/lib/read_hybrid_observables_dump.py rename to utils/python/lib/read_hybrid_observables_dump.py diff --git a/src/utils/python/plot_acq_grid.py b/utils/python/plot_acq_grid.py similarity index 100% rename from src/utils/python/plot_acq_grid.py rename to utils/python/plot_acq_grid.py diff --git a/src/utils/python/plot_tracking_quality_indicators.py b/utils/python/plot_tracking_quality_indicators.py similarity index 100% rename from src/utils/python/plot_tracking_quality_indicators.py rename to utils/python/plot_tracking_quality_indicators.py diff --git a/src/utils/reproducibility/ieee-access18/L2-access18.conf b/utils/reproducibility/ieee-access18/L2-access18.conf similarity index 100% rename from src/utils/reproducibility/ieee-access18/L2-access18.conf rename to utils/reproducibility/ieee-access18/L2-access18.conf diff --git a/src/utils/reproducibility/ieee-access18/README.md b/utils/reproducibility/ieee-access18/README.md similarity index 93% rename from src/utils/reproducibility/ieee-access18/README.md rename to utils/reproducibility/ieee-access18/README.md index 67f59ad6d..82fa59103 100644 --- a/src/utils/reproducibility/ieee-access18/README.md +++ b/utils/reproducibility/ieee-access18/README.md @@ -58,9 +58,9 @@ $ tar xvfJ L2_signal_samples.tar.xz $ echo "3a04c1eeb970776bb77f5e3b7eaff2df L2_signal_samples.tar.xz" > data.md5 $ md5sum -c data.md5 $ cd .. -$ cp ../src/utils/reproducibility/ieee-access18/L2-access18.conf . -$ cp ../src/utils/reproducibility/ieee-access18/plot_dump.m . -$ cp -r ../src/utils/matlab/libs/geoFunctions . +$ cp ../utils/reproducibility/ieee-access18/L2-access18.conf . +$ cp ../utils/reproducibility/ieee-access18/plot_dump.m . +$ cp -r ../utils/matlab/libs/geoFunctions . $ gnss-sdr --c=L2-access18.conf $ octave --no-gui plot_dump.m $ epspdf Figure2.eps Figure2.pdf diff --git a/src/utils/reproducibility/ieee-access18/plot_dump.m b/utils/reproducibility/ieee-access18/plot_dump.m similarity index 100% rename from src/utils/reproducibility/ieee-access18/plot_dump.m rename to utils/reproducibility/ieee-access18/plot_dump.m diff --git a/src/utils/rinex-tools/CMakeLists.txt b/utils/rinex-tools/CMakeLists.txt similarity index 88% rename from src/utils/rinex-tools/CMakeLists.txt rename to utils/rinex-tools/CMakeLists.txt index 94906c04c..84d361d40 100644 --- a/src/utils/rinex-tools/CMakeLists.txt +++ b/utils/rinex-tools/CMakeLists.txt @@ -33,8 +33,10 @@ if("${ARMADILLO_VERSION_STRING}" VERSION_GREATER "9.800" OR (NOT ARMADILLO_FOUND add_executable(obsdiff ${CMAKE_CURRENT_SOURCE_DIR}/obsdiff.cc obsdiff_flags.h) endif() - target_include_directories(obsdiff PUBLIC ${GNSSSDR_SOURCE_DIR}/src/tests/common-files) - set_property(TARGET obsdiff PROPERTY CXX_STANDARD 14) # Required by GPSTk v3.0.0 + target_include_directories(obsdiff PUBLIC ${GNSSSDR_SOURCE_DIR}/tests/common-files) + if(GNSSTK_VERSION AND "${GNSSTK_VERSION}" VERSION_LESS 3.0.1) + set_property(TARGET obsdiff PROPERTY CXX_STANDARD 14) # Required by GPSTk v3.0.0 + endif() # Do not show warnings raised by GPSTk v3.0.0 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") target_compile_options(obsdiff @@ -52,8 +54,10 @@ if("${ARMADILLO_VERSION_STRING}" VERSION_GREATER "9.800" OR (NOT ARMADILLO_FOUND if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) add_dependencies(obsdiff armadillo-${armadillo_RELEASE}) endif() - if(NOT GFLAGS_FOUND) - add_dependencies(obsdiff gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + if(ENABLE_GLOG_AND_GFLAGS) + if(NOT GFLAGS_FOUND) + add_dependencies(obsdiff gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION}) + endif() endif() if(NOT GNSSTK_FOUND OR ENABLE_OWN_GNSSTK) add_dependencies(obsdiff gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}) @@ -101,15 +105,24 @@ if("${ARMADILLO_VERSION_STRING}" VERSION_GREATER "9.800" OR (NOT ARMADILLO_FOUND PRIVATE Armadillo::armadillo Threads::Threads - Gflags::gflags Matio::matio Gnsstk::gnsstk ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(obsdiff PRIVATE Gflags::gflags) + target_compile_definitions(obsdiff PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(obsdiff PUBLIC absl::flags absl::flags_parse) + endif() + if(ENABLE_STRIP) set_target_properties(obsdiff PROPERTIES LINK_FLAGS "-s") endif() + include(XcodeRemoveWarningDuplicates) + xcode_remove_warning_duplicates(obsdiff) + add_custom_command(TARGET obsdiff POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${LOCAL_INSTALL_BASE_DIR}/install/$ diff --git a/src/utils/rinex-tools/README.md b/utils/rinex-tools/README.md similarity index 98% rename from src/utils/rinex-tools/README.md rename to utils/rinex-tools/README.md index 58a1bd259..453ccd7a9 100644 --- a/src/utils/rinex-tools/README.md +++ b/utils/rinex-tools/README.md @@ -17,7 +17,7 @@ observation files. Requirements: -- [Armadillo](http://arma.sourceforge.net/): A C++ library for linear algebra +- [Armadillo](https://arma.sourceforge.net/): A C++ library for linear algebra and scientific computing. This program requires version 9.800 or higher. If your installed Armadillo version is older, see below. - [Gflags](https://github.com/gflags/gflags): A C++ library that implements diff --git a/src/utils/rinex-tools/obsdiff.cc b/utils/rinex-tools/obsdiff.cc similarity index 95% rename from src/utils/rinex-tools/obsdiff.cc rename to utils/rinex-tools/obsdiff.cc index 0b156bb86..d9f04d929 100644 --- a/src/utils/rinex-tools/obsdiff.cc +++ b/utils/rinex-tools/obsdiff.cc @@ -80,12 +80,16 @@ namespace gnsstk = gpstk; #endif #endif +#if USE_GLOG_AND_GFLAGS #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } #endif +#else +#include +#endif // Create the lists of GNSS satellites std::set available_gps_prn = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, @@ -245,7 +249,7 @@ std::map ReadRinexObs(const std::string& rinex_file, char system } } } // end while - } // End of 'try' block + } // End of 'try' block catch (const gnsstk::FFStreamError& e) { std::cout << e; @@ -422,8 +426,12 @@ void carrier_phase_double_diff( << " [Cycles]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Carrier Phase error [Cycles]"); @@ -506,8 +514,12 @@ void carrier_phase_single_diff( << " [Cycles]\n"; std::cout.precision(ss); - // plots +// plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Single diff Carrier Phase error [Cycles]"); @@ -614,7 +626,11 @@ void carrier_doppler_double_diff( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Carrier Doppler error [Hz]"); @@ -697,7 +713,11 @@ void carrier_doppler_single_diff( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Single diff Carrier Doppler error [Hz]"); @@ -805,7 +825,11 @@ void code_pseudorange_double_diff( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Double diff Pseudorange error [m]"); @@ -890,7 +914,11 @@ void code_pseudorange_single_diff( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Single diff Pseudorange error [m]"); @@ -1039,7 +1067,11 @@ void coderate_phaserate_consistence( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Code rate - phase rate [m/s]"); @@ -1123,7 +1155,11 @@ void code_phase_diff( std::cout.precision(ss); // plots +#if USE_GLOG_AND_GFLAGS if (FLAGS_show_plots) +#else + if (absl::GetFlag(FLAGS_show_plots)) +#endif { Gnuplot g3("linespoints"); g3.set_title(data_title + "Code range - Carrier phase range [m]"); @@ -1372,8 +1408,8 @@ double compute_rx_clock_error(const std::string& rinex_nav_filename, const std:: rx_clock_error_s = raimSolver.Solution(3) / gnsstk::C_MPS; break; } // End of 'if( raimSolver.isValid() )' - } // End of 'if( rod.epochFlag == 0 || rod.epochFlag == 1 )' - } // End of 'while( roffs >> rod )' + } // End of 'if( rod.epochFlag == 0 || rod.epochFlag == 1 )' + } // End of 'while( roffs >> rod )' } catch (const gnsstk::FFStreamError& e) { @@ -1396,13 +1432,23 @@ void RINEX_doublediff_dupli_sat() { // special test mode for duplicated satellites // read rinex receiver-under-test observations +#if USE_GLOG_AND_GFLAGS std::map rover_obs = ReadRinexObs(FLAGS_rover_rinex_obs, 'G', std::string("1C")); +#else + std::map rover_obs = ReadRinexObs(absl::GetFlag(FLAGS_rover_rinex_obs), 'G', std::string("1C")); +#endif + + if (rover_obs.empty()) { return; } - // Cut measurement initial transitory of the measurements + // Cut measurement initial transitory of the measurements +#if USE_GLOG_AND_GFLAGS double initial_transitory_s = FLAGS_skip_obs_transitory_s; +#else + double initial_transitory_s = absl::GetFlag(FLAGS_skip_obs_transitory_s); +#endif std::cout << "Skipping initial transitory of " << initial_transitory_s << " [s]\n"; arma::uvec index; for (auto& rover_ob : rover_obs) @@ -1415,7 +1461,11 @@ void RINEX_doublediff_dupli_sat() } std::vector prn_pairs; +#if USE_GLOG_AND_GFLAGS std::stringstream ss(FLAGS_dupli_sat_prns); +#else + std::stringstream ss(absl::GetFlag(FLAGS_dupli_sat_prns)); +#endif unsigned int i; while (ss >> i) { @@ -1463,11 +1513,17 @@ void RINEX_doublediff_dupli_sat() void RINEX_doublediff(bool remove_rx_clock_error) { +#if USE_GLOG_AND_GFLAGS // read rinex base observations std::map base_obs = ReadRinexObs(FLAGS_base_rinex_obs, FLAGS_system.c_str()[0], FLAGS_signal); // read rinex receiver-under-test (rover) observations std::map rover_obs = ReadRinexObs(FLAGS_rover_rinex_obs, FLAGS_system.c_str()[0], FLAGS_signal); - +#else + // read rinex base observations + std::map base_obs = ReadRinexObs(absl::GetFlag(FLAGS_base_rinex_obs), absl::GetFlag(FLAGS_system).c_str()[0], absl::GetFlag(FLAGS_signal)); + // read rinex receiver-under-test (rover) observations + std::map rover_obs = ReadRinexObs(absl::GetFlag(FLAGS_rover_rinex_obs), absl::GetFlag(FLAGS_system).c_str()[0], absl::GetFlag(FLAGS_signal)); +#endif if (base_obs.empty() or rover_obs.empty()) { return; @@ -1478,14 +1534,24 @@ void RINEX_doublediff(bool remove_rx_clock_error) double rover_rx_clock_error_s = 0.0; if (remove_rx_clock_error == true) { +#if USE_GLOG_AND_GFLAGS base_rx_clock_error_s = compute_rx_clock_error(FLAGS_rinex_nav, FLAGS_base_rinex_obs); rover_rx_clock_error_s = compute_rx_clock_error(FLAGS_rinex_nav, FLAGS_rover_rinex_obs); +#else + base_rx_clock_error_s = compute_rx_clock_error(absl::GetFlag(FLAGS_rinex_nav), absl::GetFlag(FLAGS_base_rinex_obs)); + rover_rx_clock_error_s = compute_rx_clock_error(absl::GetFlag(FLAGS_rinex_nav), absl::GetFlag(FLAGS_rover_rinex_obs)); +#endif } double common_clock_error_s = rover_rx_clock_error_s - base_rx_clock_error_s; // Cut measurement initial transitory of the measurements + +#if USE_GLOG_AND_GFLAGS double initial_transitory_s = FLAGS_skip_obs_transitory_s; +#else + double initial_transitory_s = absl::GetFlag(FLAGS_skip_obs_transitory_s); +#endif std::cout << "Skipping initial transitory of " << initial_transitory_s << " [s]\n"; arma::uvec index; for (auto& rover_ob : rover_obs) @@ -1535,7 +1601,11 @@ void RINEX_doublediff(bool remove_rx_clock_error) base_obs_time = base_obs.begin()->second.col(0); rover_obs_time = rover_obs.begin()->second.col(0); +#if USE_GLOG_AND_GFLAGS double skip_ends_s = FLAGS_skip_obs_ends_s; +#else + double skip_ends_s = absl::GetFlag(FLAGS_skip_obs_ends_s); +#endif std::cout << "Skipping last " << skip_ends_s << " [s] of observations\n"; for (auto& rover_ob : rover_obs) { @@ -1653,16 +1723,24 @@ void RINEX_doublediff(bool remove_rx_clock_error) void RINEX_singlediff() { +#if USE_GLOG_AND_GFLAGS // read rinex receiver-under-test observations std::map rover_obs = ReadRinexObs(FLAGS_rover_rinex_obs, FLAGS_system.c_str()[0], FLAGS_signal); - +#else + // read rinex receiver-under-test observations + std::map rover_obs = ReadRinexObs(absl::GetFlag(FLAGS_rover_rinex_obs), absl::GetFlag(FLAGS_system).c_str()[0], absl::GetFlag(FLAGS_signal)); +#endif if (rover_obs.empty()) { return; } - // Cut measurement initial transitory of the measurements + // Cut measurement initial transitory of the measurements +#if USE_GLOG_AND_GFLAGS double initial_transitory_s = FLAGS_skip_obs_transitory_s; +#else + double initial_transitory_s = absl::GetFlag(FLAGS_skip_obs_transitory_s); +#endif std::cout << "Skipping initial transitory of " << initial_transitory_s << " [s]\n"; arma::uvec index; for (auto& rover_ob : rover_obs) @@ -1677,7 +1755,11 @@ void RINEX_singlediff() // also skip last seconds of the observations (some artifacts are present in some RINEX endings) arma::colvec rover_obs_time = rover_obs.begin()->second.col(0); +#if USE_GLOG_AND_GFLAGS double skip_ends_s = FLAGS_skip_obs_ends_s; +#else + double skip_ends_s = absl::GetFlag(FLAGS_skip_obs_ends_s); +#endif std::cout << "Skipping last " << skip_ends_s << " [s] of observations\n"; for (auto& rover_ob : rover_obs) { @@ -1727,12 +1809,22 @@ void RINEX_singlediff() int main(int argc, char** argv) { std::cout << "Running RINEX observables difference tool...\n"; +#if USE_GLOG_AND_GFLAGS gflags::ParseCommandLineFlags(&argc, &argv, true); +#else + absl::ParseCommandLine(argc, argv); +#endif try { +#if USE_GLOG_AND_GFLAGS if (FLAGS_single_diff) { if (FLAGS_dupli_sat) +#else + if (absl::GetFlag(FLAGS_single_diff)) + { + if (absl::GetFlag(FLAGS_dupli_sat)) +#endif { RINEX_doublediff_dupli_sat(); } @@ -1743,27 +1835,39 @@ int main(int argc, char** argv) } else { +#if USE_GLOG_AND_GFLAGS RINEX_doublediff(FLAGS_remove_rx_clock_error); +#else + RINEX_doublediff(absl::GetFlag(FLAGS_remove_rx_clock_error)); +#endif } } catch (const gnsstk::Exception& e) { std::cerr << e; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } catch (const std::exception& e) { std::cerr << "Exception: " << e.what(); +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } catch (...) { std::cerr << "Unknown error\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 0; } diff --git a/src/utils/rinex-tools/obsdiff_flags.h b/utils/rinex-tools/obsdiff_flags.h similarity index 55% rename from src/utils/rinex-tools/obsdiff_flags.h rename to utils/rinex-tools/obsdiff_flags.h index 961ae9536..d3b9a607c 100644 --- a/src/utils/rinex-tools/obsdiff_flags.h +++ b/utils/rinex-tools/obsdiff_flags.h @@ -18,6 +18,7 @@ #ifndef GNSS_SDR_OBSDIFF_FLAGS_H #define GNSS_SDR_OBSDIFF_FLAGS_H +#if USE_GLOG_AND_GFLAGS #include DEFINE_double(skip_obs_transitory_s, 30.0, "Skip the initial observable outputs to avoid transitory results [s]"); @@ -33,5 +34,24 @@ DEFINE_string(rover_rinex_obs, "base.obs", "Filename of test RINEX observation f DEFINE_string(system, "G", "GNSS satellite system: G for GPS, E for Galileo"); DEFINE_string(signal, "1C", "GNSS signal: 1C for GPS L1 CA, 1B for Galileo E1"); DEFINE_bool(remove_rx_clock_error, false, "Compute and remove the receivers clock error prior to compute observable differences (requires a valid RINEX nav file for both receivers)"); +#else +#include +#include +#include + +ABSL_FLAG(double, skip_obs_transitory_s, 30.0, "Skip the initial observable outputs to avoid transitory results [s]"); +ABSL_FLAG(double, skip_obs_ends_s, 5.0, "Skip the lasts observable outputs to avoid transitory results [s]"); +ABSL_FLAG(bool, single_diffs, false, "Compute also the single difference errors for Accumulated Carrier Phase and Carrier Doppler (requires LO synchronization between receivers)"); +ABSL_FLAG(bool, compare_with_5X, false, "Compare the E5a Doppler and Carrier Phases with the E5 full bw in RINEX (expect discrepancy due to the center frequencies difference)"); +ABSL_FLAG(bool, dupli_sat, false, "Enable special observable test mode where the scenario contains duplicated satellite orbits"); +ABSL_FLAG(bool, single_diff, false, "Enable special observable test mode using only rover observables"); +ABSL_FLAG(std::string, dupli_sat_prns, "1,2,3,4", "List of duplicated satellites PRN pairs (i.e. 1,2,3,4 indicates that the PRNs 1,2 share the same orbit. The same applies for PRNs 3,4)"); +ABSL_FLAG(std::string, base_rinex_obs, "base.obs", "Filename of reference RINEX observation file"); +ABSL_FLAG(std::string, rinex_nav, "base.nav", "Filename of reference RINEX navigation file"); +ABSL_FLAG(std::string, rover_rinex_obs, "base.obs", "Filename of test RINEX observation file"); +ABSL_FLAG(std::string, system, "G", "GNSS satellite system: G for GPS, E for Galileo"); +ABSL_FLAG(std::string, signal, "1C", "GNSS signal: 1C for GPS L1 CA, 1B for Galileo E1"); +ABSL_FLAG(bool, remove_rx_clock_error, false, "Compute and remove the receivers clock error prior to compute observable differences (requires a valid RINEX nav file for both receivers)"); #endif +#endif diff --git a/src/utils/rinex2assist/CMakeLists.txt b/utils/rinex2assist/CMakeLists.txt similarity index 83% rename from src/utils/rinex2assist/CMakeLists.txt rename to utils/rinex2assist/CMakeLists.txt index 4f9e31b88..f4cabcd3d 100644 --- a/src/utils/rinex2assist/CMakeLists.txt +++ b/utils/rinex2assist/CMakeLists.txt @@ -19,7 +19,19 @@ if(NOT GNSSTK_FOUND OR ENABLE_OWN_GNSSTK) endif() endif() -find_package(Boost COMPONENTS iostreams serialization QUIET) +if(CMAKE_VERSION VERSION_LESS 3.30) + find_package(Boost COMPONENTS iostreams serialization QUIET) +else() + find_package(Boost COMPONENTS iostreams serialization) + if(NOT TARGET Boost::iostreams) + message(STATUS "Trying deprecated FindBoost Module ...") + if(POLICY CMP0167) + cmake_policy(SET CMP0167 OLD) + find_package(Boost COMPONENTS iostreams serialization) + endif() + endif() +endif() + if(CMAKE_VERSION VERSION_LESS 3.5) if(NOT TARGET Boost::iostreams) add_library(Boost::iostreams IMPORTED SHARED) @@ -42,12 +54,10 @@ if(CMAKE_VERSION VERSION_LESS 3.5) endif() find_program(UNCOMPRESS_EXECUTABLE uncompress - PATHS /bin - /usr/bin - /usr/sbin + PATHS ${GNSSSDR_BIN_PATHS} ) -if(Boost_FOUND) +if(TARGET Boost::iostreams AND TARGET Boost::serialization) message(STATUS "The rinex2assist utility tool will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'") if(USE_CMAKE_TARGET_SOURCES) add_executable(rinex2assist) @@ -59,7 +69,10 @@ if(Boost_FOUND) add_executable(rinex2assist ${CMAKE_CURRENT_SOURCE_DIR}/main.cc) endif() - set_property(TARGET rinex2assist PROPERTY CXX_STANDARD 14) # Required by GPSTk + if(GNSSTK_VERSION AND "${GNSSTK_VERSION}" VERSION_LESS 3.0.1) + set_property(TARGET rinex2assist PROPERTY CXX_STANDARD 14) # Required by GPSTk v3.0.0 + endif() + # Do not show warnings raised by GPSTk v3.0.0 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") target_compile_options(rinex2assist @@ -79,11 +92,17 @@ if(Boost_FOUND) Boost::iostreams Boost::serialization ${GNSSTK_LIBRARY} - Gflags::gflags Threads::Threads core_system_parameters ) + if(ENABLE_GLOG_AND_GFLAGS) + target_link_libraries(rinex2assist PRIVATE Gflags::gflags) + target_compile_definitions(rinex2assist PRIVATE -DUSE_GLOG_AND_GFLAGS=1) + else() + target_link_libraries(rinex2assist PRIVATE absl::flags absl::flags_parse) + endif() + if(GNSSTK_USES_GPSTK_NAMESPACE) target_compile_definitions(rinex2assist PUBLIC -DGNSSTK_USES_GPSTK_NAMESPACE=1) target_include_directories(rinex2assist @@ -135,7 +154,7 @@ else() elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") message(STATUS " sudo zypper install libboost_iostreams-devel") else() - message(STATUS " sudo apt-get install libboost-iostreams-dev") + message(STATUS " sudo apt install libboost-iostreams-dev") endif() endif() endif() diff --git a/src/utils/rinex2assist/README.md b/utils/rinex2assist/README.md similarity index 97% rename from src/utils/rinex2assist/README.md rename to utils/rinex2assist/README.md index 4ddc4b3bd..55c746cca 100644 --- a/src/utils/rinex2assist/README.md +++ b/utils/rinex2assist/README.md @@ -32,7 +32,7 @@ The building requires two extra dependencies: the Boost Iostreams library and the program `uncompress`: - The Boost Iostreams library can be installed through a package: - - In Debian / Ubuntu: `sudo apt-get install libboost-iostreams-dev` + - In Debian / Ubuntu: `sudo apt install libboost-iostreams-dev` - In Fedora / CentOS: `sudo yum install boost-iostreams` - In OpenSUSE: `sudo zypper install libboost_iostreams-devel` - In Arch Linux: included in `boost-libs` package. @@ -51,7 +51,7 @@ $ rinex2assist /path/to/RINEX_nav_file ``` The argument is mandatory (the name of the RINEX navigation file). The name -`gps_ephemeris.xml` is given to the output if GPS NAV data is fould. If the +`gps_ephemeris.xml` is given to the output if GPS NAV data is found. If the RINEX file contains Galileo data, the corresponding `gal_ephemeris.xml` file will be generated. The program is also able to extract parameters of the UTC and the Ionospheric models from the RINEX header, if available. They will be called diff --git a/src/utils/rinex2assist/main.cc b/utils/rinex2assist/main.cc similarity index 96% rename from src/utils/rinex2assist/main.cc rename to utils/rinex2assist/main.cc index b100ac95d..7ae45a286 100644 --- a/src/utils/rinex2assist/main.cc +++ b/utils/rinex2assist/main.cc @@ -27,7 +27,6 @@ #include #include #include -#include #include // for size_t #include #include @@ -44,12 +43,21 @@ namespace gnsstk = gpstk; #include #endif +#if USE_GLOG_AND_GFLAGS +#include #if GFLAGS_OLD_NAMESPACE namespace gflags { using namespace google; } #endif +#else +#include +#include +#include +#include +std::string TstVersionString() { return "1.0"; } +#endif int main(int argc, char** argv) { @@ -61,17 +69,26 @@ int main(int argc, char** argv) "Usage: \n" + " rinex2assist "); +#if USE_GLOG_AND_GFLAGS gflags::SetUsageMessage(intro_help); google::SetVersionString("1.0"); gflags::ParseCommandLineFlags(&argc, &argv, true); - +#else + absl::FlagsUsageConfig empty_config; + empty_config.version_string = &TstVersionString; + absl::SetFlagsUsageConfig(empty_config); + absl::SetProgramUsageMessage(intro_help); + absl::ParseCommandLine(argc, argv); +#endif if ((argc != 2)) { std::cerr << "Usage:\n"; std::cerr << " " << argv[0] << " " << '\n'; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } std::string xml_filename; @@ -327,14 +344,18 @@ int main(int argc, char** argv) { std::cerr << "Error reading the RINEX file: " << e.what() << '\n'; std::cerr << "No XML file will be created.\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } if (i == 0 and j == 0) { std::cerr << "No navigation data found in the RINEX file. No XML file will be created.\n"; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } @@ -355,7 +376,9 @@ int main(int argc, char** argv) catch (std::exception& e) { std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } std::cout << "Generated file: " << xml_filename << '\n'; @@ -373,7 +396,9 @@ int main(int argc, char** argv) catch (std::exception& e) { std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } std::cout << "Generated file: " << xml_filename << '\n'; @@ -393,7 +418,9 @@ int main(int argc, char** argv) catch (std::exception& e) { std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } std::cout << "Generated file: " << xml_filename << '\n'; @@ -413,7 +440,9 @@ int main(int argc, char** argv) catch (std::exception& e) { std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } std::cout << "Generated file: " << xml_filename << '\n'; @@ -432,7 +461,9 @@ int main(int argc, char** argv) catch (std::exception& e) { std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } std::cout << "Generated file: " << xml_filename << '\n'; @@ -450,11 +481,15 @@ int main(int argc, char** argv) catch (std::exception& e) { std::cerr << "Problem creating the XML file " << xml_filename << ": " << e.what() << '\n'; +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 1; } std::cout << "Generated file: " << xml_filename << '\n'; } +#if USE_GLOG_AND_GFLAGS gflags::ShutDownCommandLineFlags(); +#endif return 0; } diff --git a/src/utils/scripts/download-galileo-almanac.sh b/utils/scripts/download-galileo-almanac.sh similarity index 100% rename from src/utils/scripts/download-galileo-almanac.sh rename to utils/scripts/download-galileo-almanac.sh diff --git a/src/utils/scripts/gnss-sdr-harness.sh b/utils/scripts/gnss-sdr-harness.sh similarity index 100% rename from src/utils/scripts/gnss-sdr-harness.sh rename to utils/scripts/gnss-sdr-harness.sh diff --git a/src/utils/simulink/MultiThread/README_gnss_sdr_tcp_connector_parallel_tracking.txt b/utils/simulink/MultiThread/README_gnss_sdr_tcp_connector_parallel_tracking.txt similarity index 100% rename from src/utils/simulink/MultiThread/README_gnss_sdr_tcp_connector_parallel_tracking.txt rename to utils/simulink/MultiThread/README_gnss_sdr_tcp_connector_parallel_tracking.txt diff --git a/src/utils/simulink/MultiThread/gnss_sdr_tcp_connector_parallel_tracking_start.m b/utils/simulink/MultiThread/gnss_sdr_tcp_connector_parallel_tracking_start.m similarity index 100% rename from src/utils/simulink/MultiThread/gnss_sdr_tcp_connector_parallel_tracking_start.m rename to utils/simulink/MultiThread/gnss_sdr_tcp_connector_parallel_tracking_start.m diff --git a/src/utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl b/utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl similarity index 100% rename from src/utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl rename to utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl diff --git a/src/utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license b/utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license similarity index 100% rename from src/utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license rename to utils/simulink/MultiThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license diff --git a/src/utils/simulink/SingleThread/README_gnss_sdr_galileo_e1_tcp_connector_tracking.txt b/utils/simulink/SingleThread/README_gnss_sdr_galileo_e1_tcp_connector_tracking.txt similarity index 100% rename from src/utils/simulink/SingleThread/README_gnss_sdr_galileo_e1_tcp_connector_tracking.txt rename to utils/simulink/SingleThread/README_gnss_sdr_galileo_e1_tcp_connector_tracking.txt diff --git a/src/utils/simulink/SingleThread/README_gnss_sdr_tcp_connector_tracking.txt b/utils/simulink/SingleThread/README_gnss_sdr_tcp_connector_tracking.txt similarity index 100% rename from src/utils/simulink/SingleThread/README_gnss_sdr_tcp_connector_tracking.txt rename to utils/simulink/SingleThread/README_gnss_sdr_tcp_connector_tracking.txt diff --git a/src/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl b/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl similarity index 100% rename from src/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl rename to utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl diff --git a/src/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl.license b/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl.license similarity index 100% rename from src/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl.license rename to utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_lib.mdl.license diff --git a/src/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_start.m b/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_start.m similarity index 100% rename from src/utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_start.m rename to utils/simulink/SingleThread/gnss_sdr_galileo_e1_tcp_connector_tracking_start.m diff --git a/src/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl b/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl similarity index 100% rename from src/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl rename to utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl diff --git a/src/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license b/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license similarity index 100% rename from src/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license rename to utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_lib.mdl.license diff --git a/src/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_start.m b/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_start.m similarity index 100% rename from src/utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_start.m rename to utils/simulink/SingleThread/gnss_sdr_tcp_connector_tracking_start.m