static int fixerr(msgblk_t * blk, const unsigned short crc, int *pr, int pn) { int i; if (pn > 0) { for (i = 0; i < 8; i++) { if (fixerr (blk, crc ^ syndrom[i + 8 * (blk->len - *pr + 1)], pr + 1, pn - 1)) { blk->txt[*pr] ^= (1 << i); return 1; } } return 0; } else { if (crc == 0) return 1; for (i = 0; i < 2 * 8; i++) if (syndrom[i] == crc) { return 1; } return 0; } }
static void *blk_thread(void *arg) { do { msgblk_t *blk; int i, pn; unsigned short crc; int pr[MAXPERR]; pthread_mutex_lock(&blkmtx); while (blkq_e == NULL) pthread_cond_wait(&blkwcd, &blkmtx); blk = blkq_e; blkq_e = blk->prev; if (blkq_e == NULL) blkq_s = NULL; pthread_mutex_unlock(&blkmtx); if (blk->len < 13) { if (verbose) fprintf(stderr, "#%d too short\n", blk->chn + 1); free(blk); continue; } /* force STX/ETX */ blk->txt[12] &= (ETX | STX); blk->txt[12] |= (ETX & STX); /* parity check */ pn = 0; for (i = 0; i < blk->len; i++) { if ((numbits[blk->txt[i]] & 1) == 0) { if (pn < MAXPERR) { pr[pn] = i; } pn++; } } if (pn > MAXPERR) { if (verbose) fprintf(stderr, "#%d too many parity errors: %d\n", blk->chn + 1, pn); free(blk); continue; } if (pn > 0 && verbose) fprintf(stderr, "#%d parity error(s): %d\n", blk->chn + 1, pn); blk->err = pn; /* crc check */ crc = 0; for (i = 0; i < blk->len; i++) { update_crc(crc, blk->txt[i]); } update_crc(crc, blk->crc[0]); update_crc(crc, blk->crc[1]); if (crc && verbose) fprintf(stderr, "#%d crc error\n", blk->chn + 1); /* try to fix error */ if (fixerr(blk, crc, pr, pn) == 0) { if (verbose) fprintf(stderr, "#%d not able to fix errors\n", blk->chn + 1); free(blk); continue; } /* redo parity checking and removing */ pn = 0; for (i = 0; i < blk->len; i++) { if ((numbits[blk->txt[i]] & 1) == 0) { pn++; } blk->txt[i] &= 0x7f; } if (pn) { fprintf(stderr, "#%d parity check problem\n", blk->chn + 1); free(blk); continue; } if (prev_t == blk->t && prev_crc[0] == blk->crc[0] && prev_crc[1] == blk->crc[1]) { if (verbose) fprintf(stderr, "#%d duplicate %d\n", blk->chn + 1, blk->lvl); free(blk); continue; } prev_t = blk->t; prev_crc[0] = blk->crc[0]; prev_crc[1] = blk->crc[1]; outputmsg(blk); free(blk); } while (1); return NULL; }
static void * blk_thread(void *arg) { do { msgblk_t *blk; acarsmsg_t msg; int i,k,pn; unsigned short crc; pthread_mutex_lock(&blkmtx); while(blkq_e==NULL) pthread_cond_wait(&blkwcd,&blkmtx); blk=blkq_e; blkq_e=blk->prev; if(blkq_e==NULL) blkq_s=NULL; pthread_mutex_unlock(&blkmtx); if(blk==NULL) return; if(blk->len<13) { if(verbose) fprintf(stderr,"#%d too short\n",blk->chn+1); free(blk); continue; } /* force STX/ETX */ blk->txt[12]&=(ETX|STX); blk->txt[12]|=(ETX&STX); msg.err=0; /* parity check */ pn=0; for(i=0;i<blk->len;i++) { if((numbits[blk->txt[i]]&1)==0) { pn++; } } if(pn>1) { if(verbose) fprintf(stderr,"#%d too much parity error : %d\n",blk->chn+1,pn); free(blk); continue; } /* crc check */ crc=0; for(i=0;i<blk->len;i++) { update_crc(crc,blk->txt[i]); } update_crc(crc,blk->crc[0]); update_crc(crc,blk->crc[1]); /* try to fix errors */ if(crc!=0) { int i,k,fx; if(verbose) fprintf(stderr,"#%d CRC error, try to recover 1 error\n",blk->chn+1); fx=0; for(i=0;i<242*8;i++) if(oneerr[i]==crc) { fixerr(blk,i/8,1<<(i%8)); fx=1; msg.err=1; break; } if(fx==0 && pn==0 && blk->len<142) { int i,k,l; unsigned char u,v; unsigned short n=0; if(verbose) fprintf(stderr,"#%d CRC error, try to recover 2 close errors\n",blk->chn+1); for(k=1,v=2;k<8;k++,v<<=1) { for(l=0,u=1;l<k;l++,u<<=1) { if(twoerr[n]==crc) { fixerr(blk,0,u|v); fx=1; msg.err=2; break; } n++; for(i=1;i<142;i++) { if(twoerr[n]==crc) { fixerr(blk,i,u|v); fx=1; msg.err=2; break; } n++; } if(i<142) break; } if(l<k) break; } } if(fx==0) { if(verbose) fprintf(stderr,"#%d not able to fix it\n",blk->chn+1); free(blk); continue; } else { if(verbose) fprintf(stderr,"#%d fix it\n",blk->chn+1); } } /* redo parity checking and remove parity */ pn=0; for(i=0;i<blk->len;i++) { if((numbits[blk->txt[i]]&1)==0) { pn++; } blk->txt[i]&=0x7f; } if(pn) { if(verbose) fprintf(stderr,"#%d parity error %d\n",blk->chn+1,pn); free(blk); continue; } /* fill msg struct */ msg.txt[0]= '\0'; msg.fid[0] = '\0'; msg.lvl = blk->lvl; k = 0; msg.mode = blk->txt[k]; k++; for (i = 0; i < 7; i++, k++) { msg.addr[i] = blk->txt[k]; } msg.addr[7] = '\0'; /* ACK/NAK */ msg.ack = blk->txt[k]; k++; msg.label[0] = blk->txt[k]; k++; msg.label[1] = blk->txt[k]; if(msg.label[1]==0x7f) msg.label[1]='d'; k++; msg.label[2] = '\0'; msg.bid = blk->txt[k]; k++; /* STX/ETX */ msg.bs=blk->txt[k]; k++; msg.no[0] = '\0'; msg.fid[0] = '\0'; if(msg.mode <= 0x5d) { /* donwlink */ if(k<blk->len) { for (i = 0; i < 4 && k<blk->len-1; i++, k++) { msg.no[i] = blk->txt[k]; } msg.no[i] = '\0'; msg.be=blk->txt[blk->len-1]; for (i = 0; i < 6 && k<blk->len-1; i++, k++) { msg.fid[i] = blk->txt[k]; } msg.fid[i] = '\0'; } } else { /* uplink */ if(airflt) { free(blk); continue; } } blk->txt[blk->len-1]='\0'; strncpy(msg.txt, &(blk->txt[k]),240);msg.txt[239]=0; if(outtype==0) printoneline(&msg,blk->chn,blk->t); else if (outtype==1) printmsg(&msg,blk->chn,blk->t); else if (outtype==2) send_udp(&msg,blk->chn,blk->t); free(blk); } while(1); }