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

📄 refclock_oncore.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* OK, we now create the NEW SHMEM. */	if ((instance->shmemfd = open(instance->shmem_fname, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {		perror(instance->shmem_fname);		return;	}	/* see how big it needs to be */	n = 1;	for (mp=oncore_messages; mp->flag[0]; mp++) {		mp->shmem = n;		/* Allocate space for multiplexed almanac, and 0D/2D/3D @@Ea records */		if (!strcmp(mp->flag, "Cb")) {			instance->shmem_Cb = n;			n += (mp->len + 3) * 34;		}		if (!strcmp(mp->flag, "Ba")) {			instance->shmem_Ba = n;			n += (mp->len + 3) * 3;		}		if (!strcmp(mp->flag, "Ea")) {			instance->shmem_Ea = n;			n += (mp->len + 3) * 3;		}		if (!strcmp(mp->flag, "Ha")) {			instance->shmem_Ha = n;			n += (mp->len + 3) * 3;		}		n += (mp->len + 3);	}	shmem_length = n + 2;	fprintf(stderr, "ONCORE: SHMEM length: %ld bytes\n", (long) shmem_length);	buf = malloc(shmem_length);	if (buf == NULL) {		perror("malloc");		close(instance->shmemfd);		return;	}	memset(buf, 0, shmem_length);	/* next build the new SHMEM buffer in memory */	for (mp=oncore_messages; mp->flag[0]; mp++) {		l = mp->shmem;		buf[l + 0] = mp->len >> 8;		buf[l + 1] = mp->len & 0xff;		buf[l + 2] = 0;		buf[l + 3] = '@';		buf[l + 4] = '@';		buf[l + 5] = mp->flag[0];		buf[l + 6] = mp->flag[1];		if (!strcmp(mp->flag, "Cb") || !strcmp(mp->flag, "Ba") || !strcmp(mp->flag, "Ea") || !strcmp(mp->flag, "Ha")) {			if (!strcmp(mp->flag, "Cb"))				n = 35;			else				n = 4;			for (i=1; i<n; i++) {				buf[l + i * (mp->len+3) + 0] = mp->len >> 8;				buf[l + i * (mp->len+3) + 1] = mp->len & 0xff;				buf[l + i * (mp->len+3) + 2] = 0;				buf[l + i * (mp->len+3) + 3] = '@';				buf[l + i * (mp->len+3) + 4] = '@';				buf[l + i * (mp->len+3) + 5] = mp->flag[0];				buf[l + i * (mp->len+3) + 6] = mp->flag[1];			}		}	}	/* we now walk thru the two buffers (shmem_old and buf, soon to become shmem)	 * copying the data in shmem_old to buf.  When we are done we write it out	 * and free both buffers.	 * If the structures change (an addition or deletion) I will stop copying.	 * The two will be the same unless we add/subtract from the oncore_messages list	 * so this should work most of the time, and takes a lot less code than doing it right.	 */	if (shmem_old) {		for (cp=buf+4, cp1=shmem_old+4; (n = 256*(*(cp-3)) + *(cp-2));	cp+=(n+3), cp1+=(n+3)) {			n1 = 256*(*(cp1-3)) + *(cp1-2);			if (n1 != n || strncmp(cp, cp1, 4))				break;			memcpy(cp, cp1, (size_t) n);		}		free(shmem_old);	}	i = write(instance->shmemfd, buf, shmem_length);	free(buf);	if (i != shmem_length) {		perror(instance->shmem_fname);		close(instance->shmemfd);		return;	}	instance->shmem = (u_char *) mmap(0, shmem_length,		PROT_READ | PROT_WRITE,#ifdef MAP_HASSEMAPHORE		MAP_HASSEMAPHORE |#endif		MAP_SHARED, instance->shmemfd, (off_t)0);	if (instance->shmem == (u_char *)MAP_FAILED) {		instance->shmem = 0;		close(instance->shmemfd);		return;	}	sprintf(Msg, "SHMEM (size = %ld) is CONFIGURED and available as %s",		(long) shmem_length, instance->shmem_fname);	record_clock_stats(&(instance->peer->srcadr), Msg);}#endif /* ONCORE_SHMEM_STATUS *//* * Read Input file if it exists. */static voidoncore_read_config(	struct instance *instance	){/* * First we try to open the configuration file *    /etc/oncoreN * where N is the unit number viz 127.127.30.N. * If we don't find it we try *    /etc/ntp.oncore.N * and then *    /etc/ntp.oncore * * If we don't find any then we don't have the cable delay or PPS offset * and we choose MODE (4) below. * * Five Choices for MODE *    (0) ONCORE is preinitialized, don't do anything to change it. *	    nb, DON'T set 0D mode, DON'T set Delay, position... *    (1) NO RESET, Read Position, delays from data file, lock it in, go to 0D mode. *    (2) NO RESET, Read Delays from data file, do SITE SURVEY to get position, *		    lock this in, go to 0D mode. *    (3) HARD RESET, Read Position, delays from data file, lock it in, go to 0D mode. *    (4) HARD RESET, Read Delays from data file, do SITE SURVEY to get position, *		    lock this in, go to 0D mode. *     NB. If a POSITION is specified in the config file with mode=(2,4) [SITE SURVEY] *	   then this position is set as the INITIAL position of the ONCORE. *	   This can reduce the time to first fix. * ------------------------------------------------------------------------------- * Note that an Oncore UT without a battery backup retains NO information if it is *   power cycled, with a Battery Backup it remembers the almanac, etc. * For an Oncore VP, there is an eeprom that will contain this data, along with the *   option of Battery Backup. * So a UT without Battery Backup is equivalent to doing a HARD RESET on each *   power cycle, since there is nowhere to store the data. * ------------------------------------------------------------------------------- * * If we open one or the other of the files, we read it looking for *   MODE, LAT, LON, (HT, HTGPS, HTMSL), DELAY, OFFSET, ASSERT, CLEAR, HARDPPS, *   STATUS, POSN3D, POSN2D, CHAN, TRAIM * then initialize using method MODE.  For Mode = (1,3) all of (LAT, LON, HT) must *   be present or mode reverts to (2,4). * * Read input file. * *	# is comment to end of line *	= allowed between 1st and 2nd fields. * *	Expect to see one line with 'MODE' as first field, followed by an integer *	   in the range 0-4 (default = 4). * *	Expect to see two lines with 'LONG', 'LAT' followed by 1-3 fields. *	All numbers are floating point. *		DDD.ddd *		DDD  MMM.mmm *		DDD  MMM  SSS.sss * *	Expect to see one line with 'HT' as first field, *	   followed by 1-2 fields.  First is a number, the second is 'FT' or 'M' *	   for feet or meters.	HT is the height above the GPS ellipsoid. *	   If the receiver reports height in both GPS and MSL, then we will report *	   the difference GPS-MSL on the clockstats file. * *	There is an optional line, starting with DELAY, followed *	   by 1 or two fields.	The first is a number (a time) the second is *	   'MS', 'US' or 'NS' for miliseconds, microseconds or nanoseconds. *	    DELAY  is cable delay, typically a few tens of ns. * *	There is an optional line, starting with OFFSET, followed *	   by 1 or two fields.	The first is a number (a time) the second is *	   'MS', 'US' or 'NS' for miliseconds, microseconds or nanoseconds. *	   OFFSET is the offset of the PPS pulse from 0. (only fully implemented *		with the PPSAPI, we need to be able to tell the Kernel about this *		offset if the Kernel PLL is in use, but can only do this presently *		when using the PPSAPI interface.  If not using the Kernel PLL, *		then there is no problem. * *	There is an optional line, with either ASSERT or CLEAR on it, which *	   determine which transition of the PPS signal is used for timing by the *	   PPSAPI.  If neither is present, then ASSERT is assumed. *	   ASSERT/CLEAR can also be set with FLAG2 of the ntp.conf input. *	   For Flag2, ASSERT=0, and hence is default. * *	There is an optional line, with HARDPPS on it.	Including this line causes *	   the PPS signal to control the kernel PLL. *	   HARDPPS can also be set with FLAG3 of the ntp.conf input. *	   For Flag3, 0 is disabled, and the default. * *	There are three options that have to do with using the shared memory option. *	   First, to enable the option there must be a SHMEM line with a file name. *	   The file name is the file associated with the shared memory. * *	In shared memory, there is one 'record' for each returned variable. *	For the @@Ea data there are three 'records' containing position data. *	   There will always be data in the record corresponding to the '0D' @@Ea record, *	   and the user has a choice of filling the '3D' record by specifying POSN3D, *	   or the '2D' record by specifying POSN2D.  In either case the '2D' or '3D' *	   record is filled once every 15s. * *	Two additional variables that can be set are CHAN and TRAIM.  These should be *	   set correctly by the code examining the @@Cj record, but we bring them out here *	   to allow the user to override either the # of channels, or the existence of TRAIM. *	   CHAN expects to be followed by in integer: 6, 8, or 12. TRAIM expects to be *	   followed by YES or NO. * *	There is an optional line with MASK on it followed by one integer field in the *	   range 0 to 89. This sets the satellite mask angle and will determine the minimum *	   elevation angle for satellites to be tracked by the receiver. The default value *	   is 10 deg for the VP and 0 deg for all other receivers. * * So acceptable input would be *	# these are my coordinates (RWC) *	LON  -106 34.610 *	LAT    35 08.999 *	HT	1589	# could equally well say HT 5215 FT *	DELAY  60 ns */	FILE	*fd;	char	*cp, *cc, *ca, line[100], units[2], device[20], Msg[160], **cpp;	char	*dirs[] = { "/etc/ntp", "/etc", 0 };	int	i, sign, lat_flg, long_flg, ht_flg, mode, mask;	double	f1, f2, f3;	fd = NULL;	/* just to shutup gcc complaint */	for (cpp=dirs; *cpp; cpp++) {		cp = *cpp;		sprintf(device, "%s/ntp.oncore.%d", cp, instance->unit); /* try "ntp.oncore.0 */		if ((fd=fopen(device, "r")))			break;		sprintf(device, "%s/ntp.oncore%d", cp, instance->unit);  /* try "ntp.oncore0" */		if ((fd=fopen(device, "r")))			break;		sprintf(device, "%s/ntp.oncore", cp);   /* and finally "ntp.oncore" */		if ((fd=fopen(device, "r")))			break;	}	if (!fd) {	/* no inputfile, default to the works ... */		instance->init_type = 4;		return;	}	mode = mask = 0;	lat_flg = long_flg = ht_flg = 0;	while (fgets(line, 100, fd)) {		/* Remove comments */		if ((cp = strchr(line, '#')))			*cp = '\0';		/* Remove trailing space */		for (i = strlen(line);		     i > 0 && isascii((int)line[i - 1]) && isspace((int)line[i - 1]);			)			line[--i] = '\0';		/* Remove leading space */		for (cc = line; *cc && isascii((int)*cc) && isspace((int)*cc); cc++)			continue;		/* Stop if nothing left */		if (!*cc)			continue;		/* Uppercase the command and find the arg */		for (ca = cc; *ca; ca++) {			if (isascii((int)*ca)) {				if (islower((int)*ca)) {					*ca = toupper(*ca);				} else if (isspace((int)*ca) || (*ca == '='))					break;			}		}		/* Remove space (and possible =) leading the arg */		for (; *ca && isascii((int)*ca) && (isspace((int)*ca) || (*ca == '=')); ca++)			continue;		if (!strncmp(cc, "STATUS", (size_t) 6) || !strncmp(cc, "SHMEM", (size_t) 5)) {			i = strlen(ca);			instance->shmem_fname = (char *) malloc((unsigned) (i+1));			strcpy(instance->shmem_fname, ca);			continue;		}		/* Uppercase argument as well */		for (cp = ca; *cp; cp++)			if (isascii((int)*cp) && islower((int)*cp))				*cp = toupper(*cp);		if (!strncmp(cc, "LAT", (size_t) 3)) {			f1 = f2 = f3 = 0;			sscanf(ca, "%lf %lf %lf", &f1, &f2, &f3);			sign = 1;			if (f1 < 0) {				f1 = -f1;				sign = -1;			}			instance->ss_lat = sign*1000*(fabs(f3) + 60*(fabs(f2) + 60*f1)); /*miliseconds*/			lat_flg++;		} else if (!strncmp(cc, "LON", (size_t) 3)) {			f1 = f2 = f3 = 0;			sscanf(ca, "%lf %lf %lf", &f1, &f2, &f3);			sign = 1;			if (f1 < 0) {				f1 = -f1;				sign = -1;			}			instance->ss_long = sign*1000*(fabs(f3) + 60*(fabs(f2) + 60*f1)); /*miliseconds*/			long_flg++;		} else if (!strncmp(cc, "HT", (size_t) 2)) {			f1 = 0;			units[0] = '\0';			sscanf(ca, "%lf %1s", &f1, units);			if (units[0] == 'F')				f1 = 0.3048 * f1;			instance->ss_ht = 100 * f1;    /* cm */			ht_flg++;		} else if (!strncmp(cc, "DELAY", (size_t) 5)) {			f1 = 0;			units[0] = '\0';			sscanf(ca, "%lf %1s", &f1, units);			if (units[0] == 'N')				;			else if (units[0] == 'U')				f1 = 1000 * f1;			else if (units[0] == 'M')				f1 = 1000000 * f1;			else				f1 = 1000000000 * f1;			if (f1 < 0 || f1 > 1.e9)				f1 = 0;			if (f1 < 0 || f1 > 999999) {				sprintf(Msg, "PPS Cable delay of %fns out of Range, ignored", f1);				record_clock_stats(&(instance->peer->srcadr), Msg);			} else				instance->delay = f1;		/* delay in ns */		} else if (!strncmp(cc, "OFFSET", (size_t) 6)) {			f1 = 0;			units[0] = '\0';			sscanf(ca, "%lf %1s", &f1, units);			if (units[0] == 'N')				;			else if (units[0] == 'U')				f1 = 1000 * f1;			else if (units[0] == 'M')				f1 = 1000000 * f1;			else				f1 = 1000000000 * f1;			if (f1 < 0 || f1 > 1.e9)				f1 = 0;			if (f1 < 0 || f1 > 999999999.) {				sprintf(Msg, "PPS Offset of %fns out of Range, ignored", f1);				record_clock_stats(&(instance->peer->srcadr), Msg);			} else				instance->offset = f1;		/* offset in ns */		} else if (!strncmp(cc, "MODE", (size_t) 4)) {			sscanf(ca, "%d", &mode);			if (mode < 0 || mode > 4)				mode = 4;		} else if (!strncmp(cc, "ASSERT", (size_t) 6)) {			instance->assert = 1;		} else if (!strncmp(cc, "CLEAR", (size_t) 5)) {			instance->assert = 0;		} else if (!strncmp(cc, "HARDPPS", (size_t) 7)) {			instance->hardpps = 1;		} else if (!strncmp(cc, "POSN2D", (size_t) 6)) {			instance->shmem_Posn = 2;		} else if (!strncmp(cc, "POSN3D", (size_t) 6)) {			instance->shmem_Posn = 3;		} else if (!strncmp(cc, "CHAN", (size_t) 4)) {			sscanf(ca, "%d", &i);			if ((i == 6) || (i == 8) || (i == 12))				instance->chan_in = i;		} else if (!strncmp(cc, "TRAIM", (size_t) 5)) {			instance->traim_in = 1; 	/* so TRAIM alone is YES */			if (!strcmp(ca, "NO") || !strcmp(ca, "OFF"))    /* Yes/No, On/Off */				instance->traim_in = 0;		} else if (!strncmp(cc, "MASK", (size_t) 4)) {			sscanf(ca, "%d", &mask);			if (mask > -1 && mask < 90)				instance->Ag = mask;			/* Satellite mask angle */		}	}	fclose(fd);	/*	 *    OK, have read all of data file, and extracted the good stuff.	 *    If lat/long/ht specified they ALL must be specified for mode = (1,3).	 */

⌨️ 快捷键说明

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