123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996 |
- #include "gpsd_config.h"
- #include <stdio.h>
- #include <string.h>
- #include "gpsd.h"
- #if HAVE_BUILTIN_ENDIANNESS
- #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
- #define WORDS_BIGENDIAN 1
- #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- #undef WORDS_BIGENDIAN
- #else
- #error Unknown endianness!
- #endif
- #else
- #if defined(HAVE_ENDIAN_H)
- #include <endian.h>
- #elif defined(HAVE_SYS_ENDIAN_H)
- #include <sys/endian.h>
- #elif defined(HAVE_MACHINE_ENDIAN_H)
- #include <machine/endian.h>
- #endif
- #if !defined( __BYTE_ORDER) && defined(__DARWIN_BYTE_ORDER)
- #define __BYTE_ORDER __DARWIN_BYTE_ORDER
- #endif
- #if !defined( __BIG_ENDIAN) && defined(__DARWIN_BIG_ENDIAN)
- #define __BIG_ENDIAN __DARWIN_BIG_ENDIAN
- #endif
- #if !defined( __LITTLE_ENDIAN) && defined(__DARWIN_LITTLE_ENDIAN)
- #define __LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
- #endif
- #if !defined( __BYTE_ORDER) && defined(_BYTE_ORDER)
- #define __BYTE_ORDER _BYTE_ORDER
- #endif
- #if !defined( __BIG_ENDIAN) && defined(_BIG_ENDIAN)
- #define __BIG_ENDIAN _BIG_ENDIAN
- #endif
- #if !defined( __LITTLE_ENDIAN) && defined(_LITTLE_ENDIAN)
- #define __LITTLE_ENDIAN _LITTLE_ENDIAN
- #endif
- #if !defined(__BYTE_ORDER) || !defined(__BIG_ENDIAN) || !defined(__LITTLE_ENDIAN)
- #error endianness macros are not defined
- #endif
- #if __BYTE_ORDER == __BIG_ENDIAN
- #define WORDS_BIGENDIAN 1
- #elif __BYTE_ORDER == __LITTLE_ENDIAN
- #undef WORDS_BIGENDIAN
- #else
- #error Unknown endianness!
- #endif
- #endif
- #define ZCOUNT_SCALE 0.6
- #define PRCSMALL 0.02
- #define PRCLARGE 0.32
- #define RRSMALL 0.002
- #define RRLARGE 0.032
- #define MAXPCSMALL (0x7FFF * PCSMALL)
- #define MAXRRSMALL (0x7F * RRSMALL)
- #define XYZ_SCALE 0.01
- #define DXYZ_SCALE 0.1
- #define LA_SCALE (90.0/32767.0)
- #define LO_SCALE (180.0/32767.0)
- #define FREQ_SCALE 0.1
- #define FREQ_OFFSET 190.0
- #define CNR_OFFSET 24
- #define TU_SCALE 5
- #define LATLON_SCALE 0.01
- #define RANGE_SCALE 4
- #pragma pack(1)
- #ifndef WORDS_BIGENDIAN
- struct rtcm2_msg_t {
- struct rtcm2_msghw1 {
- unsigned int parity:6;
- unsigned int refstaid:10;
- unsigned int msgtype:6;
- unsigned int preamble:8;
- unsigned int _pad:2;
- } w1;
- struct rtcm2_msghw2 {
- unsigned int parity:6;
- unsigned int stathlth:3;
- unsigned int frmlen:5;
- unsigned int sqnum:3;
- unsigned int zcnt:13;
- unsigned int _pad:2;
- } w2;
- union {
-
- struct rtcm2_msg1 {
- struct gps_correction_t {
- struct {
- unsigned int parity:6;
- int prc1:16;
- unsigned int satident1:5;
- unsigned int udre1:2;
- unsigned int scale1:1;
- unsigned int _pad:2;
- } w3;
- struct {
- unsigned int parity:6;
- unsigned int satident2:5;
- unsigned int udre2:2;
- unsigned int scale2:1;
- unsigned int iod1:8;
- int rrc1:8;
- unsigned int _pad:2;
- } w4;
- struct {
- unsigned int parity:6;
- int rrc2:8;
- int prc2:16;
- unsigned int _pad:2;
- } w5;
- struct {
- unsigned int parity:6;
- int prc3_h:8;
- unsigned int satident3:5;
- unsigned int udre3:2;
- unsigned int scale3:1;
- unsigned int iod2:8;
- unsigned int _pad:2;
- } w6;
- struct {
- unsigned int parity:6;
- unsigned int iod3:8;
- int rrc3:8;
- unsigned int prc3_l:8;
- unsigned int _pad:2;
- } w7;
- } corrections[(RTCM2_WORDS_MAX - 2) / 5];
- } type1;
-
- struct rtcm2_msg3 {
- struct {
- unsigned int parity:6;
- unsigned int x_h:24;
- unsigned int _pad:2;
- } w3;
- struct {
- unsigned int parity:6;
- unsigned int y_h:16;
- unsigned int x_l:8;
- unsigned int _pad:2;
- } w4;
- struct {
- unsigned int parity:6;
- unsigned int z_h:8;
- unsigned int y_l:16;
- unsigned int _pad:2;
- } w5;
- struct {
- unsigned int parity:6;
- unsigned int z_l:24;
- unsigned int _pad:2;
- } w6;
- } type3;
-
- struct rtcm2_msg4 {
- struct {
- unsigned int parity:6;
- unsigned int datum_alpha_char2:8;
- unsigned int datum_alpha_char1:8;
- unsigned int spare:4;
- unsigned int dat:1;
- unsigned int dgnss:3;
- unsigned int _pad:2;
- } w3;
- struct {
- unsigned int parity:6;
- unsigned int datum_sub_div_char2:8;
- unsigned int datum_sub_div_char1:8;
- unsigned int datum_sub_div_char3:8;
- unsigned int _pad:2;
- } w4;
- struct {
- unsigned int parity:6;
- unsigned int dy_h:8;
- unsigned int dx:16;
- unsigned int _pad:2;
- } w5;
- struct {
- unsigned int parity:6;
- unsigned int dz:24;
- unsigned int dy_l:8;
- unsigned int _pad:2;
- } w6;
- } type4;
-
- struct rtcm2_msg5 {
- struct b_health_t {
- unsigned int parity:6;
- unsigned int unassigned:2;
- unsigned int time_unhealthy:4;
- unsigned int loss_warn:1;
- unsigned int new_nav_data:1;
- unsigned int health_enable:1;
- unsigned int cn0:5;
- unsigned int data_health:3;
- unsigned int issue_of_data_link:1;
- unsigned int sat_id:5;
- unsigned int reserved:1;
- unsigned int _pad:2;
- } health[MAXHEALTH];
- } type5;
-
-
- struct rtcm2_msg7 {
- struct b_station_t {
- struct {
- unsigned int parity:6;
- int lon_h:8;
- int lat:16;
- unsigned int _pad:2;
- } w3;
- struct {
- unsigned int parity:6;
- unsigned int freq_h:6;
- unsigned int range:10;
- unsigned int lon_l:8;
- unsigned int _pad:2;
- } w4;
- struct {
- unsigned int parity:6;
- unsigned int encoding:1;
- unsigned int sync_type:1;
- unsigned int mod_mode:1;
- unsigned int bit_rate:3;
-
- unsigned int station_id:10;
- unsigned int health:2;
- unsigned int freq_l:6;
- unsigned int _pad:2;
- } w5;
- } almanac[(RTCM2_WORDS_MAX - 2)/3];
- } type7;
-
- struct rtcm2_msg13 {
- struct {
- unsigned int parity:6;
- int lat:16;
- unsigned int reserved:6;
- unsigned int rangeflag:1;
- unsigned int status:1;
- unsigned int _pad:2;
- } w1;
- struct {
- unsigned int parity:6;
- unsigned int range:8;
- int lon:16;
- unsigned int _pad:2;
- } w2;
- } type13;
-
- struct rtcm2_msg14 {
- struct {
- unsigned int parity:6;
- unsigned int leapsecs:6;
- unsigned int hour:8;
- unsigned int week:10;
- unsigned int _pad:2;
- } w1;
- } type14;
-
- struct rtcm2_msg16 {
- struct {
- unsigned int parity:6;
- unsigned int byte3:8;
- unsigned int byte2:8;
- unsigned int byte1:8;
- unsigned int _pad:2;
- } txt[RTCM2_WORDS_MAX-2];
- } type16;
-
- struct rtcm2_msg31 {
- struct glonass_correction_t {
- struct {
- unsigned int parity:6;
- int prc1:16;
- unsigned int satident1:5;
- unsigned int udre1:2;
- unsigned int scale1:1;
- unsigned int _pad:2;
- } w3;
- struct {
- unsigned int parity:6;
- unsigned int satident2:5;
- unsigned int udre2:2;
- unsigned int scale2:1;
- unsigned int tod1:7;
- unsigned int change1:1;
- int rrc1:8;
- unsigned int _pad:2;
- } w4;
- struct {
- unsigned int parity:6;
- int rrc2:8;
- int prc2:16;
- unsigned int _pad:2;
- } w5;
- struct {
- unsigned int parity:6;
- int prc3_h:8;
- unsigned int satident3:5;
- unsigned int udre3:2;
- unsigned int scale3:1;
- unsigned int tod2:7;
- unsigned int change2:1;
- unsigned int _pad:2;
- } w6;
- struct {
- unsigned int parity:6;
- unsigned int tod3:7;
- unsigned int change3:1;
- int rrc3:8;
- unsigned int prc3_l:8;
- unsigned int _pad:2;
- } w7;
- } corrections[(RTCM2_WORDS_MAX - 2) / 5];
- } type31;
-
- isgps30bits_t rtcm2_msgunk[RTCM2_WORDS_MAX-2];
- } msg_type;
- } __attribute__((__packed__));
- #endif
- #ifdef WORDS_BIGENDIAN
- struct rtcm2_msg_t {
- struct rtcm2_msghw1 {
- unsigned int _pad:2;
- unsigned int preamble:8;
- unsigned int msgtype:6;
- unsigned int refstaid:10;
- unsigned int parity:6;
- } w1;
- struct rtcm2_msghw2 {
- unsigned int _pad:2;
- unsigned int zcnt:13;
- unsigned int sqnum:3;
- unsigned int frmlen:5;
- unsigned int stathlth:3;
- unsigned int parity:6;
- } w2;
- union {
-
- struct rtcm2_msg1 {
- struct gps_correction_t {
- struct {
- unsigned int _pad:2;
- unsigned int scale1:1;
- unsigned int udre1:2;
- unsigned int satident1:5;
- int prc1:16;
- unsigned int parity:6;
- } w3;
- struct {
- unsigned int _pad:2;
- int rrc1:8;
- unsigned int iod1:8;
- unsigned int scale2:1;
- unsigned int udre2:2;
- unsigned int satident2:5;
- unsigned int parity:6;
- } w4;
- struct {
- unsigned int _pad:2;
- int prc2:16;
- int rrc2:8;
- unsigned int parity:6;
- } w5;
- struct {
- unsigned int _pad:2;
- unsigned int iod2:8;
- unsigned int scale3:1;
- unsigned int udre3:2;
- unsigned int satident3:5;
- int prc3_h:8;
- unsigned int parity:6;
- } w6;
- struct {
- unsigned int _pad:2;
- unsigned int prc3_l:8;
- int rrc3:8;
- unsigned int iod3:8;
- unsigned int parity:6;
- } w7;
- } corrections[(RTCM2_WORDS_MAX - 2) / 5];
- } type1;
-
- struct rtcm2_msg3 {
- struct {
- unsigned int _pad:2;
- unsigned int x_h:24;
- unsigned int parity:6;
- } w3;
- struct {
- unsigned int _pad:2;
- unsigned int x_l:8;
- unsigned int y_h:16;
- unsigned int parity:6;
- } w4;
- struct {
- unsigned int _pad:2;
- unsigned int y_l:16;
- unsigned int z_h:8;
- unsigned int parity:6;
- } w5;
- struct {
- unsigned int _pad:2;
- unsigned int z_l:24;
- unsigned int parity:6;
- } w6;
- } type3;
-
- struct rtcm2_msg4 {
- struct {
- unsigned int _pad:2;
- unsigned int dgnss:3;
- unsigned int dat:1;
- unsigned int spare:4;
- unsigned int datum_alpha_char1:8;
- unsigned int datum_alpha_char2:8;
- unsigned int parity:6;
- } w3;
- struct {
- unsigned int _pad:2;
- unsigned int datum_sub_div_char3:8;
- unsigned int datum_sub_div_char1:8;
- unsigned int datum_sub_div_char2:8;
- unsigned int parity:6;
- } w4;
- struct {
- unsigned int _pad:2;
- unsigned int dx:16;
- unsigned int dy_h:8;
- unsigned int parity:6;
- } w5;
- struct {
- unsigned int _pad:2;
- unsigned int dy_l:8;
- unsigned int dz:24;
- unsigned int parity:6;
- } w6;
- } type4;
-
- struct rtcm2_msg5 {
- struct b_health_t {
- unsigned int _pad:2;
- unsigned int reserved:1;
- unsigned int sat_id:5;
- unsigned int issue_of_data_link:1;
- unsigned int data_health:3;
- unsigned int cn0:5;
- unsigned int health_enable:1;
- unsigned int new_nav_data:1;
- unsigned int loss_warn:1;
- unsigned int time_unhealthy:4;
- unsigned int unassigned:2;
- unsigned int parity:6;
- } health[MAXHEALTH];
- } type5;
-
-
- struct rtcm2_msg7 {
- struct b_station_t {
- struct {
- unsigned int _pad:2;
- int lat:16;
- int lon_h:8;
- unsigned int parity:6;
- } w3;
- struct {
- unsigned int _pad:2;
- unsigned int lon_l:8;
- unsigned int range:10;
- unsigned int freq_h:6;
- unsigned int parity:6;
- } w4;
- struct {
- unsigned int _pad:2;
- unsigned int freq_l:6;
- unsigned int health:2;
- unsigned int station_id:10;
-
- unsigned int bit_rate:3;
- unsigned int mod_mode:1;
- unsigned int sync_type:1;
- unsigned int encoding:1;
- unsigned int parity:6;
- } w5;
- } almanac[(RTCM2_WORDS_MAX - 2)/3];
- } type7;
-
- struct rtcm2_msg13 {
- struct {
- unsigned int _pad:2;
- unsigned int status:1;
- unsigned int rangeflag:1;
- unsigned int reserved:6;
- int lat:16;
- unsigned int parity:6;
- } w1;
- struct {
- unsigned int _pad:2;
- int lon:16;
- unsigned int range:8;
- unsigned int parity:6;
- } w2;
- } type13;
-
- struct rtcm2_msg14 {
- struct {
- unsigned int _pad:2;
- unsigned int week:10;
- unsigned int hour:8;
- unsigned int leapsecs:6;
- unsigned int parity:6;
- } w1;
- } type14;
-
- struct rtcm2_msg16 {
- struct {
- unsigned int _pad:2;
- unsigned int byte1:8;
- unsigned int byte2:8;
- unsigned int byte3:8;
- unsigned int parity:6;
- } txt[RTCM2_WORDS_MAX-2];
- } type16;
-
- struct rtcm2_msg31 {
- struct glonass_correction_t {
- struct {
- unsigned int _pad:2;
- unsigned int scale1:1;
- unsigned int udre1:2;
- unsigned int satident1:5;
- int prc1:16;
- unsigned int parity:6;
- } w3;
- struct {
- unsigned int _pad:2;
- int rrc1:8;
- unsigned int change1:1;
- unsigned int tod1:7;
- unsigned int scale2:1;
- unsigned int udre2:2;
- unsigned int satident2:5;
- unsigned int parity:6;
- } w4;
- struct {
- unsigned int _pad:2;
- int prc2:16;
- int rrc2:8;
- unsigned int parity:6;
- } w5;
- struct {
- unsigned int _pad:2;
- unsigned int change2:1;
- unsigned int tod2:7;
- unsigned int scale3:1;
- unsigned int udre3:2;
- unsigned int satident3:5;
- int prc3_h:8;
- unsigned int parity:6;
- } w6;
- struct {
- unsigned int _pad:2;
- unsigned int prc3_l:8;
- int rrc3:8;
- unsigned int change3:1;
- unsigned int tod3:7;
- unsigned int parity:6;
- } w7;
- } corrections[(RTCM2_WORDS_MAX - 2) / 5];
- } type31;
-
- isgps30bits_t rtcm2_msgunk[RTCM2_WORDS_MAX-2];
- } msg_type;
- } __attribute__((__packed__));
- #endif
- #ifdef RTCM104V2_ENABLE
- #define PREAMBLE_PATTERN 0x66
- static unsigned int tx_speed[] = { 25, 50, 100, 110, 150, 200, 250, 300 };
- #define DIMENSION(a) (unsigned)(sizeof(a)/sizeof(a[0]))
- void rtcm2_unpack(struct rtcm2_t *tp, char *buf)
- {
- int len;
- unsigned int n, w;
- struct rtcm2_msg_t *msg = (struct rtcm2_msg_t *)buf;
- tp->type = msg->w1.msgtype;
- tp->length = msg->w2.frmlen;
- tp->zcount = msg->w2.zcnt * ZCOUNT_SCALE;
- tp->refstaid = msg->w1.refstaid;
- tp->seqnum = msg->w2.sqnum;
- tp->stathlth = msg->w2.stathlth;
- len = (int)tp->length;
- n = 0;
- switch (tp->type) {
- case 1:
- case 9:
- {
- struct gps_correction_t *m = &msg->msg_type.type1.corrections[0];
- while (len >= 0) {
- if (len >= 2) {
- tp->gps_ranges.sat[n].ident = m->w3.satident1;
- tp->gps_ranges.sat[n].udre = m->w3.udre1;
- tp->gps_ranges.sat[n].iod = m->w4.iod1;
- tp->gps_ranges.sat[n].prc = m->w3.prc1 *
- (m->w3.scale1 ? PRCLARGE : PRCSMALL);
- tp->gps_ranges.sat[n].rrc = m->w4.rrc1 *
- (m->w3.scale1 ? RRLARGE : RRSMALL);
- n++;
- }
- if (len >= 4) {
- tp->gps_ranges.sat[n].ident = m->w4.satident2;
- tp->gps_ranges.sat[n].udre = m->w4.udre2;
- tp->gps_ranges.sat[n].iod = m->w6.iod2;
- tp->gps_ranges.sat[n].prc = m->w5.prc2 *
- (m->w4.scale2 ? PRCLARGE : PRCSMALL);
- tp->gps_ranges.sat[n].rrc = m->w5.rrc2 *
- (m->w4.scale2 ? RRLARGE : RRSMALL);
- n++;
- }
- if (len >= 5) {
- tp->gps_ranges.sat[n].ident = m->w6.satident3;
- tp->gps_ranges.sat[n].udre = m->w6.udre3;
- tp->gps_ranges.sat[n].iod = m->w7.iod3;
- tp->gps_ranges.sat[n].prc =
- ((m->w6.prc3_h << 8) | (m->w7.prc3_l)) *
- (m->w6.scale3 ? PRCLARGE : PRCSMALL);
- tp->gps_ranges.sat[n].rrc =
- m->w7.rrc3 * (m->w6.scale3 ? RRLARGE : RRSMALL);
- n++;
- }
- len -= 5;
- m++;
- }
- tp->gps_ranges.nentries = n;
- }
- break;
- case 3:
- {
- struct rtcm2_msg3 *m = &msg->msg_type.type3;
- if ((tp->ecef.valid = len >= 4)) {
- tp->ecef.x = ((m->w3.x_h << 8) | (m->w4.x_l)) * XYZ_SCALE;
- tp->ecef.y = ((m->w4.y_h << 16) | (m->w5.y_l)) * XYZ_SCALE;
- tp->ecef.z = ((m->w5.z_h << 24) | (m->w6.z_l)) * XYZ_SCALE;
- }
- }
- break;
- case 4:
- if ((tp->reference.valid = len >= 2)) {
- struct rtcm2_msg4 *m = &msg->msg_type.type4;
- tp->reference.system =
- (m->w3.dgnss == 0) ? NAVSYSTEM_GPS :
- ((m->w3.dgnss == 1) ? NAVSYSTEM_GLONASS : NAVSYSTEM_UNKNOWN);
- tp->reference.sense =
- (m->w3.dat != 0) ? SENSE_GLOBAL : SENSE_LOCAL;
- if (m->w3.datum_alpha_char1) {
- tp->reference.datum[n++] = (char)(m->w3.datum_alpha_char1);
- }
- if (m->w3.datum_alpha_char2) {
- tp->reference.datum[n++] = (char)(m->w3.datum_alpha_char2);
- }
- if (m->w4.datum_sub_div_char1) {
- tp->reference.datum[n++] = (char)(m->w4.datum_sub_div_char1);
- }
- if (m->w4.datum_sub_div_char2) {
- tp->reference.datum[n++] = (char)(m->w4.datum_sub_div_char2);
- }
- if (m->w4.datum_sub_div_char3) {
- tp->reference.datum[n++] = (char)(m->w4.datum_sub_div_char3);
- }
-
- tp->reference.datum[n] = '\0';
- if (len >= 4) {
- tp->reference.dx = m->w5.dx * DXYZ_SCALE;
- tp->reference.dy =
- ((m->w5.dy_h << 8) | m->w6.dy_l) * DXYZ_SCALE;
- tp->reference.dz = m->w6.dz * DXYZ_SCALE;
- } else
- tp->reference.sense = SENSE_INVALID;
- }
- break;
- case 5:
- for (n = 0; n < (unsigned)len; n++) {
- struct consat_t *csp = &tp->conhealth.sat[n];
- struct b_health_t *m = &msg->msg_type.type5.health[n];
- csp->ident = m->sat_id;
- csp->iodl = m->issue_of_data_link != 0;
- csp->health = m->data_health;
- csp->snr = (int)(m->cn0 ? (m->cn0 + CNR_OFFSET) : SNR_BAD);
- csp->health_en = m->health_enable != 0;
- csp->new_data = m->new_nav_data != 0;
- csp->los_warning = m->loss_warn != 0;
- csp->tou = m->time_unhealthy * TU_SCALE;
- }
- tp->conhealth.nentries = n;
- break;
- case 7:
- for (w = 0; w < (unsigned)len; w++) {
- struct station_t *np = &tp->almanac.station[n];
- struct b_station_t *mp = &msg->msg_type.type7.almanac[w];
- np->latitude = mp->w3.lat * LA_SCALE;
- np->longitude = ((mp->w3.lon_h << 8) | mp->w4.lon_l) * LO_SCALE;
- np->range = mp->w4.range;
- np->frequency =
- (((mp->w4.freq_h << 6) | mp->w5.freq_l) * FREQ_SCALE) +
- FREQ_OFFSET;
- np->health = mp->w5.health;
- np->station_id = mp->w5.station_id,
- np->bitrate = tx_speed[mp->w5.bit_rate];
- n++;
- }
- tp->almanac.nentries = (unsigned)(len / 3);
- break;
- case 13:
- tp->xmitter.status = (bool)msg->msg_type.type13.w1.status;
- tp->xmitter.rangeflag = (bool)msg->msg_type.type13.w1.rangeflag;
- tp->xmitter.lat = msg->msg_type.type13.w1.lat * LATLON_SCALE;
- tp->xmitter.lon = msg->msg_type.type13.w2.lon * LATLON_SCALE;
- tp->xmitter.range = msg->msg_type.type13.w2.range * RANGE_SCALE;
- if (tp->xmitter.range == 0)
- tp->xmitter.range = 1024;
- break;
- case 14:
- tp->gpstime.week = msg->msg_type.type14.w1.week;
- tp->gpstime.hour = msg->msg_type.type14.w1.hour;
- tp->gpstime.leapsecs = msg->msg_type.type14.w1.leapsecs;
- break;
- case 16:
- for (w = 0; w < (unsigned)len; w++) {
- if (!msg->msg_type.type16.txt[w].byte1) {
- break;
- }
- tp->message[n++] = (char)(msg->msg_type.type16.txt[w].byte1);
- if (!msg->msg_type.type16.txt[w].byte2) {
- break;
- }
- tp->message[n++] = (char)(msg->msg_type.type16.txt[w].byte2);
- if (!msg->msg_type.type16.txt[w].byte3) {
- break;
- }
- tp->message[n++] = (char)(msg->msg_type.type16.txt[w].byte3);
- }
- tp->message[n] = '\0';
- break;
- case 31:
- {
- struct glonass_correction_t *m = &msg->msg_type.type31.corrections[0];
- while (len >= 0) {
- if (len >= 2) {
- tp->glonass_ranges.sat[n].ident = m->w3.satident1;
- tp->glonass_ranges.sat[n].udre = m->w3.udre1;
- tp->glonass_ranges.sat[n].change = (bool)m->w4.change1;
- tp->glonass_ranges.sat[n].tod = m->w4.tod1;
- tp->glonass_ranges.sat[n].prc = m->w3.prc1 *
- (m->w3.scale1 ? PRCLARGE : PRCSMALL);
- tp->glonass_ranges.sat[n].rrc = m->w4.rrc1 *
- (m->w3.scale1 ? RRLARGE : RRSMALL);
- n++;
- }
- if (len >= 4) {
- tp->glonass_ranges.sat[n].ident = m->w4.satident2;
- tp->glonass_ranges.sat[n].udre = m->w4.udre2;
- tp->glonass_ranges.sat[n].change = (bool)m->w6.change2;
- tp->glonass_ranges.sat[n].tod = m->w6.tod2;
- tp->glonass_ranges.sat[n].prc = m->w5.prc2 *
- (m->w4.scale2 ? PRCLARGE : PRCSMALL);
- tp->glonass_ranges.sat[n].rrc = m->w5.rrc2 *
- (m->w4.scale2 ? RRLARGE : RRSMALL);
- n++;
- }
- if (len >= 5) {
- tp->glonass_ranges.sat[n].ident = m->w6.satident3;
- tp->glonass_ranges.sat[n].udre = m->w6.udre3;
- tp->glonass_ranges.sat[n].change = (bool)m->w7.change3;
- tp->glonass_ranges.sat[n].tod = m->w7.tod3;
- tp->glonass_ranges.sat[n].prc =
- ((m->w6.prc3_h << 8) | (m->w7.prc3_l)) *
- (m->w6.scale3 ? PRCLARGE : PRCSMALL);
- tp->glonass_ranges.sat[n].rrc =
- m->w7.rrc3 * (m->w6.scale3 ? RRLARGE : RRSMALL);
- n++;
- }
- len -= 5;
- m++;
- }
- tp->glonass_ranges.nentries = n;
- }
- break;
- default:
- memcpy(tp->words, msg->msg_type.rtcm2_msgunk,
- (RTCM2_WORDS_MAX - 2) * sizeof(isgps30bits_t));
- break;
- }
- }
- static bool preamble_match(isgps30bits_t * w)
- {
- return (((struct rtcm2_msghw1 *)w)->preamble == PREAMBLE_PATTERN);
- }
- static bool length_check(struct gps_lexer_t *lexer)
- {
- return lexer->isgps.bufindex >= 2
- && lexer->isgps.bufindex >=
- ((struct rtcm2_msg_t *)lexer->isgps.buf)->w2.frmlen + 2u;
- }
- enum isgpsstat_t rtcm2_decode(struct gps_lexer_t *lexer, unsigned int c)
- {
- return isgps_decode(lexer,
- preamble_match, length_check, RTCM2_WORDS_MAX, c);
- }
- #endif
|