⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 refclock_neoclock4x.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
  neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_SECOND], &pp->second, 2);  neol_atoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_HSEC], &dsec, 2);#if defined(NTP_PRE_420)  pp->msec *= 10; /* convert 1/100s from neoclock to real miliseconds */#else  pp->nsec = dsec * 10000; /* convert 1/100s from neoclock to nanoseconds */#endif  memcpy(up->radiosignal, &pp->a_lastcode[NEOCLOCK4X_OFFSET_RADIOSIGNAL], 3);  up->radiosignal[3] = 0;  memcpy(up->serial, &pp->a_lastcode[NEOCLOCK4X_OFFSET_SERIAL], 6);  up->serial[6] = 0;  up->dststatus = pp->a_lastcode[NEOCLOCK4X_OFFSET_DSTSTATUS];  neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_ANTENNA1], &up->antenna1, 2);  neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_ANTENNA2], &up->antenna2, 2);  /*    Validate received values at least enough to prevent internal    array-bounds problems, etc.  */  if((pp->hour < 0) || (pp->hour > 23) ||     (pp->minute < 0) || (pp->minute > 59) ||     (pp->second < 0) || (pp->second > 60) /*Allow for leap seconds.*/ ||     (day < 1) || (day > 31) ||     (month < 1) || (month > 12) ||     (pp->year < 0) || (pp->year > 99)) {    /* Data out of range. */    NLOG(NLOG_CLOCKEVENT)      msyslog(LOG_WARNING, "NeoClock4X(%d): date/time out of range: %s",	      up->unit, pp->a_lastcode);    refclock_report(peer, CEVNT_BADDATE);    return;  }  /* Year-2000 check not needed anymore. Same problem   * will arise at 2099 but what should we do...?   *   * wrap 2-digit date into 4-digit   *   * if(pp->year < YEAR_PIVOT)   * {   *   pp->year += 100;   * }  */  pp->year += 2000;  /* adjust NeoClock4X local time to UTC */  calc_utc = neol_mktime(pp->year, month, day, pp->hour, pp->minute, pp->second);  calc_utc -= 3600;  /* adjust NeoClock4X daylight saving time if needed */  if('S' == up->dststatus)    calc_utc -= 3600;  neol_localtime(calc_utc, &pp->year, &month, &day, &pp->hour, &pp->minute, &pp->second);  /*    some preparations  */  pp->day = ymd2yd(pp->year, month, day);  pp->leap = 0;  if(pp->sloppyclockflag & CLK_FLAG4)    {      msyslog(LOG_DEBUG, "NeoClock4X(%d): calculated UTC date/time: %04d-%02d-%02d %02d:%02d:%02d.%03d",	      up->unit,	      pp->year, month, day,	      pp->hour, pp->minute, pp->second,#if defined(NTP_PRE_420)              pp->msec#else              pp->nsec/1000#endif              );    }  up->utc_year   = pp->year;  up->utc_month  = month;  up->utc_day    = day;  up->utc_hour   = pp->hour;  up->utc_minute = pp->minute;  up->utc_second = pp->second;#if defined(NTP_PRE_420)  up->utc_msec   = pp->msec;#else  up->utc_msec   = pp->nsec/1000;#endif  if(!refclock_process(pp))    {      NLOG(NLOG_CLOCKEVENT)	msyslog(LOG_WARNING, "NeoClock4X(%d): refclock_process failed!", up->unit);      refclock_report(peer, CEVNT_FAULT);      return;    }  refclock_receive(peer);  /* report good status */  refclock_report(peer, CEVNT_NOMINAL);  record_clock_stats(&peer->srcadr, pp->a_lastcode);}static voidneoclock4x_poll(int unit,		struct peer *peer){  struct neoclock4x_unit *up;  struct refclockproc *pp;  pp = peer->procptr;  up = (struct neoclock4x_unit *)pp->unitptr;  pp->polls++;  up->recvnow = 1;}static voidneoclock4x_control(int unit,		   struct refclockstat *in,		   struct refclockstat *out,		   struct peer *peer){  struct neoclock4x_unit *up;  struct refclockproc *pp;  if(NULL == peer)    {      msyslog(LOG_ERR, "NeoClock4X(%d): control: unit invalid/inactive", unit);      return;    }  pp = peer->procptr;  if(NULL == pp)    {      msyslog(LOG_ERR, "NeoClock4X(%d): control: unit invalid/inactive", unit);      return;    }  up = (struct neoclock4x_unit *)pp->unitptr;  if(NULL == up)    {      msyslog(LOG_ERR, "NeoClock4X(%d): control: unit invalid/inactive", unit);      return;    }  if(NULL != in)    {      /* check to see if a user supplied time offset is given */      if(in->haveflags & CLK_HAVETIME1)	{	  pp->fudgetime1 = in->fudgetime1;	  NLOG(NLOG_CLOCKINFO)	    msyslog(LOG_NOTICE, "NeoClock4X(%d): using fudgetime1 with %0.5fs from ntp.conf.",		    unit, pp->fudgetime1);	}      /* notify */      if(pp->sloppyclockflag & CLK_FLAG1)	{	  NLOG(NLOG_CLOCKINFO)	    msyslog(LOG_NOTICE, "NeoClock4X(%d): quartz clock is used to synchronize time if radio clock has no reception.", unit);	}      else	{	  NLOG(NLOG_CLOCKINFO)	    msyslog(LOG_NOTICE, "NeoClock4X(%d): time is only adjusted with radio signal reception.", unit);	}    }  if(NULL != out)    {      char *tt;      char tmpbuf[80];      out->kv_list = (struct ctl_var *)0;      out->type    = REFCLK_NEOCLOCK4X;      snprintf(tmpbuf, sizeof(tmpbuf)-1,	       "%04d-%02d-%02d %02d:%02d:%02d.%03d",	       up->utc_year, up->utc_month, up->utc_day,	       up->utc_hour, up->utc_minute, up->utc_second,	       up->utc_msec);      tt = add_var(&out->kv_list, sizeof(tmpbuf)-1, RO|DEF);      snprintf(tt, sizeof(tmpbuf)-1, "calc_utc=\"%s\"", tmpbuf);      tt = add_var(&out->kv_list, 40, RO|DEF);      snprintf(tt, 39, "radiosignal=\"%s\"", up->radiosignal);      tt = add_var(&out->kv_list, 40, RO|DEF);      snprintf(tt, 39, "antenna1=\"%d\"", up->antenna1);      tt = add_var(&out->kv_list, 40, RO|DEF);      snprintf(tt, 39, "antenna2=\"%d\"", up->antenna2);      tt = add_var(&out->kv_list, 40, RO|DEF);      if('A' == up->timesource)	snprintf(tt, 39, "timesource=\"radio\"");      else if('C' == up->timesource)	snprintf(tt, 39, "timesource=\"quartz\"");      else	snprintf(tt, 39, "timesource=\"unknown\"");      tt = add_var(&out->kv_list, 40, RO|DEF);      if('I' == up->quarzstatus)	snprintf(tt, 39, "quartzstatus=\"synchronized\"");      else if('X' == up->quarzstatus)        snprintf(tt, 39, "quartzstatus=\"not synchronized\"");      else	snprintf(tt, 39, "quartzstatus=\"unknown\"");      tt = add_var(&out->kv_list, 40, RO|DEF);      if('S' == up->dststatus)        snprintf(tt, 39, "dststatus=\"summer\"");      else if('W' == up->dststatus)        snprintf(tt, 39, "dststatus=\"winter\"");      else        snprintf(tt, 39, "dststatus=\"unknown\"");      tt = add_var(&out->kv_list, 80, RO|DEF);      snprintf(tt, 79, "firmware=\"%s\"", up->firmware);      tt = add_var(&out->kv_list, 40, RO|DEF);      snprintf(tt, 39, "firmwaretag=\"%c\"", up->firmwaretag);      tt = add_var(&out->kv_list, 80, RO|DEF);      snprintf(tt, 79, "driver version=\"%s\"", NEOCLOCK4X_DRIVER_VERSION);      tt = add_var(&out->kv_list, 80, RO|DEF);      snprintf(tt, 79, "serialnumber=\"%s\"", up->serial);    }}static intneol_hexatoi_len(const char str[],		 int *result,		 int maxlen){  int hexdigit;  int i;  int n = 0;  for(i=0; isxdigit((int)str[i]) && i < maxlen; i++)    {      hexdigit = isdigit((int)str[i]) ? toupper(str[i]) - '0' : toupper(str[i]) - 'A' + 10;      n = 16 * n + hexdigit;    }  *result = n;  return (n);}static intneol_atoi_len(const char str[],		  int *result,		  int maxlen){  int digit;  int i;  int n = 0;  for(i=0; isdigit((int)str[i]) && i < maxlen; i++)    {      digit = str[i] - '0';      n = 10 * n + digit;    }  *result = n;  return (n);}/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. * * [For the Julian calendar (which was used in Russia before 1917, * Britain & colonies before 1752, anywhere else before 1582, * and is still in use by some communities) leave out the * -year/100+year/400 terms, and add 10.] * * This algorithm was first published by Gauss (I think). * * WARNING: this function will overflow on 2106-02-07 06:28:16 on * machines were long is 32-bit! (However, as time_t is signed, we * will already get problems at other places on 2038-01-19 03:14:08) */static unsigned longneol_mktime(int year,	    int mon,	    int day,	    int hour,	    int min,	    int sec){  if (0 >= (int) (mon -= 2)) {    /* 1..12 . 11,12,1..10 */    mon += 12;      /* Puts Feb last since it has leap day */    year -= 1;  }  return (((            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +            year*365 - 719499            )*24 + hour /* now have hours */           )*60 + min /* now have minutes */          )*60 + sec; /* finally seconds */}static voidneol_localtime(unsigned long utc,	       int* year,	       int* month,	       int* day,	       int* hour,	       int* min,	       int* sec){  *sec = utc % 60;  utc /= 60;  *min = utc % 60;  utc /= 60;  *hour = utc % 24;  utc /= 24;  /*             JDN Date 1/1/1970 */  neol_jdn_to_ymd(utc + 2440588L, year, month, day);}static voidneol_jdn_to_ymd(unsigned long jdn,		int *yy,		int *mm,		int *dd){  unsigned long x, z, m, d, y;  unsigned long daysPer400Years = 146097UL;  unsigned long fudgedDaysPer4000Years = 1460970UL + 31UL;  x = jdn + 68569UL;  z = 4UL * x / daysPer400Years;  x = x - (daysPer400Years * z + 3UL) / 4UL;  y = 4000UL * (x + 1) / fudgedDaysPer4000Years;  x = x - 1461UL * y / 4UL + 31UL;  m = 80UL * x / 2447UL;  d = x - 2447UL * m / 80UL;  x = m / 11UL;  m = m + 2UL - 12UL * x;  y = 100UL * (z - 49UL) + y + x;  *yy = (int)y;  *mm = (int)m;  *dd = (int)d;}#if 0/* *  delay in milliseconds */static voidneol_mdelay(int milliseconds){  struct timeval tv;  if(milliseconds)    {      tv.tv_sec  = 0;      tv.tv_usec = milliseconds * 1000;      select(1, NULL, NULL, NULL, &tv);    }}#endif#if !defined(NEOCLOCK4X_FIRMWARE)static intneol_query_firmware(int fd,		    int unit,		    char *firmware,		    int maxlen){  char tmpbuf[256];  int len;  int lastsearch;  unsigned char c;  int last_c_was_crlf;  int last_crlf_conv_len;  int init;  int read_errors;  int flag = 0;  int chars_read;  /* wait a little bit */  sleep(1);  if(-1 != write(fd, "V", 1))    {      /* wait a little bit */      sleep(1);      memset(tmpbuf, 0x00, sizeof(tmpbuf));      len = 0;      lastsearch = 0;      last_c_was_crlf = 0;      last_crlf_conv_len = 0;      init = 1;      read_errors = 0;      chars_read = 0;      for(;;)	{	  if(read_errors > 5)	    {	      msyslog(LOG_ERR, "NeoClock4X(%d): can't read firmware version (timeout)", unit);	      strcpy(tmpbuf, "unknown due to timeout");	      break;	    }          if(chars_read > 500)            {	      msyslog(LOG_ERR, "NeoClock4X(%d): can't read firmware version (garbage)", unit);	      strcpy(tmpbuf, "unknown due to garbage input");	      break;            }	  if(-1 == read(fd, &c, 1))	    {              if(EAGAIN != errno)                {                  msyslog(LOG_DEBUG, "NeoClock4x(%d): read: %s", unit ,strerror(errno));                  read_errors++;                }              else                {                  sleep(1);                }	      continue;	    }          else            {              chars_read++;            }	  if(init)	    {	      if(0xA9 != c) /* wait for (c) char in input stream */		continue;	      strcpy(tmpbuf, "(c)");	      len = 3;	      init = 0;	      continue;	    }#if 0	  msyslog(LOG_NOTICE, "NeoClock4X(%d): firmware %c = %02Xh", unit, c, c);#endif	  if(0x0A == c || 0x0D == c)	    {	      if(last_c_was_crlf)		{		  char *ptr;		  ptr = strstr(&tmpbuf[lastsearch], "S/N");		  if(NULL != ptr)		    {		      tmpbuf[last_crlf_conv_len] = 0;		      flag = 1;		      break;		    }		  /* convert \n to / */		  last_crlf_conv_len = len;		  tmpbuf[len++] = ' ';		  tmpbuf[len++] = '/';		  tmpbuf[len++] = ' ';		  lastsearch = len;		}	      last_c_was_crlf = 1;	    }	  else	    {	      last_c_was_crlf = 0;	      if(0x00 != c)		tmpbuf[len++] = (char) c;	    }	  tmpbuf[len] = '\0';	  if(len > sizeof(tmpbuf)-5)	    break;	}    }  else    {      msyslog(LOG_ERR, "NeoClock4X(%d): can't query firmware version", unit);      strcpy(tmpbuf, "unknown error");    }  strncpy(firmware, tmpbuf, maxlen);  firmware[maxlen] = '\0';  if(flag)    {      NLOG(NLOG_CLOCKINFO)	msyslog(LOG_INFO, "NeoClock4X(%d): firmware version: %s", unit, firmware);    }  return (flag);}static intneol_check_firmware(int unit,                    const char *firmware,                    char *firmwaretag){  char *ptr;  *firmwaretag = '?';  ptr = strstr(firmware, "NDF:");  if(NULL != ptr)    {      if((strlen(firmware) - strlen(ptr)) >= 7)        {          if(':' == *(ptr+5) && '*' == *(ptr+6))            *firmwaretag = *(ptr+4);        }    }  if('A' != *firmwaretag)    {      msyslog(LOG_CRIT, "NeoClock4X(%d): firmware version \"%c\" not supported with this driver version!", unit, *firmwaretag);      return (0);    }  return (1);}#endif#elseint refclock_neoclock4x_bs;#endif /* REFCLOCK *//* * History: * refclock_neoclock4x.c * * 2002/04/27 cjh * Revision 1.0  first release * * 2002/07/15 cjh * preparing for bitkeeper reposity * * 2002/09/09 cjh * Revision 1.1 * - don't assume sprintf returns an int anymore * - change the way the firmware version is read * - some customers would like to put a device called *   data diode to the NeoClock4X device to disable *   the write line. We need to now the firmware *   version even in this case. We made a compile time *   definition in this case. The code was previously *   only available on request. * * 2003/01/08 cjh * Revision 1.11 * - changing xprinf to xnprinf to avoid buffer overflows * - change some logic * - fixed memory leaks if drivers can't initialize * * 2003/01/10 cjh * Revision 1.12 * - replaced ldiv * - add code to support FreeBSD * * 2003/07/07 cjh * Revision 1.13 * - fix reporting of clock status *   changes. previously a bad clock *   status was never reset. * * 2004/04/07 cjh * Revision 1.14 * - open serial port in a way *   AIX and some other OS can *   handle much better * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -