From 4095e911d85a0225f180a401694e49c23e1dfb6b Mon Sep 17 00:00:00 2001 From: Phil Crump Date: Sat, 22 Feb 2020 23:24:00 +0000 Subject: [PATCH 001/197] ubxtool.cc: Use monotonic clock for uptime calculation. --- ubxtool.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ubxtool.cc b/ubxtool.cc index a1d69cb..1f4fdab 100644 --- a/ubxtool.cc +++ b/ubxtool.cc @@ -565,7 +565,7 @@ int initFD(const char* fname, bool doRTSCTS) // ubxtool device srcid int main(int argc, char** argv) { - time_t starttime=time(0); + auto starttime = std::chrono::steady_clock::now(); GOOGLE_PROTOBUF_VERIFY_VERSION; CLI::App app(program); @@ -1629,7 +1629,7 @@ int main(int argc, char** argv) nmm.mutable_od()->set_owner(owner); nmm.mutable_od()->set_remark(remark); nmm.mutable_od()->set_recvgithash(g_gitHash); - nmm.mutable_od()->set_uptime(time(0) - starttime); + nmm.mutable_od()->set_uptime(std::chrono::duration_cast(std::chrono::steady_clock::now()-starttime).count()); ns.emitNMM( nmm); From c94f6bad24503713b947c31e2c9686f2110c014b Mon Sep 17 00:00:00 2001 From: Brad Cowie Date: Sun, 2 Feb 2020 13:58:47 +1300 Subject: [PATCH 002/197] Add docker image building via github actions. --- .github/workflows/docker.yml | 32 ++++++++++++++++++++++++++++++++ Dockerfile | 2 +- README.md | 21 ++++++++++++++------- 3 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..824e24d --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,32 @@ +name: Build and publish Docker image + +on: + push: + branches: master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Checkout submodules + run: git submodule update --init --recursive + - name: Set up docker buildx + id: buildx + uses: crazy-max/ghaction-docker-buildx@v3 + with: + buildx-version: latest + qemu-version: latest + - name: Login to docker registry + run: | + docker login --username ${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_TOKEN }} + - name: Run buildx + run: | + docker buildx build \ + --tag galmon/galmon \ + --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8 \ + --output "type=registry" \ + --build-arg MAKE_FLAGS=-j1 \ + --file Dockerfile \ + . diff --git a/Dockerfile b/Dockerfile index 7081bbc..d8d5a5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:disco +FROM ubuntu:eoan ENV DEBIAN_FRONTEND noninteractive ENV LC_ALL C.UTF-8 diff --git a/README.md b/README.md index e53f083..75f32ed 100644 --- a/README.md +++ b/README.md @@ -92,22 +92,29 @@ library installed. If you get an error about 'wslay', do the following, and run echo WSLAY=-lwslay > Makefile.local ``` -Build in Docker ---------------- +Running in Docker +----------------- -To build it in Docker: +We publish official Docker images for galmon on +[docker hub](https://hub.docker.com/r/faucet/faucet) for multiple architectures. + +To run a container with a shell in there (this will also expose a port so you +can view the UI too and assumes a ublox GPS device too - +you may need to tweak as necessary): ``` -git clone https://github.com/ahupowerdns/galmon.git --recursive -docker build -t galmon --build-arg MAKE_FLAGS=-j2 . +docker run -it --rm --device=/dev/ttyACM0 -p 10000:10000 galmon/galmon ``` -To run a container with a shell in there (this will also expose a port so you can view the UI too and assumes a ublox GPS device too - you may need to tweak as necessary): +Running a daemonized docker container reporting data to a remote server +might look like: ``` -docker run -it --rm --device=/dev/ttyACM0 -p 10000:10000 galmon +docker run -d --restart=always --device=/dev/ttyACM0 --name=galmon galmon/galmon /galmon/ubxtool --wait --port /dev/ttyACM0 --gps --galileo --glonass --destination [server] --station [station-id] --owner [owner] ``` +To make your docker container update automatically you could use a tool such as +[watchtower](https://containrrr.github.io/watchtower/). Running ------- From bf66486f633d1d35a071d0f6e2944ccc4f321a02 Mon Sep 17 00:00:00 2001 From: Brad Cowie Date: Fri, 10 Jul 2020 10:24:58 +1200 Subject: [PATCH 003/197] Update official docker image name in README.md. --- .github/workflows/docker.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 824e24d..d5184c7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -24,7 +24,7 @@ jobs: - name: Run buildx run: | docker buildx build \ - --tag galmon/galmon \ + --tag berthubert/galmon \ --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8 \ --output "type=registry" \ --build-arg MAKE_FLAGS=-j1 \ diff --git a/README.md b/README.md index e0cddef..6f8f0eb 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ Running in Docker ----------------- We publish official Docker images for galmon on -[docker hub](https://hub.docker.com/r/faucet/faucet) for multiple architectures. +[docker hub](https://hub.docker.com/r/berthubert/galmon) for multiple architectures. To run a container with a shell in there (this will also expose a port so you can view the UI too and assumes a ublox GPS device too - From 24dbcd27ab16b1b3f14ba931f6bfd73067b72a39 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Fri, 10 Jul 2020 13:03:36 +0200 Subject: [PATCH 004/197] add compilation warning --- zstdwrap.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zstdwrap.hh b/zstdwrap.hh index 11a07fb..0cb9d85 100644 --- a/zstdwrap.hh +++ b/zstdwrap.hh @@ -1,6 +1,7 @@ #pragma once #include -#include // can't easily be moved to zstdwrap.cc, trust me +#include // apt-get install libzstd-dev if you miss this. +// can't easily be moved to zstdwrap.cc, trust me #include #include #include From 3b638de1ee11e985537924e4b3b3dc5c28ab274d Mon Sep 17 00:00:00 2001 From: bert hubert Date: Fri, 10 Jul 2020 21:06:54 +0200 Subject: [PATCH 005/197] adjust for NEO-8MP not doing *anything* with Galileo --- ubxtool.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ubxtool.cc b/ubxtool.cc index c750253..be80e4d 100644 --- a/ubxtool.cc +++ b/ubxtool.cc @@ -955,9 +955,11 @@ int main(int argc, char** argv) if (doDEBUG) { cerr< Date: Thu, 16 Jul 2020 14:05:39 +0200 Subject: [PATCH 006/197] add gndate tool to get weeknumber for gps or galileo, plus TOW --- Makefile | 6 +++++- gndate.cc | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 gndate.cc diff --git a/Makefile b/Makefile index 884c31f..a008e1b 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ endif CHEAT_ARG := $(shell ./update-git-hash-if-necessary) PROGRAMS = navparse ubxtool navnexus navcat navrecv navdump testrunner navdisplay tlecatch reporter sp3feed \ - galmonmon rinreport rtcmtool + galmonmon rinreport rtcmtool gndate all: navmon.pb.cc $(PROGRAMS) @@ -127,5 +127,9 @@ ubxtool: navmon.pb.o ubxtool.o ubx.o bits.o ext/fmt-6.1.2/src/format.o galileo.o testrunner: navmon.pb.o testrunner.o ubx.o bits.o ext/fmt-6.1.2/src/format.o galileo.o gps.o beidou.o ephemeris.o sp3.o osen.o navmon.o rinex.o githash.o $(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -lz +gndate: gndate.o githash.o ext/fmt-6.1.2/src/format.o navmon.o + $(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib + + check: testrunner ./testrunner diff --git a/gndate.cc b/gndate.cc new file mode 100644 index 0000000..d027981 --- /dev/null +++ b/gndate.cc @@ -0,0 +1,57 @@ +#include "navmon.hh" +#include +#include "CLI/CLI.hpp" +#include "version.hh" + +extern const char* g_gitHash; +using namespace std; + +int main(int argc, char** argv) +{ + string program("gndate"); + CLI::App app(program); + string date; + bool doGPSWN{false}, doGALWN{false}, doVERSION{false}, doUTC{false}; + app.add_flag("--version", doVERSION, "show program version and copyright"); + app.add_option("--date,-d", date, "yyyy-mm-dd hh:mm"); + app.add_flag("--utc,-u", doUTC, "Interpret --date,-d as UTC"); + app.add_flag("--gps-wn", doGPSWN, "Print GPS week number"); + app.add_flag("--gal-wn", doGALWN, "Print GPS week number"); + try { + app.parse(argc, argv); + } catch(const CLI::Error &e) { + return app.exit(e); + } + + if(doVERSION) { + showVersion(program.c_str(), g_gitHash); + exit(0); + } + + + time_t now; + if(date.empty()) + now = time(0); + else { + if(doUTC) + setenv("TZ", "UTC", 1); + now = parseTime(date); + } + + int wn, tow; + + if(doGPSWN) { + getGPSDateFromUTC(now, wn, tow); + cout< Date: Thu, 16 Jul 2020 14:13:57 +0200 Subject: [PATCH 007/197] move functions around for gndate --- navcat.cc | 22 ---------------------- navmon.cc | 42 +++++++++++++++++++++++++++++++++++++++++- navmon.hh | 5 +++++ 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/navcat.cc b/navcat.cc index c7150c5..592641b 100644 --- a/navcat.cc +++ b/navcat.cc @@ -26,28 +26,6 @@ using namespace std; extern const char* g_gitHash; -time_t parseTime(std::string_view in) -{ - time_t now=time(0); - - vector formats({"%Y-%m-%d %H:%M", "%Y%m%d %H%M", "%H:%M", "%H%M"}); - for(const auto& f : formats) { - struct tm tm; - memset(&tm, 0, sizeof(tm)); - - localtime_r(&now, &tm); - tm.tm_isdst = -1; - tm.tm_sec = 0; - char* res = strptime(&in[0], f.c_str(), &tm); - if(res && !*res) { - cerr<<"Matched on "< getSources(string_view dirname) { diff --git a/navmon.cc b/navmon.cc index 01ae6d4..a26dfd8 100644 --- a/navmon.cc +++ b/navmon.cc @@ -9,7 +9,7 @@ #include #include #include - +#include using namespace std; using Clock = std::chrono::steady_clock; @@ -280,6 +280,20 @@ std::string makeSatPartialName(const SatID& satid) return fmt::sprintf("%c%02d", getGNSSChar(satid.gnss), satid.sv); } +void getGPSDateFromUTC(time_t t, int& wn, int& tow) +{ + t -= 315964800; + t += 18; + wn = t/(7*86400); + tow = t%(7*86400); +} +void getGalDateFromUTC(time_t t, int& wn, int& tow) +{ + t -= 935280000; + t += 18; + wn = t/(7*86400); + tow = t%(7*86400); +} int g_dtLS{18}, g_dtLSBeidou{4}; uint64_t utcFromGST(int wn, int tow) @@ -356,3 +370,29 @@ void unixDie(const std::string& reason) { throw std::runtime_error(reason+": "+strerror(errno)); } + +time_t parseTime(std::string_view in) +{ + time_t now=time(0); + + vector formats({"%Y-%m-%d %H:%M", "%Y%m%d %H%M", "%H:%M", "%H%M"}); + for(const auto& f : formats) { + struct tm tm; + memset(&tm, 0, sizeof(tm)); + + localtime_r(&now, &tm); + tm.tm_isdst = -1; + tm.tm_sec = 0; + char* res = strptime(&in[0], f.c_str(), &tm); + if(res && !*res) { + // cerr<<"Matched on "< Date: Thu, 16 Jul 2020 14:22:36 +0200 Subject: [PATCH 008/197] update version function signature --- version.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.hh b/version.hh index d65fa50..42c8833 100644 --- a/version.hh +++ b/version.hh @@ -1,6 +1,6 @@ #pragma once -void showVersion(char *pname, const char *hash) { +void showVersion(const char *pname, const char *hash) { std::cout <<"galmon tools (" < Date: Thu, 16 Jul 2020 14:33:17 +0200 Subject: [PATCH 009/197] various rtcm improvements, some documentation, navdump emitted 0x0 values for af2. rtcm can now parse ephemerides for Galileo. --- influxdb.md | 4 ++-- navdump.cc | 33 ++++++++++++++++++++++++++++----- rtcm.cc | 41 ++++++++++++++++++++++++++++++++++++++++- rtcm.hh | 5 ++++- rtcmtool.cc | 7 ++++++- 5 files changed, 80 insertions(+), 10 deletions(-) diff --git a/influxdb.md b/influxdb.md index ea6b0de..4c725ae 100644 --- a/influxdb.md +++ b/influxdb.md @@ -84,8 +84,8 @@ These measurements are tagged by gnssid, sv * tow * udi * rtcm-clock-correction - * dclock0 - * dclock1 + * dclock0: in meters + * dclock1: meters/s * dclock2 * ssr-iod * ssr-provider diff --git a/navdump.cc b/navdump.cc index ae12ee5..f5c1153 100644 --- a/navdump.cc +++ b/navdump.cc @@ -535,7 +535,13 @@ try if(gm.alma3.e1bhs != 0) { cout <<" gm.tow "< 31) + dw = 31- dw; + int delta = dw*7*86400 + gm.tow - gm.getT0g(); // NOT ephemeris age tricks + cout<<" wn%64 "<< (gm.wn%64) << " dw " << dw <<" delta " << delta; } cout<second.t0c != gs.t0c) { auto oldOffset = getGPSAtomicOffset(gs.tow, iter->second); auto newOffset = getGPSAtomicOffset(gs.tow, gs); @@ -693,8 +699,25 @@ try cout<buff,i,12,1045 ); i+=12; + setbitu(rtcm->buff,i, 6,prn ); i+= 6; + setbitu(rtcm->buff,i,12,week ); i+=12; + setbitu(rtcm->buff,i,10,eph->iode); i+=10; + setbitu(rtcm->buff,i, 8,eph->sva ); i+= 8; + setbits(rtcm->buff,i,14,idot ); i+=14; + setbitu(rtcm->buff,i,14,toc ); i+=14; + setbits(rtcm->buff,i, 6,af2 ); i+= 6; + setbits(rtcm->buff,i,21,af1 ); i+=21; + setbits(rtcm->buff,i,31,af0 ); i+=31; + */ + + } } diff --git a/rtcm.hh b/rtcm.hh index 16b6335..eaced78 100644 --- a/rtcm.hh +++ b/rtcm.hh @@ -3,6 +3,8 @@ #include #include "navmon.hh" #include +#include "galileo.hh" + struct RTCMFrame { std::string payload; @@ -50,5 +52,6 @@ struct RTCMMessage std::vector d_ephs; std::vector d_clocks; - + GalileoMessage d_gm; + int d_sv; }; diff --git a/rtcmtool.cc b/rtcmtool.cc index 31d58f6..eef3441 100644 --- a/rtcmtool.cc +++ b/rtcmtool.cc @@ -13,10 +13,14 @@ using namespace std; bool RTCMReader::get(RTCMFrame& rf) { int c; + bool skipped=false; while( ((c=fgetc(d_fp)) != -1) && c != 211) { - cerr<<"Skipped, not yet 211 character "< Date: Thu, 16 Jul 2020 16:08:08 +0200 Subject: [PATCH 010/197] update to newer version of CLI11 --- ext/CLI11/CLI/App.hpp | 3400 +++++++++++++++++++++++++-------- ext/CLI11/CLI/CLI.hpp | 42 +- ext/CLI11/CLI/Error.hpp | 329 +++- ext/CLI11/CLI/Ini.hpp | 115 -- ext/CLI11/CLI/Option.hpp | 1305 ++++++++++--- ext/CLI11/CLI/Split.hpp | 90 +- ext/CLI11/CLI/StringTools.hpp | 277 ++- ext/CLI11/CLI/Timer.hpp | 47 +- ext/CLI11/CLI/TypeTools.hpp | 981 +++++++++- ext/CLI11/CLI/Validators.hpp | 1158 ++++++++++- 10 files changed, 6329 insertions(+), 1415 deletions(-) delete mode 100644 ext/CLI11/CLI/Ini.hpp diff --git a/ext/CLI11/CLI/App.hpp b/ext/CLI11/CLI/App.hpp index cdb91ab..111a13d 100644 --- a/ext/CLI11/CLI/App.hpp +++ b/ext/CLI11/CLI/App.hpp @@ -1,12 +1,16 @@ +// Copyright (c) 2017-2020, University of Cincinnati, developed by Henry Schreiner +// under NSF AWARD 1414736 and by the respective contributors. +// All rights reserved. +// +// SPDX-License-Identifier: BSD-3-Clause + #pragma once -// Distributed under the 3-Clause BSD License. See accompanying -// file LICENSE or https://github.com/CLIUtils/CLI11 for details. - #include -#include +#include #include #include +#include #include #include #include @@ -16,28 +20,49 @@ #include // CLI Library includes -#include "CLI/Error.hpp" -#include "CLI/Ini.hpp" -#include "CLI/Option.hpp" -#include "CLI/Split.hpp" -#include "CLI/StringTools.hpp" -#include "CLI/TypeTools.hpp" +#include "ConfigFwd.hpp" +#include "Error.hpp" +#include "FormatterFwd.hpp" +#include "Macros.hpp" +#include "Option.hpp" +#include "Split.hpp" +#include "StringTools.hpp" +#include "TypeTools.hpp" namespace CLI { +#ifndef CLI11_PARSE +#define CLI11_PARSE(app, argc, argv) \ + try { \ + (app).parse((argc), (argv)); \ + } catch(const CLI::ParseError &e) { \ + return (app).exit(e); \ + } +#endif + namespace detail { -enum class Classifer { NONE, POSITIONAL_MARK, SHORT, LONG, SUBCOMMAND }; +enum class Classifier { NONE, POSITIONAL_MARK, SHORT, LONG, WINDOWS, SUBCOMMAND, SUBCOMMAND_TERMINATOR }; struct AppFriend; -} // namespace detail +} // namespace detail + +namespace FailureMessage { +std::string simple(const App *app, const Error &e); +std::string help(const App *app, const Error &e); +} // namespace FailureMessage + +/// enumeration of modes of how to deal with extras in config files + +enum class config_extras_mode : char { error = 0, ignore, capture }; class App; -using App_p = std::unique_ptr; +using App_p = std::shared_ptr; +class Option_group; /// Creates a command line program, with very few defaults. /** To use, create a new `Program()` instance with `argc`, `argv`, and a help description. The templated -* add_option methods make it easy to prepare options. Remember to call `.start` before starting your -* program, so that the options can be evaluated and the help option doesn't accidentally run your program. */ + * add_option methods make it easy to prepare options. Remember to call `.start` before starting your + * program, so that the options can be evaluated and the help option doesn't accidentally run your program. */ class App { friend Option; friend detail::AppFriend; @@ -48,87 +73,216 @@ class App { /// @name Basics ///@{ - /// Subcommand name or program name (from parser) - std::string name_{"program"}; + /// Subcommand name or program name (from parser if name is empty) + std::string name_{}; /// Description of the current program/subcommand - std::string description_; + std::string description_{}; - /// If true, allow extra arguments (ie, don't throw an error). + /// If true, allow extra arguments (ie, don't throw an error). INHERITABLE bool allow_extras_{false}; - /// If true, return immediatly on an unrecognised option (implies allow_extras) + /// If ignore, allow extra arguments in the ini file (ie, don't throw an error). INHERITABLE + /// if error error on an extra argument, and if capture feed it to the app + config_extras_mode allow_config_extras_{config_extras_mode::ignore}; + + /// If true, return immediately on an unrecognized option (implies allow_extras) INHERITABLE bool prefix_command_{false}; - /// This is a function that runs when complete. Great for subcommands. Can throw. - std::function callback_; + /// If set to true the name was automatically generated from the command line vs a user set name + bool has_automatic_name_{false}; + + /// If set to true the subcommand is required to be processed and used, ignored for main app + bool required_{false}; + + /// If set to true the subcommand is disabled and cannot be used, ignored for main app + bool disabled_{false}; + + /// Flag indicating that the pre_parse_callback has been triggered + bool pre_parse_called_{false}; + + /// Flag indicating that the callback for the subcommand should be executed immediately on parse completion which is + /// before help or ini files are processed. INHERITABLE + bool immediate_callback_{false}; + + /// This is a function that runs prior to the start of parsing + std::function pre_parse_callback_{}; + + /// This is a function that runs when parsing has finished. + std::function parse_complete_callback_{}; + /// This is a function that runs when all processing has completed + std::function final_callback_{}; ///@} /// @name Options ///@{ - /// The list of options, stored locally - std::vector options_; + /// The default values for options, customizable and changeable INHERITABLE + OptionDefaults option_defaults_{}; - /// A pointer to the help flag if there is one + /// The list of options, stored locally + std::vector options_{}; + + ///@} + /// @name Help + ///@{ + + /// Footer to put after all options in the help output INHERITABLE + std::string footer_{}; + + /// This is a function that generates a footer to put after all other options in help output + std::function footer_callback_{}; + + /// A pointer to the help flag if there is one INHERITABLE Option *help_ptr_{nullptr}; + /// A pointer to the help all flag if there is one INHERITABLE + Option *help_all_ptr_{nullptr}; + + /// This is the formatter for help printing. Default provided. INHERITABLE (same pointer) + std::shared_ptr formatter_{new Formatter()}; + + /// The error message printing function INHERITABLE + std::function failure_message_{FailureMessage::simple}; + ///@} /// @name Parsing ///@{ - using missing_t = std::vector>; + using missing_t = std::vector>; /// Pair of classifier, string for missing options. (extra detail is removed on returning from parse) /// /// This is faster and cleaner than storing just a list of strings and reparsing. This may contain the -- separator. - missing_t missing_; + missing_t missing_{}; - /// This is a list of pointers to options with the orignal parse order - std::vector