bug修复--rtklib demo5_b34e decode_obsdata函数

最近,我在使用rtklib低成本优化版本demo5进行静态ppp解算时,发现程序读取的观测数据错误,经过反复排查后发现是程序bug引起的。
demo5_b34e rinex.c 中 decode_obsdata函数按照优先级的选取观测值部分存在问题,导致数组超界。

原函数(存在bug):

/* decode observation data ---------------------------------------------------*/
static int decode_obsdata(FILE *fp, char *buff, double ver, int mask,
						  sigind_t *index, obsd_t *obs)
{
    sigind_t *ind;
    double val[MAXOBSTYPE]={0};
    uint8_t lli[MAXOBSTYPE]={0};
    uint8_t std[MAXOBSTYPE]={0};
    char satid[8]="";
    int i,j,n,m,q,stat=1,p[MAXOBSTYPE],k[16],l[16],r[16];
    
	trace(4,"decode_obsdata: ver=%.2f\n",ver);
    
	if (ver>2.99) { /* ver.3 */
        sprintf(satid,"%.3s",buff);
        obs->sat=(uint8_t)satid2no(satid);
    }
    if (!obs->sat) {
        trace(4,"decode_obsdata: unsupported sat sat=%s\n",satid);
        stat=0;
    }
    else if (!(satsys(obs->sat,NULL)&mask)) {
        stat=0;
    }
    /* read observation data fields */
    switch (satsys(obs->sat,NULL)) {
        case SYS_GLO: ind=index+1; break;
        case SYS_GAL: ind=index+2; break;
        case SYS_QZS: ind=index+3; break;
        case SYS_SBS: ind=index+4; break;
        case SYS_CMP: ind=index+5; break;
        case SYS_IRN: ind=index+6; break;
        default:      ind=index  ; break;
    }
	for (i=0,j=ver<=2.99?0:3;i<ind->n;i++,j+=16) {
        
        if (ver<=2.99&&j>=80) { /* ver.2 */
            if (!fgets(buff,MAXRNXLEN,fp)) break;
            j=0;
        }
        if (stat) {
            val[i]=str2num(buff,j,14)+ind->shift[i];
			lli[i]=(uint8_t)str2num(buff,j+14,1)&3;
            /* measurement std from receiver */
            std[i]=(uint8_t)str2num(buff,j+15,1);
		}
    }
    if (!stat) return 0;

	for (i=0;i<NFREQ+NEXOBS;i++) {
		obs->P[i]=obs->L[i]=0.0; obs->D[i]=0.0f;
        obs->SNR[i]=obs->LLI[i]=obs->Lstd[i]=obs->Pstd[i]=obs->code[i]=0;
	}

	/* assign position in observation data */
    for (i=n=m=q=0;i<ind->n;i++) {
        
		p[i]=ind->idx[i];
        
        if (ind->type[i]==0&&p[i]==0) k[n++]=i; /* C1? index */
        if (ind->type[i]==0&&p[i]==1) l[m++]=i; /* C2? index */
        if (ind->type[i]==0&&p[i]==2) r[q++]=i; /* C3? index */
    }
        
	/* if multiple codes (C1/P1,C2/P2), select higher priority */
    if (n>=2) {
        if (val[k[0]]==0.0&&val[k[1]]==0.0) {
            p[k[0]]=-1; p[k[1]]=-1;
        }
        else if (val[k[0]]!=0.0&&val[k[1]]==0.0) {
            p[k[0]]=0; p[k[1]]=-1;
        }
        else if (val[k[0]]==0.0&&val[k[1]]!=0.0) {
            p[k[0]]=-1; p[k[1]]=0;
        }
        else if (ind->pri[k[1]]>ind->pri[k[0]]) {
            p[k[1]]=0; p[k[0]]=NEXOBS<1?-1:NFREQ;
		}
        else {
            p[k[0]]=0; p[k[1]]=NEXOBS<1?-1:NFREQ;
        }
    }
	if (m>=2) {
        if (val[l[0]]==0.0&&val[l[1]]==0.0) {
            p[l[0]]=-1; p[l[1]]=-1;
        }
        else if (val[l[0]]!=0.0&&val[l[1]]==0.0) {
            p[l[0]]=1; p[l[1]]=-1;
        }
        else if (val[l[0]]==0.0&&val[l[1]]!=0.0) {
            p[l[0]]=-1; p[l[1]]=1; 
        }
        else if (ind->pri[l[1]]>ind->pri[l[0]]) {
            p[l[1]]=1; p[l[0]]=NEXOBS<2?-1:NFREQ+1;
        }
        else {
            p[l[0]]=1; p[l[1]]=NEXOBS<2?-1:NFREQ+1;
        }
    }
    if (q>=2) {
        if (val[r[0]]==0.0&&val[r[1]]==0.0) {
            p[r[0]]=-1; p[r[1]]=-1;
        }
        else if (val[r[0]]!=0.0&&val[r[1]]==0.0) {
            p[l[0]]=1; p[l[1]]=-1;
        }
        else if (val[r[0]]==0.0&&val[r[1]]!=0.0) {
            p[r[0]]=-1; p[r[1]]=1;
        }
        else if (ind->pri[r[1]]>ind->pri[r[0]]) {
            p[r[1]]=1; p[r[0]]=NEXOBS<3?-1:NFREQ+2;
        }
        else {
            p[r[0]]=1; p[r[1]]=NEXOBS<3?-1:NFREQ+2;
		}
    }
    /* save observation data */
	for (i=0;i<ind->n;i++) {
		if (p[i]<0||(val[i]==0.0&&lli[i]==0)) continue;
        switch (ind->type[i]) {
			case 0: obs->P[p[i]]=val[i];
                    obs->code[p[i]]=ind->code[i];
                    obs->Pstd[p[i]]=std[i]>0?std[i]:1;
                    break;
            case 1: obs->L[p[i]]=val[i];
					obs->LLI[p[i]]=lli[i];
                    obs->Lstd[p[i]]=std[i]>0?std[i]:1;
                    break;
			case 2: obs->D[p[i]]=(float)val[i];                     break;
            case 3: obs->SNR[p[i]]=(uint16_t)(val[i]/SNR_UNIT+0.5); break;
        }
    }
	trace(4,"decode_obsdata: time=%s sat=%2d\n",time_str(obs->time,0),obs->sat);
    return 1;
}

