@@ -104,6 +104,7 @@ typedef struct {
104104 int frnr ;
105105 char id [9 ];
106106 ui8_t numSV ;
107+ ui8_t isUTC ;
107108 int week ; int tow_ms ; int gpssec ;
108109 int jahr ; int monat ; int tag ;
109110 int wday ;
@@ -383,6 +384,12 @@ GPS chip: ublox UBX-G6010-ST
383384#define pck_SGM_xTU 0x7F1B // temperature/humidity
384385#define pck_SGM_CRYPT 0x80A7 // Packet type for an Encrypted payload
385386
387+ // fw 0x50dd
388+ #define pck_960A 0x960A //
389+ #define pck_8226_POSDATETIME 0x8226 // ECEF-POS/VEL , DATE/TIME
390+ #define pck_8329 0x8329 //
391+
392+
386393/*
387394 frame[pos_FRAME-1] == 0x0F: len == NDATA_LEN(320)
388395 frame[pos_FRAME-1] == 0xF0: len == FRAME_LEN(518)
@@ -470,6 +477,7 @@ static int get_SondeID(gpx_t *gpx, int crc, int ofs) {
470477 gpx -> lat = 0.0 ; gpx -> lon = 0.0 ; gpx -> alt = 0.0 ;
471478 gpx -> vH = 0.0 ; gpx -> vD = 0.0 ; gpx -> vV = 0.0 ;
472479 gpx -> numSV = 0 ;
480+ gpx -> isUTC = 0 ;
473481 gpx -> T = -273.15f ;
474482 gpx -> RH = -1.0f ;
475483 gpx -> P = -1.0f ;
@@ -942,6 +950,7 @@ static int get_GPStime(gpx_t *gpx, int ofs) {
942950 gpx -> std = gpstime / 3600 ;
943951 gpx -> min = (gpstime % 3600 ) / 60 ;
944952 gpx -> sek = gpstime % 60 + ms /1000.0 ;
953+ gpx -> isUTC = 0 ;
945954
946955 return 0 ;
947956}
@@ -956,6 +965,7 @@ static int get_GPS1(gpx_t *gpx, int ofs) {
956965 // reset GPS1-data (json)
957966 gpx -> jahr = 0 ; gpx -> monat = 0 ; gpx -> tag = 0 ;
958967 gpx -> std = 0 ; gpx -> min = 0 ; gpx -> sek = 0.0 ;
968+ gpx -> isUTC = 0 ;
959969 return -1 ;
960970 }
961971
@@ -1005,7 +1015,7 @@ static void ecef2elli(double X[], double *lat, double *lon, double *alt) {
10051015 * lon = lam * 180 /M_PI ;
10061016}
10071017
1008- static int get_GPSkoord (gpx_t * gpx , int ofs ) {
1018+ static int get_ECEFkoord (gpx_t * gpx , int pos_ecef ) {
10091019 int i , k ;
10101020 unsigned byte ;
10111021 ui8_t XYZ_bytes [4 ];
@@ -1021,14 +1031,14 @@ static int get_GPSkoord(gpx_t *gpx, int ofs) {
10211031 for (k = 0 ; k < 3 ; k ++ ) {
10221032
10231033 for (i = 0 ; i < 4 ; i ++ ) {
1024- byte = gpx -> frame [pos_GPSecefX + ofs + 4 * k + i ];
1034+ byte = gpx -> frame [pos_ecef + 4 * k + i ];
10251035 XYZ_bytes [i ] = byte ;
10261036 }
10271037 memcpy (& XYZ , XYZ_bytes , 4 );
10281038 X [k ] = XYZ / 100.0 ;
10291039
10301040 for (i = 0 ; i < 2 ; i ++ ) {
1031- byte = gpx -> frame [pos_GPSecefV + ofs + 2 * k + i ];
1041+ byte = gpx -> frame [pos_ecef + 12 + 2 * k + i ];
10321042 gpsVel_bytes [i ] = byte ;
10331043 }
10341044 vel16 = gpsVel_bytes [0 ] | gpsVel_bytes [1 ] << 8 ;
@@ -1068,8 +1078,6 @@ static int get_GPSkoord(gpx_t *gpx, int ofs) {
10681078
10691079 gpx -> vV = vU ;
10701080
1071- gpx -> numSV = gpx -> frame [pos_numSats + ofs ];
1072-
10731081 return 0 ;
10741082}
10751083
@@ -1086,12 +1094,72 @@ static int get_GPS3(gpx_t *gpx, int ofs) {
10861094 gpx -> numSV = 0 ;
10871095 return -1 ;
10881096 }
1097+ // pos_GPS3+2 = pos_GPSecefX
1098+ err |= get_ECEFkoord (gpx , pos_GPS3 + ofs + 2 ); // plausibility-check: altitude, if ecef=(0,0,0)
1099+
1100+ gpx -> numSV = gpx -> frame [pos_numSats + ofs ];
1101+
1102+ return err ;
1103+ }
1104+
1105+ static int get_posdatetime (gpx_t * gpx , int pos_posdatetime ) {
1106+ int err = 0 ;
1107+
1108+ err = check_CRC (gpx , pos_posdatetime , pck_8226_POSDATETIME );
1109+ if (err ) {
1110+ ///TODO: fw 0x50dd , ec < 0
1111+ gpx -> crc |= crc_GPS1 | crc_GPS3 ;
1112+ // reset GPS1-data (json)
1113+ gpx -> jahr = 0 ; gpx -> monat = 0 ; gpx -> tag = 0 ;
1114+ gpx -> std = 0 ; gpx -> min = 0 ; gpx -> sek = 0.0 ;
1115+ gpx -> isUTC = 0 ;
1116+ // reset GPS3-data (json)
1117+ gpx -> lat = 0.0 ; gpx -> lon = 0.0 ; gpx -> alt = 0.0 ;
1118+ gpx -> vH = 0.0 ; gpx -> vD = 0.0 ; gpx -> vV = 0.0 ;
1119+ // gpx->numSV = 0;
1120+ return -1 ;
1121+ }
1122+
1123+ // ublox M10 UBX-NAV-POSECEF (0x01 0x01) ?
1124+ err |= get_ECEFkoord (gpx , pos_posdatetime + 2 ); // plausibility-check: altitude, if ecef=(0,0,0)
1125+
1126+ // ublox M10 UBX-NAV-PVT (0x01 0x07) ? (UTC?)
1127+ // date
1128+ gpx -> jahr = gpx -> frame [pos_posdatetime + 20 ] | gpx -> frame [pos_posdatetime + 21 ]<<8 ;
1129+ gpx -> monat = gpx -> frame [pos_posdatetime + 22 ];
1130+ gpx -> tag = gpx -> frame [pos_posdatetime + 23 ];
1131+ // time
1132+ gpx -> std = gpx -> frame [pos_posdatetime + 24 ];
1133+ gpx -> min = gpx -> frame [pos_posdatetime + 25 ];
1134+ gpx -> sek = gpx -> frame [pos_posdatetime + 26 ];
1135+ gpx -> isUTC = 1 ;
10891136
1090- err |= get_GPSkoord (gpx , ofs ); // plausibility-check: altitude, if ecef=(0,0,0)
1137+ ///TODO: numSV/fixOK
1138+ //gpx->numSV = gpx->frame[pos_numSats+ofs];
10911139
10921140 return err ;
10931141}
10941142
1143+ static int get_newnumsv (gpx_t * gpx , int pos_posdatetime ) {
1144+ // Attempt at extracting the numSVs used for the new 0x83 block type (X-series RS41s)
1145+ // Counts bits from byte 18-21 of the data section of the 0x83 block, which *appears* to be
1146+ // a bitfield with each bit indicating which of the 32 rx channels are in use.
1147+ int err = 0 ;
1148+
1149+ err = check_CRC (gpx , pos_posdatetime , pck_8329 );
1150+ if (err ) {
1151+ gpx -> numSV = 0 ;
1152+ return -1 ;
1153+ }
1154+
1155+ int sats = 0 ;
1156+ for (int i = 0 ; i < 32 ; i ++ ) {
1157+ if ( gpx -> frame [pos_posdatetime + 20 + i /8 ] & (1 <<(i & 7 )) ) sats ++ ;
1158+ }
1159+ gpx -> numSV = sats ;
1160+
1161+ return err ;
1162+ }
10951163
10961164static int hex2uint (char * str , int nibs ) {
10971165 int i ;
@@ -1859,6 +1927,23 @@ static int prn_gpspos(gpx_t *gpx) {
18591927 return 0 ;
18601928}
18611929
1930+ static int prn_posdatetime (gpx_t * gpx ) {
1931+ //Gps2Date(gpx);
1932+ //fprintf(stdout, "%s ", weekday[gpx->wday]);
1933+ fprintf (stdout , "%04d-%02d-%02d %02d:%02d:%02d" ,
1934+ gpx -> jahr , gpx -> monat , gpx -> tag , gpx -> std , gpx -> min , (int )gpx -> sek );
1935+ //if (gpx->option.vbs == 3) fprintf(stdout, " (W %d)", gpx->week);
1936+ fprintf (stdout , " " );
1937+
1938+ fprintf (stdout , " " );
1939+ fprintf (stdout , " lat: %.5f " , gpx -> lat );
1940+ fprintf (stdout , " lon: %.5f " , gpx -> lon );
1941+ fprintf (stdout , " alt: %.2f " , gpx -> alt );
1942+ fprintf (stdout , " vH: %4.1f D: %5.1f vV: %3.1f " , gpx -> vH , gpx -> vD , gpx -> vV );
1943+ //if (gpx->option.vbs == 3) fprintf(stdout, " sats: %02d ", gpx->numSV);
1944+ return 0 ;
1945+ }
1946+
18621947static int prn_sat1 (gpx_t * gpx , int ofs ) {
18631948
18641949 fprintf (stdout , "\n" );
@@ -1935,7 +2020,8 @@ static int prn_sat3(gpx_t *gpx, int ofs) {
19352020
19362021static int print_position (gpx_t * gpx , int ec ) {
19372022 int i ;
1938- int err , err0 , err1 , err2 , err3 ;
2023+ int err = 1 ;
2024+ int err0 = 1 , err1 = 1 , err2 = 1 , err3 = 1 , err13 = 1 ;
19392025 //int output, out_mask;
19402026 int encrypted = 0 ;
19412027 int unexp = 0 ;
@@ -2044,6 +2130,21 @@ static int print_position(gpx_t *gpx, int ec) {
20442130 if (out ) fprintf (stdout , " [%04X] (RS41-SGM) " , pck_SGM_CRYPT );
20452131 break ;
20462132
2133+ case pck_960A : // 0x960A
2134+ // ? 64 bit data integrity and authenticity ?
2135+ break ;
2136+
2137+ case pck_8226_POSDATETIME : // 0x8226
2138+ err13 = get_posdatetime (gpx , pos );
2139+ if ( !err13 ) {
2140+ if (out ) prn_posdatetime (gpx );
2141+ }
2142+ break ;
2143+
2144+ case pck_8329 : // 0x8329
2145+ err13 = get_newnumsv (gpx , pos );
2146+ break ;
2147+
20472148 default :
20482149 if (blk == 0x7E ) {
20492150 if (pos_aux == 0 ) pos_aux = pos ; // pos == pos_AUX ?
@@ -2089,7 +2190,7 @@ static int print_position(gpx_t *gpx, int ec) {
20892190
20902191 if (gpx -> option .jsn ) {
20912192 // Print out telemetry data as JSON
2092- if (( !err && !err1 && !err3 ) || (! err && encrypted )) { // frame-nb/id && gps-time && gps-position (crc-)ok; 3 CRCs, RS not needed
2193+ if ( !err && (( !err1 && !err3 ) || ! err13 || encrypted ) ) { // frame-nb/id && gps-time && gps-position (crc-)ok; 3 CRCs, RS not needed
20932194 // eigentlich GPS, d.h. UTC = GPS - 18sec (ab 1.1.2017)
20942195 char * ver_jsn = NULL ;
20952196 fprintf (stdout , "{ \"type\": \"%s\"" , "RS41" );
@@ -2169,8 +2270,8 @@ static int print_position(gpx_t *gpx, int ec) {
21692270 fprintf (stdout , ", \"tx_frequency\": %d" , gpx -> freq );
21702271 }
21712272
2172- // Reference time/position
2173- fprintf (stdout , ", \"ref_datetime\": \"%s\"" , "GPS" ); // {"GPS", "UTC"} GPS-UTC=leap_sec
2273+ // Reference time/position (fw 0x50dd: datetime UTC ?)
2274+ fprintf (stdout , ", \"ref_datetime\": \"%s\"" , gpx -> isUTC ? "UTC" : "GPS" ); // {"GPS", "UTC"} GPS-UTC=leap_sec
21742275 fprintf (stdout , ", \"ref_position\": \"%s\"" , "GPS" ); // {"GPS", "MSL"} GPS=ellipsoid , MSL=geoid
21752276
21762277 #ifdef VER_JSN_STR
@@ -2204,6 +2305,7 @@ static int print_position(gpx_t *gpx, int ec) {
22042305
22052306 pck = (gpx -> frame [pos_PTU ]<<8 ) | gpx -> frame [pos_PTU + 1 ];
22062307 ofs = 0 ;
2308+ ///TODO: fw 0x50dd
22072309
22082310 if (pck < 0x8000 ) {
22092311 //err0 = get_PTU(gpx, 0, pck, 0);
0 commit comments