From 49787af9d174d6ba5fd293ccbd09834ba7e1877b Mon Sep 17 00:00:00 2001 From: Joseph Fox-Rabinovitz Date: Tue, 19 May 2026 17:32:37 +0000 Subject: [PATCH] Support for Advanced Navigation ANPP format --- app/consapp/convbin/bcc/_convbin.cbproj | 3 + app/consapp/convbin/convbin.c | 9 + app/consapp/convbin/gcc/makefile | 5 +- app/consapp/convbin/msc/msc.vcxproj | 1 + app/consapp/rtkrcv/gcc/makefile | 5 +- app/consapp/rtkrcv/rtkrcv.c | 4 +- app/consapp/str2str/gcc/makefile | 5 +- app/consapp/str2str/str2str.c | 2 + app/qtapp/rtkconv_qt/convmain.cpp | 4 +- app/qtapp/rtknavi_qt/navimain.cpp | 2 +- app/winapp/rtkconv/convmain.cpp | 1 + app/winapp/rtkconv/convmain.dfm | 2 +- app/winapp/rtkconv/rtkconv.cbproj | 3 + app/winapp/rtknavi/naviopt.cpp | 2 +- app/winapp/rtknavi/rtknavi.cbproj | 3 + app/winapp/rtkplot/rtkplot.cbproj | 3 + app/winapp/srctblbrows/srctblbrows.cbproj | 3 + app/winapp/strsvr/strsvr.cbproj | 3 + src/CMakeLists.txt | 1 + src/convrnx.c | 12 +- src/rcv/adnav.c | 613 ++++++++++++++++++++++ src/rcvraw.c | 6 +- src/rtkcmn.c | 29 +- src/rtklib.h | 25 +- src/src.pro | 3 +- 25 files changed, 716 insertions(+), 33 deletions(-) create mode 100644 src/rcv/adnav.c diff --git a/app/consapp/convbin/bcc/_convbin.cbproj b/app/consapp/convbin/bcc/_convbin.cbproj index b6391586d..4103f4ac5 100644 --- a/app/consapp/convbin/bcc/_convbin.cbproj +++ b/app/consapp/convbin/bcc/_convbin.cbproj @@ -230,6 +230,9 @@ 26 + + 28 + 8 13 diff --git a/app/consapp/convbin/convbin.c b/app/consapp/convbin/convbin.c index 44aa24234..f1c0479bb 100644 --- a/app/consapp/convbin/convbin.c +++ b/app/consapp/convbin/convbin.c @@ -86,6 +86,7 @@ static const char *help[]={ " 0x01-01,0x01-02,0x01-03,0x01-04,0x01-06,0x7f-05", " Trimble : RT17", " Septentrio : SBF", +" Advanded Navigation : ANPP", " RINEX : OBS, NAV, GNAV, HNAV, LNAV, QNAV", "", " Options [default]", @@ -111,6 +112,7 @@ static const char *help[]={ " rt17 = Trimble RT17", " sbf = Septentrio SBF", " unicore = Unicore binary data output", +" anpp = Advanced Navigation Packet Protocol", " rinex= RINEX", " -ro opt receiver options", " -f freq number of frequencies [all]", @@ -170,6 +172,7 @@ static const char *help[]={ " *.rt17 Trimble RT17", " *.sbf Septentrio SBF", " *.unc Unicore binary data output", +" *.anpp Advanced Navigation Packet Protocol", " *.obs,*.*o RINEX OBS", " *.rnx RINEX OBS", " *.nav,*.*n RINEX NAV", @@ -403,7 +406,11 @@ static int get_filetime(const char *file, gtime_t *time) struct stat st; if (!stat(path, &st)) { struct tm tm; +#ifdef _MSC_VER + if (gmtime_s(&tm, &st.st_mtime) != 0) { +#else if (gmtime_r(&st.st_mtime, &tm)) { +#endif double ep[6]; ep[0] = tm.tm_year + 1900; ep[1] = tm.tm_mon + 1; @@ -633,6 +640,7 @@ static int cmdopts(int argc, char **argv, rnxopt_t *opt, char **ifile, #ifdef RTK_DISABLED else if (!strcmp(fmt,"tersus")) format=STRFMT_TERSUS; #endif + else if (!strcmp(fmt,"anpp" )) format=STRFMT_ANPP; else if (!strcmp(fmt,"rinex")) format=STRFMT_RINEX; } else { @@ -657,6 +665,7 @@ static int cmdopts(int argc, char **argv, rnxopt_t *opt, char **ifile, #ifdef RTK_DISABLED else if (!strcmp(p,".trs" )) format=STRFMT_TERSUS; #endif + else if (!strcmp(p,".anpp" )) format=STRFMT_ANPP; else if (!strcmp(p,".obs" )) format=STRFMT_RINEX; else if (!strcmp(p+3,"o" )) format=STRFMT_RINEX; else if (!strcmp(p+3,"O" )) format=STRFMT_RINEX; diff --git a/app/consapp/convbin/gcc/makefile b/app/consapp/convbin/gcc/makefile index b6399ceac..9e0deba38 100644 --- a/app/consapp/convbin/gcc/makefile +++ b/app/consapp/convbin/gcc/makefile @@ -17,7 +17,7 @@ all : convbin convbin : convbin.o rtkcmn.o trace.o rinex.o sbas.o preceph.o rcvraw.o convrnx.o convbin : rtcm.o rtcm2.o rtcm3.o rtcm3e.o pntpos.o ephemeris.o ionex.o convbin : novatel.o ublox.o crescent.o skytraq.o javad.o nvs.o -convbin : binex.o rt17.o septentrio.o swiftnav.o unicore.o +convbin : binex.o rt17.o septentrio.o swiftnav.o unicore.o adnav.o convbin : sofa.o convbin.o : ../convbin.c @@ -72,6 +72,8 @@ swiftnav.o: $(SRC)/rcv/swiftnav.c $(CC) -c $(CFLAGS) $(SRC)/rcv/swiftnav.c unicore.o: $(SRC)/rcv/unicore.c $(CC) -c $(CFLAGS) $(SRC)/rcv/unicore.c +adnav.o : $(SRC)/rcv/adnav.c + $(CC) -c $(CFLAGS) $(SRC)/rcv/adnav.c sofa.o : $(SRC)/sofa.c $(CC) -c $(CFLAGS) $(SRC)/sofa.c @@ -101,6 +103,7 @@ rt17.o : $(SRC)/rtklib.h septentrio.o: $(SRC)/rtklib.h swiftnav.o : $(SRC)/rtklib.h unciore.o : $(SRC)/rtklib.h +adnav.o : $(SRC)/rtklib.h DATDIR = ../../../test/data/rcvraw diff --git a/app/consapp/convbin/msc/msc.vcxproj b/app/consapp/convbin/msc/msc.vcxproj index 7186a99e8..ad262aa1e 100644 --- a/app/consapp/convbin/msc/msc.vcxproj +++ b/app/consapp/convbin/msc/msc.vcxproj @@ -198,6 +198,7 @@ + diff --git a/app/consapp/rtkrcv/gcc/makefile b/app/consapp/rtkrcv/gcc/makefile index fdde9a9c7..5d7e44e0d 100644 --- a/app/consapp/rtkrcv/gcc/makefile +++ b/app/consapp/rtkrcv/gcc/makefile @@ -15,7 +15,7 @@ rtkrcv : rtkrcv.o vt.o rtkcmn.o trace.o rtksvr.o rtkpos.o geoid.o solution.o rtkrcv : sbas.o stream.o rcvraw.o rtcm.o preceph.o options.o pntpos.o ppp.o ppp_ar.o rtkrcv : novatel.o ublox.o crescent.o skytraq.o javad.o nvs.o binex.o rtkrcv : rt17.o ephemeris.o rinex.o ionex.o rtcm2.o rtcm3.o rtcm3e.o -rtkrcv : tides.o septentrio.o swiftnav.o unicore.o +rtkrcv : tides.o septentrio.o swiftnav.o unicore.o adnav.o rtkrcv : sofa.o @@ -91,6 +91,8 @@ septentrio.o: $(SRC)/rcv/septentrio.c $(CC) -c $(CFLAGS) $(SRC)/rcv/septentrio.c unicore.o: $(SRC)/rcv/unicore.c $(CC) -c $(CFLAGS) $(SRC)/rcv/unicore.c +adnav.o: $(SRC)/rcv/adnav.c + $(CC) -c $(CFLAGS) $(SRC)/rcv/adnav.c sofa.o : $(SRC)/sofa.c $(CC) -c $(CFLAGS) $(SRC)/sofa.c @@ -126,6 +128,7 @@ binex.o : $(SRC)/rtklib.h rt17.o : $(SRC)/rtklib.h septentrio.o: $(SRC)/rtklib.h unciore.o : $(SRC)/rtklib.h +adnav.o : $(SRC)/rtklib.h ephemeris.o: $(SRC)/rtklib.h rinex.o : $(SRC)/rtklib.h ionex.o : $(SRC)/rtklib.h diff --git a/app/consapp/rtkrcv/rtkrcv.c b/app/consapp/rtkrcv/rtkrcv.c index f0eba0b1c..5dd5dbbb0 100644 --- a/app/consapp/rtkrcv/rtkrcv.c +++ b/app/consapp/rtkrcv/rtkrcv.c @@ -185,7 +185,7 @@ static const char *pathopts[]={ /* path options help */ #define FLGOPT "0:off,1:std+2:age/ratio/ns" #define ISTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http" #define OSTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,5:ntripsvr,9:ntripcas,11:udpcli" -#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:rinex,16:sp3,17:clk" +#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:anpp,16:rinex,17:sp3,18:clk" #define NMEOPT "0:off,1:latlon,2:single" #define SOLOPT "0:llh,1:xyz,2:enu,3:nmea,4:stat" #define MSGOPT "0:all,1:rover,2:base,3:corr" @@ -1029,7 +1029,7 @@ static void prstream(vt_t *vt) "http","ntripcas","udpsvr","udpcli","membuf" }; const char *fmt[]={"rtcm2","rtcm3","oem4","","ubx","swift","hemis","skytreq", - "javad","nvs","binex","rt17","sbf","","unicore","sp3",""}; + "javad","nvs","binex","rt17","sbf","","unicore","anpp","sp3",""}; const char *sol[]={"llh","xyz","enu","nmea","stat","-"}; stream_t stream[9]; int i,format[9]={0}; diff --git a/app/consapp/str2str/gcc/makefile b/app/consapp/str2str/gcc/makefile index 0c6bd9c24..f0f33018b 100644 --- a/app/consapp/str2str/gcc/makefile +++ b/app/consapp/str2str/gcc/makefile @@ -15,7 +15,7 @@ all : str2str str2str : str2str.o stream.o rtkcmn.o trace.o solution.o sbas.o geoid.o str2str : rcvraw.o novatel.o ublox.o crescent.o skytraq.o javad.o str2str : nvs.o binex.o rt17.o rtcm.o rtcm2.o rtcm3.o rtcm3e.o preceph.o streamsvr.o -str2str : septentrio.o swiftnav.o unicore.o +str2str : septentrio.o swiftnav.o unicore.o adnav.o str2str : sofa.o str2str.o : ../str2str.c @@ -68,6 +68,8 @@ swiftnav.o: $(SRC)/rcv/swiftnav.c $(CC) -c $(CFLAGS) $(SRC)/rcv/swiftnav.c unicore.o: $(SRC)/rcv/unicore.c $(CC) -c $(CFLAGS) $(SRC)/rcv/unicore.c +adnav.o: $(SRC)/rcv/adnav.c + $(CC) -c $(CFLAGS) $(SRC)/rcv/adnav.c sofa.o: $(SRC)/sofa.c $(CC) -c $(CFLAGS) $(SRC)/sofa.c @@ -96,6 +98,7 @@ preceph.o : $(SRC)/rtklib.h septentrio.o: $(SRC)/rtklib.h swiftnav.o : $(SRC)/rtklib.h unicore.o : $(SRC)/rtklib.h +adnav.o : $(SRC)/rtklib.h install: cp str2str $(BINDIR) diff --git a/app/consapp/str2str/str2str.c b/app/consapp/str2str/str2str.c index 7c1708a44..fff2e2b94 100644 --- a/app/consapp/str2str/str2str.c +++ b/app/consapp/str2str/str2str.c @@ -91,6 +91,7 @@ static const char *help[]={ " rt17 : Trimble RT17 (only in)", " sbf : Septentrio SBF (only in)", " unicore : Unicore (only in)", +" anpp : Advanced Navigation Packet Protocol (only in)", "", " -msg \"type[(tint)][,type[(tint)]...]\"", " rtcm message types and output intervals (s)", @@ -168,6 +169,7 @@ static void decodefmt(char *path, int *fmt) else if (!strcmp(p,"#rt17" )) *fmt=STRFMT_RT17; else if (!strcmp(p,"#sbf" )) *fmt=STRFMT_SEPT; else if (!strcmp(p,"#unicore" )) *fmt=STRFMT_UNICORE; + else if (!strcmp(p,"#anpp" )) *fmt=STRFMT_ANPP; else return; *p='\0'; } diff --git a/app/qtapp/rtkconv_qt/convmain.cpp b/app/qtapp/rtkconv_qt/convmain.cpp index 183cc6d93..63415ea82 100644 --- a/app/qtapp/rtkconv_qt/convmain.cpp +++ b/app/qtapp/rtkconv_qt/convmain.cpp @@ -449,7 +449,7 @@ void MainWindow::selectInputFile() { QString filename = QFileDialog::getOpenFileName(this, tr("Input RTCM, RCV RAW or RINEX File"), ui->cBInputFile->currentText(), tr("All (*.*);;RTCM 2 (*.rtcm2);;RTCM 3 (*.rtcm3);;NovtAtel (*.gps);;ublox (*.ubx);;" - "Hemisphere (*.bin);;Javad (*.jps);;RINEX OBS (*.obs *.*O);;Septentrio (*.sbf)")); + "Hemisphere (*.bin);;Javad (*.jps);;RINEX OBS (*.obs *.*O);;Septentrio (*.sbf);;ANPP (*.anpp)")); if (!filename.isEmpty()) { ui->cBInputFile->setCurrentText(QDir::toNativeSeparators(filename)); @@ -798,6 +798,8 @@ void MainWindow::convertFile() conversionThread->format = STRFMT_SEPT; } else if (fi.completeSuffix() == "unc") { conversionThread->format = STRFMT_UNICORE; + } else if (fi.completeSuffix() == "anpp") { + conversionThread->format = STRFMT_ANPP; } else if (fi.completeSuffix().toLower() == "obs") { conversionThread->format = STRFMT_RINEX; } else if (fi.completeSuffix().toLower().contains("nav")) { diff --git a/app/qtapp/rtknavi_qt/navimain.cpp b/app/qtapp/rtknavi_qt/navimain.cpp index 1f3f4db6b..31a7e7be2 100644 --- a/app/qtapp/rtknavi_qt/navimain.cpp +++ b/app/qtapp/rtknavi_qt/navimain.cpp @@ -94,7 +94,7 @@ static int strfmt[] = { /* stream formats */ #define FLGOPT "0:off,1:std+2:age/ratio/ns" #define ISTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http" #define OSTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,5:ntripsvr,9:ntripcas" -#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:rinex,16:sp3,17:clk" +#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:anpp,16:rinex,17:sp3,18:clk" #define NMEOPT "0:off,1:latlon,2:single" #define SOLOPT "0:llh,1:xyz,2:enu,3:nmea,4:stat" diff --git a/app/winapp/rtkconv/convmain.cpp b/app/winapp/rtkconv/convmain.cpp index df004f4fa..fcdf4bc70 100644 --- a/app/winapp/rtkconv/convmain.cpp +++ b/app/winapp/rtkconv/convmain.cpp @@ -896,6 +896,7 @@ void __fastcall TMainWindow::ConvertFile(void) else if (!strcmp(p,".trs" )) format=STRFMT_TERSUS; else if (!strcmp(p,".cnb" )) format=STRFMT_CNAV; #endif + else if (!strcmp(p,".anpp" )) format=STRFMT_ANPP; else if (!strcmp(p,".obs" )) format=STRFMT_RINEX; else if (!strcmp(p,".OBS" )) format=STRFMT_RINEX; else if (!strcmp(p,".nav" )) format=STRFMT_RINEX; diff --git a/app/winapp/rtkconv/convmain.dfm b/app/winapp/rtkconv/convmain.dfm index 2fd620a70..a781b0601 100644 --- a/app/winapp/rtkconv/convmain.dfm +++ b/app/winapp/rtkconv/convmain.dfm @@ -1151,7 +1151,7 @@ object MainWindow: TMainWindow 'All (*.*)|*.*|RTCM 2 (*.rtcm2)|*.rtcm2|RTCM 3 (*.rtcm3)|*.rtcm3|' + 'NovtAtel (*.gps)|*.gps|ublox (*.ubx)|*.ubx' + '|Hemisphere (*.bin)|*.bin|Javad (*.jps)|*.jps|' + - 'Septentrio (*.sbf)|*.sbf|' + + 'Septentrio (*.sbf)|*.sbf|ANPP (*.anpp)|*.anpp|' + 'RINEX OBS (*.obs,*.*O)|*.obs;*.*O' Options = [ofHideReadOnly, ofNoChangeDir, ofEnableSizing] Left = 260 diff --git a/app/winapp/rtkconv/rtkconv.cbproj b/app/winapp/rtkconv/rtkconv.cbproj index dfd5d201c..58355a0aa 100644 --- a/app/winapp/rtkconv/rtkconv.cbproj +++ b/app/winapp/rtkconv/rtkconv.cbproj @@ -338,6 +338,9 @@ 39 + + 42 + 31 diff --git a/app/winapp/rtknavi/naviopt.cpp b/app/winapp/rtknavi/naviopt.cpp index c974459d9..a291b92b4 100644 --- a/app/winapp/rtknavi/naviopt.cpp +++ b/app/winapp/rtknavi/naviopt.cpp @@ -47,7 +47,7 @@ static char proxyaddr[MAXSTR]=""; /* proxy address */ #define FLGOPT "0:off,1:std+2:age/ratio/ns" #define ISTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http" #define OSTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,5:ntripsvr,9:ntripcas" -#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:rinex,16:sp3,17:clk" +#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:anpp,16:rinex,17:sp3,18:clk" #define NMEOPT "0:off,1:latlon,2:single" #define SOLOPT "0:llh,1:xyz,2:enu,3:nmea,4:stat" #define MSGOPT "0:all,1:rover,2:base,3:corr" diff --git a/app/winapp/rtknavi/rtknavi.cbproj b/app/winapp/rtknavi/rtknavi.cbproj index 62857f6a5..4095e151c 100644 --- a/app/winapp/rtknavi/rtknavi.cbproj +++ b/app/winapp/rtknavi/rtknavi.cbproj @@ -445,6 +445,9 @@ 60 + + 64 + 47 16 diff --git a/app/winapp/rtkplot/rtkplot.cbproj b/app/winapp/rtkplot/rtkplot.cbproj index d00b039b8..27d1df2d6 100644 --- a/app/winapp/rtkplot/rtkplot.cbproj +++ b/app/winapp/rtkplot/rtkplot.cbproj @@ -457,6 +457,9 @@ 60 + + 64 + 52 diff --git a/app/winapp/srctblbrows/srctblbrows.cbproj b/app/winapp/srctblbrows/srctblbrows.cbproj index 9e57cee70..4de264c03 100644 --- a/app/winapp/srctblbrows/srctblbrows.cbproj +++ b/app/winapp/srctblbrows/srctblbrows.cbproj @@ -290,6 +290,9 @@ 23 + + 27 + 23 diff --git a/app/winapp/strsvr/strsvr.cbproj b/app/winapp/strsvr/strsvr.cbproj index 26f509edc..000fb6747 100644 --- a/app/winapp/strsvr/strsvr.cbproj +++ b/app/winapp/strsvr/strsvr.cbproj @@ -365,6 +365,9 @@ 41 + + 43 + 31 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1801464de..59251ef76 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,7 @@ endif() aux_source_directory(. DIR_SRCS_RTKLIB) set(DIR_SRCS_RTKLIB_RCV ${DIR_SRCS_RTKLIB_RCV} + rcv/adnav.c rcv/binex.c rcv/crescent.c rcv/javad.c diff --git a/src/convrnx.c b/src/convrnx.c index 696666e69..31f92d58a 100644 --- a/src/convrnx.c +++ b/src/convrnx.c @@ -340,15 +340,9 @@ static int open_strfile(strfile_t *str, const char *file) static void close_strfile(strfile_t *str) { trace(3,"close_strfile:\n"); - - if (str->format==STRFMT_RTCM2||str->format==STRFMT_RTCM3) { - if (str->fp) fclose(str->fp); - } - else if (str->format<=MAXRCVFMT) { - if (str->fp) fclose(str->fp); - } - else if (str->format==STRFMT_RINEX) { - if (str->fp) fclose(str->fp); + if (str->fp) { + fclose(str->fp); + str->fp = NULL; } } /* set format and files in RINEX options comments ----------------------------*/ diff --git a/src/rcv/adnav.c b/src/rcv/adnav.c new file mode 100644 index 000000000..9d7fa190f --- /dev/null +++ b/src/rcv/adnav.c @@ -0,0 +1,613 @@ +/*------------------------------------------------------------------------------ + * adnav.c : Advanced Navigation Packet Protocol (ANPP) decoder + * + * Copyright (C) 2026 by Joseph Fox-Rabinovitz, All rights reserved. + * + * reference : + * [1] Advanced Navigation, Advanced Navigation Packet Protocol Reference, + * https://docs.advancednavigation.com/boreas-d/ANPP/Advanced%20Navigation%20Packet.htm + * + * history : 2026/05/05 1.0 new + *-----------------------------------------------------------------------------*/ +#include + +#include "rtklib.h" + +/* ANPP packet IDs */ +#define ID_SYSTEMSTATE 20 /* system state */ +#define ID_UNIXTIME 21 /* unix time */ +#define ID_RAWSATDATA 60 /* raw satellite data */ +#define ID_RAWSATEPH 61 /* raw satellite ephemeris */ + +/* ANPP satellite system IDs (packets 60/61 sys field) */ +#define ANPP_SYS_UNK 0 // Unknown +#define ANPP_SYS_GPS 1 // GPS +#define ANPP_SYS_GLO 2 // GLONASS +#define ANPP_SYS_BDS 3 // BeiDou +#define ANPP_SYS_GAL 4 // Galileo +#define ANPP_SYS_SBS 5 // SBAS +#define ANPP_SYS_QZS 6 // QZSS +// 7 // Reserved +#define ANPP_SYS_OMN 8 // OmniStar +// 9 // Reserved +#define ANPP_SYS_NAV 10 // NavIC + +/* header size for all packets */ +#define HDR_LEN 5 + +/* packet 20 payload length */ +#define SYSSTATE_LEN 100 /* system state */ + +/* packet 21 payload length */ +#define UNIXTIME_LEN 8 /* unix time */ + +/* packet 60 sub-record sizes */ +#define OBS_HDR_LEN 16 /* per-epoch header (time + counters) */ +#define SAT_HDR_LEN 6 /* per-satellite header */ +#define FREQ_BLK_LEN 26 /* per-frequency block size */ + +/* tracking status bits (packet 60, per-frequency block, byte 1) */ +#define TRKS_CARRIER 0x01 /* carrier phase valid */ +#define TRKS_SLIP 0x02 /* cycle slip detected */ +#define TRKS_HALFCYCLE 0x04 /* half-cycle ambiguity unresolved */ +#define TRKS_PSEUDORANGE 0x08 /* pseudorange valid */ +#define TRKS_DOPPLER 0x10 /* Doppler valid */ +#define TRKS_SNR 0x20 /* SNR valid */ + +/* packet 61 payload lengths */ +#define EPH_LEN_GPS 132 /* GPS ephemeris */ +#define EPH_LEN_GLO 94 /* GLONASS ephemeris */ + +/* get fields (little-endian) ------------------------------------------------*/ +static uint8_t U1(const raw_t* raw, size_t index) { + RTKBOUNDSCHECK(raw->buff, sizeof(raw->buff), index); + RTKBOUNDSCHECK(raw->buff, raw->len, index); + return raw->buff[index]; +} +static int8_t I1(const raw_t* raw, size_t index) { + RTKBOUNDSCHECK(raw->buff, sizeof(raw->buff), index); + RTKBOUNDSCHECK(raw->buff, raw->len, index); + return (int8_t)raw->buff[index]; +} +static uint16_t U2(const raw_t* raw, size_t index) { + RTKBOUNDSCHECK(raw->buff, sizeof(raw->buff), index + 1); + RTKBOUNDSCHECK(raw->buff, raw->len, index + 1); + uint16_t u; + memcpy(&u, raw->buff + index, 2); + return u; +} +static uint32_t U4(const raw_t* raw, size_t index) { + RTKBOUNDSCHECK(raw->buff, sizeof(raw->buff), index + 3); + RTKBOUNDSCHECK(raw->buff, raw->len, index + 3); + uint32_t u; + memcpy(&u, raw->buff + index, 4); + return u; +} +static float R4(const raw_t* raw, size_t index) { + RTKBOUNDSCHECK(raw->buff, sizeof(raw->buff), index + 3); + RTKBOUNDSCHECK(raw->buff, raw->len, index + 3); + float r; + memcpy(&r, raw->buff + index, 4); + return r; +} +static double R8(const raw_t* raw, size_t index) { + RTKBOUNDSCHECK(raw->buff, sizeof(raw->buff), index + 7); + RTKBOUNDSCHECK(raw->buff, raw->len, index + 7); + double r; + memcpy(&r, raw->buff + index, 8); + return r; +} + +/* receiver state ------------------------------------------------------------*/ +typedef struct { + gtime_t time; /* last cached epoch time (UTC) */ + uint32_t cur_unix_time; /* unix_time of packet-60 epoch being assembled */ + uint32_t cur_nanoseconds; /* nanoseconds of packet-60 epoch being assembled */ + int epoch_active; /* 1 if obuf currently holds a partial epoch */ +} anpp_t; + +/* init/free -----------------------------------------------------------------*/ +extern int init_anpp(raw_t* raw) { + if (raw->format != STRFMT_ANPP) return 0; + anpp_t* anpp = calloc(1, sizeof(anpp_t)); + if (!anpp) { + trace(0, "init_anpp: memory allocation error\n"); + return 0; + } + raw->rcv_data = (void*)anpp; + return 1; +} + +extern void free_anpp(raw_t* raw) { + if (raw->format != STRFMT_ANPP) return; + if (raw->rcv_data) { + free(raw->rcv_data); + raw->rcv_data = NULL; + } +} + +/* initialize one obs buffer slot --------------------------------------------*/ +static void init_obsd_anpp(gtime_t time, int sat, obsd_t* data) { + data->time = time; + data->sat = (uint8_t)sat; + + for (int i = 0; i < NFREQ + NEXOBS; i++) { + data->L[i] = data->P[i] = 0.0; + data->D[i] = data->SNR[i] = 0.0; + data->Lstd[i] = data->Pstd[i] = 0.0; + data->LLI[i] = 0; + data->code[i] = CODE_NONE; + } +} + +/* flush observation data buffer ---------------------------------------------*/ +static int flush_obuf_anpp(raw_t* raw) { + trace(3, "flush_obuf_anpp: n=%d\n", raw->obuf.n); + + int n = 0; + for (int i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + if (!satsys(raw->obuf.data[i].sat, NULL)) continue; + if (raw->obuf.data[i].time.time == 0) continue; + raw->obs.data[n++] = raw->obuf.data[i]; + } + raw->obs.n = n; + + for (int i = 0; i < MAXOBS; i++) { + raw->obuf.data[i].time.time = 0; + raw->obuf.data[i].time.sec = 0.0; + for (int j = 0; j < NFREQ + NEXOBS; j++) { + raw->obuf.data[i].L[j] = raw->obuf.data[i].P[j] = 0.0; + raw->obuf.data[i].D[j] = raw->obuf.data[i].SNR[j] = 0.0; + raw->obuf.data[i].Lstd[j] = raw->obuf.data[i].Pstd[j] = 0.0; + raw->obuf.data[i].LLI[j] = 0; + raw->obuf.data[i].code[j] = CODE_NONE; + } + } + return n > 0 ? 1 : 0; +} + +/* map ANPP satellite system code to rtklib SYS_* ---------------------------*/ +static int anpp2sys(uint8_t anpp_sys) { + switch (anpp_sys) { + case ANPP_SYS_UNK: + return SYS_NONE; + case ANPP_SYS_GPS: + return SYS_GPS; + case ANPP_SYS_GLO: + return SYS_GLO; + case ANPP_SYS_BDS: + return SYS_CMP; + case ANPP_SYS_GAL: + return SYS_GAL; + case ANPP_SYS_SBS: + return SYS_SBS; + case ANPP_SYS_QZS: + return SYS_QZS; + case ANPP_SYS_OMN: + return SYS_SBS; + case ANPP_SYS_NAV: + return SYS_IRN; + } + return SYS_NONE; +} + +/* map ANPP (sys, freq_code) to rtklib observation code ---------------------*/ +static uint8_t anpp2code(uint8_t anpp_sys, uint8_t freq_code) { + switch (anpp_sys) { + case ANPP_SYS_GPS: + switch (freq_code) { + case 1: + return CODE_L1C; /* L1 C/A */ + case 2: + return CODE_L1L; /* L1 C */ + case 3: + return CODE_L1W; /* L1 P */ + case 4: + return CODE_L1M; /* L1 M */ + case 5: + return CODE_L2C; /* L2 C */ + case 6: + return CODE_L2W; /* L2 P */ + case 7: + return CODE_L2M; /* L2 M */ + case 8: + return CODE_L5Q; /* L5 */ + } + break; + case ANPP_SYS_GLO: + switch (freq_code) { + case 1: + return CODE_L1C; /* G1 C/A */ + case 3: + return CODE_L1P; /* G1 P */ + case 5: + return CODE_L2C; /* G2 C/A */ + case 6: + return CODE_L2P; /* G2 P */ + case 8: + return CODE_L3Q; /* G3 */ + } + break; + case ANPP_SYS_GAL: + switch (freq_code) { + case 1: + return CODE_L1C; /* E1 OS ?? */ + case 2: + return CODE_L1A; /* E1 PRS */ + case 5: + return CODE_L6B; /* E6 CS ?? */ + case 6: + return CODE_L6A; /* E6 PRS ?? */ + case 8: + return CODE_L5Q; /* E5 a */ + case 9: + return CODE_L7Q; /* E5 b */ + case 10: + return CODE_L8Q; /* E5 a+b */ + } + break; + case ANPP_SYS_BDS: + switch (freq_code) { + case 1: + return CODE_L2I; /* B1 */ + case 5: + return CODE_L7I; /* B2 */ + case 8: + return CODE_L6I; /* B3 */ + } + break; + case ANPP_SYS_SBS: + switch (freq_code) { + case 1: + return CODE_L1C; /* L1 C/A */ + case 8: + return CODE_L5Q; /* L5 */ + } + break; + case ANPP_SYS_QZS: + switch (freq_code) { + case 1: + return CODE_L1C; /* L1 C/A */ + case 2: + return CODE_L1L; /* L1 C */ + case 3: + return CODE_L1Z; /* L1 SAIF */ + case 5: + return CODE_L2L; /* L2 C */ + case 6: + return CODE_L6L; /* LEX */ + case 8: + return CODE_L5Q; /* L5 ?? */ + } + break; + case ANPP_SYS_OMN: + switch (freq_code) { + case 0: + return CODE_L1C; /* L1 C/A */ + } + break; + case ANPP_SYS_NAV: + switch (freq_code) { + case 8: + return CODE_L5A; /* L5 ?? */ + } + break; + } + return CODE_NONE; +} + +/* find or allocate-and-init obs buffer slot for satellite -------------------*/ +static int obuf_slot(raw_t* raw, gtime_t time, int sat) { + for (int i = 0; i < raw->obuf.n; i++) { + if (raw->obuf.data[i].sat == sat) return i; + } + if (raw->obuf.n >= MAXOBS) { + trace(2, "obuf_slot: buffer full sat=%d\n", sat); + return -1; + } + + int n = raw->obuf.n++; + init_obsd_anpp(time, sat, &raw->obuf.data[n]); + return n; +} + +/* packet 20/21: cache epoch time --------------------------------------------*/ +static int decode_systemstate(raw_t* raw) { + if (raw->len < HDR_LEN + SYSSTATE_LEN) { + trace(2, "decode_systemstate: short packet len=%d\n", raw->len); + return 0; + } + anpp_t* anpp = raw->rcv_data; + anpp->time.time = (time_t)U4(raw, HDR_LEN + 4); + anpp->time.sec = U4(raw, HDR_LEN + 8) * 1e-6; + return 0; +} + +static int decode_unixtime(raw_t* raw) { + if (raw->len < HDR_LEN + UNIXTIME_LEN) { + trace(2, "decode_unixtime: short packet len=%d\n", raw->len); + return 0; + } + anpp_t* anpp = (anpp_t*)raw->rcv_data; + anpp->time.time = (time_t)U4(raw, HDR_LEN); + anpp->time.sec = U4(raw, HDR_LEN + 4) * 1e-6; + return 0; +} + +/* packet 60: raw satellite data (observations) ------------------------------*/ +static int decode_rawsatdata(raw_t* raw) { + if (raw->len < HDR_LEN + OBS_HDR_LEN) { + trace(2, "decode_rawsatdata: short packet len=%d\n", raw->len); + return 0; + } + + uint32_t unix_time = U4(raw, HDR_LEN); + uint32_t nanoseconds = U4(raw, HDR_LEN + 4); + uint8_t receiver_number = U1(raw, HDR_LEN + 12); + uint8_t packet_number = U1(raw, HDR_LEN + 13); + uint8_t total_packets = U1(raw, HDR_LEN + 14); + uint8_t nsats = U1(raw, HDR_LEN + 15); + + /* select which receiver_number to emit: parse -RCVR from raw->opt + (default 0) */ + const char* q; + int rcvr_sel = 0; + if ((q = strstr(raw->opt, "-RCVR")) != NULL) sscanf(q + 5, "%d", &rcvr_sel); + + /* skip fragments from antennae we are not interested in */ + if (receiver_number != (uint8_t)rcvr_sel) return 0; + + /* if a new epoch begins before the previous one finished, flush partial */ + int ret = 0; + anpp_t* anpp = (anpp_t*)raw->rcv_data; + if (anpp->epoch_active && + (unix_time != anpp->cur_unix_time || nanoseconds != anpp->cur_nanoseconds)) { + ret = flush_obuf_anpp(raw); + anpp->epoch_active = 0; + } + + /* start a fresh epoch if no assembly is in progress */ + if (!anpp->epoch_active) { + gtime_t time; + time.time = (time_t)unix_time; + time.sec = nanoseconds * 1e-9; + raw->time = utc2gpst(time); + raw->obuf.n = 0; + anpp->cur_unix_time = unix_time; + anpp->cur_nanoseconds = nanoseconds; + anpp->epoch_active = 1; + } + + size_t offset = HDR_LEN + OBS_HDR_LEN; + + for (int i = 0; i < nsats && offset + SAT_HDR_LEN <= (size_t)raw->len; i++) { + uint8_t sys_id = U1(raw, offset); + int sys = anpp2sys(sys_id); + int sat = satno(sys, U1(raw, offset + 1)); + uint8_t nfreqs = U1(raw, offset + 5); + offset += SAT_HDR_LEN; + + if (sat == 0) { + offset += nfreqs * FREQ_BLK_LEN; + continue; + } + int n = obuf_slot(raw, raw->time, sat); + if (n < 0) { + offset += nfreqs * FREQ_BLK_LEN; + continue; + } + + for (; nfreqs > 0 && offset + FREQ_BLK_LEN <= (size_t)raw->len; + nfreqs--, offset += FREQ_BLK_LEN) { + uint8_t freq_id = U1(raw, offset); + uint8_t trks = U1(raw, offset + 1); + uint8_t code = anpp2code(sys_id, freq_id); + if (code == CODE_NONE) continue; + int idx = code2idx(sys, code); + if (idx < 0 || idx >= NFREQ + NEXOBS) continue; + + if (trks & TRKS_CARRIER) { + raw->obuf.data[n].L[idx] = R8(raw, offset + 2); + raw->obuf.data[n].LLI[idx] = (trks & TRKS_SLIP) ? LLI_SLIP : 0; + raw->obuf.data[n].LLI[idx] |= (trks & TRKS_HALFCYCLE) ? LLI_HALFC : 0; + } + if (trks & TRKS_PSEUDORANGE) raw->obuf.data[n].P[idx] = R8(raw, offset + 10); + if (trks & TRKS_DOPPLER) raw->obuf.data[n].D[idx] = R4(raw, offset + 18); + if (trks & TRKS_SNR) raw->obuf.data[n].SNR[idx] = R4(raw, offset + 22); + + raw->obuf.data[n].code[idx] = code; + } + } + + /* flush when the final fragment of this epoch arrives */ + if (packet_number == total_packets) { + ret = flush_obuf_anpp(raw); + anpp->epoch_active = 0; + } + return ret; +} + +/* packet 61: raw satellite ephemeris ----------------------------------------*/ +static int decode_gps_eph(raw_t* raw, int sat, size_t e) { + eph_t eph = {0}; + eph.sat = sat; + eph.iodc = (int)U2(raw, e + 4); + eph.iode = (int)U2(raw, e + 6); + eph.week = (int)U2(raw, e + 116); + eph.toes = (double)U4(raw, e + 0); + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = eph.toe; + eph.ttr = gpst2time(eph.week, (double)U4(raw, e + 118)); + eph.f0 = (double)R4(raw, e + 8); + eph.f1 = (double)R4(raw, e + 12); + eph.f2 = (double)R4(raw, e + 16); + eph.crs = (double)R4(raw, e + 20); + eph.deln = (double)R4(raw, e + 24); + eph.M0 = R8(raw, e + 28); + eph.cuc = (double)R4(raw, e + 36); + eph.e = R8(raw, e + 40); + eph.cus = (double)R4(raw, e + 48); + double sqrtA = R8(raw, e + 52); + eph.A = sqrtA * sqrtA; + eph.cic = (double)R4(raw, e + 60); + eph.OMG0 = R8(raw, e + 64); + eph.cis = (double)R4(raw, e + 72); + eph.i0 = R8(raw, e + 76); + eph.crc = (double)R4(raw, e + 84); + eph.omg = R8(raw, e + 88); + eph.OMGd = R8(raw, e + 96); + eph.idot = R8(raw, e + 104); + eph.tgd[0] = (double)R4(raw, e + 112); + eph.sva = 0; + eph.svh = 0; + eph.code = 0; + eph.flag = 0; + eph.fit = 4.0; + + if (eph.iode == raw->nav.eph[sat - 1].iode && eph.iodc == raw->nav.eph[sat - 1].iodc && + fabs(timediff(eph.toe, raw->nav.eph[sat - 1].toe)) < 1e-9) + return 0; + + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; +} + +static int decode_glo_eph(raw_t* raw, int prn, size_t e) { + geph_t geph = {0}; + geph.sat = satno(SYS_GLO, prn); + geph.frq = (int)I1(raw, e + 85); + geph.svh = (int)U1(raw, e + 86); + geph.age = (int)U1(raw, e + 84); + geph.taun = (double)R4(raw, e + 0); + geph.gamn = (double)R4(raw, e + 4); + geph.pos[0] = R8(raw, e + 8); + geph.pos[1] = R8(raw, e + 16); + geph.pos[2] = R8(raw, e + 24); + geph.vel[0] = R8(raw, e + 32); + geph.vel[1] = R8(raw, e + 40); + geph.vel[2] = R8(raw, e + 48); + geph.acc[0] = R8(raw, e + 56); + geph.acc[1] = R8(raw, e + 64); + geph.acc[2] = R8(raw, e + 72); + gtime_t utc; + utc.time = (time_t)U4(raw, e + 80); + utc.sec = 0.0; + geph.toe = utc2gpst(utc); + geph.tof = geph.toe; + + if (geph.svh == raw->nav.geph[prn - 1].svh && + fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1e-9) + return 0; + + raw->nav.geph[prn - 1] = geph; + raw->ephsat = geph.sat; + raw->ephset = 0; + return 2; +} + +static int decode_rawsateph(raw_t* raw) { + uint8_t sys_id = U1(raw, HDR_LEN + 4); + int sys = anpp2sys(sys_id); + int prn = (int)U1(raw, HDR_LEN + 5); + int sat = satno(sys, prn); + if (sat == 0) return 0; + + switch (sys) { + case SYS_GPS: + if (raw->len < HDR_LEN + EPH_LEN_GPS) { + trace(2, "decode_rawsateph GPS: short packet len=%d\n", raw->len); + return 0; + } + return decode_gps_eph(raw, sat, HDR_LEN + 6); + case SYS_GLO: + if (raw->len < HDR_LEN + EPH_LEN_GLO) { + trace(2, "decode_rawsateph GLO: short packet len=%d\n", raw->len); + return 0; + } + return decode_glo_eph(raw, prn, HDR_LEN + 6); + default: + trace(2, "decode_rawsateph: unsupported sys=%d\n", sys_id); + return 0; + } +} + +/* sync, dispatch, public API ------------------------------------------------*/ +static uint16_t crc_ccitt(const uint8_t* buff, int len) { + uint16_t crc = 0xFFFF; + for (int i = 0; i < len; i++) { + crc ^= (uint16_t)buff[i] << 8; + for (int j = 0; j < 8; j++) { + crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : crc << 1; + } + } + return crc; +} + +static int valid_hdr(const raw_t* raw) { + return ((U1(raw, 0) + U1(raw, 1) + U1(raw, 2) + U1(raw, 3) + U1(raw, 4)) & 0xFF) == 0; +} + +static int decode_anpp(raw_t* raw) { + int id = (int)U1(raw, 1); + + trace(4, "decode_anpp: id=%d len=%d\n", id, raw->len); + + switch (id) { + case ID_SYSTEMSTATE: + return decode_systemstate(raw); + case ID_UNIXTIME: + return decode_unixtime(raw); + case ID_RAWSATDATA: + return decode_rawsatdata(raw); + case ID_RAWSATEPH: + return decode_rawsateph(raw); + } + return 0; +} + +extern int input_anpp(raw_t* raw, uint8_t data) { + RTKBOUNDSCHECK(raw->buff, sizeof(raw->buff), raw->nbyte); + raw->buff[raw->nbyte] = data; + raw->nbyte++; + + if (raw->nbyte < HDR_LEN) return 0; + + if (raw->nbyte == HDR_LEN) { + raw->len = HDR_LEN; + if (!valid_hdr(raw)) { + memmove(raw->buff, raw->buff + 1, HDR_LEN - 1); + raw->nbyte = raw->len = HDR_LEN - 1; + return 0; + } + raw->len = HDR_LEN + (int)U1(raw, 2); + if (raw->len > MAXRAWLEN) { + trace(2, "adnav length error: len=%d\n", raw->len); + raw->nbyte = raw->len = 0; + return -1; + } + } + + if (raw->nbyte < raw->len) return 0; + raw->nbyte = 0; + + if (crc_ccitt(raw->buff + HDR_LEN, raw->len - HDR_LEN) != U2(raw, 3)) { + trace(2, "input_anpp: CRC error id=%d\n", (int)raw->buff[1]); + raw->nbyte = raw->len = 0; + return -1; + } + return decode_anpp(raw); +} + +extern int input_anppf(raw_t* raw, FILE* fp) { + trace(4, "input_anppf:\n"); + + for (int i = 0; i < 4096; i++) { + int data = fgetc(fp); + if (data == EOF) return -2; + int ret = input_anpp(raw, (uint8_t)data); + if (ret != 0) return ret; + } + return 0; +} diff --git a/src/rcvraw.c b/src/rcvraw.c index 512040e3f..76e54f012 100644 --- a/src/rcvraw.c +++ b/src/rcvraw.c @@ -1382,6 +1382,7 @@ extern int init_raw(raw_t *raw, int format) /* initialize receiver dependent data */ raw->format=format; switch (format) { + case STRFMT_ANPP: ret=init_anpp(raw); break; case STRFMT_RT17: ret=init_rt17(raw); break; case STRFMT_SEPT: ret=init_sbf(raw); break; } @@ -1409,6 +1410,7 @@ extern void free_raw(raw_t *raw) /* free receiver dependent data */ switch (raw->format) { + case STRFMT_ANPP: free_anpp(raw); break; case STRFMT_RT17: free_rt17(raw); break; case STRFMT_SEPT: free_sbf(raw); break; } @@ -1441,6 +1443,7 @@ extern int input_raw(raw_t *raw, int format, uint8_t data) case STRFMT_SEPT : return input_sbf (raw,data); /*case STRFMT_TERSUS: return input_tersus(raw,data);*/ case STRFMT_UNICORE : return input_unicore (raw,data); + case STRFMT_ANPP : return input_anpp (raw,data); } return 0; } @@ -1467,8 +1470,9 @@ extern int input_rawf(raw_t *raw, int format, FILE *fp) case STRFMT_BINEX: return input_bnxf (raw,fp); case STRFMT_RT17 : return input_rt17f (raw,fp); case STRFMT_SEPT : return input_sbff (raw,fp); - /*case STRFMT_TERSUS: return input_tersusf(raw,fp); */ + /*case STRFMT_TERSUS: return input_tersusf (raw,fp); */ case STRFMT_UNICORE : return input_unicoref (raw,fp); + case STRFMT_ANPP : return input_anppf (raw,fp); } return -2; } diff --git a/src/rtkcmn.c b/src/rtkcmn.c index bb4ac760c..349d722bd 100644 --- a/src/rtkcmn.c +++ b/src/rtkcmn.c @@ -247,11 +247,12 @@ const char *formatstrs[32]={ /* stream format strings */ "Septentrio SBF", /* 12 */ "------", /* 13 Tersus currently not supported */ "Unicore", /* 14 */ - "RINEX", /* 15 */ - "SP3", /* 16 */ - "RINEX CLK", /* 17 */ - "SBAS", /* 18 */ - "NMEA 0183", /* 19 */ + "Adv. Nav. ANPP", /* 15 */ + "RINEX", /* 16 */ + "SP3", /* 17 */ + "RINEX CLK", /* 18 */ + "SBAS", /* 19 */ + "NMEA 0183", /* 20 */ NULL }; @@ -389,6 +390,24 @@ extern void add_fatal(fatalfunc_t *func) { fatalfunc=func; } +/* check indices within bounds ------------------------------------------------- +* Check that the index is within the buffer, generating a fatal error if not. +* See the macro RTKBOUNDSCHECK() +* args : const char *func I name of caller performing check +* int line I line number +* const void *buff I buffer to check against +* size_t size I size of the buffer in bytes +* size_t index I index to check; when checking against a byte +* size, this is the index of the last byte to +* be accessed +*-----------------------------------------------------------------------------*/ +extern void rtkboundscheck(const char *func, int line, const void *buff, size_t size, size_t index) { + if (index >= size) { + fatalerr("rtk out of bound in %s line %d for buffer %p of size %zu at index %zu\n", + func, line, buff, size, index); + } +} + /* satellite system+prn/slot number to satellite number ------------------------ * convert satellite system+prn/slot number to satellite number * args : int sys I satellite system (SYS_GPS,SYS_GLO,...) diff --git a/src/rtklib.h b/src/rtklib.h index 2d3093453..5f941d44d 100644 --- a/src/rtklib.h +++ b/src/rtklib.h @@ -328,7 +328,7 @@ extern "C" { #define CODE_L1B 11 /* obs code: E1B (GAL) */ #define CODE_L1X 12 /* obs code: E1B+C,L1C(D+P),B1D+P (GAL,QZS,BDS) */ #define CODE_L1Z 13 /* obs code: E1A+B+C,L1S (GAL,QZS) */ -#define CODE_L2C 14 /* obs code: L2C/A,G1C/A (GPS,GLO) */ +#define CODE_L2C 14 /* obs code: L2C/A,G2C/A (GPS,GLO) */ #define CODE_L2D 15 /* obs code: L2 L1C/A-(P2-P1) (GPS) */ #define CODE_L2S 16 /* obs code: L2C(M) (GPS,QZS) */ #define CODE_L2L 17 /* obs code: L2C(L) (GPS,QZS) */ @@ -498,13 +498,14 @@ extern "C" { #define STRFMT_SEPT 12 /* stream format: Septentrio */ /* Tersus currently not supported */ /* #define STRFMT_TERSUS 13 */ /* stream format: TERSUS */ -#define STRFMT_UNICORE 14 /* stream format: UNICORE */ -#define STRFMT_RINEX 15 /* stream format: RINEX */ -#define STRFMT_SP3 16 /* stream format: SP3 */ -#define STRFMT_RNXCLK 17 /* stream format: RINEX CLK */ -#define STRFMT_SBAS 18 /* stream format: SBAS messages */ -#define STRFMT_NMEA 19 /* stream format: NMEA 0183 */ -#define MAXRCVFMT 14 /* max number of receiver format */ +#define STRFMT_UNICORE 14 /* stream format: UNICORE */ +#define STRFMT_ANPP 15 /* stream format: Advanced Navigation ANPP */ +#define STRFMT_RINEX 16 /* stream format: RINEX */ +#define STRFMT_SP3 17 /* stream format: SP3 */ +#define STRFMT_RNXCLK 18 /* stream format: RINEX CLK */ +#define STRFMT_SBAS 19 /* stream format: SBAS messages */ +#define STRFMT_NMEA 20 /* stream format: NMEA 0183 */ +#define MAXRCVFMT STRFMT_ANPP /* number of raw receiver formats */ #define STR_MODE_R 0x1 /* stream mode: read */ #define STR_MODE_W 0x2 /* stream mode: write */ @@ -1564,6 +1565,10 @@ EXPORT void traceb_impl (int level, const uint8_t *p, int n); #endif /* TRACE */ +/* correctness utility function ----------------------------------------------*/ +#define RTKBOUNDSCHECK(buff, size, index) rtkboundscheck(__func__, __LINE__, buff, size, index); +EXPORT void rtkboundscheck(const char *func, int line, const void *buff, size_t size, size_t index); + /* platform dependent functions ----------------------------------------------*/ EXPORT int execcmd(const char *cmd); EXPORT int expath (const char *path, char *paths[], int nmax); @@ -1714,8 +1719,10 @@ EXPORT int input_rawf (raw_t *raw, int format, FILE *fp); EXPORT int init_rt17 (raw_t *raw); EXPORT int init_sbf (raw_t *raw); +EXPORT int init_anpp (raw_t *raw); EXPORT void free_rt17 (raw_t *raw); EXPORT void free_sbf (raw_t *raw); +EXPORT void free_anpp (raw_t *raw); EXPORT int input_oem4 (raw_t *raw, uint8_t data); EXPORT int input_cnav (raw_t *raw, uint8_t data); @@ -1730,6 +1737,7 @@ EXPORT int input_rt17 (raw_t *raw, uint8_t data); EXPORT int input_sbf (raw_t *raw, uint8_t data); EXPORT int input_tersus(raw_t *raw, uint8_t data); EXPORT int input_unicore(raw_t *raw, uint8_t data); +EXPORT int input_anpp (raw_t *raw, uint8_t data); EXPORT int input_oem4f (raw_t *raw, FILE *fp); EXPORT int input_cnavf (raw_t *raw, FILE *fp); EXPORT int input_ubxf (raw_t *raw, FILE *fp); @@ -1743,6 +1751,7 @@ EXPORT int input_rt17f (raw_t *raw, FILE *fp); EXPORT int input_sbff (raw_t *raw, FILE *fp); EXPORT int input_tersusf(raw_t *raw, FILE *fp); EXPORT int input_unicoref(raw_t *raw, FILE *fp); +EXPORT int input_anppf (raw_t *raw, FILE *fp); EXPORT int gen_ubx (const char *msg, uint8_t *buff); EXPORT int gen_stq (const char *msg, uint8_t *buff); diff --git a/src/src.pro b/src/src.pro index 720560808..f57d7fa3a 100644 --- a/src/src.pro +++ b/src/src.pro @@ -78,7 +78,8 @@ SOURCES += rtkcmn.c \ rcv/skytraq.c \ rcv/swiftnav.c \ rcv/ublox.c \ - rcv/unicore.c + rcv/unicore.c \ + rcv/adnav.c HEADERS += rtklib.h