修复后函数:

/* decode observation data ---------------------------------------------------*/
static int decode_obsdata(FILE *fp, char *buff, double ver, int mask,
                          sigind_t *index, obsd_t *obs)
{
    sigind_t *ind;
    double val[MAXOBSTYPE]={0};
    uint8_t lli[MAXOBSTYPE]={0};
    uint8_t std[MAXOBSTYPE]={0};
    char satid[8]="";
    int i,j,n,m,q,stat=1,ifrq[MAXOBSTYPE],k[16],l[16],r[16];
    int f, iobs[NFREQ][MAXOBSTYPE / 4], nobs[NFREQ], maxpri, imax;
    
    trace(4,"decode_obsdata: ver=%.2f\n",ver);
    
    if (ver>2.99) { /* ver.3 */
        sprintf(satid,"%.3s",buff);
        obs->sat=(uint8_t)satid2no(satid);
    }
    if (!obs->sat) {
        trace(4,"decode_obsdata: unsupported sat sat=%s\n",satid);
        stat=0;
    }
    else if (!(satsys(obs->sat,NULL)&mask)) {
        stat=0;
    }
    /* read observation data fields */
    switch (satsys(obs->sat,NULL)) {
        case SYS_GLO: ind=index+1; break;
        case SYS_GAL: ind=index+2; break;
        case SYS_QZS: ind=index+3; break;
        case SYS_SBS: ind=index+4; break;
        case SYS_CMP: ind=index+5; break;
        case SYS_IRN: ind=index+6; break;
        default:      ind=index  ; break;
    }
    for (i=0,j=ver<=2.99?0:3;i<ind->n;i++,j+=16) {
        
        if (ver<=2.99&&j>=80) { /* ver.2 */
            if (!fgets(buff,MAXRNXLEN,fp)) break;
            j=0;
        }
        if (stat) {
            val[i]=str2num(buff,j,14)+ind->shift[i];
            lli[i]=(uint8_t)str2num(buff,j+14,1)&3;
            /* measurement std from receiver */
            std[i]=(uint8_t)str2num(buff,j+15,1);
        }
    }
    if (!stat) return 0;
    
    for (i=0;i<NFREQ+NEXOBS;i++) {
        obs->P[i]=obs->L[i]=0.0; obs->D[i]=0.0f;
        obs->SNR[i]=obs->LLI[i]=obs->Lstd[i]=obs->Pstd[i]=obs->code[i]=0;
    }

    /* initialize iobs and nobs */
    for (f = 0; f < NFREQ; f++) {
        nobs[f] = 0;
        for (j = 0; j < MAXOBSTYPE / 4; j++) {
            iobs[f][j] = -1;
        }
    }
    
    /* 每个频率伪距观测值类型个数统计 */
    for (i = 0; i < ind->n; i++) {                  /* assign position in observation data */
        ifrq[i] = -1;                               // initial ifrq

        if (ind->type[i] != 0) continue;            // not pseudo-range type
        if (val[i] == 0.0) continue;                // null value

        f = ind->idx[i];                            // frequancy index
        iobs[f][nobs[f]++] = i;                     
    }

    /* 每个频率选择一个码类型 */
    for (f = 0; f < NFREQ; f++) {
        /* 具有最高优先级的码类型 */
        for (i = 0, maxpri = -1, imax = -1; i < nobs[f]; i++) {
            if (ind->pri[iobs[f][i]] > maxpri) {
                imax = i;
                maxpri = ind->pri[iobs[f][i]];
            }
        }
        if (imax < 0) continue;
        /* the pesudo-range obs of frequency f with highest priority */
        for (i = 0; i < ind->n; i++) {
            if (ind->code[i] == ind->code[iobs[f][imax]]) {
                ifrq[i] = f;
            }
        }
    }

    /* assign index of extended observation data */
    for (f = 0; f < NEXOBS; f++) {
        /* 具有最高优先级的码类型 */
        for (i = 0, maxpri = -1, imax = -1; i < nobs[f]; i++) {
            if (ifrq[iobs[f][i]] > 0) continue;

            if (ind->pri[iobs[f][i]] > maxpri) {
                imax = i;
                maxpri = ind->pri[iobs[f][i]];
            }
        }
        if (imax < 0) continue;
        /* the pesudo-range obs of frequency f with highest priority */
        for (i = 0; i < ind->n; i++) {
            if (ind->code[i] == ind->code[iobs[f][imax]]) {
                ifrq[i] = f + NFREQ;
            }
        }
    }

    /* save observation data */
    for (i=0;i<ind->n;i++) {
        if (ifrq[i]<0 || ifrq[i] >= NFREQ + NEXOBS ||(val[i]==0.0&&lli[i]==0)) continue;
        switch (ind->type[i]) {
            case 0: obs->P[ifrq[i]]=val[i];
                    obs->code[ifrq[i]]=ind->code[i];
                    obs->Pstd[ifrq[i]]=std[i]>0?std[i]:1;
                    break;
            case 1: obs->L[ifrq[i]]=val[i];
                    obs->LLI[ifrq[i]]=lli[i];
                    obs->Lstd[ifrq[i]]=std[i]>0?std[i]:1;
                    break;
            case 2: obs->D[ifrq[i]]=(float)val[i];                     break;
            case 3: obs->SNR[ifrq[i]]=(uint16_t)(val[i]/SNR_UNIT+0.5); break;
        }
    }
    trace(4,"decode_obsdata: time=%s sat=%2d\n",time_str(obs->time,0),obs->sat);
    return 1;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值