ZhiQiang_Yang98 79f5c035ab Revert "syn"
This reverts commit 34a3ce7899a56f426ddb1f91073dfcd1cd373b5b.
2022-11-28 10:49:41 +08:00

2698 lines
104 KiB
C

/*------------------------------------------------------------------------------
* rtcm3.c : RTCM ver.3 message decorder functions
*
* Copyright (C) 2009-2020 by T.TAKASU, All rights reserved.
*
* references :
* see rtcm.c
*
* version : $Revision:$ $Date:$
* history : 2012/05/14 1.0 separated from rtcm.c
* 2012/12/12 1.1 support gal/qzs ephemeris, gal/qzs ssr, msm
* add station id consistency test for obs data
* 2012/12/25 1.2 change compass msm id table
* 2013/01/31 1.3 change signal id by the latest draft (ref [13])
* 2013/02/23 1.4 change reference for rtcm 3 message (ref [14])
* 2013/05/19 1.5 gpst -> bdt of time-tag in beidou msm message
* 2014/05/02 1.6 fix bug on dropping last field of ssr message
* comply with rtcm 3.2 with amendment 1/2 (ref[15])
* delete MT 1046 according to ref [15]
* 2014/09/14 1.7 add receiver option -RT_INP
* 2014/12/06 1.8 support SBAS/BeiDou SSR messages (ref [16])
* 2015/03/22 1.9 add handling of iodcrc for beidou/sbas ssr messages
* 2015/04/27 1.10 support phase bias messages (MT2065-2070)
* 2015/09/07 1.11 add message count of MT 2000-2099
* 2015/10/21 1.12 add MT1046 support for IGS MGEX
* fix bug on decode of SSR 3/7 (code/phase bias)
* 2015/12/04 1.13 add MT63 beidou ephemeris (rtcm draft)
* fix bug on ssr 3 message decoding (#321)
* 2016/01/22 1.14 fix bug on L2C code in MT1004 (#131)
* 2016/08/20 1.15 fix bug on loss-of-lock detection in MSM 6/7 (#134)
* 2016/09/20 1.16 fix bug on MT1045 Galileo week rollover
* 2016/10/09 1.17 support MT1029 unicode text string
* 2017/04/11 1.18 fix bug on unchange-test of beidou ephemeris
* fix bug on week number in galileo ephemeris struct
* 2018/10/10 1.19 merge changes for 2.4.2 p13
* fix problem on eph.code for galileo ephemeris
* change mt for ssr 7 phase biases
* add rtcm option -GALINAV, -GALFNAV
* 2018/11/05 1.20 fix problem on invalid time in message monitor
* 2019/05/10 1.21 save galileo E5b data to obs index 2
* 2020/11/30 1.22 support MT1230 GLONASS code-phase biases
* support MT1131-1137,1041 (NavIC MSM and ephemeris)
* support MT4076 IGS SSR
* update MSM signal ID table (ref [17])
* update SSR signal and tracking mode ID table
* add week adjustment in MT1019,1044,1045,1046,1042
* use API code2idx() to get freq-index
* use API code2freq() to get carrier frequency
* use integer types in stdint.h
*-----------------------------------------------------------------------------*/
#include "rtklib.h"
/* constants -----------------------------------------------------------------*/
#define PRUNIT_GPS 299792.458 /* rtcm ver.3 unit of gps pseudorange (m) */
#define PRUNIT_GLO 599584.916 /* rtcm ver.3 unit of glonass pseudorange (m) */
#define RANGE_MS (CLIGHT*0.001) /* range in 1 ms */
#define P2_10 0.0009765625 /* 2^-10 */
#define P2_28 3.725290298461914E-09 /* 2^-28 */
#define P2_34 5.820766091346740E-11 /* 2^-34 */
#define P2_41 4.547473508864641E-13 /* 2^-41 */
#define P2_46 1.421085471520200E-14 /* 2^-46 */
#define P2_59 1.734723475976810E-18 /* 2^-59 */
#define P2_66 1.355252715606880E-20 /* 2^-66 */
/* type definition -----------------------------------------------------------*/
typedef struct { /* multi-signal-message header type */
uint8_t iod; /* issue of data station */
uint8_t time_s; /* cumulative session transmitting time */
uint8_t clk_str; /* clock steering indicator */
uint8_t clk_ext; /* external clock indicator */
uint8_t smooth; /* divergence free smoothing indicator */
uint8_t tint_s; /* soothing interval */
uint8_t nsat,nsig; /* number of satellites/signals */
uint8_t sats[64]; /* satellites */
uint8_t sigs[32]; /* signals */
uint8_t cellmask[64]; /* cell mask */
} msm_h_t;
/* MSM signal ID table -------------------------------------------------------*/
const char *msm_sig_gps[32]={
/* GPS: ref [17] table 3.5-91 */
"" ,"1C","1P","1W","" ,"" ,"" ,"2C","2P","2W","" ,"" , /* 1-12 */
"" ,"" ,"2S","2L","2X","" ,"" ,"" ,"" ,"5I","5Q","5X", /* 13-24 */
"" ,"" ,"" ,"" ,"" ,"1S","1L","1X" /* 25-32 */
};
const char *msm_sig_glo[32]={
/* GLONASS: ref [17] table 3.5-96 */
"" ,"1C","1P","" ,"" ,"" ,"" ,"2C","2P","" ,"" ,"" ,
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,
"" ,"" ,"" ,"" ,"" ,"" ,"" ,""
};
const char *msm_sig_gal[32]={
/* Galileo: ref [17] table 3.5-99 */
"" ,"1C","1A","1B","1X","1Z","" ,"6C","6A","6B","6X","6Z",
"" ,"7I","7Q","7X","" ,"8I","8Q","8X","" ,"5I","5Q","5X",
"" ,"" ,"" ,"" ,"" ,"" ,"" ,""
};
const char *msm_sig_qzs[32]={
/* QZSS: ref [17] table 3.5-105 */
"" ,"1C","" ,"" ,"" ,"" ,"" ,"" ,"6S","6L","6X","" ,
"" ,"" ,"2S","2L","2X","" ,"" ,"" ,"" ,"5I","5Q","5X",
"" ,"" ,"" ,"" ,"" ,"1S","1L","1X"
};
const char *msm_sig_sbs[32]={
/* SBAS: ref [17] table 3.5-102 */
"" ,"1C","" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"5I","5Q","5X",
"" ,"" ,"" ,"" ,"" ,"" ,"" ,""
};
const char *msm_sig_cmp[32]={
/* BeiDou: ref [17] table 3.5-108 */
"" ,"2I","2Q","2X","","","" ,"6I","6Q","6X","" ,"" ,
"" ,"7I","7Q","7X","" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,
"" ,"" ,"" ,"" ,"" ,"" ,"" ,""
};
const char *msm_sig_irn[32]={
/* NavIC/IRNSS: ref [17] table 3.5-108.3 */
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"5A","" ,"" ,
"" ,"" ,"" ,"" ,"" ,"" ,"" ,""
};
/* SSR signal and tracking mode IDs ------------------------------------------*/
const uint8_t ssr_sig_gps[32]={
CODE_L1C,CODE_L1P,CODE_L1W,CODE_L1S,CODE_L1L,CODE_L2C,CODE_L2D,CODE_L2S,
CODE_L2L,CODE_L2X,CODE_L2P,CODE_L2W, 0, 0,CODE_L5I,CODE_L5Q
};
const uint8_t ssr_sig_glo[32]={
CODE_L1C,CODE_L1P,CODE_L2C,CODE_L2P,CODE_L4A,CODE_L4B,CODE_L6A,CODE_L6B,
CODE_L3I,CODE_L3Q
};
const uint8_t ssr_sig_gal[32]={
CODE_L1A,CODE_L1B,CODE_L1C, 0, 0,CODE_L5I,CODE_L5Q, 0,
CODE_L7I,CODE_L7Q, 0,CODE_L8I,CODE_L8Q, 0,CODE_L6A,CODE_L6B,
CODE_L6C
};
const uint8_t ssr_sig_qzs[32]={
CODE_L1C,CODE_L1S,CODE_L1L,CODE_L2S,CODE_L2L, 0,CODE_L5I,CODE_L5Q,
0,CODE_L6S,CODE_L6L, 0, 0, 0, 0, 0,
0,CODE_L6E
};
const uint8_t ssr_sig_cmp[32]={
CODE_L2I,CODE_L2Q, 0,CODE_L6I,CODE_L6Q, 0,CODE_L7I,CODE_L7Q,
0,CODE_L1D,CODE_L1P, 0,CODE_L5D,CODE_L5P, 0,CODE_L1A,
0, 0,CODE_L6A
};
const uint8_t ssr_sig_sbs[32]={
CODE_L1C,CODE_L5I,CODE_L5Q
};
/* SSR update intervals ------------------------------------------------------*/
static const double ssrudint[16]={
1,2,5,10,15,30,60,120,240,300,600,900,1800,3600,7200,10800
};
/* get sign-magnitude bits ---------------------------------------------------*/
static double getbitg(const uint8_t *buff, int pos, int len)
{
double value=getbitu(buff,pos+1,len-1);
return getbitu(buff,pos,1)?-value:value;
}
/* adjust weekly rollover of GPS time ----------------------------------------*/
static void adjweek(rtcm_t *rtcm, double tow)
{
double tow_p;
int week;
/* if no time, get cpu time */
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tow_p=time2gpst(rtcm->time,&week);
if (tow<tow_p-302400.0) tow+=604800.0;
else if (tow>tow_p+302400.0) tow-=604800.0;
rtcm->time=gpst2time(week,tow);
}
/* adjust weekly rollover of BDS time ----------------------------------------*/
static int adjbdtweek(int week)
{
int w;
(void)time2bdt(gpst2bdt(utc2gpst(timeget())),&w);
if (w<1) w=1; /* use 2006/1/1 if time is earlier than 2006/1/1 */
return week+(w-week+512)/1024*1024;
}
/* adjust daily rollover of GLONASS time -------------------------------------*/
static void adjday_glot(rtcm_t *rtcm, double tod)
{
gtime_t time;
double tow,tod_p;
int week;
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
time=timeadd(gpst2utc(rtcm->time),10800.0); /* glonass time */
tow=time2gpst(time,&week);
tod_p=fmod(tow,86400.0); tow-=tod_p;
if (tod<tod_p-43200.0) tod+=86400.0;
else if (tod>tod_p+43200.0) tod-=86400.0;
time=gpst2time(week,tow+tod);
rtcm->time=utc2gpst(timeadd(time,-10800.0));
}
/* adjust carrier-phase rollover ---------------------------------------------*/
static double adjcp(rtcm_t *rtcm, int sat, int idx, double cp)
{
if (rtcm->cp[sat-1][idx]==0.0) ;
else if (cp<rtcm->cp[sat-1][idx]-750.0) cp+=1500.0;
else if (cp>rtcm->cp[sat-1][idx]+750.0) cp-=1500.0;
rtcm->cp[sat-1][idx]=cp;
return cp;
}
/* loss-of-lock indicator ----------------------------------------------------*/
static int lossoflock(rtcm_t *rtcm, int sat, int idx, int lock)
{
int lli=(!lock&&!rtcm->lock[sat-1][idx])||lock<rtcm->lock[sat-1][idx];
rtcm->lock[sat-1][idx]=(uint16_t)lock;
return lli;
}
/* S/N ratio -----------------------------------------------------------------*/
static uint16_t snratio(double snr)
{
return (uint16_t)(snr<=0.0||100.0<=snr?0.0:snr/SNR_UNIT+0.5);
}
/* get observation data index ------------------------------------------------*/
static int obsindex(obs_t *obs, gtime_t time, int sat)
{
int i,j;
for (i=0;i<obs->n;i++) {
if (obs->data[i].sat==sat) return i; /* field already exists */
}
if (i>=MAXOBS) return -1; /* overflow */
/* add new field */
obs->data[i].time=time;
obs->data[i].sat=sat;
for (j=0;j<NFREQ+NEXOBS;j++) {
obs->data[i].L[j]=obs->data[i].P[j]=0.0;
obs->data[i].D[j]=0.0;
obs->data[i].SNR[j]=obs->data[i].LLI[j]=obs->data[i].code[j]=0;
}
obs->n++;
return i;
}
/* test station ID consistency -----------------------------------------------*/
static int test_staid(rtcm_t *rtcm, int staid)
{
char *p;
int type,id;
/* test station id option */
if ((p=strstr(rtcm->opt,"-STA="))&&sscanf(p,"-STA=%d",&id)==1) {
if (staid!=id) return 0;
}
/* save station id */
if (rtcm->staid==0||rtcm->obsflag) {
rtcm->staid=staid;
}
else if (staid!=rtcm->staid) {
type=getbitu(rtcm->buff,24,12);
trace(2,"rtcm3 %d staid invalid id=%d %d\n",type,staid,rtcm->staid);
/* reset station id if station id error */
rtcm->staid=0;
return 0;
}
return 1;
}
/* decode type 1001-1004 message header --------------------------------------*/
static int decode_head1001(rtcm_t *rtcm, int *sync)
{
double tow;
char *msg,tstr[64];
int i=24,staid,nsat,type;
type=getbitu(rtcm->buff,i,12); i+=12;
if (i+52<=rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12;
tow =getbitu(rtcm->buff,i,30)*0.001; i+=30;
*sync=getbitu(rtcm->buff,i, 1); i+= 1;
nsat =getbitu(rtcm->buff,i, 5);
}
else {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
/* test station ID */
if (!test_staid(rtcm,staid)) return -1;
adjweek(rtcm,tow);
time2str(rtcm->time,tstr,2);
trace(4,"decode_head1001: time=%s nsat=%d sync=%d\n",tstr,nsat,*sync);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," staid=%4d %s nsat=%2d sync=%d",staid,tstr,nsat,*sync);
}
return nsat;
}
/* decode type 1001: L1-only GPS RTK observation -----------------------------*/
static int decode_type1001(rtcm_t *rtcm)
{
int sync;
if (decode_head1001(rtcm,&sync)<0) return -1;
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode type 1002: extended L1-only GPS RTK observables --------------------*/
static int decode_type1002(rtcm_t *rtcm)
{
double pr1,cnr1,tt,cp1,freq=FREQL1;
int i=24+64,j,index,nsat,sync,prn,code,sat,ppr1,lock1,amb,sys;
if ((nsat=decode_head1001(rtcm,&sync))<0) return -1;
for (j=0;j<nsat&&rtcm->obs.n<MAXOBS&&i+74<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
code =getbitu(rtcm->buff,i, 1); i+= 1;
pr1 =getbitu(rtcm->buff,i,24); i+=24;
ppr1 =getbits(rtcm->buff,i,20); i+=20;
lock1=getbitu(rtcm->buff,i, 7); i+= 7;
amb =getbitu(rtcm->buff,i, 8); i+= 8;
cnr1 =getbitu(rtcm->buff,i, 8); i+= 8;
if (prn<40) {
sys=SYS_GPS;
}
else {
sys=SYS_SBS; prn+=80;
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1002 satellite number error: prn=%d\n",prn);
continue;
}
tt=timediff(rtcm->obs.data[0].time,rtcm->time);
if (rtcm->obsflag||fabs(tt)>1E-9) {
rtcm->obs.n=rtcm->obsflag=0;
}
if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue;
pr1=pr1*0.02+amb*PRUNIT_GPS;
rtcm->obs.data[index].P[0]=pr1;
if (ppr1!=(int)0xFFF80000) {
cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq/CLIGHT);
rtcm->obs.data[index].L[0]=pr1*freq/CLIGHT+cp1;
}
rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1);
rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25);
rtcm->obs.data[index].code[0]=code?CODE_L1P:CODE_L1C;
}
return sync?0:1;
}
/* decode type 1003: L1&L2 gps rtk observables -------------------------------*/
static int decode_type1003(rtcm_t *rtcm)
{
int sync;
if (decode_head1001(rtcm,&sync)<0) return -1;
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode type 1004: extended L1&L2 GPS RTK observables ----------------------*/
static int decode_type1004(rtcm_t *rtcm)
{
const int L2codes[]={CODE_L2X,CODE_L2P,CODE_L2D,CODE_L2W};
double pr1,cnr1,cnr2,tt,cp1,cp2,freq[2]={FREQL1,FREQL2};
int i=24+64,j,index,nsat,sync,prn,sat,code1,code2,pr21,ppr1,ppr2;
int lock1,lock2,amb,sys;
if ((nsat=decode_head1001(rtcm,&sync))<0) return -1;
for (j=0;j<nsat&&rtcm->obs.n<MAXOBS&&i+125<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
code1=getbitu(rtcm->buff,i, 1); i+= 1;
pr1 =getbitu(rtcm->buff,i,24); i+=24;
ppr1 =getbits(rtcm->buff,i,20); i+=20;
lock1=getbitu(rtcm->buff,i, 7); i+= 7;
amb =getbitu(rtcm->buff,i, 8); i+= 8;
cnr1 =getbitu(rtcm->buff,i, 8); i+= 8;
code2=getbitu(rtcm->buff,i, 2); i+= 2;
pr21 =getbits(rtcm->buff,i,14); i+=14;
ppr2 =getbits(rtcm->buff,i,20); i+=20;
lock2=getbitu(rtcm->buff,i, 7); i+= 7;
cnr2 =getbitu(rtcm->buff,i, 8); i+= 8;
if (prn<40) {
sys=SYS_GPS;
}
else {
sys=SYS_SBS; prn+=80;
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1004 satellite number error: sys=%d prn=%d\n",sys,prn);
continue;
}
tt=timediff(rtcm->obs.data[0].time,rtcm->time);
if (rtcm->obsflag||fabs(tt)>1E-9) {
rtcm->obs.n=rtcm->obsflag=0;
}
if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue;
pr1=pr1*0.02+amb*PRUNIT_GPS;
rtcm->obs.data[index].P[0]=pr1;
if (ppr1!=(int)0xFFF80000) {
cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq[0]/CLIGHT);
rtcm->obs.data[index].L[0]=pr1*freq[0]/CLIGHT+cp1;
}
rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1);
rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25);
rtcm->obs.data[index].code[0]=code1?CODE_L1P:CODE_L1C;
if (pr21!=(int)0xFFFFE000) {
rtcm->obs.data[index].P[1]=pr1+pr21*0.02;
}
if (ppr2!=(int)0xFFF80000) {
cp2=adjcp(rtcm,sat,1,ppr2*0.0005*freq[1]/CLIGHT);
rtcm->obs.data[index].L[1]=pr1*freq[1]/CLIGHT+cp2;
}
rtcm->obs.data[index].LLI[1]=lossoflock(rtcm,sat,1,lock2);
rtcm->obs.data[index].SNR[1]=snratio(cnr2*0.25);
rtcm->obs.data[index].code[1]=L2codes[code2];
}
rtcm->obsflag=!sync;
return sync?0:1;
}
/* get signed 38bit field ----------------------------------------------------*/
static double getbits_38(const uint8_t *buff, int pos)
{
return (double)getbits(buff,pos,32)*64.0+getbitu(buff,pos+32,6);
}
/* decode type 1005: stationary RTK reference station ARP --------------------*/
static int decode_type1005(rtcm_t *rtcm)
{
double rr[3],re[3],pos[3];
char *msg;
int i=24+12,j,staid,itrf;
if (i+140==rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12;
itrf =getbitu(rtcm->buff,i, 6); i+= 6+4;
rr[0]=getbits_38(rtcm->buff,i); i+=38+2;
rr[1]=getbits_38(rtcm->buff,i); i+=38+2;
rr[2]=getbits_38(rtcm->buff,i);
}
else {
trace(2,"rtcm3 1005 length error: len=%d\n",rtcm->len);
return -1;
}
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
for (j=0;j<3;j++) re[j]=rr[j]*0.0001;
ecef2pos(re,pos);
sprintf(msg," staid=%4d pos=%.8f %.8f %.3f",staid,pos[0]*R2D,pos[1]*R2D,
pos[2]);
}
/* test station id */
if (!test_staid(rtcm,staid)) return -1;
sprintf(rtcm->sta.name,"%04d",staid);
rtcm->sta.deltype=0; /* xyz */
for (j=0;j<3;j++) {
rtcm->sta.pos[j]=rr[j]*0.0001;
rtcm->sta.del[j]=0.0;
}
rtcm->sta.hgt=0.0;
rtcm->sta.itrf=itrf;
return 5;
}
/* decode type 1006: stationary RTK reference station ARP with height --------*/
static int decode_type1006(rtcm_t *rtcm)
{
double rr[3],re[3],pos[3],anth;
char *msg;
int i=24+12,j,staid,itrf;
if (i+156<=rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12;
itrf =getbitu(rtcm->buff,i, 6); i+= 6+4;
rr[0]=getbits_38(rtcm->buff,i); i+=38+2;
rr[1]=getbits_38(rtcm->buff,i); i+=38+2;
rr[2]=getbits_38(rtcm->buff,i); i+=38;
anth =getbitu(rtcm->buff,i,16);
}
else {
trace(2,"rtcm3 1006 length error: len=%d\n",rtcm->len);
return -1;
}
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
for (j=0;j<3;j++) re[j]=rr[j]*0.0001;
ecef2pos(re,pos);
sprintf(msg," staid=%4d pos=%.8f %.8f %.3f anth=%.3f",staid,pos[0]*R2D,
pos[1]*R2D,pos[2],anth*0.0001);
}
/* test station id */
if (!test_staid(rtcm,staid)) return -1;
sprintf(rtcm->sta.name,"%04d",staid);
rtcm->sta.deltype=1; /* xyz */
for (j=0;j<3;j++) {
rtcm->sta.pos[j]=rr[j]*0.0001;
rtcm->sta.del[j]=0.0;
}
rtcm->sta.hgt=anth*0.0001;
rtcm->sta.itrf=itrf;
return 5;
}
/* decode type 1007: antenna descriptor --------------------------------------*/
static int decode_type1007(rtcm_t *rtcm)
{
char des[32]="";
char *msg;
int i=24+12,j,staid,n,setup;
n=getbitu(rtcm->buff,i+12,8);
if (i+28+8*n<=rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12+8;
for (j=0;j<n&&j<31;j++) {
des[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
setup=getbitu(rtcm->buff,i, 8);
}
else {
trace(2,"rtcm3 1007 length error: len=%d\n",rtcm->len);
return -1;
}
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," staid=%4d",staid);
}
/* test station ID */
if (!test_staid(rtcm,staid)) return -1;
sprintf(rtcm->sta.name,"%04d",staid);
strncpy(rtcm->sta.antdes,des,n); rtcm->sta.antdes[n]='\0';
rtcm->sta.antsetup=setup;
rtcm->sta.antsno[0]='\0';
return 5;
}
/* decode type 1008: antenna descriptor & serial number ----------------------*/
static int decode_type1008(rtcm_t *rtcm)
{
char des[32]="",sno[32]="";
char *msg;
int i=24+12,j,staid,n,m,setup;
n=getbitu(rtcm->buff,i+12,8);
m=getbitu(rtcm->buff,i+28+8*n,8);
if (i+36+8*(n+m)<=rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12+8;
for (j=0;j<n&&j<31;j++) {
des[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
setup=getbitu(rtcm->buff,i, 8); i+=8+8;
for (j=0;j<m&&j<31;j++) {
sno[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
}
else {
trace(2,"rtcm3 1008 length error: len=%d\n",rtcm->len);
return -1;
}
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," staid=%4d",staid);
}
/* test station ID */
if (!test_staid(rtcm,staid)) return -1;
sprintf(rtcm->sta.name,"%04d",staid);
strncpy(rtcm->sta.antdes,des,n); rtcm->sta.antdes[n]='\0';
rtcm->sta.antsetup=setup;
strncpy(rtcm->sta.antsno,sno,m); rtcm->sta.antsno[m]='\0';
return 5;
}
/* decode type 1009-1012 message header --------------------------------------*/
static int decode_head1009(rtcm_t *rtcm, int *sync)
{
double tod;
char *msg,tstr[64];
int i=24,staid,nsat,type;
type=getbitu(rtcm->buff,i,12); i+=12;
if (i+49<=rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12;
tod =getbitu(rtcm->buff,i,27)*0.001; i+=27; /* sec in a day */
*sync=getbitu(rtcm->buff,i, 1); i+= 1;
nsat =getbitu(rtcm->buff,i, 5);
}
else {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
/* test station ID */
if (!test_staid(rtcm,staid)) return -1;
adjday_glot(rtcm,tod);
time2str(rtcm->time,tstr,2);
trace(4,"decode_head1009: time=%s nsat=%d sync=%d\n",tstr,nsat,*sync);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," staid=%4d %s nsat=%2d sync=%d",staid,tstr,nsat,*sync);
}
return nsat;
}
/* decode type 1009: L1-only glonass rtk observables -------------------------*/
static int decode_type1009(rtcm_t *rtcm)
{
int sync;
if (decode_head1009(rtcm,&sync)<0) return -1;
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode type 1010: extended L1-only glonass rtk observables ----------------*/
static int decode_type1010(rtcm_t *rtcm)
{
double pr1,cnr1,tt,cp1,freq1;
int i=24+61,j,index,nsat,sync,prn,sat,code,fcn,ppr1,lock1,amb,sys=SYS_GLO;
if ((nsat=decode_head1009(rtcm,&sync))<0) return -1;
for (j=0;j<nsat&&rtcm->obs.n<MAXOBS&&i+79<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
code =getbitu(rtcm->buff,i, 1); i+= 1;
fcn =getbitu(rtcm->buff,i, 5); i+= 5; /* fcn+7 */
pr1 =getbitu(rtcm->buff,i,25); i+=25;
ppr1 =getbits(rtcm->buff,i,20); i+=20;
lock1=getbitu(rtcm->buff,i, 7); i+= 7;
amb =getbitu(rtcm->buff,i, 7); i+= 7;
cnr1 =getbitu(rtcm->buff,i, 8); i+= 8;
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1010 satellite number error: prn=%d\n",prn);
continue;
}
if (!rtcm->nav.glo_fcn[prn-1]) {
rtcm->nav.glo_fcn[prn-1]=fcn-7+8; /* fcn+8 */
}
tt=timediff(rtcm->obs.data[0].time,rtcm->time);
if (rtcm->obsflag||fabs(tt)>1E-9) {
rtcm->obs.n=rtcm->obsflag=0;
}
if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue;
pr1=pr1*0.02+amb*PRUNIT_GLO;
rtcm->obs.data[index].P[0]=pr1;
if (ppr1!=(int)0xFFF80000) {
freq1=code2freq(SYS_GLO,CODE_L1C,fcn-7);
cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq1/CLIGHT);
rtcm->obs.data[index].L[0]=pr1*freq1/CLIGHT+cp1;
}
rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1);
rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25);
rtcm->obs.data[index].code[0]=code?CODE_L1P:CODE_L1C;
}
return sync?0:1;
}
/* decode type 1011: L1&L2 GLONASS RTK observables ---------------------------*/
static int decode_type1011(rtcm_t *rtcm)
{
int sync;
if (decode_head1009(rtcm,&sync)<0) return -1;
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode type 1012: extended L1&L2 GLONASS RTK observables ------------------*/
static int decode_type1012(rtcm_t *rtcm)
{
double pr1,cnr1,cnr2,tt,cp1,cp2,freq1,freq2;
int i=24+61,j,index,nsat,sync,prn,sat,fcn,code1,code2,pr21,ppr1,ppr2;
int lock1,lock2,amb,sys=SYS_GLO;
if ((nsat=decode_head1009(rtcm,&sync))<0) return -1;
for (j=0;j<nsat&&rtcm->obs.n<MAXOBS&&i+130<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
code1=getbitu(rtcm->buff,i, 1); i+= 1;
fcn =getbitu(rtcm->buff,i, 5); i+= 5; /* fcn+7 */
pr1 =getbitu(rtcm->buff,i,25); i+=25;
ppr1 =getbits(rtcm->buff,i,20); i+=20;
lock1=getbitu(rtcm->buff,i, 7); i+= 7;
amb =getbitu(rtcm->buff,i, 7); i+= 7;
cnr1 =getbitu(rtcm->buff,i, 8); i+= 8;
code2=getbitu(rtcm->buff,i, 2); i+= 2;
pr21 =getbits(rtcm->buff,i,14); i+=14;
ppr2 =getbits(rtcm->buff,i,20); i+=20;
lock2=getbitu(rtcm->buff,i, 7); i+= 7;
cnr2 =getbitu(rtcm->buff,i, 8); i+= 8;
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1012 satellite number error: sys=%d prn=%d\n",sys,prn);
continue;
}
if (!rtcm->nav.glo_fcn[prn-1]) {
rtcm->nav.glo_fcn[prn-1]=fcn-7+8; /* fcn+8 */
}
tt=timediff(rtcm->obs.data[0].time,rtcm->time);
if (rtcm->obsflag||fabs(tt)>1E-9) {
rtcm->obs.n=rtcm->obsflag=0;
}
if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue;
pr1=pr1*0.02+amb*PRUNIT_GLO;
rtcm->obs.data[index].P[0]=pr1;
if (ppr1!=(int)0xFFF80000) {
freq1=code2freq(SYS_GLO,CODE_L1C,fcn-7);
cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq1/CLIGHT);
rtcm->obs.data[index].L[0]=pr1*freq1/CLIGHT+cp1;
}
rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1);
rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25);
rtcm->obs.data[index].code[0]=code1?CODE_L1P:CODE_L1C;
if (pr21!=(int)0xFFFFE000) {
rtcm->obs.data[index].P[1]=pr1+pr21*0.02;
}
if (ppr2!=(int)0xFFF80000) {
freq2=code2freq(SYS_GLO,CODE_L2C,fcn-7);
cp2=adjcp(rtcm,sat,1,ppr2*0.0005*freq2/CLIGHT);
rtcm->obs.data[index].L[1]=pr1*freq2/CLIGHT+cp2;
}
rtcm->obs.data[index].LLI[1]=lossoflock(rtcm,sat,1,lock2);
rtcm->obs.data[index].SNR[1]=snratio(cnr2*0.25);
rtcm->obs.data[index].code[1]=code2?CODE_L2P:CODE_L2C;
}
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode type 1013: system parameters ---------------------------------------*/
static int decode_type1013(rtcm_t *rtcm)
{
return 0;
}
/* decode type 1019: GPS ephemerides -----------------------------------------*/
static int decode_type1019(rtcm_t *rtcm)
{
eph_t eph={0};
double toc,sqrtA,tt;
char *msg;
int i=24+12,prn,sat,week,sys=SYS_GPS;
if (i+476<=rtcm->len*8) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
week =getbitu(rtcm->buff,i,10); i+=10;
eph.sva =getbitu(rtcm->buff,i, 4); i+= 4;
eph.code =getbitu(rtcm->buff,i, 2); i+= 2;
eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14;
eph.iode =getbitu(rtcm->buff,i, 8); i+= 8;
toc =getbitu(rtcm->buff,i,16)*16.0; i+=16;
eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8;
eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16;
eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22;
eph.iodc =getbitu(rtcm->buff,i,10); i+=10;
eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16;
eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32;
eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16;
sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32;
eph.toes =getbitu(rtcm->buff,i,16)*16.0; i+=16;
eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24;
eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8;
eph.svh =getbitu(rtcm->buff,i, 6); i+= 6;
eph.flag =getbitu(rtcm->buff,i, 1); i+= 1;
eph.fit =getbitu(rtcm->buff,i, 1)?0.0:4.0; /* 0:4hr,1:>4hr */
}
else {
trace(2,"rtcm3 1019 length error: len=%d\n",rtcm->len);
return -1;
}
if (prn>=40) {
sys=SYS_SBS; prn+=80;
}
trace(4,"decode_type1019: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X",
prn,eph.iode,eph.iodc,week,eph.toes,toc,eph.svh);
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1019 satellite number error: prn=%d\n",prn);
return -1;
}
eph.sat=sat;
eph.week=adjgpsweek(week);
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time);
if (tt<-302400.0) eph.week++;
else if (tt>=302400.0) eph.week--;
eph.toe=gpst2time(eph.week,eph.toes);
eph.toc=gpst2time(eph.week,toc);
eph.ttr=rtcm->time;
eph.A=sqrtA*sqrtA;
if (!strstr(rtcm->opt,"-EPHALL")) {
if (eph.iode==rtcm->nav.eph[sat-1].iode) return 0; /* unchanged */
}
rtcm->nav.eph[sat-1]=eph;
rtcm->ephsat=sat;
rtcm->ephset=0;
return 2;
}
/* decode type 1020: GLONASS ephemerides -------------------------------------*/
static int decode_type1020(rtcm_t *rtcm)
{
geph_t geph={0};
double tk_h,tk_m,tk_s,toe,tow,tod,tof;
char *msg;
int i=24+12,prn,sat,week,tb,bn,sys=SYS_GLO;
if (i+348<=rtcm->len*8) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
geph.frq =getbitu(rtcm->buff,i, 5)-7; i+= 5+2+2;
tk_h =getbitu(rtcm->buff,i, 5); i+= 5;
tk_m =getbitu(rtcm->buff,i, 6); i+= 6;
tk_s =getbitu(rtcm->buff,i, 1)*30.0; i+= 1;
bn =getbitu(rtcm->buff,i, 1); i+= 1+1;
tb =getbitu(rtcm->buff,i, 7); i+= 7;
geph.vel[0]=getbitg(rtcm->buff,i,24)*P2_20*1E3; i+=24;
geph.pos[0]=getbitg(rtcm->buff,i,27)*P2_11*1E3; i+=27;
geph.acc[0]=getbitg(rtcm->buff,i, 5)*P2_30*1E3; i+= 5;
geph.vel[1]=getbitg(rtcm->buff,i,24)*P2_20*1E3; i+=24;
geph.pos[1]=getbitg(rtcm->buff,i,27)*P2_11*1E3; i+=27;
geph.acc[1]=getbitg(rtcm->buff,i, 5)*P2_30*1E3; i+= 5;
geph.vel[2]=getbitg(rtcm->buff,i,24)*P2_20*1E3; i+=24;
geph.pos[2]=getbitg(rtcm->buff,i,27)*P2_11*1E3; i+=27;
geph.acc[2]=getbitg(rtcm->buff,i, 5)*P2_30*1E3; i+= 5+1;
geph.gamn =getbitg(rtcm->buff,i,11)*P2_40; i+=11+3;
geph.taun =getbitg(rtcm->buff,i,22)*P2_30; i+=22;
geph.dtaun =getbitg(rtcm->buff,i, 5)*P2_30; i+=5;
geph.age =getbitu(rtcm->buff,i, 5);
}
else {
trace(2,"rtcm3 1020 length error: len=%d\n",rtcm->len);
return -1;
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1020 satellite number error: prn=%d\n",prn);
return -1;
}
trace(4,"decode_type1020: prn=%d tk=%02.0f:%02.0f:%02.0f\n",prn,tk_h,tk_m,tk_s);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," prn=%2d tk=%02.0f:%02.0f:%02.0f frq=%2d bn=%d tb=%d",
prn,tk_h,tk_m,tk_s,geph.frq,bn,tb);
}
geph.sat=sat;
geph.svh=bn;
geph.iode=tb&0x7F;
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tow=time2gpst(gpst2utc(rtcm->time),&week);
tod=fmod(tow,86400.0); tow-=tod;
tof=tk_h*3600.0+tk_m*60.0+tk_s-10800.0; /* lt->utc */
if (tof<tod-43200.0) tof+=86400.0;
else if (tof>tod+43200.0) tof-=86400.0;
geph.tof=utc2gpst(gpst2time(week,tow+tof));
toe=tb*900.0-10800.0; /* lt->utc */
if (toe<tod-43200.0) toe+=86400.0;
else if (toe>tod+43200.0) toe-=86400.0;
geph.toe=utc2gpst(gpst2time(week,tow+toe)); /* utc->gpst */
if (!strstr(rtcm->opt,"-EPHALL")) {
if (fabs(timediff(geph.toe,rtcm->nav.geph[prn-1].toe))<1.0&&
geph.svh==rtcm->nav.geph[prn-1].svh) return 0; /* unchanged */
}
rtcm->nav.geph[prn-1]=geph;
rtcm->ephsat=sat;
rtcm->ephset=0;
return 2;
}
/* decode type 1021: helmert/abridged molodenski -----------------------------*/
static int decode_type1021(rtcm_t *rtcm)
{
trace(2,"rtcm3 1021: not supported message\n");
return 0;
}
/* decode type 1022: Moledenski-Badekas transfromation -----------------------*/
static int decode_type1022(rtcm_t *rtcm)
{
trace(2,"rtcm3 1022: not supported message\n");
return 0;
}
/* decode type 1023: residual, ellipsoidal grid representation ---------------*/
static int decode_type1023(rtcm_t *rtcm)
{
trace(2,"rtcm3 1023: not supported message\n");
return 0;
}
/* decode type 1024: residual, plane grid representation ---------------------*/
static int decode_type1024(rtcm_t *rtcm)
{
trace(2,"rtcm3 1024: not supported message\n");
return 0;
}
/* decode type 1025: projection (types except LCC2SP,OM) ---------------------*/
static int decode_type1025(rtcm_t *rtcm)
{
trace(2,"rtcm3 1025: not supported message\n");
return 0;
}
/* decode type 1026: projection (LCC2SP - lambert conic conformal (2sp)) -----*/
static int decode_type1026(rtcm_t *rtcm)
{
trace(2,"rtcm3 1026: not supported message\n");
return 0;
}
/* decode type 1027: projection (type OM - oblique mercator) -----------------*/
static int decode_type1027(rtcm_t *rtcm)
{
trace(2,"rtcm3 1027: not supported message\n");
return 0;
}
/* decode type 1029: UNICODE text string -------------------------------------*/
static int decode_type1029(rtcm_t *rtcm)
{
char *msg;
int i=24+12,j,staid,mjd,tod,nchar,cunit;
if (i+60<=rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12;
mjd =getbitu(rtcm->buff,i,16); i+=16;
tod =getbitu(rtcm->buff,i,17); i+=17;
nchar=getbitu(rtcm->buff,i, 7); i+= 7;
cunit=getbitu(rtcm->buff,i, 8); i+= 8;
}
else {
trace(2,"rtcm3 1029 length error: len=%d\n",rtcm->len);
return -1;
}
if (i+nchar*8>rtcm->len*8) {
trace(2,"rtcm3 1029 length error: len=%d nchar=%d\n",rtcm->len,nchar);
return -1;
}
for (j=0;j<nchar&&j<126;j++) {
rtcm->msg[j]=getbitu(rtcm->buff,i,8); i+=8;
}
rtcm->msg[j]='\0';
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," staid=%4d text=%s",staid,rtcm->msg);
}
return 0;
}
/* decode type 1030: network RTK residual ------------------------------------*/
static int decode_type1030(rtcm_t *rtcm)
{
trace(2,"rtcm3 1030: not supported message\n");
return 0;
}
/* decode type 1031: GLONASS network RTK residual ----------------------------*/
static int decode_type1031(rtcm_t *rtcm)
{
trace(2,"rtcm3 1031: not supported message\n");
return 0;
}
/* decode type 1032: physical reference station position information ---------*/
static int decode_type1032(rtcm_t *rtcm)
{
trace(2,"rtcm3 1032: not supported message\n");
return 0;
}
/* decode type 1033: receiver and antenna descriptor -------------------------*/
static int decode_type1033(rtcm_t *rtcm)
{
char des[32]="",sno[32]="",rec[32]="",ver[32]="",rsn[32]="";
char *msg;
int i=24+12,j,staid,n,m,n1,n2,n3,setup;
n =getbitu(rtcm->buff,i+12,8);
m =getbitu(rtcm->buff,i+28+8*n,8);
n1=getbitu(rtcm->buff,i+36+8*(n+m),8);
n2=getbitu(rtcm->buff,i+44+8*(n+m+n1),8);
n3=getbitu(rtcm->buff,i+52+8*(n+m+n1+n2),8);
if (i+60+8*(n+m+n1+n2+n3)<=rtcm->len*8) {
staid=getbitu(rtcm->buff,i,12); i+=12+8;
for (j=0;j<n&&j<31;j++) {
des[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
setup=getbitu(rtcm->buff,i, 8); i+=8+8;
for (j=0;j<m&&j<31;j++) {
sno[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
i+=8;
for (j=0;j<n1&&j<31;j++) {
rec[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
i+=8;
for (j=0;j<n2&&j<31;j++) {
ver[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
i+=8;
for (j=0;j<n3&&j<31;j++) {
rsn[j]=(char)getbitu(rtcm->buff,i,8); i+=8;
}
}
else {
trace(2,"rtcm3 1033 length error: len=%d\n",rtcm->len);
return -1;
}
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," staid=%4d",staid);
}
/* test station id */
if (!test_staid(rtcm,staid)) return -1;
sprintf(rtcm->sta.name,"%04d",staid);
strncpy(rtcm->sta.antdes, des,n ); rtcm->sta.antdes [n] ='\0';
rtcm->sta.antsetup=setup;
strncpy(rtcm->sta.antsno, sno,m ); rtcm->sta.antsno [m] ='\0';
strncpy(rtcm->sta.rectype,rec,n1); rtcm->sta.rectype[n1]='\0';
strncpy(rtcm->sta.recver, ver,n2); rtcm->sta.recver [n2]='\0';
strncpy(rtcm->sta.recsno, rsn,n3); rtcm->sta.recsno [n3]='\0';
trace(3,"rtcm3 1033: ant=%s:%s rec=%s:%s:%s\n",des,sno,rec,ver,rsn);
return 5;
}
/* decode type 1034: GPS network FKP gradient --------------------------------*/
static int decode_type1034(rtcm_t *rtcm)
{
trace(2,"rtcm3 1034: not supported message\n");
return 0;
}
/* decode type 1035: GLONASS network FKP gradient ----------------------------*/
static int decode_type1035(rtcm_t *rtcm)
{
trace(2,"rtcm3 1035: not supported message\n");
return 0;
}
/* decode type 1037: GLONASS network RTK ionospheric correction difference ---*/
static int decode_type1037(rtcm_t *rtcm)
{
trace(2,"rtcm3 1037: not supported message\n");
return 0;
}
/* decode type 1038: GLONASS network RTK geometic correction difference ------*/
static int decode_type1038(rtcm_t *rtcm)
{
trace(2,"rtcm3 1038: not supported message\n");
return 0;
}
/* decode type 1039: GLONASS network RTK combined correction difference ------*/
static int decode_type1039(rtcm_t *rtcm)
{
trace(2,"rtcm3 1039: not supported message\n");
return 0;
}
/* decode type 1041: NavIC/IRNSS ephemerides ---------------------------------*/
static int decode_type1041(rtcm_t *rtcm)
{
eph_t eph={0};
double toc,sqrtA,tt;
char *msg;
int i=24+12,prn,sat,week,sys=SYS_IRN;
if (i+482-12<=rtcm->len*8) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
week =getbitu(rtcm->buff,i,10); i+=10;
eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22;
eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16;
eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8;
eph.sva =getbitu(rtcm->buff,i, 4); i+= 4;
toc =getbitu(rtcm->buff,i,16)*16.0; i+=16;
eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8;
eph.deln =getbits(rtcm->buff,i,22)*P2_41*SC2RAD; i+=22;
eph.iode =getbitu(rtcm->buff,i, 8); i+= 8+10; /* IODEC */
eph.svh =getbitu(rtcm->buff,i, 2); i+= 2; /* L5+Sflag */
eph.cuc =getbits(rtcm->buff,i,15)*P2_28; i+=15;
eph.cus =getbits(rtcm->buff,i,15)*P2_28; i+=15;
eph.cic =getbits(rtcm->buff,i,15)*P2_28; i+=15;
eph.cis =getbits(rtcm->buff,i,15)*P2_28; i+=15;
eph.crc =getbits(rtcm->buff,i,15)*0.0625; i+=15;
eph.crs =getbits(rtcm->buff,i,15)*0.0625; i+=15;
eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14;
eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.toes =getbitu(rtcm->buff,i,16)*16.0; i+=16;
eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32;
sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32;
eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.OMGd =getbits(rtcm->buff,i,22)*P2_41*SC2RAD; i+=22;
eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD;
}
else {
trace(2,"rtcm3 1041 length error: len=%d\n",rtcm->len);
return -1;
}
trace(4,"decode_type1041: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X",
prn,eph.iode,week,eph.toes,toc,eph.svh);
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1041 satellite number error: prn=%d\n",prn);
return -1;
}
eph.sat=sat;
eph.week=adjgpsweek(week);
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time);
if (tt<-302400.0) eph.week++;
else if (tt>=302400.0) eph.week--;
eph.toe=gpst2time(eph.week,eph.toes);
eph.toc=gpst2time(eph.week,toc);
eph.ttr=rtcm->time;
eph.A=sqrtA*sqrtA;
eph.iodc=eph.iode;
if (!strstr(rtcm->opt,"-EPHALL")) {
if (eph.iode==rtcm->nav.eph[sat-1].iode) return 0; /* unchanged */
}
rtcm->nav.eph[sat-1]=eph;
rtcm->ephsat=sat;
rtcm->ephset=0;
return 2;
}
/* decode type 1044: QZSS ephemerides ----------------------------------------*/
static int decode_type1044(rtcm_t *rtcm)
{
eph_t eph={0};
double toc,sqrtA,tt;
char *msg;
int i=24+12,prn,sat,week,sys=SYS_QZS;
if (i+473<=rtcm->len*8) {
prn =getbitu(rtcm->buff,i, 4)+192; i+= 4;
toc =getbitu(rtcm->buff,i,16)*16.0; i+=16;
eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8;
eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16;
eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22;
eph.iode =getbitu(rtcm->buff,i, 8); i+= 8;
eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16;
eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32;
eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16;
sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32;
eph.toes =getbitu(rtcm->buff,i,16)*16.0; i+=16;
eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24;
eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14;
eph.code =getbitu(rtcm->buff,i, 2); i+= 2;
week =getbitu(rtcm->buff,i,10); i+=10;
eph.sva =getbitu(rtcm->buff,i, 4); i+= 4;
eph.svh =getbitu(rtcm->buff,i, 6); i+= 6;
eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8;
eph.iodc =getbitu(rtcm->buff,i,10); i+=10;
eph.fit =getbitu(rtcm->buff,i, 1)?0.0:2.0; /* 0:2hr,1:>2hr */
}
else {
trace(2,"rtcm3 1044 length error: len=%d\n",rtcm->len);
return -1;
}
trace(4,"decode_type1044: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," prn=%3d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X",
prn,eph.iode,eph.iodc,week,eph.toes,toc,eph.svh);
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1044 satellite number error: prn=%d\n",prn);
return -1;
}
eph.sat=sat;
eph.week=adjgpsweek(week);
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time);
if (tt<-302400.0) eph.week++;
else if (tt>=302400.0) eph.week--;
eph.toe=gpst2time(eph.week,eph.toes);
eph.toc=gpst2time(eph.week,toc);
eph.ttr=rtcm->time;
eph.A=sqrtA*sqrtA;
eph.flag=1; /* fixed to 1 */
if (!strstr(rtcm->opt,"-EPHALL")) {
if (eph.iode==rtcm->nav.eph[sat-1].iode&&
eph.iodc==rtcm->nav.eph[sat-1].iodc) return 0; /* unchanged */
}
rtcm->nav.eph[sat-1]=eph;
rtcm->ephsat=sat;
rtcm->ephset=0;
return 2;
}
/* decode type 1045: Galileo F/NAV satellite ephemerides ---------------------*/
static int decode_type1045(rtcm_t *rtcm)
{
eph_t eph={0};
double toc,sqrtA,tt;
char *msg;
int i=24+12,prn,sat,week,e5a_hs,e5a_dvs,rsv,sys=SYS_GAL;
if (strstr(rtcm->opt,"-GALINAV")) return 0;
if (i+484<=rtcm->len*8) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
week =getbitu(rtcm->buff,i,12); i+=12; /* gst-week */
eph.iode =getbitu(rtcm->buff,i,10); i+=10;
eph.sva =getbitu(rtcm->buff,i, 8); i+= 8;
eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14;
toc =getbitu(rtcm->buff,i,14)*60.0; i+=14;
eph.f2 =getbits(rtcm->buff,i, 6)*P2_59; i+= 6;
eph.f1 =getbits(rtcm->buff,i,21)*P2_46; i+=21;
eph.f0 =getbits(rtcm->buff,i,31)*P2_34; i+=31;
eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16;
eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32;
eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16;
sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32;
eph.toes =getbitu(rtcm->buff,i,14)*60.0; i+=14;
eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24;
eph.tgd[0]=getbits(rtcm->buff,i,10)*P2_32; i+=10; /* E5a/E1 */
e5a_hs =getbitu(rtcm->buff,i, 2); i+= 2; /* OSHS */
e5a_dvs =getbitu(rtcm->buff,i, 1); i+= 1; /* OSDVS */
rsv =getbitu(rtcm->buff,i, 7);
}
else {
trace(2,"rtcm3 1045 length error: len=%d\n",rtcm->len);
return -1;
}
trace(4,"decode_type1045: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d dvs=%d",
prn,eph.iode,week,eph.toes,toc,e5a_hs,e5a_dvs);
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1045 satellite number error: prn=%d\n",prn);
return -1;
}
if (strstr(rtcm->opt,"-GALINAV")) {
return 0;
}
eph.sat=sat;
eph.week=week+1024; /* gal-week = gst-week + 1024 */
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time);
if (tt<-302400.0) eph.week++;
else if (tt>=302400.0) eph.week--;
eph.toe=gpst2time(eph.week,eph.toes);
eph.toc=gpst2time(eph.week,toc);
eph.ttr=rtcm->time;
eph.A=sqrtA*sqrtA;
eph.svh=(e5a_hs<<4)+(e5a_dvs<<3);
eph.code=(1<<1)+(1<<8); /* data source = F/NAV+E5a */
eph.iodc=eph.iode;
if (!strstr(rtcm->opt,"-EPHALL")) {
if (eph.iode==rtcm->nav.eph[sat-1+MAXSAT].iode) return 0; /* unchanged */
}
rtcm->nav.eph[sat-1+MAXSAT]=eph;
rtcm->ephsat=sat;
rtcm->ephset=1; /* F/NAV */
return 2;
}
/* decode type 1046: Galileo I/NAV satellite ephemerides ---------------------*/
static int decode_type1046(rtcm_t *rtcm)
{
eph_t eph={0};
double toc,sqrtA,tt;
char *msg;
int i=24+12,prn,sat,week,e5b_hs,e5b_dvs,e1_hs,e1_dvs,sys=SYS_GAL;
if (strstr(rtcm->opt,"-GALFNAV")) return 0;
if (i+492<=rtcm->len*8) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
week =getbitu(rtcm->buff,i,12); i+=12;
eph.iode =getbitu(rtcm->buff,i,10); i+=10;
eph.sva =getbitu(rtcm->buff,i, 8); i+= 8;
eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14;
toc =getbitu(rtcm->buff,i,14)*60.0; i+=14;
eph.f2 =getbits(rtcm->buff,i, 6)*P2_59; i+= 6;
eph.f1 =getbits(rtcm->buff,i,21)*P2_46; i+=21;
eph.f0 =getbits(rtcm->buff,i,31)*P2_34; i+=31;
eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16;
eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32;
eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16;
sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32;
eph.toes =getbitu(rtcm->buff,i,14)*60.0; i+=14;
eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16;
eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16;
eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24;
eph.tgd[0]=getbits(rtcm->buff,i,10)*P2_32; i+=10; /* E5a/E1 */
eph.tgd[1]=getbits(rtcm->buff,i,10)*P2_32; i+=10; /* E5b/E1 */
e5b_hs =getbitu(rtcm->buff,i, 2); i+= 2; /* E5b OSHS */
e5b_dvs =getbitu(rtcm->buff,i, 1); i+= 1; /* E5b OSDVS */
e1_hs =getbitu(rtcm->buff,i, 2); i+= 2; /* E1 OSHS */
e1_dvs =getbitu(rtcm->buff,i, 1); i+= 1; /* E1 OSDVS */
}
else {
trace(2,"rtcm3 1046 length error: len=%d\n",rtcm->len);
return -1;
}
trace(4,"decode_type1046: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d %d dvs=%d %d",
prn,eph.iode,week,eph.toes,toc,e5b_hs,e1_hs,e5b_dvs,e1_dvs);
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1046 satellite number error: prn=%d\n",prn);
return -1;
}
if (strstr(rtcm->opt,"-GALFNAV")) {
return 0;
}
eph.sat=sat;
eph.week=week+1024; /* gal-week = gst-week + 1024 */
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time);
if (tt<-302400.0) eph.week++;
else if (tt>=302400.0) eph.week--;
eph.toe=gpst2time(eph.week,eph.toes);
eph.toc=gpst2time(eph.week,toc);
eph.ttr=rtcm->time;
eph.A=sqrtA*sqrtA;
eph.svh=(e5b_hs<<7)+(e5b_dvs<<6)+(e1_hs<<1)+(e1_dvs<<0);
eph.code=(1<<0)+(1<<2)+(1<<9); /* data source = I/NAV+E1+E5b */
eph.iodc=eph.iode;
if (!strstr(rtcm->opt,"-EPHALL")) {
if (eph.iode==rtcm->nav.eph[sat-1].iode) return 0; /* unchanged */
}
rtcm->nav.eph[sat-1]=eph;
rtcm->ephsat=sat;
rtcm->ephset=0; /* I/NAV */
return 2;
}
/* decode type 1042/63: Beidou ephemerides -----------------------------------*/
static int decode_type1042(rtcm_t *rtcm)
{
eph_t eph={0};
double toc,sqrtA,tt;
char *msg;
int i=24+12,prn,sat,week,sys=SYS_CMP;
if (i+499<=rtcm->len*8) {
prn =getbitu(rtcm->buff,i, 6); i+= 6;
week =getbitu(rtcm->buff,i,13); i+=13;
eph.sva =getbitu(rtcm->buff,i, 4); i+= 4;
eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14;
eph.iode =getbitu(rtcm->buff,i, 5); i+= 5; /* AODE */
toc =getbitu(rtcm->buff,i,17)*8.0; i+=17;
eph.f2 =getbits(rtcm->buff,i,11)*P2_66; i+=11;
eph.f1 =getbits(rtcm->buff,i,22)*P2_50; i+=22;
eph.f0 =getbits(rtcm->buff,i,24)*P2_33; i+=24;
eph.iodc =getbitu(rtcm->buff,i, 5); i+= 5; /* AODC */
eph.crs =getbits(rtcm->buff,i,18)*P2_6; i+=18;
eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16;
eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cuc =getbits(rtcm->buff,i,18)*P2_31; i+=18;
eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32;
eph.cus =getbits(rtcm->buff,i,18)*P2_31; i+=18;
sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32;
eph.toes =getbitu(rtcm->buff,i,17)*8.0; i+=17;
eph.cic =getbits(rtcm->buff,i,18)*P2_31; i+=18;
eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.cis =getbits(rtcm->buff,i,18)*P2_31; i+=18;
eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.crc =getbits(rtcm->buff,i,18)*P2_6; i+=18;
eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32;
eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24;
eph.tgd[0]=getbits(rtcm->buff,i,10)*1E-10; i+=10;
eph.tgd[1]=getbits(rtcm->buff,i,10)*1E-10; i+=10;
eph.svh =getbitu(rtcm->buff,i, 1); i+= 1;
}
else {
trace(2,"rtcm3 1042 length error: len=%d\n",rtcm->len);
return -1;
}
trace(4,"decode_type1042: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X",
prn,eph.iode,eph.iodc,week,eph.toes,toc,eph.svh);
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 1042 satellite number error: prn=%d\n",prn);
return -1;
}
eph.sat=sat;
eph.week=adjbdtweek(week);
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());
tt=timediff(bdt2gpst(bdt2time(eph.week,eph.toes)),rtcm->time);
if (tt<-302400.0) eph.week++;
else if (tt>=302400.0) eph.week--;
eph.toe=bdt2gpst(bdt2time(eph.week,eph.toes)); /* bdt -> gpst */
eph.toc=bdt2gpst(bdt2time(eph.week,toc)); /* bdt -> gpst */
eph.ttr=rtcm->time;
eph.A=sqrtA*sqrtA;
if (!strstr(rtcm->opt,"-EPHALL")) {
if (timediff(eph.toe,rtcm->nav.eph[sat-1].toe)==0.0&&
eph.iode==rtcm->nav.eph[sat-1].iode&&
eph.iodc==rtcm->nav.eph[sat-1].iodc) return 0; /* unchanged */
}
rtcm->nav.eph[sat-1]=eph;
rtcm->ephset=0;
rtcm->ephsat=sat;
return 2;
}
/* decode SSR message epoch time ---------------------------------------------*/
static int decode_ssr_epoch(rtcm_t *rtcm, int sys, int subtype)
{
double tod,tow;
int i=24+12;
if (subtype==0) { /* RTCM SSR */
if (sys==SYS_GLO) {
tod=getbitu(rtcm->buff,i,17); i+=17;
adjday_glot(rtcm,tod);
}
else {
tow=getbitu(rtcm->buff,i,20); i+=20;
adjweek(rtcm,tow);
}
}
else { /* IGS SSR */
i+=3+8;
tow=getbitu(rtcm->buff,i,20); i+=20;
adjweek(rtcm,tow);
}
return i;
}
/* decode SSR 1,4 message header ---------------------------------------------*/
static int decode_ssr1_head(rtcm_t *rtcm, int sys, int subtype, int *sync,
int *iod, double *udint, int *refd, int *hsize)
{
char *msg,tstr[64];
int i=24+12,nsat,udi,provid=0,solid=0,ns;
if (subtype==0) { /* RTCM SSR */
ns=(sys==SYS_QZS)?4:6;
if (i+((sys==SYS_GLO)?53:50+ns)>rtcm->len*8) return -1;
}
else { /* IGS SSR */
ns=6;
if (i+3+8+50+ns>rtcm->len*8) return -1;
}
i=decode_ssr_epoch(rtcm,sys,subtype);
udi =getbitu(rtcm->buff,i, 4); i+= 4;
*sync =getbitu(rtcm->buff,i, 1); i+= 1;
if (subtype==0) { /* RTCM SSR */
*refd =getbitu(rtcm->buff,i, 1); i+= 1; /* satellite ref datum */
}
*iod =getbitu(rtcm->buff,i, 4); i+= 4; /* IOD SSR */
provid=getbitu(rtcm->buff,i,16); i+=16; /* provider ID */
solid =getbitu(rtcm->buff,i, 4); i+= 4; /* solution ID */
if (subtype>0) { /* IGS SSR */
*refd=getbitu(rtcm->buff,i,1); i+=1; /* global/regional CRS indicator */
}
nsat =getbitu(rtcm->buff,i,ns); i+=ns;
*udint=ssrudint[udi];
time2str(rtcm->time,tstr,2);
trace(4,"decode_ssr1_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d"
" provid=%d solid=%d\n",tstr,sys,subtype,nsat,*sync,*iod,provid,solid);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," %s nsat=%2d iod=%2d udi=%2d sync=%d",tstr,nsat,*iod,udi,
*sync);
}
*hsize=i;
return nsat;
}
/* decode SSR 2,3,5,6 message header -----------------------------------------*/
static int decode_ssr2_head(rtcm_t *rtcm, int sys, int subtype, int *sync,
int *iod, double *udint, int *hsize)
{
char *msg,tstr[64];
int i=24+12,nsat,udi,provid=0,solid=0,ns;
if (subtype==0) { /* RTCM SSR */
ns=(sys==SYS_QZS)?4:6;
if (i+((sys==SYS_GLO)?52:49+ns)>rtcm->len*8) return -1;
}
else {
ns=6;
if (i+3+8+49+ns>rtcm->len*8) return -1;
}
i=decode_ssr_epoch(rtcm,sys,subtype);
udi =getbitu(rtcm->buff,i, 4); i+= 4;
*sync =getbitu(rtcm->buff,i, 1); i+= 1;
*iod =getbitu(rtcm->buff,i, 4); i+= 4;
provid=getbitu(rtcm->buff,i,16); i+=16; /* provider ID */
solid =getbitu(rtcm->buff,i, 4); i+= 4; /* solution ID */
nsat =getbitu(rtcm->buff,i,ns); i+=ns;
*udint=ssrudint[udi];
time2str(rtcm->time,tstr,2);
trace(4,"decode_ssr2_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d"
" provid=%d solid=%d\n",tstr,sys,subtype,nsat,*sync,*iod,provid,solid);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," %s nsat=%2d iod=%2d udi=%2d sync=%d",tstr,nsat,*iod,udi,
*sync);
}
*hsize=i;
return nsat;
}
/* decode SSR 1: orbit corrections -------------------------------------------*/
static int decode_ssr1(rtcm_t *rtcm, int sys, int subtype)
{
double udint,deph[3],ddeph[3];
int i,j,k,type,sync,iod,nsat,prn,sat,iode,iodcrc=0,refd=0,np,ni,nj,offp;
type=getbitu(rtcm->buff,24,12);
if ((nsat=decode_ssr1_head(rtcm,sys,subtype,&sync,&iod,&udint,&refd,&i))<0) {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
switch (sys) {
case SYS_GPS: np=6; ni= 8; nj= 0; offp= 0; break;
case SYS_GLO: np=5; ni= 8; nj= 0; offp= 0; break;
case SYS_GAL: np=6; ni=10; nj= 0; offp= 0; break;
case SYS_QZS: np=4; ni= 8; nj= 0; offp=192; break;
case SYS_CMP: np=6; ni=10; nj=24; offp= 1; break;
case SYS_SBS: np=6; ni= 9; nj=24; offp=120; break;
default: return sync?0:10;
}
if (subtype>0) { /* IGS SSR */
np=6; ni=8; nj=0;
if (sys==SYS_CMP) offp=0;
else if (sys==SYS_SBS) offp=119;
}
for (j=0;j<nsat&&i+121+np+ni+nj<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i,np)+offp; i+=np;
iode =getbitu(rtcm->buff,i,ni); i+=ni;
iodcrc =getbitu(rtcm->buff,i,nj); i+=nj;
deph [0]=getbits(rtcm->buff,i,22)*1E-4; i+=22;
deph [1]=getbits(rtcm->buff,i,20)*4E-4; i+=20;
deph [2]=getbits(rtcm->buff,i,20)*4E-4; i+=20;
ddeph[0]=getbits(rtcm->buff,i,21)*1E-6; i+=21;
ddeph[1]=getbits(rtcm->buff,i,19)*4E-6; i+=19;
ddeph[2]=getbits(rtcm->buff,i,19)*4E-6; i+=19;
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn);
continue;
}
rtcm->ssr[sat-1].t0 [0]=rtcm->time;
rtcm->ssr[sat-1].udi[0]=udint;
rtcm->ssr[sat-1].iod[0]=iod;
rtcm->ssr[sat-1].iode=iode; /* SBAS/BDS: toe/t0 modulo */
rtcm->ssr[sat-1].iodcrc=iodcrc; /* SBAS/BDS: IOD CRC */
rtcm->ssr[sat-1].refd=refd;
for (k=0;k<3;k++) {
rtcm->ssr[sat-1].deph [k]=deph [k];
rtcm->ssr[sat-1].ddeph[k]=ddeph[k];
}
rtcm->ssr[sat-1].update=1;
}
return sync?0:10;
}
/* decode SSR 2: clock corrections -------------------------------------------*/
static int decode_ssr2(rtcm_t *rtcm, int sys, int subtype)
{
double udint,dclk[3];
int i,j,k,type,sync,iod,nsat,prn,sat,np,offp;
type=getbitu(rtcm->buff,24,12);
if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
switch (sys) {
case SYS_GPS: np=6; offp= 0; break;
case SYS_GLO: np=5; offp= 0; break;
case SYS_GAL: np=6; offp= 0; break;
case SYS_QZS: np=4; offp=192; break;
case SYS_CMP: np=6; offp= 1; break;
case SYS_SBS: np=6; offp=120; break;
default: return sync?0:10;
}
if (subtype>0) { /* IGS SSR */
np=6;
if (sys==SYS_CMP) offp=0;
else if (sys==SYS_SBS) offp=119;
}
for (j=0;j<nsat&&i+70+np<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i,np)+offp; i+=np;
dclk[0]=getbits(rtcm->buff,i,22)*1E-4; i+=22;
dclk[1]=getbits(rtcm->buff,i,21)*1E-6; i+=21;
dclk[2]=getbits(rtcm->buff,i,27)*2E-8; i+=27;
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn);
continue;
}
rtcm->ssr[sat-1].t0 [1]=rtcm->time;
rtcm->ssr[sat-1].udi[1]=udint;
rtcm->ssr[sat-1].iod[1]=iod;
for (k=0;k<3;k++) {
rtcm->ssr[sat-1].dclk[k]=dclk[k];
}
rtcm->ssr[sat-1].update=1;
}
return sync?0:10;
}
/* decode SSR 3: satellite code biases ---------------------------------------*/
static int decode_ssr3(rtcm_t *rtcm, int sys, int subtype)
{
const uint8_t *sigs;
double udint,bias,cbias[MAXCODE];
int i,j,k,type,mode,sync,iod,nsat,prn,sat,nbias,np,offp;
type=getbitu(rtcm->buff,24,12);
if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
switch (sys) {
case SYS_GPS: np=6; offp= 0; sigs=ssr_sig_gps; break;
case SYS_GLO: np=5; offp= 0; sigs=ssr_sig_glo; break;
case SYS_GAL: np=6; offp= 0; sigs=ssr_sig_gal; break;
case SYS_QZS: np=4; offp=192; sigs=ssr_sig_qzs; break;
case SYS_CMP: np=6; offp= 1; sigs=ssr_sig_cmp; break;
case SYS_SBS: np=6; offp=120; sigs=ssr_sig_sbs; break;
default: return sync?0:10;
}
if (subtype>0) { /* IGS SSR */
np=6;
if (sys==SYS_CMP) offp=0;
else if (sys==SYS_SBS) offp=119;
}
for (j=0;j<nsat&&i+5+np<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i,np)+offp; i+=np;
nbias=getbitu(rtcm->buff,i, 5); i+= 5;
for (k=0;k<MAXCODE;k++) cbias[k]=0.0;
for (k=0;k<nbias&&i+19<=rtcm->len*8;k++) {
mode=getbitu(rtcm->buff,i, 5); i+= 5;
bias=getbits(rtcm->buff,i,14)*0.01; i+=14;
if (sigs[mode]) {
cbias[sigs[mode]-1]=(float)bias;
}
else {
trace(2,"rtcm3 %d not supported mode: mode=%d\n",type,mode);
}
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn);
continue;
}
rtcm->ssr[sat-1].t0 [4]=rtcm->time;
rtcm->ssr[sat-1].udi[4]=udint;
rtcm->ssr[sat-1].iod[4]=iod;
for (k=0;k<MAXCODE;k++) {
rtcm->ssr[sat-1].cbias[k]=(float)cbias[k];
}
rtcm->ssr[sat-1].update=1;
}
return sync?0:10;
}
/* decode SSR 4: combined orbit and clock corrections ------------------------*/
static int decode_ssr4(rtcm_t *rtcm, int sys, int subtype)
{
double udint,deph[3],ddeph[3],dclk[3];
int i,j,k,type,nsat,sync,iod,prn,sat,iode,iodcrc=0,refd=0,np,ni,nj,offp;
type=getbitu(rtcm->buff,24,12);
if ((nsat=decode_ssr1_head(rtcm,sys,subtype,&sync,&iod,&udint,&refd,&i))<0) {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
switch (sys) {
case SYS_GPS: np=6; ni= 8; nj= 0; offp= 0; break;
case SYS_GLO: np=5; ni= 8; nj= 0; offp= 0; break;
case SYS_GAL: np=6; ni=10; nj= 0; offp= 0; break;
case SYS_QZS: np=4; ni= 8; nj= 0; offp=192; break;
case SYS_CMP: np=6; ni=10; nj=24; offp= 1; break;
case SYS_SBS: np=6; ni= 9; nj=24; offp=120; break;
default: return sync?0:10;
}
if (subtype>0) { /* IGS SSR */
np=6; ni=8; nj=0;
if (sys==SYS_CMP) offp=0;
else if (sys==SYS_SBS) offp=119;
}
for (j=0;j<nsat&&i+191+np+ni+nj<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i,np)+offp; i+=np;
iode =getbitu(rtcm->buff,i,ni); i+=ni;
iodcrc =getbitu(rtcm->buff,i,nj); i+=nj;
deph [0]=getbits(rtcm->buff,i,22)*1E-4; i+=22;
deph [1]=getbits(rtcm->buff,i,20)*4E-4; i+=20;
deph [2]=getbits(rtcm->buff,i,20)*4E-4; i+=20;
ddeph[0]=getbits(rtcm->buff,i,21)*1E-6; i+=21;
ddeph[1]=getbits(rtcm->buff,i,19)*4E-6; i+=19;
ddeph[2]=getbits(rtcm->buff,i,19)*4E-6; i+=19;
dclk [0]=getbits(rtcm->buff,i,22)*1E-4; i+=22;
dclk [1]=getbits(rtcm->buff,i,21)*1E-6; i+=21;
dclk [2]=getbits(rtcm->buff,i,27)*2E-8; i+=27;
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn);
continue;
}
rtcm->ssr[sat-1].t0 [0]=rtcm->ssr[sat-1].t0 [1]=rtcm->time;
rtcm->ssr[sat-1].udi[0]=rtcm->ssr[sat-1].udi[1]=udint;
rtcm->ssr[sat-1].iod[0]=rtcm->ssr[sat-1].iod[1]=iod;
rtcm->ssr[sat-1].iode=iode;
rtcm->ssr[sat-1].iodcrc=iodcrc;
rtcm->ssr[sat-1].refd=refd;
for (k=0;k<3;k++) {
rtcm->ssr[sat-1].deph [k]=deph [k];
rtcm->ssr[sat-1].ddeph[k]=ddeph[k];
rtcm->ssr[sat-1].dclk [k]=dclk [k];
}
rtcm->ssr[sat-1].update=1;
}
return sync?0:10;
}
/* decode SSR 5: URA ---------------------------------------------------------*/
static int decode_ssr5(rtcm_t *rtcm, int sys, int subtype)
{
double udint;
int i,j,type,nsat,sync,iod,prn,sat,ura,np,offp;
type=getbitu(rtcm->buff,24,12);
if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
switch (sys) {
case SYS_GPS: np=6; offp= 0; break;
case SYS_GLO: np=5; offp= 0; break;
case SYS_GAL: np=6; offp= 0; break;
case SYS_QZS: np=4; offp=192; break;
case SYS_CMP: np=6; offp= 1; break;
case SYS_SBS: np=6; offp=120; break;
default: return sync?0:10;
}
if (subtype>0) { /* IGS SSR */
np=6;
if (sys==SYS_CMP) offp=0;
else if (sys==SYS_SBS) offp=119;
}
for (j=0;j<nsat&&i+6+np<=rtcm->len*8;j++) {
prn=getbitu(rtcm->buff,i,np)+offp; i+=np;
ura=getbitu(rtcm->buff,i, 6); i+= 6;
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn);
continue;
}
rtcm->ssr[sat-1].t0 [3]=rtcm->time;
rtcm->ssr[sat-1].udi[3]=udint;
rtcm->ssr[sat-1].iod[3]=iod;
rtcm->ssr[sat-1].ura=ura;
rtcm->ssr[sat-1].update=1;
}
return sync?0:10;
}
/* decode SSR 6: high rate clock correction ----------------------------------*/
static int decode_ssr6(rtcm_t *rtcm, int sys, int subtype)
{
double udint,hrclk;
int i,j,type,nsat,sync,iod,prn,sat,np,offp;
type=getbitu(rtcm->buff,24,12);
if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
switch (sys) {
case SYS_GPS: np=6; offp= 0; break;
case SYS_GLO: np=5; offp= 0; break;
case SYS_GAL: np=6; offp= 0; break;
case SYS_QZS: np=4; offp=192; break;
case SYS_CMP: np=6; offp= 1; break;
case SYS_SBS: np=6; offp=120; break;
default: return sync?0:10;
}
if (subtype>0) { /* IGS SSR */
np=6;
if (sys==SYS_CMP) offp=0;
else if (sys==SYS_SBS) offp=119;
}
for (j=0;j<nsat&&i+22+np<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i,np)+offp; i+=np;
hrclk=getbits(rtcm->buff,i,22)*1E-4; i+=22;
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn);
continue;
}
rtcm->ssr[sat-1].t0 [2]=rtcm->time;
rtcm->ssr[sat-1].udi[2]=udint;
rtcm->ssr[sat-1].iod[2]=iod;
rtcm->ssr[sat-1].hrclk=hrclk;
rtcm->ssr[sat-1].update=1;
}
return sync?0:10;
}
/* decode SSR 7 message header -----------------------------------------------*/
static int decode_ssr7_head(rtcm_t *rtcm, int sys, int subtype, int *sync,
int *iod, double *udint, int *dispe, int *mw,
int *hsize)
{
char *msg,tstr[64];
int i=24+12,nsat,udi,provid=0,solid=0,ns;
if (subtype==0) { /* RTCM SSR */
ns=(sys==SYS_QZS)?4:6;
if (i+((sys==SYS_GLO)?54:51+ns)>rtcm->len*8) return -1;
}
else { /* IGS SSR */
ns=6;
if (i+3+8+51+ns>rtcm->len*8) return -1;
}
i=decode_ssr_epoch(rtcm,sys,subtype);
udi =getbitu(rtcm->buff,i, 4); i+= 4;
*sync =getbitu(rtcm->buff,i, 1); i+= 1;
*iod =getbitu(rtcm->buff,i, 4); i+= 4;
provid=getbitu(rtcm->buff,i,16); i+=16; /* provider ID */
solid =getbitu(rtcm->buff,i, 4); i+= 4; /* solution ID */
*dispe=getbitu(rtcm->buff,i, 1); i+= 1; /* dispersive bias consistency ind */
*mw =getbitu(rtcm->buff,i, 1); i+= 1; /* MW consistency indicator */
nsat =getbitu(rtcm->buff,i,ns); i+=ns;
*udint=ssrudint[udi];
time2str(rtcm->time,tstr,2);
trace(4,"decode_ssr7_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d"
" provid=%d solid=%d\n",tstr,sys,subtype,nsat,*sync,*iod,provid,solid);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," %s nsat=%2d iod=%2d udi=%2d sync=%d",tstr,nsat,*iod,udi,
*sync);
}
*hsize=i;
return nsat;
}
/* decode SSR 7: phase bias --------------------------------------------------*/
static int decode_ssr7(rtcm_t *rtcm, int sys, int subtype)
{
const uint8_t *sigs;
double udint,bias,std=0.0,pbias[MAXCODE],stdpb[MAXCODE];
int i,j,k,type,mode,sync,iod,nsat,prn,sat,nbias,np,mw,offp,sii,swl;
int dispe,sdc,yaw_ang,yaw_rate;
type=getbitu(rtcm->buff,24,12);
if ((nsat=decode_ssr7_head(rtcm,sys,subtype,&sync,&iod,&udint,&dispe,&mw,
&i))<0) {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
switch (sys) {
case SYS_GPS: np=6; offp= 0; sigs=ssr_sig_gps; break;
case SYS_GLO: np=5; offp= 0; sigs=ssr_sig_glo; break;
case SYS_GAL: np=6; offp= 0; sigs=ssr_sig_gal; break;
case SYS_QZS: np=4; offp=192; sigs=ssr_sig_qzs; break;
case SYS_CMP: np=6; offp= 1; sigs=ssr_sig_cmp; break;
default: return sync?0:10;
}
if (subtype>0) { /* IGS SSR */
np=6;
if (sys==SYS_CMP) offp=0;
else if (sys==SYS_SBS) offp=119;
}
for (j=0;j<nsat&&i+5+17+np<=rtcm->len*8;j++) {
prn =getbitu(rtcm->buff,i,np)+offp; i+=np;
nbias =getbitu(rtcm->buff,i, 5); i+= 5;
yaw_ang =getbitu(rtcm->buff,i, 9); i+= 9;
yaw_rate=getbits(rtcm->buff,i, 8); i+= 8;
for (k=0;k<MAXCODE;k++) pbias[k]=stdpb[k]=0.0;
for (k=0;k<nbias&&i+((subtype==0)?49:32)<=rtcm->len*8;k++) {
mode=getbitu(rtcm->buff,i, 5); i+= 5;
sii =getbitu(rtcm->buff,i, 1); i+= 1; /* integer-indicator */
swl =getbitu(rtcm->buff,i, 2); i+= 2; /* WL integer-indicator */
sdc =getbitu(rtcm->buff,i, 4); i+= 4; /* discontinuity counter */
bias=getbits(rtcm->buff,i,20); i+=20; /* phase bias (m) */
if (subtype==0) {
std =getbitu(rtcm->buff,i,17); i+=17; /* phase bias std-dev (m) */
}
if (sigs[mode]) {
pbias[sigs[mode]-1]=bias*0.0001; /* (m) */
stdpb[sigs[mode]-1]=std *0.0001; /* (m) */
}
else {
trace(2,"rtcm3 %d not supported mode: mode=%d\n",type,mode);
}
}
if (!(sat=satno(sys,prn))) {
trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn);
continue;
}
rtcm->ssr[sat-1].t0 [5]=rtcm->time;
rtcm->ssr[sat-1].udi[5]=udint;
rtcm->ssr[sat-1].iod[5]=iod;
rtcm->ssr[sat-1].yaw_ang =yaw_ang / 256.0*180.0; /* (deg) */
rtcm->ssr[sat-1].yaw_rate=yaw_rate/8192.0*180.0; /* (deg/s) */
for (k=0;k<MAXCODE;k++) {
rtcm->ssr[sat-1].pbias[k]=pbias[k];
rtcm->ssr[sat-1].stdpb[k]=(float)stdpb[k];
}
}
return 20;
}
/* get signal index ----------------------------------------------------------*/
static void sigindex(int sys, const uint8_t *code, int n, const char *opt,
int *idx)
{
int i,nex,pri,pri_h[8]={0},index[8]={0},ex[32]={0};
/* test code priority */
for (i=0;i<n;i++) {
if (!code[i]) continue;
if (idx[i]>=NFREQ) { /* save as extended signal if idx >= NFREQ */
ex[i]=1;
continue;
}
/* code priority */
pri=getcodepri(sys,code[i],opt);
/* select highest priority signal */
if (pri>pri_h[idx[i]]) {
if (index[idx[i]]) ex[index[idx[i]]-1]=1;
pri_h[idx[i]]=pri;
index[idx[i]]=i+1;
}
else ex[i]=1;
}
/* signal index in obs data */
for (i=nex=0;i<n;i++) {
if (ex[i]==0) ;
else if (nex<NEXOBS) idx[i]=NFREQ+nex++;
else { /* no space in obs data */
trace(2,"rtcm msm: no space in obs data sys=%d code=%d\n",sys,code[i]);
idx[i]=-1;
}
#if 0 /* for debug */
trace(2,"sig pos: sys=%d code=%d ex=%d idx=%d\n",sys,code[i],ex[i],idx[i]);
#endif
}
}
/* save obs data in MSM message ----------------------------------------------*/
static void save_msm_obs(rtcm_t *rtcm, int sys, msm_h_t *h, const double *r,
const double *pr, const double *cp, const double *rr,
const double *rrf, const double *cnr, const int *lock,
const int *ex, const int *half)
{
const char *sig[32];
double tt,freq;
uint8_t code[32];
char *msm_type="",*q=NULL;
int i,j,k,type,prn,sat,fcn,index=0,idx[32];
type=getbitu(rtcm->buff,24,12);
switch (sys) {
case SYS_GPS: msm_type=q=rtcm->msmtype[0]; break;
case SYS_GLO: msm_type=q=rtcm->msmtype[1]; break;
case SYS_GAL: msm_type=q=rtcm->msmtype[2]; break;
case SYS_QZS: msm_type=q=rtcm->msmtype[3]; break;
case SYS_SBS: msm_type=q=rtcm->msmtype[4]; break;
case SYS_CMP: msm_type=q=rtcm->msmtype[5]; break;
case SYS_IRN: msm_type=q=rtcm->msmtype[6]; break;
}
/* id to signal */
for (i=0;i<h->nsig;i++) {
switch (sys) {
case SYS_GPS: sig[i]=msm_sig_gps[h->sigs[i]-1]; break;
case SYS_GLO: sig[i]=msm_sig_glo[h->sigs[i]-1]; break;
case SYS_GAL: sig[i]=msm_sig_gal[h->sigs[i]-1]; break;
case SYS_QZS: sig[i]=msm_sig_qzs[h->sigs[i]-1]; break;
case SYS_SBS: sig[i]=msm_sig_sbs[h->sigs[i]-1]; break;
case SYS_CMP: sig[i]=msm_sig_cmp[h->sigs[i]-1]; break;
case SYS_IRN: sig[i]=msm_sig_irn[h->sigs[i]-1]; break;
default: sig[i]=""; break;
}
/* signal to rinex obs type */
code[i]=obs2code(sig[i]);
idx[i]=code2idx(sys,code[i]);
if (code[i]!=CODE_NONE) {
if (q) q+=sprintf(q,"L%s%s",sig[i],i<h->nsig-1?",":"");
}
else {
if (q) q+=sprintf(q,"(%d)%s",h->sigs[i],i<h->nsig-1?",":"");
trace(2,"rtcm3 %d: unknown signal id=%2d\n",type,h->sigs[i]);
}
}
trace(3,"rtcm3 %d: signals=%s\n",type,msm_type);
/* get signal index */
sigindex(sys,code,h->nsig,rtcm->opt,idx);
for (i=j=0;i<h->nsat;i++) {
prn=h->sats[i];
if (sys==SYS_QZS) prn+=MINPRNQZS-1;
else if (sys==SYS_SBS) prn+=MINPRNSBS-1;
if ((sat=satno(sys,prn))) {
tt=timediff(rtcm->obs.data[0].time,rtcm->time);
if (rtcm->obsflag||fabs(tt)>1E-9) {
rtcm->obs.n=rtcm->obsflag=0;
}
index=obsindex(&rtcm->obs,rtcm->time,sat);
}
else {
trace(2,"rtcm3 %d satellite error: prn=%d\n",type,prn);
}
fcn=0;
if (sys==SYS_GLO) {
fcn=-8; /* no glonass fcn info */
if (ex&&ex[i]<=13) {
fcn=ex[i]-7;
if (!rtcm->nav.glo_fcn[prn-1]) {
rtcm->nav.glo_fcn[prn-1]=fcn+8; /* fcn+8 */
}
}
else if (rtcm->nav.geph[prn-1].sat==sat) {
fcn=rtcm->nav.geph[prn-1].frq;
}
else if (rtcm->nav.glo_fcn[prn-1]>0) {
fcn=rtcm->nav.glo_fcn[prn-1]-8;
}
}
for (k=0;k<h->nsig;k++) {
if (!h->cellmask[k+i*h->nsig]) continue;
if (sat&&index>=0&&idx[k]>=0) {
freq=fcn<-7?0.0:code2freq(sys,code[k],fcn);
/* pseudorange (m) */
if (r[i]!=0.0&&pr[j]>-1E12) {
rtcm->obs.data[index].P[idx[k]]=r[i]+pr[j];
}
/* carrier-phase (cycle) */
if (r[i]!=0.0&&cp[j]>-1E12) {
rtcm->obs.data[index].L[idx[k]]=(r[i]+cp[j])*freq/CLIGHT;
}
/* doppler (hz) */
if (rr&&rrf&&rrf[j]>-1E12) {
rtcm->obs.data[index].D[idx[k]]=
(float)(-(rr[i]+rrf[j])*freq/CLIGHT);
}
rtcm->obs.data[index].LLI[idx[k]]=
lossoflock(rtcm,sat,idx[k],lock[j])+(half[j]?2:0);
rtcm->obs.data[index].SNR [idx[k]]=(uint16_t)(cnr[j]/SNR_UNIT+0.5);
rtcm->obs.data[index].code[idx[k]]=code[k];
}
j++;
}
}
}
/* decode type MSM message header --------------------------------------------*/
static int decode_msm_head(rtcm_t *rtcm, int sys, int *sync, int *iod,
msm_h_t *h, int *hsize)
{
msm_h_t h0={0};
double tow,tod;
char *msg,tstr[64];
int i=24,j,dow,mask,staid,type,ncell=0;
type=getbitu(rtcm->buff,i,12); i+=12;
*h=h0;
if (i+157<=rtcm->len*8) {
staid =getbitu(rtcm->buff,i,12); i+=12;
if (sys==SYS_GLO) {
dow =getbitu(rtcm->buff,i, 3); i+= 3;
tod =getbitu(rtcm->buff,i,27)*0.001; i+=27;
adjday_glot(rtcm,tod);
}
else if (sys==SYS_CMP) {
tow =getbitu(rtcm->buff,i,30)*0.001; i+=30;
tow+=14.0; /* BDT -> GPST */
adjweek(rtcm,tow);
}
else {
tow =getbitu(rtcm->buff,i,30)*0.001; i+=30;
adjweek(rtcm,tow);
}
*sync =getbitu(rtcm->buff,i, 1); i+= 1;
*iod =getbitu(rtcm->buff,i, 3); i+= 3;
h->time_s =getbitu(rtcm->buff,i, 7); i+= 7;
h->clk_str=getbitu(rtcm->buff,i, 2); i+= 2;
h->clk_ext=getbitu(rtcm->buff,i, 2); i+= 2;
h->smooth =getbitu(rtcm->buff,i, 1); i+= 1;
h->tint_s =getbitu(rtcm->buff,i, 3); i+= 3;
for (j=1;j<=64;j++) {
mask=getbitu(rtcm->buff,i,1); i+=1;
if (mask) h->sats[h->nsat++]=j;
}
for (j=1;j<=32;j++) {
mask=getbitu(rtcm->buff,i,1); i+=1;
if (mask) h->sigs[h->nsig++]=j;
}
}
else {
trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len);
return -1;
}
/* test station id */
if (!test_staid(rtcm,staid)) return -1;
if (h->nsat*h->nsig>64) {
trace(2,"rtcm3 %d number of sats and sigs error: nsat=%d nsig=%d\n",
type,h->nsat,h->nsig);
return -1;
}
if (i+h->nsat*h->nsig>rtcm->len*8) {
trace(2,"rtcm3 %d length error: len=%d nsat=%d nsig=%d\n",type,
rtcm->len,h->nsat,h->nsig);
return -1;
}
for (j=0;j<h->nsat*h->nsig;j++) {
h->cellmask[j]=getbitu(rtcm->buff,i,1); i+=1;
if (h->cellmask[j]) ncell++;
}
*hsize=i;
time2str(rtcm->time,tstr,2);
trace(4,"decode_head_msm: time=%s sys=%d staid=%d nsat=%d nsig=%d sync=%d iod=%d ncell=%d\n",
tstr,sys,staid,h->nsat,h->nsig,*sync,*iod,ncell);
if (rtcm->outtype) {
msg=rtcm->msgtype+strlen(rtcm->msgtype);
sprintf(msg," staid=%4d %s nsat=%2d nsig=%2d iod=%2d ncell=%2d sync=%d",
staid,tstr,h->nsat,h->nsig,*iod,ncell,*sync);
}
return ncell;
}
/* decode unsupported MSM message --------------------------------------------*/
static int decode_msm0(rtcm_t *rtcm, int sys)
{
msm_h_t h={0};
int i,sync,iod;
if (decode_msm_head(rtcm,sys,&sync,&iod,&h,&i)<0) return -1;
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode MSM 4: full pseudorange and phaserange plus CNR --------------------*/
static int decode_msm4(rtcm_t *rtcm, int sys)
{
msm_h_t h={0};
double r[64],pr[64],cp[64],cnr[64];
int i,j,type,sync,iod,ncell,rng,rng_m,prv,cpv,lock[64],half[64];
type=getbitu(rtcm->buff,24,12);
/* decode msm header */
if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1;
if (i+h.nsat*18+ncell*48>rtcm->len*8) {
trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat,
ncell,rtcm->len);
return -1;
}
for (j=0;j<h.nsat;j++) r[j]=0.0;
for (j=0;j<ncell;j++) pr[j]=cp[j]=-1E16;
/* decode satellite data */
for (j=0;j<h.nsat;j++) { /* range */
rng =getbitu(rtcm->buff,i, 8); i+= 8;
if (rng!=255) r[j]=rng*RANGE_MS;
}
for (j=0;j<h.nsat;j++) {
rng_m=getbitu(rtcm->buff,i,10); i+=10;
if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS;
}
/* decode signal data */
for (j=0;j<ncell;j++) { /* pseudorange */
prv=getbits(rtcm->buff,i,15); i+=15;
if (prv!=-16384) pr[j]=prv*P2_24*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* phaserange */
cpv=getbits(rtcm->buff,i,22); i+=22;
if (cpv!=-2097152) cp[j]=cpv*P2_29*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* lock time */
lock[j]=getbitu(rtcm->buff,i,4); i+=4;
}
for (j=0;j<ncell;j++) { /* half-cycle ambiguity */
half[j]=getbitu(rtcm->buff,i,1); i+=1;
}
for (j=0;j<ncell;j++) { /* cnr */
cnr[j]=getbitu(rtcm->buff,i,6)*1.0; i+=6;
}
/* save obs data in msm message */
save_msm_obs(rtcm,sys,&h,r,pr,cp,NULL,NULL,cnr,lock,NULL,half);
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode MSM 5: full pseudorange, phaserange, phaserangerate and CNR --------*/
static int decode_msm5(rtcm_t *rtcm, int sys)
{
msm_h_t h={0};
double r[64],rr[64],pr[64],cp[64],rrf[64],cnr[64];
int i,j,type,sync,iod,ncell,rng,rng_m,rate,prv,cpv,rrv,lock[64];
int ex[64],half[64];
type=getbitu(rtcm->buff,24,12);
/* decode msm header */
if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1;
if (i+h.nsat*36+ncell*63>rtcm->len*8) {
trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat,
ncell,rtcm->len);
return -1;
}
for (j=0;j<h.nsat;j++) {
r[j]=rr[j]=0.0; ex[j]=15;
}
for (j=0;j<ncell;j++) pr[j]=cp[j]=rrf[j]=-1E16;
/* decode satellite data */
for (j=0;j<h.nsat;j++) { /* range */
rng =getbitu(rtcm->buff,i, 8); i+= 8;
if (rng!=255) r[j]=rng*RANGE_MS;
}
for (j=0;j<h.nsat;j++) { /* extended info */
ex[j]=getbitu(rtcm->buff,i, 4); i+= 4;
}
for (j=0;j<h.nsat;j++) {
rng_m=getbitu(rtcm->buff,i,10); i+=10;
if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS;
}
for (j=0;j<h.nsat;j++) { /* phaserangerate */
rate =getbits(rtcm->buff,i,14); i+=14;
if (rate!=-8192) rr[j]=rate*1.0;
}
/* decode signal data */
for (j=0;j<ncell;j++) { /* pseudorange */
prv=getbits(rtcm->buff,i,15); i+=15;
if (prv!=-16384) pr[j]=prv*P2_24*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* phaserange */
cpv=getbits(rtcm->buff,i,22); i+=22;
if (cpv!=-2097152) cp[j]=cpv*P2_29*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* lock time */
lock[j]=getbitu(rtcm->buff,i,4); i+=4;
}
for (j=0;j<ncell;j++) { /* half-cycle ambiguity */
half[j]=getbitu(rtcm->buff,i,1); i+=1;
}
for (j=0;j<ncell;j++) { /* cnr */
cnr[j]=getbitu(rtcm->buff,i,6)*1.0; i+=6;
}
for (j=0;j<ncell;j++) { /* phaserangerate */
rrv=getbits(rtcm->buff,i,15); i+=15;
if (rrv!=-16384) rrf[j]=rrv*0.0001;
}
/* save obs data in msm message */
save_msm_obs(rtcm,sys,&h,r,pr,cp,rr,rrf,cnr,lock,ex,half);
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode MSM 6: full pseudorange and phaserange plus CNR (high-res) ---------*/
static int decode_msm6(rtcm_t *rtcm, int sys)
{
msm_h_t h={0};
double r[64],pr[64],cp[64],cnr[64];
int i,j,type,sync,iod,ncell,rng,rng_m,prv,cpv,lock[64],half[64];
type=getbitu(rtcm->buff,24,12);
/* decode msm header */
if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1;
if (i+h.nsat*18+ncell*65>rtcm->len*8) {
trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat,
ncell,rtcm->len);
return -1;
}
for (j=0;j<h.nsat;j++) r[j]=0.0;
for (j=0;j<ncell;j++) pr[j]=cp[j]=-1E16;
/* decode satellite data */
for (j=0;j<h.nsat;j++) { /* range */
rng =getbitu(rtcm->buff,i, 8); i+= 8;
if (rng!=255) r[j]=rng*RANGE_MS;
}
for (j=0;j<h.nsat;j++) {
rng_m=getbitu(rtcm->buff,i,10); i+=10;
if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS;
}
/* decode signal data */
for (j=0;j<ncell;j++) { /* pseudorange */
prv=getbits(rtcm->buff,i,20); i+=20;
if (prv!=-524288) pr[j]=prv*P2_29*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* phaserange */
cpv=getbits(rtcm->buff,i,24); i+=24;
if (cpv!=-8388608) cp[j]=cpv*P2_31*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* lock time */
lock[j]=getbitu(rtcm->buff,i,10); i+=10;
}
for (j=0;j<ncell;j++) { /* half-cycle ambiguity */
half[j]=getbitu(rtcm->buff,i,1); i+=1;
}
for (j=0;j<ncell;j++) { /* cnr */
cnr[j]=getbitu(rtcm->buff,i,10)*0.0625; i+=10;
}
/* save obs data in msm message */
save_msm_obs(rtcm,sys,&h,r,pr,cp,NULL,NULL,cnr,lock,NULL,half);
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode MSM 7: full pseudorange, phaserange, phaserangerate and CNR (h-res) */
static int decode_msm7(rtcm_t *rtcm, int sys)
{
msm_h_t h={0};
double r[64],rr[64],pr[64],cp[64],rrf[64],cnr[64];
int i,j,type,sync,iod,ncell,rng,rng_m,rate,prv,cpv,rrv,lock[64];
int ex[64],half[64];
type=getbitu(rtcm->buff,24,12);
/* decode msm header */
if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1;
if (i+h.nsat*36+ncell*80>rtcm->len*8) {
trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat,
ncell,rtcm->len);
return -1;
}
for (j=0;j<h.nsat;j++) {
r[j]=rr[j]=0.0; ex[j]=15;
}
for (j=0;j<ncell;j++) pr[j]=cp[j]=rrf[j]=-1E16;
/* decode satellite data */
for (j=0;j<h.nsat;j++) { /* range */
rng =getbitu(rtcm->buff,i, 8); i+= 8;
if (rng!=255) r[j]=rng*RANGE_MS;
}
for (j=0;j<h.nsat;j++) { /* extended info */
ex[j]=getbitu(rtcm->buff,i, 4); i+= 4;
}
for (j=0;j<h.nsat;j++) {
rng_m=getbitu(rtcm->buff,i,10); i+=10;
if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS;
}
for (j=0;j<h.nsat;j++) { /* phaserangerate */
rate =getbits(rtcm->buff,i,14); i+=14;
if (rate!=-8192) {
rr[j]=rate*1.0;
if (strstr(rtcm->opt,"-INVPRR")) rr[j] = -rr[j];
}
}
/* decode signal data */
for (j=0;j<ncell;j++) { /* pseudorange */
prv=getbits(rtcm->buff,i,20); i+=20;
if (prv!=-524288) pr[j]=prv*P2_29*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* phaserange */
cpv=getbits(rtcm->buff,i,24); i+=24;
if (cpv!=-8388608) cp[j]=cpv*P2_31*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* lock time */
lock[j]=getbitu(rtcm->buff,i,10); i+=10;
}
for (j=0;j<ncell;j++) { /* half-cycle amiguity */
half[j]=getbitu(rtcm->buff,i,1); i+=1;
}
for (j=0;j<ncell;j++) { /* cnr */
cnr[j]=getbitu(rtcm->buff,i,10)*0.0625; i+=10;
}
for (j=0;j<ncell;j++) { /* phaserangerate */
rrv=getbits(rtcm->buff,i,15); i+=15;
if (rrv!=-16384) {
rrf[j]=rrv*0.0001;
if (strstr(rtcm->opt,"-INVPRR")) rrf[j] = -rrf[j];
}
}
/* save obs data in msm message */
save_msm_obs(rtcm,sys,&h,r,pr,cp,rr,rrf,cnr,lock,ex,half);
rtcm->obsflag=!sync;
return sync?0:1;
}
/* decode type 1230: GLONASS L1 and L2 code-phase biases ---------------------*/
static int decode_type1230(rtcm_t *rtcm)
{
int i=24+12,j,staid,align,mask,bias;
if (i+20>=rtcm->len*8) {
trace(2,"rtcm3 1230: length error len=%d\n",rtcm->len);
return -1;
}
staid=getbitu(rtcm->buff,i,12); i+=12;
align=getbitu(rtcm->buff,i, 1); i+= 1+3;
mask =getbitu(rtcm->buff,i, 4); i+= 4;
if (rtcm->outtype) {
sprintf(rtcm->msgtype+strlen(rtcm->msgtype),
" staid=%4d align=%d mask=0x%X",staid,align,mask);
}
/* test station ID */
if (!test_staid(rtcm,staid)) return -1;
rtcm->sta.glo_cp_align=align;
for (j=0;j<4;j++) {
rtcm->sta.glo_cp_bias[j]=0.0;
}
for (j=0;j<4&&i+16<=rtcm->len*8;j++) {
if (!(mask&(1<<(3-j)))) continue;
bias=getbits(rtcm->buff,i,16); i+=16;
if (bias!=-32768) {
rtcm->sta.glo_cp_bias[j]=bias*0.02;
}
}
return 5;
}
/* decode type 4073: proprietary message Mitsubishi Electric -----------------*/
static int decode_type4073(rtcm_t *rtcm)
{
int i=24+12,subtype;
subtype=getbitu(rtcm->buff,i,4); i+=4;
if (rtcm->outtype) {
sprintf(rtcm->msgtype+strlen(rtcm->msgtype)," subtype=%d",subtype);
}
trace(2,"rtcm3 4073: unsupported message subtype=%d\n",subtype);
return 0;
}
/* decode type 4076: proprietary message IGS ---------------------------------*/
static int decode_type4076(rtcm_t *rtcm)
{
int i=24+12,ver,subtype;
if (i+3+8>=rtcm->len*8) {
trace(2,"rtcm3 4076: length error len=%d\n",rtcm->len);
return -1;
}
ver =getbitu(rtcm->buff,i,3); i+=3;
subtype=getbitu(rtcm->buff,i,8); i+=8;
if (rtcm->outtype) {
sprintf(rtcm->msgtype+strlen(rtcm->msgtype)," ver=%d subtype=%3d",ver,
subtype);
}
switch (subtype) {
case 21: return decode_ssr1(rtcm,SYS_GPS,subtype);
case 22: return decode_ssr2(rtcm,SYS_GPS,subtype);
case 23: return decode_ssr4(rtcm,SYS_GPS,subtype);
case 24: return decode_ssr6(rtcm,SYS_GPS,subtype);
case 25: return decode_ssr3(rtcm,SYS_GPS,subtype);
case 26: return decode_ssr7(rtcm,SYS_GPS,subtype);
case 27: return decode_ssr5(rtcm,SYS_GPS,subtype);
case 41: return decode_ssr1(rtcm,SYS_GLO,subtype);
case 42: return decode_ssr2(rtcm,SYS_GLO,subtype);
case 43: return decode_ssr4(rtcm,SYS_GLO,subtype);
case 44: return decode_ssr6(rtcm,SYS_GLO,subtype);
case 45: return decode_ssr3(rtcm,SYS_GLO,subtype);
case 46: return decode_ssr7(rtcm,SYS_GLO,subtype);
case 47: return decode_ssr5(rtcm,SYS_GLO,subtype);
case 61: return decode_ssr1(rtcm,SYS_GAL,subtype);
case 62: return decode_ssr2(rtcm,SYS_GAL,subtype);
case 63: return decode_ssr4(rtcm,SYS_GAL,subtype);
case 64: return decode_ssr6(rtcm,SYS_GAL,subtype);
case 65: return decode_ssr3(rtcm,SYS_GAL,subtype);
case 66: return decode_ssr7(rtcm,SYS_GAL,subtype);
case 67: return decode_ssr5(rtcm,SYS_GAL,subtype);
case 81: return decode_ssr1(rtcm,SYS_QZS,subtype);
case 82: return decode_ssr2(rtcm,SYS_QZS,subtype);
case 83: return decode_ssr4(rtcm,SYS_QZS,subtype);
case 84: return decode_ssr6(rtcm,SYS_QZS,subtype);
case 85: return decode_ssr3(rtcm,SYS_QZS,subtype);
case 86: return decode_ssr7(rtcm,SYS_QZS,subtype);
case 87: return decode_ssr5(rtcm,SYS_QZS,subtype);
case 101: return decode_ssr1(rtcm,SYS_CMP,subtype);
case 102: return decode_ssr2(rtcm,SYS_CMP,subtype);
case 103: return decode_ssr4(rtcm,SYS_CMP,subtype);
case 104: return decode_ssr6(rtcm,SYS_CMP,subtype);
case 105: return decode_ssr3(rtcm,SYS_CMP,subtype);
case 106: return decode_ssr7(rtcm,SYS_CMP,subtype);
case 107: return decode_ssr5(rtcm,SYS_CMP,subtype);
case 121: return decode_ssr1(rtcm,SYS_SBS,subtype);
case 122: return decode_ssr2(rtcm,SYS_SBS,subtype);
case 123: return decode_ssr4(rtcm,SYS_SBS,subtype);
case 124: return decode_ssr6(rtcm,SYS_SBS,subtype);
case 125: return decode_ssr3(rtcm,SYS_SBS,subtype);
case 126: return decode_ssr7(rtcm,SYS_SBS,subtype);
case 127: return decode_ssr5(rtcm,SYS_SBS,subtype);
}
trace(2,"rtcm3 4076: unsupported message subtype=%d\n",subtype);
return 0;
}
/* decode RTCM ver.3 message -------------------------------------------------*/
extern int decode_rtcm3(rtcm_t *rtcm)
{
double tow;
int ret=0,type=getbitu(rtcm->buff,24,12),week;
// trace(3,"decode_rtcm3: len=%3d type=%d\n",rtcm->len,type);
if (rtcm->outtype) {
sprintf(rtcm->msgtype,"RTCM %4d (%4d):",type,rtcm->len);
}
/* real-time input option */
if (strstr(rtcm->opt,"-RT_INP")) {
tow=time2gpst(utc2gpst(timeget()),&week);
rtcm->time=gpst2time(week,floor(tow));
}
switch (type) {
case 999: ret=decode_typeIMU(rtcm); break;
case 1001: ret=decode_type1001(rtcm); break; /* not supported */
case 1002: ret=decode_type1002(rtcm); break;
case 1003: ret=decode_type1003(rtcm); break; /* not supported */
case 1004: ret=decode_type1004(rtcm); break;
case 1005: ret=decode_type1005(rtcm); break;
case 1006: ret=decode_type1006(rtcm); break;
case 1007: ret=decode_type1007(rtcm); break;
case 1008: ret=decode_type1008(rtcm); break;
case 1009: ret=decode_type1009(rtcm); break; /* not supported */
case 1010: ret=decode_type1010(rtcm); break;
case 1011: ret=decode_type1011(rtcm); break; /* not supported */
case 1012: ret=decode_type1012(rtcm); break;
case 1013: ret=decode_type1013(rtcm); break; /* not supported */
case 1019: ret=decode_type1019(rtcm); break;
case 1020: ret=decode_type1020(rtcm); break;
case 1021: ret=decode_type1021(rtcm); break; /* not supported */
case 1022: ret=decode_type1022(rtcm); break; /* not supported */
case 1023: ret=decode_type1023(rtcm); break; /* not supported */
case 1024: ret=decode_type1024(rtcm); break; /* not supported */
case 1025: ret=decode_type1025(rtcm); break; /* not supported */
case 1026: ret=decode_type1026(rtcm); break; /* not supported */
case 1027: ret=decode_type1027(rtcm); break; /* not supported */
case 1029: ret=decode_type1029(rtcm); break;
case 1030: ret=decode_type1030(rtcm); break; /* not supported */
case 1031: ret=decode_type1031(rtcm); break; /* not supported */
case 1032: ret=decode_type1032(rtcm); break; /* not supported */
case 1033: ret=decode_type1033(rtcm); break;
case 1034: ret=decode_type1034(rtcm); break; /* not supported */
case 1035: ret=decode_type1035(rtcm); break; /* not supported */
case 1037: ret=decode_type1037(rtcm); break; /* not supported */
case 1038: ret=decode_type1038(rtcm); break; /* not supported */
case 1039: ret=decode_type1039(rtcm); break; /* not supported */
case 1041: ret=decode_type1041(rtcm); break;
case 1044: ret=decode_type1044(rtcm); break;
case 1045: ret=decode_type1045(rtcm); break;
case 1046: ret=decode_type1046(rtcm); break;
case 63: ret=decode_type1042(rtcm); break; /* RTCM draft */
case 1042: ret=decode_type1042(rtcm); break;
case 1057: ret=decode_ssr1(rtcm,SYS_GPS,0); break;
case 1058: ret=decode_ssr2(rtcm,SYS_GPS,0); break;
case 1059: ret=decode_ssr3(rtcm,SYS_GPS,0); break;
case 1060: ret=decode_ssr4(rtcm,SYS_GPS,0); break;
case 1061: ret=decode_ssr5(rtcm,SYS_GPS,0); break;
case 1062: ret=decode_ssr6(rtcm,SYS_GPS,0); break;
case 1063: ret=decode_ssr1(rtcm,SYS_GLO,0); break;
case 1064: ret=decode_ssr2(rtcm,SYS_GLO,0); break;
case 1065: ret=decode_ssr3(rtcm,SYS_GLO,0); break;
case 1066: ret=decode_ssr4(rtcm,SYS_GLO,0); break;
case 1067: ret=decode_ssr5(rtcm,SYS_GLO,0); break;
case 1068: ret=decode_ssr6(rtcm,SYS_GLO,0); break;
case 1071: ret=decode_msm0(rtcm,SYS_GPS); break; /* not supported */
case 1072: ret=decode_msm0(rtcm,SYS_GPS); break; /* not supported */
case 1073: ret=decode_msm0(rtcm,SYS_GPS); break; /* not supported */
case 1074: ret=decode_msm4(rtcm,SYS_GPS); break;
case 1075: ret=decode_msm5(rtcm,SYS_GPS); break;
case 1076: ret=decode_msm6(rtcm,SYS_GPS); break;
case 1077: ret=decode_msm7(rtcm,SYS_GPS); break;
case 1081: ret=decode_msm0(rtcm,SYS_GLO); break; /* not supported */
case 1082: ret=decode_msm0(rtcm,SYS_GLO); break; /* not supported */
case 1083: ret=decode_msm0(rtcm,SYS_GLO); break; /* not supported */
case 1084: ret=decode_msm4(rtcm,SYS_GLO); break;
case 1085: ret=decode_msm5(rtcm,SYS_GLO); break;
case 1086: ret=decode_msm6(rtcm,SYS_GLO); break;
case 1087: ret=decode_msm7(rtcm,SYS_GLO); break;
case 1091: ret=decode_msm0(rtcm,SYS_GAL); break; /* not supported */
case 1092: ret=decode_msm0(rtcm,SYS_GAL); break; /* not supported */
case 1093: ret=decode_msm0(rtcm,SYS_GAL); break; /* not supported */
case 1094: ret=decode_msm4(rtcm,SYS_GAL); break;
case 1095: ret=decode_msm5(rtcm,SYS_GAL); break;
case 1096: ret=decode_msm6(rtcm,SYS_GAL); break;
case 1097: ret=decode_msm7(rtcm,SYS_GAL); break;
case 1101: ret=decode_msm0(rtcm,SYS_SBS); break; /* not supported */
case 1102: ret=decode_msm0(rtcm,SYS_SBS); break; /* not supported */
case 1103: ret=decode_msm0(rtcm,SYS_SBS); break; /* not supported */
case 1104: ret=decode_msm4(rtcm,SYS_SBS); break;
case 1105: ret=decode_msm5(rtcm,SYS_SBS); break;
case 1106: ret=decode_msm6(rtcm,SYS_SBS); break;
case 1107: ret=decode_msm7(rtcm,SYS_SBS); break;
case 1111: ret=decode_msm0(rtcm,SYS_QZS); break; /* not supported */
case 1112: ret=decode_msm0(rtcm,SYS_QZS); break; /* not supported */
case 1113: ret=decode_msm0(rtcm,SYS_QZS); break; /* not supported */
case 1114: ret=decode_msm4(rtcm,SYS_QZS); break;
case 1115: ret=decode_msm5(rtcm,SYS_QZS); break;
case 1116: ret=decode_msm6(rtcm,SYS_QZS); break;
case 1117: ret=decode_msm7(rtcm,SYS_QZS); break;
case 1121: ret=decode_msm0(rtcm,SYS_CMP); break; /* not supported */
case 1122: ret=decode_msm0(rtcm,SYS_CMP); break; /* not supported */
case 1123: ret=decode_msm0(rtcm,SYS_CMP); break; /* not supported */
case 1124: ret=decode_msm4(rtcm,SYS_CMP); break;
case 1125: ret=decode_msm5(rtcm,SYS_CMP); break;
case 1126: ret=decode_msm6(rtcm,SYS_CMP); break;
case 1127: ret=decode_msm7(rtcm,SYS_CMP); break;
case 1131: ret=decode_msm0(rtcm,SYS_IRN); break; /* not supported */
case 1132: ret=decode_msm0(rtcm,SYS_IRN); break; /* not supported */
case 1133: ret=decode_msm0(rtcm,SYS_IRN); break; /* not supported */
case 1134: ret=decode_msm4(rtcm,SYS_IRN); break;
case 1135: ret=decode_msm5(rtcm,SYS_IRN); break;
case 1136: ret=decode_msm6(rtcm,SYS_IRN); break;
case 1137: ret=decode_msm7(rtcm,SYS_IRN); break;
case 1230: ret=decode_type1230(rtcm); break;
case 1240: ret=decode_ssr1(rtcm,SYS_GAL,0); break; /* draft */
case 1241: ret=decode_ssr2(rtcm,SYS_GAL,0); break; /* draft */
case 1242: ret=decode_ssr3(rtcm,SYS_GAL,0); break; /* draft */
case 1243: ret=decode_ssr4(rtcm,SYS_GAL,0); break; /* draft */
case 1244: ret=decode_ssr5(rtcm,SYS_GAL,0); break; /* draft */
case 1245: ret=decode_ssr6(rtcm,SYS_GAL,0); break; /* draft */
case 1246: ret=decode_ssr1(rtcm,SYS_QZS,0); break; /* draft */
case 1247: ret=decode_ssr2(rtcm,SYS_QZS,0); break; /* draft */
case 1248: ret=decode_ssr3(rtcm,SYS_QZS,0); break; /* draft */
case 1249: ret=decode_ssr4(rtcm,SYS_QZS,0); break; /* draft */
case 1250: ret=decode_ssr5(rtcm,SYS_QZS,0); break; /* draft */
case 1251: ret=decode_ssr6(rtcm,SYS_QZS,0); break; /* draft */
case 1252: ret=decode_ssr1(rtcm,SYS_SBS,0); break; /* draft */
case 1253: ret=decode_ssr2(rtcm,SYS_SBS,0); break; /* draft */
case 1254: ret=decode_ssr3(rtcm,SYS_SBS,0); break; /* draft */
case 1255: ret=decode_ssr4(rtcm,SYS_SBS,0); break; /* draft */
case 1256: ret=decode_ssr5(rtcm,SYS_SBS,0); break; /* draft */
case 1257: ret=decode_ssr6(rtcm,SYS_SBS,0); break; /* draft */
case 1258: ret=decode_ssr1(rtcm,SYS_CMP,0); break; /* draft */
case 1259: ret=decode_ssr2(rtcm,SYS_CMP,0); break; /* draft */
case 1260: ret=decode_ssr3(rtcm,SYS_CMP,0); break; /* draft */
case 1261: ret=decode_ssr4(rtcm,SYS_CMP,0); break; /* draft */
case 1262: ret=decode_ssr5(rtcm,SYS_CMP,0); break; /* draft */
case 1263: ret=decode_ssr6(rtcm,SYS_CMP,0); break; /* draft */
case 11: ret=decode_ssr7(rtcm,SYS_GPS,0); break; /* tentative */
case 12: ret=decode_ssr7(rtcm,SYS_GAL,0); break; /* tentative */
case 13: ret=decode_ssr7(rtcm,SYS_QZS,0); break; /* tentative */
case 14: ret=decode_ssr7(rtcm,SYS_CMP,0); break; /* tentative */
case 4073: ret=decode_type4073(rtcm); break;
case 4076: ret=decode_type4076(rtcm); break;
}
if (ret>=0) {
if (1001<=type&&type<=1299) rtcm->nmsg3[type-1000]++; /* 1-299 */
else if (4070<=type&&type<=4099) rtcm->nmsg3[type-3770]++; /* 300-329 */
else rtcm->nmsg3[0]++; /* other */
}
return ret;
}