📄 refclock_oncore.c
字号:
instance->posn_set = 1; if (!( lat_flg && long_flg && ht_flg )) { printf("ONCORE: incomplete data on %s\n", device); instance->posn_set = 0; if (mode == 1 || mode == 3) { sprintf(Msg, "Input Mode = %d, but no/incomplete position, mode set to %d", mode, mode+1); record_clock_stats(&(instance->peer->srcadr), Msg); mode++; } } instance->init_type = mode; sprintf(Msg, "Input mode = %d", mode); record_clock_stats(&(instance->peer->srcadr), Msg);}/* * move data from NTP to buffer (toss the extra in the unlikely case it won't fit) */static voidoncore_receive( struct recvbuf *rbufp ){ size_t i; u_char *p; struct peer *peer; struct instance *instance; peer = (struct peer *)rbufp->recv_srcclock; instance = (struct instance *) peer->procptr->unitptr; p = (u_char *) &rbufp->recv_space;#if 0 if (debug > 4) { int i; printf("ONCORE: >>>"); for(i=0; i<rbufp->recv_length; i++) printf("%02x ", p[i]); printf("\n"); printf("ONCORE: >>>"); for(i=0; i<rbufp->recv_length; i++) printf("%03o ", p[i]); printf("\n"); }#endif i = rbufp->recv_length; if (rcvbuf+rcvptr+i > &rcvbuf[sizeof rcvbuf]) i = sizeof(rcvbuf) - rcvptr; /* and some char will be lost */ memcpy(rcvbuf+rcvptr, p, i); rcvptr += i; oncore_consume(instance);}/* * Deal with any complete messages */static voidoncore_consume( struct instance *instance ){ int i, m; unsigned l; while (rcvptr >= 7) { if (rcvbuf[0] != '@' || rcvbuf[1] != '@') { /* We're not in sync, lets try to get there */ for (i=1; i < rcvptr-1; i++) if (rcvbuf[i] == '@' && rcvbuf[i+1] == '@') break; if (debug > 4) printf("ONCORE[%d]: >>> skipping %d chars\n", instance->unit, i); if (i != rcvptr) memcpy(rcvbuf, rcvbuf+i, (size_t)(rcvptr-i)); rcvptr -= i; continue; } /* Ok, we have a header now */ l = sizeof(oncore_messages)/sizeof(oncore_messages[0]) -1; for(m=0; m<l; m++) if (!strncmp(oncore_messages[m].flag, (char *)(rcvbuf+2), (size_t) 2)) break; if (m == l) { if (debug > 4) printf("ONCORE[%d]: >>> Unknown MSG, skipping 4 (%c%c)\n", instance->unit, rcvbuf[2], rcvbuf[3]); memcpy(rcvbuf, rcvbuf+4, (size_t) 4); rcvptr -= 4; continue; } l = oncore_messages[m].len;#if 0 if (debug > 3) printf("ONCORE[%d]: GOT: %c%c %d of %d entry %d\n", instance->unit, rcvbuf[2], rcvbuf[3], rcvptr, l, m);#endif /* Got the entire message ? */ if (rcvptr < l) return; /* are we at the end of message? should be <Cksum><CR><LF> */ if (rcvbuf[l-2] != '\r' || rcvbuf[l-1] != '\n') { if (debug) printf("ONCORE[%d]: NO <CR><LF> at end of message\n", instance->unit); } else { /* check the CheckSum */ if (oncore_checksum_ok(rcvbuf, l)) { if (instance->shmem != NULL) { instance->shmem[oncore_messages[m].shmem + 2]++; memcpy(instance->shmem + oncore_messages[m].shmem + 3, rcvbuf, (size_t) l); } oncore_msg_any(instance, rcvbuf, (size_t) (l-3), m); if (oncore_messages[m].handler) oncore_messages[m].handler(instance, rcvbuf, (size_t) (l-3)); } else if (debug) { printf("ONCORE[%d]: Checksum mismatch!\n", instance->unit); printf("ONCORE[%d]: @@%c%c ", instance->unit, rcvbuf[2], rcvbuf[3]); for (i=4; i<l; i++) printf("%03o ", rcvbuf[i]); printf("\n"); } } if (l != rcvptr) memcpy(rcvbuf, rcvbuf+l, (size_t) (rcvptr-l)); rcvptr -= l; }}static voidoncore_get_timestamp( struct instance *instance, long dt1, /* tick offset THIS time step */ long dt2 /* tick offset NEXT time step */ ){ int Rsm; u_long j; l_fp ts, ts_tmp; double dmy;#ifdef HAVE_STRUCT_TIMESPEC struct timespec *tsp = 0;#else struct timeval *tsp = 0;#endif int current_mode; u_long i; pps_params_t current_params; struct timespec timeout; pps_info_t pps_i;#if 1 /* If we are in SiteSurvey mode, then we are in 3D mode, and we fall thru. * If we have Finished the SiteSurvey, then we fall thru for the 14/15 * times we get here in 0D mode (the 1/15 is in 3D for SHMEM). * This gives good time, which gets better when the SS is done. */ if ((instance->site_survey == ONCORE_SS_DONE) && (instance->mode != MODE_0D))#else /* old check, only fall thru for SS_DONE and 0D mode, 2h45m wait for ticks */ if ((instance->site_survey != ONCORE_SS_DONE) || (instance->mode != MODE_0D))#endif return; /* Don't do anything without an almanac to define the GPS->UTC delta */ if (instance->rsm.bad_almanac) return; j = instance->ev_serial; timeout.tv_sec = 0; timeout.tv_nsec = 0; if (time_pps_fetch(instance->pps_h, PPS_TSFMT_TSPEC, &pps_i, &timeout) < 0) { printf("ONCORE: time_pps_fetch failed\n"); return; } if (instance->assert) { tsp = &pps_i.assert_timestamp; if (debug > 2) { i = (u_long) pps_i.assert_sequence;#ifdef HAVE_STRUCT_TIMESPEC printf("ONCORE[%d]: serial/j (%lu, %lu) %ld.%09ld\n", instance->unit, i, j, (long)tsp->tv_sec, (long)tsp->tv_nsec);#else printf("ONCORE[%d]: serial/j (%lu, %lu) %ld.%06ld\n", instance->unit, i, j, (long)tsp->tv_sec, (long)tsp->tv_usec);#endif } if (pps_i.assert_sequence == j) { printf("ONCORE: oncore_get_timestamp, error serial pps\n"); return; } instance->ev_serial = pps_i.assert_sequence; } else { tsp = &pps_i.clear_timestamp; if (debug > 2) { i = (u_long) pps_i.clear_sequence;#ifdef HAVE_STRUCT_TIMESPEC printf("ONCORE[%d]: serial/j (%lu, %lu) %ld.%09ld\n", instance->unit, i, j, (long)tsp->tv_sec, (long)tsp->tv_nsec);#else printf("ONCORE[%d]: serial/j (%lu, %lu) %ld.%06ld\n", instance->unit, i, j, (long)tsp->tv_sec, (long)tsp->tv_usec);#endif } if (pps_i.clear_sequence == j) { printf("ONCORE: oncore_get_timestamp, error serial pps\n"); return; } instance->ev_serial = pps_i.clear_sequence; } /* convert timespec -> ntp l_fp */ dmy = tsp->tv_nsec; dmy /= 1e9; ts.l_uf = dmy * 4294967296.0; ts.l_ui = tsp->tv_sec;#if 0 alternate code for previous 4 lines is dmy = 1.0e-9*tsp->tv_nsec; /* fractional part */ DTOLFP(dmy, &ts); dmy = tsp->tv_sec; /* integer part */ DTOLFP(dmy, &ts_tmp); L_ADD(&ts, &ts_tmp); or more simply dmy = 1.0e-9*tsp->tv_nsec; /* fractional part */ DTOLFP(dmy, &ts); ts.l_ui = tsp->tv_sec;#endif /* 0 */ /* now have timestamp in ts */ /* add in saw_tooth and offset, these will be ZERO if no TRAIM */ /* they will be IGNORED if the PPSAPI cant do PPS_OFFSET/ASSERT/CLEAR */ /* we just try to add them in and dont test for that here */ /* saw_tooth not really necessary if using TIMEVAL */ /* since its only precise to us, but do it anyway. */ /* offset in ns, and is positive (late), we subtract */ /* to put the PPS time transition back where it belongs */ /* must hand the offset for the NEXT sec off to the Kernel to do */ /* the addition, so that the Kernel PLL sees the offset too */ if (instance->assert) instance->pps_p.assert_offset.tv_nsec = -dt2; else instance->pps_p.clear_offset.tv_nsec = -dt2; /* The following code is necessary, and not just a time_pps_setparams, * using the saved instance->pps_p, since some other process on the * machine may have diddled with the mode bits (say adding something * that it needs). We take what is there and ADD what we need. * [[ The results from the time_pps_getcap is unlikely to change so * we could probably just save it, but I choose to do the call ]] * Unfortunately, there is only ONE set of mode bits in the kernel per * interface, and not one set for each open handle. * * There is still a race condition here where we might mess up someone * elses mode, but if he is being careful too, he should survive. */ if (time_pps_getcap(instance->pps_h, ¤t_mode) < 0) { msyslog(LOG_ERR, "time_pps_getcap failed: %m"); return; } if (time_pps_getparams(instance->pps_h, ¤t_params) < 0) { msyslog(LOG_ERR, "time_pps_getparams failed: %m"); return; } /* or current and mine */ current_params.mode |= instance->pps_p.mode; /* but only set whats legal */ current_params.mode &= current_mode; current_params.assert_offset.tv_sec = 0; current_params.assert_offset.tv_nsec = -dt2; current_params.clear_offset.tv_sec = 0; current_params.clear_offset.tv_nsec = -dt2; if (time_pps_setparams(instance->pps_h, ¤t_params)) perror("time_pps_setparams"); /* have time from UNIX origin, convert to NTP origin. */ ts.l_ui += JAN_1970; instance->pp->lastrec = ts; /* print out information about this timestamp (long line) */ ts_tmp = ts; ts_tmp.l_ui = 0; /* zero integer part */ LFPTOD(&ts_tmp, dmy); /* convert fractional part to a double */ j = 1.0e9*dmy; /* then to integer ns */ Rsm = 0; if (instance->chan == 6) Rsm = instance->BEHa[64]; else if (instance->chan == 8) Rsm = instance->BEHa[72]; else if (instance->chan == 12) Rsm = ((instance->BEHa[129]<<8) | instance->BEHa[130]); if (instance->chan == 6 || instance->chan == 8) { char f1[5], f2[5], f3[5], f4[5]; if (instance->traim) { sprintf(f1, "%d", instance->BEHn[21]); sprintf(f2, "%d", instance->BEHn[22]); sprintf(f3, "%2d", instance->BEHn[23]*256+instance->BEHn[24]); sprintf(f4, "%3d", (s_char) instance->BEHn[25]); } else { strcpy(f1, "x"); strcpy(f2, "x"); strcpy(f3, "xx"); strcpy(f4, "xxx"); } sprintf(instance->pp->a_lastcode, /* MAX length 128, currently at 121 */ "%u.%09lu %d %d %2d %2d %2d %2ld rstat %02x dop %4.1f nsat %2d,%d traim %d,%s,%s sigma %s neg-sawtooth %s sat %d%d%d%d%d%d%d%d", ts.l_ui, j, instance->pp->year, instance->pp->day, instance->pp->hour, instance->pp->minute, instance->pp->second, (long) tsp->tv_sec % 60, Rsm, 0.1*(256*instance->BEHa[35]+instance->BEHa[36]), /*rsat dop */ instance->BEHa[38], instance->BEHa[39], instance->traim, f1, f2, /* nsat visible, nsat tracked, traim,traim,traim */ f3, f4, /* sigma neg-sawtooth */ /*sat*/ instance->BEHa[41], instance->BEHa[45], instance->BEHa[49], instance->BEHa[53], instance->BEHa[57], instance->BEHa[61], instance->BEHa[65], instance->BEHa[69] ); /* will be 0 for 6 chan */ } else if (instance->chan == 12) { char f1[5], f2[5], f3[5], f4[5]; if (instance->traim) { sprintf(f1, "%d", instance->BEHn[6]); sprintf(f2, "%d", instance->BEHn[7]); sprintf(f3, "%d", instance->BEHn[12]*256+instance->BEHn[13]); sprintf(f4, "%3d", (s_char) instance->BEHn[14]); } else { strcpy(f1, "x"); strcpy(f2, "x"); strcpy(f3, "x"); strcpy(f4, "xxx"); } sprintf(instance->pp->a_lastcode, "%u.%09lu %d %d %2d %2d %2d %2ld rstat %02x dop %4.1f nsat %2d,%d traim %d,%s,%s sigma %s neg-sawtooth %s sat %d%d%d%d%d%d%d%d%d%d%d%d", ts.l_ui, j, instance->pp->year, instance->pp->day, instance->pp->hour, instance->pp->minute, instance->pp->second, (long) tsp->tv_sec % 60, Rsm, 0.1*(256*instance->BEHa[53]+instance->BEHa[54]), /*rsat dop */ instance->BEHa[55], instance->BEHa[56], instance->traim, f1, f2, /* nsat visible, nsat tracked traim,traim,traim */ f3, f4, /* sigma neg-sawtooth */ /*sat*/ instance->BEHa[58], instance->BEHa[64], instance->BEHa[70], instance->BEHa[76], instance->BEHa[82], instance->BEHa[88], instance->BEHa[94], instance->BEHa[100], instance->BEHa[106], instance->BEHa[112], instance->BEHa[118], instance->BEHa[124] ); } if (debug > 2) { int n; n = strlen(instance->pp->a_lastcode); printf("ONCORE[%d]: len = %d %s\n", instance->unit, n, instance->pp->a_lastcode); } /* and some things I dont understand (magic ntp things) */ if (!refclock_process(instance->pp)) { refclock_report(instance->peer, CEVNT_BADTIME); return; } record_clock_stats(&(instance->peer->srcadr), instance->pp->a_lastcode); instance->pollcnt = 2; if (instance->polled) { instance->polled = 0; /* instance->pp->dispersion = instance->pp->skew = 0; */ instance->pp->lastref = instance->pp->lastrec; refclock_receive(instance->peer); }}/*************** oncore_msg_XX routines start here *******************//* * print Oncore response message.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -