25extern int satno(
int sys,
int prn);
26extern void satno2id(
int sat,
char*
id);
32#define HAS_DUMMY_HEADER 0xAF3BC3
33#define HAS_TIMEOUT 150.0
40#define HAS_HASS_DONTUSE 3
42#define HAS_SATM_BITS 40
43#define HAS_SIGM_BITS 16
45#define HAS_DR_NA (-4096)
46#define HAS_DIT_NA (-2048)
47#define HAS_DCT_NA (-2048)
48#define HAS_DCC_NA (-4096)
49#define HAS_DCC_NU (4095)
50#define HAS_CB_NA (-1024)
51#define HAS_PB_NA (-1024)
152 return (freq > 0.0) ?
CLIGHT / freq : 0.0;
160static int has_bits_ok(
int i,
int n,
int nbit) {
return i >= 0 && n >= 0 && i + n <= nbit; }
165#define HAS_MAX_LATENCY 600.0
171 for (i = 0; i < len; i++) {
172 if (
getbitu(buff, pos + i, 1)) {
181 double sow_r, hr3600;
185 hr3600 = floor(sow_r / 3600.0) * 3600.0;
186 if (hr3600 + (
double)toh > sow_r) {
189 return gpst2time(week, hr3600 + (
double)toh);
197 int j, k, s, nsys, gnssid, cmaf, nm, nsat, nsig, sys, prn;
198 int seen_gnss[16] = {0};
206 nsys = (int)
getbitu(msg, i, 4);
211 for (j = 0; j < nsys; j++) {
215 gnssid = (int)
getbitu(msg, i, 4);
221 trace(NULL, 2,
"decode_has_mask: unknown gnssid=%d, abort\n", gnssid);
224 if (seen_gnss[gnssid]) {
227 trace(NULL, 2,
"decode_has_mask: duplicate gnssid=%d, abort\n", gnssid);
230 seen_gnss[gnssid] = 1;
239 trace(NULL, 2,
"decode_has_mask: slot overflow s=%d+nsat=%d > %d, abort\n", s, nsat,
MAXSAT);
269 for (k = s - nsat; k < s; k++) {
273 for (c = 0; c < nsig; c++) {
274 m->
code[k][c] = codes[c];
280 cell = (uint16_t)
getbitu(msg, i, nsig);
283 cell = (uint16_t)((nsig >= 16) ? 0xFFFF : ((1u << nsig) - 1u));
293 for (k = s - nsat; k < s; k++) {
297 trace(NULL, 4,
"decode_has_mask: gnssid=%d, nsat=%d, nsig=%d, cmaf=%d, nm=%d\n", gnssid, nsat, nsig, cmaf, nm);
307 for (k = 0; k < s; k++) {
310 trace(NULL, 4,
"decode_has_mask: slot=%d, sat=%s, nsig=%d, cell=0x%04X\n", k, satid, m->
nsig[k],
321 int j, sat, nb, iodref, dr, dit, dct;
330 for (j = 0; j < m->
nsat; j++) {
335 iodref = (int)
getbitu(msg, i, nb);
355 has->
ssr[sat - 1].
deph[0] = -dr * 0.0025;
356 has->
ssr[sat - 1].
deph[1] = -dit * 0.0080;
357 has->
ssr[sat - 1].
deph[2] = -dct * 0.0080;
361 has->
ssr[sat - 1].
iode = iodref;
367 has->
ssr[sat - 1].
iod[0] = iodset;
368 has->
ssr[sat - 1].
t0[0] = t0;
369 has->
ssr[sat - 1].
udi[0] = 0.0;
379 int j, sat, dcm[
HAS_MAX_SIG], mult, dcc, prevgid = -1, sysidx = -1;
388 for (j = 0; j < m->
nsys; j++) {
392 dcm[j] = (int)
getbitu(msg, i, 2);
396 for (j = 0; j < m->
nsat; j++) {
397 if (m->
gnssid[j] != prevgid) {
401 mult = dcm[sysidx] + 1;
423 has->
ssr[sat - 1].
dclk[0] = dcc * 0.0025 * mult;
424 has->
ssr[sat - 1].
dclk[1] = 0.0;
425 has->
ssr[sat - 1].
dclk[2] = 0.0;
427 has->
ssr[sat - 1].
iod[1] = iodset;
428 has->
ssr[sat - 1].
t0[1] = t0;
429 has->
ssr[sat - 1].
udi[1] = 0.0;
438 int g, j, gnssid, dcm, mult, dcc, sat, nsat_gnss, base, submask_pos, nsys_sub;
444 nsys_sub = (int)
getbitu(msg, i, 4);
447 for (g = 0; g < nsys_sub; g++) {
451 gnssid = (int)
getbitu(msg, i, 4);
460 for (j = 0; j < m->
nsat; j++) {
461 if (m->
gnssid[j] == gnssid) {
469 trace(NULL, 2,
"decode_has_clock_subset: gnssid=%d not in mask\n", gnssid);
480 for (j = 0; j < nsat_gnss; j++) {
481 if (!
getbitu(msg, submask_pos + j, 1)) {
490 sat = m->
sat[base + j];
502 has->
ssr[sat - 1].
dclk[0] = dcc * 0.0025 * mult;
503 has->
ssr[sat - 1].
dclk[1] = 0.0;
504 has->
ssr[sat - 1].
dclk[2] = 0.0;
506 has->
ssr[sat - 1].
iod[1] = iodset;
507 has->
ssr[sat - 1].
t0[1] = t0;
508 has->
ssr[sat - 1].
udi[1] = 0.0;
525 for (j = 0; j < m->
nsat; j++) {
528 has->
ssr[sat - 1].
t0[4] = t0;
529 has->
ssr[sat - 1].
udi[4] = 0.0;
531 for (c = 0; c < m->
nsig[j]; c++) {
532 if (!((m->
cellmask[j] >> (m->
nsig[j] - 1 - c)) & 0x1)) {
544 code = m->
code[j][c];
554 has->
ssr[sat - 1].
cbias[code - 1] = 0.0f;
559 has->
ssr[sat - 1].
cbias[code - 1] = (float)(cb * 0.02);
569 int j, c, sat, pb, pdi, sys;
578 for (j = 0; j < m->
nsat; j++) {
582 has->
ssr[sat - 1].
t0[5] = t0;
583 has->
ssr[sat - 1].
udi[5] = 0.0;
585 for (c = 0; c < m->
nsig[j]; c++) {
586 if (!((m->
cellmask[j] >> (m->
nsig[j] - 1 - c)) & 0x1)) {
600 code = m->
code[j][c];
613 has->
ssr[sat - 1].
pbias[code - 1] = 0.0;
619 has->
ssr[sat - 1].
pbias[code - 1] = pb * 0.01 * lam;
621 has->
ssr[sat - 1].
discnt[code - 1] = pdi;
630 int i = 0, toh, fmask, forbit, fcfull, fcsub, fcb, fpb, mid, iodset, week;
631 double sow_r, latency;
638 toh = (int)
getbitu(msg, i, 12);
640 fmask = (int)
getbitu(msg, i, 1);
642 forbit = (int)
getbitu(msg, i, 1);
644 fcfull = (int)
getbitu(msg, i, 1);
646 fcsub = (int)
getbitu(msg, i, 1);
655 iodset = (int)
getbitu(msg, i, 5);
662 trace(NULL, 2,
"decode_has_mt1: invalid toh=%d (>=3600), reject\n", toh);
668 latency = fmod(sow_r - (
double)toh, 3600.0);
673 trace(NULL, 2,
"decode_has_mt1: latency=%.0f s > %.0f, reject (toh=%d)\n", latency,
HAS_MAX_LATENCY, toh);
679 trace(NULL, 4,
"decode_has_mt1: %s, toh=%d, flags=%d%d%d%d%d%d, mid=%d, iodset=%d\n",
time_str(t0, 3), toh, fmask,
680 forbit, fcfull, fcsub, fcb, fpb, mid, iodset);
688 trace(NULL, 2,
"decode_has_mt1: %s, mask id=%d not yet received\n",
time_str(t0, 3), mid);
697 trace(NULL, 2,
"decode_has_mt1: %s, iodset (mid=%d,id=%d) not yet received\n",
time_str(t0, 3), mid, iodset);
734 trace(NULL, 2,
"has_complete: RS decode failed mid=%d, k=%d\n", col->
mid, col->
ms);
751 double age, maxage = -1.0;
786 trace(NULL, 2,
"has_flush: HAS state discarded\n");
807 int hass, mt, mid, ms, pid, k;
811 header =
getbitu(page56, 0, 24);
816 hass = (int)
getbitu(page56, 0, 2);
818 mt = (int)
getbitu(page56, 4, 2);
819 mid = (int)
getbitu(page56, 6, 5);
820 ms = (int)
getbitu(page56, 11, 5) + 1;
821 pid = (int)
getbitu(page56, 16, 8);
827 if (pid == 0 || mt !=
HAS_MT1) {
841 if (!col->
active || col->
mid != mid || col->
mt != mt || col->
ms != ms) {
842 if (col->
active && col->
mid == mid && col->
mt == mt && col->
ms != ms) {
843 trace(NULL, 4,
"has_input_page: MS change mid=%d %d->%d, restart collection\n", mid, col->
ms, ms);
853 for (k = 0; k < col->
npid; k++) {
854 if (col->
pid[k] == pid) {
861 col->
pid[col->
npid] = (uint8_t)pid;
865 if (col->
npid >= col->
ms) {
876 int wnc, prn, ret, completed = 0;
878 while (fread(rec, 1, 64, fp) == 64) {
880 tow_ms = (uint32_t)rec[0] | ((uint32_t)rec[1] << 8) | ((uint32_t)rec[2] << 16) | ((uint32_t)rec[3] << 24);
881 wnc = (int)((uint16_t)rec[4] | ((uint16_t)rec[5] << 8));
887 fseek(fp, -64, SEEK_CUR);
894 }
else if (ret < 0) {
895 trace(NULL, 2,
"has_input_file: page decode error\n");
uint32_t getbitu(const uint8_t *buff, int pos, int len)
Extract unsigned bits from byte data.
int32_t getbits(const uint8_t *buff, int pos, int len)
Extract signed bits from byte data.
MRTKLIB Bits Module — Binary bit operations and CRC functions.
MRTKLIB Constants — Physical, navigation, and system constants.
void satno2id(int sat, char *id)
static int has_gnssid2sys(int gnssid)
static int decode_has_orbit(has_t *has, const uint8_t *msg, int i, int nbit, int mid, int iodset, gtime_t t0)
static int decode_has_phasebias(has_t *has, const uint8_t *msg, int i, int nbit, gtime_t t0, const has_mask_t *m)
static int decode_has_mt1(has_t *has, const uint8_t *msg, int nbit, gtime_t time)
static int decode_has_clock(has_t *has, const uint8_t *msg, int i, int nbit, int mid, int iodset, gtime_t t0)
static int has_bits_ok(int i, int n, int nbit)
void has_free(has_t *has)
Free a Galileo HAS decode context.
int satno(int sys, int prn)
static uint8_t has_sigcode(int gnssid, int sigidx)
static int has_complete(has_t *has, has_collect_t *col, gtime_t time)
static const uint8_t has_sig_gal[HAS_MAX_SIG]
static double has_code2lam(int sys, uint8_t code)
int has_input_file(has_t *has, FILE *fp, gtime_t tmax)
Read .has records from a file and feed them to has_input_page().
int has_input_page(has_t *has, int prn, const uint8_t *page56, gtime_t time)
Input one received Galileo HAS page.
static int has_iodref_bits(int gnssid)
static int popcount_field(const uint8_t *buff, int pos, int len)
double time2gpst(gtime_t t, int *week)
static int decode_has_clock_subset(has_t *has, const uint8_t *msg, int i, int nbit, int mid, int iodset, gtime_t t0)
static void has_flush(has_t *has)
static const uint8_t has_sig_gps[HAS_MAX_SIG]
char * time_str(gtime_t t, int n)
static gtime_t has_t_mt1(gtime_t time, int toh)
static int decode_has_codebias(has_t *has, const uint8_t *msg, int i, int nbit, gtime_t t0, const has_mask_t *m)
has_t * has_new(void)
Allocate and initialize a Galileo HAS decode context.
static int decode_has_mask(has_t *has, const uint8_t *msg, int i, int nbit, int mid)
static has_collect_t * has_find_collect(has_t *has, int mid, int mt, gtime_t time)
int has_sel_biascode(int sys, uint8_t code)
Select the HAS bias slot obs code for an observation code.
MRTKLIB Galileo HAS Module — E6-B C/NAV HAS page collection and Message Type 1 (MT1) decode into ssr_...
int has_rs_init(void)
Build the GF(256) log/antilog tables and the systematic generator matrix G. Idempotent: safe to call ...
int has_rs_decode(const uint8_t pages[][53], const uint8_t *pids, int k, uint8_t *out)
Decode a k-page HAS message from k distinct received encoded pages using the RS(255,...
gtime_t gpst2time(int week, double sec)
Convert GPS week/tow to gtime_t.
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
MRTKLIB Time Module — GNSS time types and conversion functions.
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
GNSS time representation.
uint16_t cellmask[MAXSAT]
has_iodset_t iodset[32][32]