Replied: Tue, 18 Mar 1997 19:21:30 -0500
Replied: "Marc Brett <Marc.Brett@waii.com> Marc.Brett@rgs0.london.waii.com, Frank.Vance@rgs0.london.waii.com,
Replied: Mills@huey.udel.edu"
Received: from snow-white.ee.udel.edu by whimsy.udel.edu id aa06626;
          18 Mar 97 13:09 GMT
Received: by diamond.waii.com; id HAA06460; Tue, 18 Mar 1997 07:08:10 -0600
Received: from mail.wg.waii.com(137.144.128.17) by diamond.waii.com via smap (3.2)
	id xma006324; Tue, 18 Mar 97 07:00:53 -0600
Received: from merlin.london.waii.com (merlin.london.waii.com [136.250.33.1]) by mail1.wg.waii.com (8.7.5/8.7.3) with SMTP id HAA50294; Tue, 18 Mar 1997 07:00:40 -0600
Received: from rgs0.london.waii.com by merlin.london.waii.com with SMTP id AA13615
  (5.65c/IDA-1.4.4); Tue, 18 Mar 1997 13:00:47 GMT
Received: by rgs0.london.waii.com (940816.SGI.8.6.9/920502.SGI)
	 id NAA17250; Tue, 18 Mar 1997 13:00:45 GMT
From: Marc Brett <Marc.Brett@waii.com>
Message-Id: <9703181300.ZM17248@rgs0.london.waii.com>
Date: Tue, 18 Mar 1997 13:00:43 +0000
X-Mailer: Z-Mail (3.2.0 26oct94 MediaMail)
To: stenn@whimsy.udel.edu
Subject: Updates to MX 4200 driver
Cc: Marc.Brett@rgs0.london.waii.com, Frank.Vance@rgs0.london.waii.com, 
    Mills@huey.udel.edu
Mime-Version: 1.0
Content-Type: multipart/mixed;
	boundary="PART-BOUNDARY=.19703181300.ZM17248.london.waii.com"

--
--PART-BOUNDARY=.19703181300.ZM17248.london.waii.com
Content-Type: text/plain; charset=us-ascii

Harlan,

Here are some updates to the MX 4200 driver, based on the xntp3-5.89.8 code.

The main new features are:

	o  Allowed operation on either fixed or mobile platforms (eg. ships)
	o  Added leap second debug information to the syslog
	o  Added receiver mode information to the syslog
	o  Reduced the total number of messages coming from the receiver

Best Regards,

Marc Brett


-- 
Marc Brett                     Western Atlas
Marc.Brett@waii.com            +44 181 977 6279

--PART-BOUNDARY=.19703181300.ZM17248.london.waii.com
X-Zm-Content-Name: driver9.html.diff
Content-Description: Text
Content-Type: text/plain ; name="driver9.html.diff" ; charset=us-ascii

*** driver9.html.orig	Tue Mar 18 11:03:01 1997
--- html/driver9.html	Tue Mar 18 11:03:25 1997
***************
*** 27,45 ****
  <p>This driver supports all compatible receivers such as the 6-channel
  MX 4200, MX 4200D, and the 12-channel MX 9212, MX 9012R, MX 9112.
  
! <p>This driver assumes that the GPS antenna is in a fixed location.  The
! receiver is initially placed in a "Static, 3D Nav" mode, where latitude,
! longitude, elevation and time are calculated for a fixed station.  A
! DOP-weighted running average position is calculated from this data.
! After 24 hours, the receiver is placed into a "Known Position" mode,
! initialized with the calculated position, and then solves only for time.
! 
! <p>The requirement for a fixed installation precludes operation of
! this driver aboard moving ships, aircraft, or land vehicles.  Also,
! the position averaging algorithm does not take into account boundary
! conditions, so operation very near the international date line or the
! poles is not recommended.
  
  <p><h4>Monitor Data</h4>
  
  <p>The driver writes each timecode as received to the
--- 27,52 ----
  <p>This driver supports all compatible receivers such as the 6-channel
  MX 4200, MX 4200D, and the 12-channel MX 9212, MX 9012R, MX 9112.
  
! <p><h4>Operating Modes</h4>
  
+ <p>This driver supports two modes of operation, static and mobile,
+ controlled by clock flag 2.
+ 
+ <p>In static mode (the default) the driver assumes that the GPS antenna
+ is in a fixed location.  The receiver is initially placed in a "Static,
+ 3D Nav" mode, where latitude, longitude, elevation and time are
+ calculated for a fixed station.  A DOP-weighted running average position
+ is calculated from this data.  After 24 hours, the receiver is placed
+ into a "Known Position" mode, initialized with the calculated position,
+ and then solves only for time.  The position averaging algorithm does
+ not take into account boundary conditions, so this mode of operation
+ very near the international date line or the poles is not recommended.
+ 
+ <p>In mobile mode, the driver assumes the GPS antenna is mounted on
+ a moving platform such as a car, ship, or aircraft.  The receiver is
+ placed in "Dynamic, 3D Nav" mode and solves for position, altitude and
+ time while moving.  No position averaging is performed.
+ 
  <p><h4>Monitor Data</h4>
  
  <p>The driver writes each timecode as received to the
***************
*** 69,78 ****
  <dd>Not used by this driver.
  
  <p><dt><code>flag2 0 | 1</code>
! <dd>Not used by this driver.
  
  <p><dt><code>flag3 0 | 1</code>
! <dd>Enable <code>ppsclock</code> line discipline/streams module if set.
  
  <p><dt><code>flag4 0 | 1</code>
  <dd>Not used by this driver.
--- 76,85 ----
  <dd>Not used by this driver.
  
  <p><dt><code>flag2 0 | 1</code>
! <dd>Assume GPS receiver is on a mobile platform if set.
  
  <p><dt><code>flag3 0 | 1</code>
! <dd>Not used by this driver.
  
  <p><dt><code>flag4 0 | 1</code>
  <dd>Not used by this driver.

--PART-BOUNDARY=.19703181300.ZM17248.london.waii.com
X-Zm-Content-Name: refclock_mx4200.c.diff
Content-Description: Text
Content-Type: text/plain ; name="refclock_mx4200.c.diff" ; charset=us-ascii

*** refclock_mx4200.c.orig	Wed Feb 19 04:37:48 1997
--- xntpd/refclock_mx4200.c	Tue Mar 18 12:04:39 1997
***************
*** 98,109 ****
  #define	DESCRIPTION	"Magnavox MX4200 GPS Receiver" /* who we are */
  #define	DEFFUDGETIME	0	/* default fudge time (ms) */
  
  /*
   * Position Averaging.
   * Reference: Dr. Thomas A. Clark's Totally Accurate Clock (TAC) files at
   * ftp://aleph.gsfc.nasa.gov/GPS/totally.accurate.clock/
   */
- #define MAX_VEL_SQUARED	(1.0)	/* Maximum acceptable velocity (squared) (m/s)*/
  #define INTERVAL	1	/* Interval between position measurements (s) */
  #define AVGING_TIME	24	/* Number of hours to average */
  #define USUAL_EDOP	0.75	/* used for normalizing EDOP */
--- 98,110 ----
  #define	DESCRIPTION	"Magnavox MX4200 GPS Receiver" /* who we are */
  #define	DEFFUDGETIME	0	/* default fudge time (ms) */
  
+ #define	SLEEPTIME	32	/* seconds to wait for reconfig to complete */
+ 
  /*
   * Position Averaging.
   * Reference: Dr. Thomas A. Clark's Totally Accurate Clock (TAC) files at
   * ftp://aleph.gsfc.nasa.gov/GPS/totally.accurate.clock/
   */
  #define INTERVAL	1	/* Interval between position measurements (s) */
  #define AVGING_TIME	24	/* Number of hours to average */
  #define USUAL_EDOP	0.75	/* used for normalizing EDOP */
***************
*** 153,161 ****
  	double edop;			/* EDOP (east DOP) */
  	double ndop;			/* NDOP (north DOP) */
  	double vdop;			/* VDOP (vertical DOP) */
! 	u_int  moving;			/* are we moving? */
  	u_int  known;			/* position known yet? */
  	u_long clamp_time;		/* when to stop postion averaging */
  	int    coderecv;		/* total received samples */
  	int    nkeep;			/* number of samples to preserve */
  	int    rshift;			/* number of rshifts for division */
--- 154,165 ----
  	double edop;			/* EDOP (east DOP) */
  	double ndop;			/* NDOP (north DOP) */
  	double vdop;			/* VDOP (vertical DOP) */
! 	int    last_leap;		/* leap second warning */
! 	u_int  moving;			/* mobile platform? */
! 	u_long sloppyclockflag;		/* fudge flags */
  	u_int  known;			/* position known yet? */
  	u_long clamp_time;		/* when to stop postion averaging */
+ 	u_long log_time;		/* when to print receiver status */
  	int    coderecv;		/* total received samples */
  	int    nkeep;			/* number of samples to preserve */
  	int    rshift;			/* number of rshifts for division */
***************
*** 218,224 ****
  	register struct mx4200unit *up;
  	struct refclockproc *pp;
  	int fd;
- 	int i;
  	char gpsdev[20];
  
  	/*
--- 222,227 ----
***************
*** 261,296 ****
  	pp->clockdesc = DESCRIPTION;
  	memcpy((char *)&pp->refid, REFID, 4);
  
- 	up->pollcnt  = 2;
- 	up->polled   = 0;
- 	up->moving   = 0;	/* not moving */
- 	up->known    = 0;	/* not moving */
- 	up->avg_lat  = 0.0;
- 	up->avg_lon  = 0.0;
- 	up->avg_alt  = 0.0;
- 	up->filt_lat = 0.0;
- 	up->filt_lon = 0.0;
- 	up->filt_alt = 0.0;
- 	up->edop     = USUAL_EDOP;
- 	up->ndop     = USUAL_NDOP;
- 	up->vdop     = USUAL_VDOP;
- 	up->clamp_time = current_time + (AVGING_TIME * 60 * 60);
- 	up->coderecv = 0;
- 	up->nkeep    = NKEEP;
- 	if (up->nkeep > NSAMPLES) up->nkeep = NSAMPLES;
- 	if (up->nkeep >=   1) up->rshift =  0;
- 	if (up->nkeep >=   2) up->rshift =  1;
- 	if (up->nkeep >=   4) up->rshift =  2;
- 	if (up->nkeep >=   8) up->rshift =  3;
- 	if (up->nkeep >=  16) up->rshift =  4;
- 	if (up->nkeep >=  32) up->rshift =  5;
- 	if (up->nkeep >=  64) up->rshift =  6;
- 	up->nkeep =1;
- 	i = up->rshift;
- 	while (i > 0) {
- 		up->nkeep *= 2;
- 		i--;
- 	}
  
  	/* Ensure the receiver is properly configured */
  	mx4200_config(peer);
--- 264,269 ----
***************
*** 323,328 ****
--- 296,304 ----
  mx4200_config(peer)
  	struct peer *peer;
  {
+ 	char tr_mode;
+ 	char add_mode;
+ 	int i;
  	register struct mx4200unit *up;
  	struct refclockproc *pp;
  
***************
*** 330,335 ****
--- 306,357 ----
  	up = (struct mx4200unit *)pp->unitptr;
  
  	/*
+ 	 * Initialize the unit variables
+ 	 *
+ 	 * STRANGE BEHAVIOUR WARNING: The fudge flags are not available
+ 	 * at the time mx4200_start is called.  These are set later,
+ 	 * and so the code must be prepared to handle changing flags.
+ 	 */
+ 	up->sloppyclockflag = pp->sloppyclockflag;
+ 	if (pp->sloppyclockflag & CLK_FLAG2) {
+ 		up->moving   = 1;	/* Receiver on mobile platform */
+ 		msyslog(LOG_DEBUG, "mx4200_config: mobile platform");
+ 	} else {
+ 		up->moving   = 0;	/* Static Installation */
+ 	}
+ 	up->pollcnt     = 2;
+ 	up->polled      = 0;
+ 	up->known       = 0;
+ 	up->avg_lat     = 0.0;
+ 	up->avg_lon     = 0.0;
+ 	up->avg_alt     = 0.0;
+ 	up->filt_lat    = 0.0;
+ 	up->filt_lon    = 0.0;
+ 	up->filt_alt    = 0.0;
+ 	up->edop        = USUAL_EDOP;
+ 	up->ndop        = USUAL_NDOP;
+ 	up->vdop        = USUAL_VDOP;
+ 	up->last_leap   = 0;	/* LEAP_NOWARNING */
+ 	up->clamp_time  = current_time + (AVGING_TIME * 60 * 60);
+ 	up->log_time    = current_time + SLEEPTIME;
+ 	up->coderecv    = 0;
+ 	up->nkeep       = NKEEP;
+ 	if (up->nkeep > NSAMPLES) up->nkeep = NSAMPLES;
+ 	if (up->nkeep >=   1) up->rshift = 0;
+ 	if (up->nkeep >=   2) up->rshift = 1;
+ 	if (up->nkeep >=   4) up->rshift = 2;
+ 	if (up->nkeep >=   8) up->rshift = 3;
+ 	if (up->nkeep >=  16) up->rshift = 4;
+ 	if (up->nkeep >=  32) up->rshift = 5;
+ 	if (up->nkeep >=  64) up->rshift = 6;
+ 	up->nkeep =1;
+ 	i = up->rshift;
+ 	while (i > 0) {
+ 		up->nkeep *= 2;
+ 		i--;
+ 	}
+ 
+ 	/*
  	 * "007" Control Port Configuration
  	 * Zero the output list (do it twice to flush possible junk)
  	 */
***************
*** 392,400 ****
  	 * (Set field 1 'S' == static  if we are not moving).
  	 * (Set field 1 'K' == known position if we can initialize lat/lon/alt).
  	 */
  	mx4200_send(peer, "%s,%03d,%c,%c,%c,%d,%d,%d,", pmvxg,
  	    PMVXG_S_TRECOVCONF,
! 	    'S',	/* static: solve for pos, alt, time, while stationary */
  	    'U',	/* synchronize to UTC */
  	    'A',	/* always output a time pulse */
  	    500,	/* max time error in ns */
--- 414,438 ----
  	 * (Set field 1 'S' == static  if we are not moving).
  	 * (Set field 1 'K' == known position if we can initialize lat/lon/alt).
  	 */
+ 
+ 	if (pp->sloppyclockflag & CLK_FLAG2)
+ 		up->moving   = 1;	/* Receiver on mobile platform */
+ 	else
+ 		up->moving   = 0;	/* Static Installation */
+ 
+ 	up->pollcnt  = 2;
+ 	if (up->moving) {
+ 		/* dynamic: solve for pos, alt, time, while moving */
+ 		tr_mode = 'D';
+ 		add_mode = 0;
+ 	} else {
+ 		/* static: solve for pos, alt, time, while stationary */
+ 		tr_mode = 'S';
+ 		add_mode = 1;
+ 	}
  	mx4200_send(peer, "%s,%03d,%c,%c,%c,%d,%d,%d,", pmvxg,
  	    PMVXG_S_TRECOVCONF,
! 	    tr_mode,	/* time recovery mode (see above ) */
  	    'U',	/* synchronize to UTC */
  	    'A',	/* always output a time pulse */
  	    500,	/* max time error in ns */
***************
*** 403,421 ****
  			/* Multi-satellite mode */
  
  	/*
! 	 * "007" Control Port Configuration
! 	 * Output "004" mode data
  	 */
! 	mx4200_send(peer, "%s,%03d,%03d,%d,%d,,%d,,,", pmvxg,
! 	    PMVXG_S_PORTCONF,
! 	    PMVXG_D_MODEDATA, /* control port output block Label */
! 	    0,		/* clear current output control list (0=no) */
! 	    1,		/* add/delete sentences from list (1=add) */
! 			/* must be null */
! 	    INTERVAL*10);/* sentence output rate (sec) */
! 	    		/* precision for position output */
! 			/* nmea version for cga & gll output */
! 			/* pass-through control */
  
  	/*
  	 * "007" Control Port Configuration
--- 441,454 ----
  			/* Multi-satellite mode */
  
  	/*
! 	 * Output position information (to calculate fixed installation
! 	 * location) only if we are not moving
  	 */
! 	if (up->moving) {
! 		add_mode = 0;	/* delete from list */
! 	} else {
! 		add_mode = 1;	/* add to list */
! 	}
  
  	/*
  	 * "007" Control Port Configuration
***************
*** 425,431 ****
  	    PMVXG_S_PORTCONF,
  	    PMVXG_D_DOPS, /* control port output block Label */
  	    0,		/* clear current output control list (0=no) */
! 	    1,		/* add/delete sentences from list (1=add) */
  			/* must be null */
  	    INTERVAL);	/* sentence output rate (sec) */
  	    		/* precision for position output */
--- 458,464 ----
  	    PMVXG_S_PORTCONF,
  	    PMVXG_D_DOPS, /* control port output block Label */
  	    0,		/* clear current output control list (0=no) */
! 	    add_mode,	/* add/delete sentences from list (1=add) */
  			/* must be null */
  	    INTERVAL);	/* sentence output rate (sec) */
  	    		/* precision for position output */
***************
*** 432,451 ****
  			/* nmea version for cga & gll output */
  			/* pass-through control */
  
- 	/*
- 	 * "007" Control Port Configuration
- 	 * Output "523" time recovery parameters currently in use
- 	 */
- 	mx4200_send(peer, "%s,%03d,%03d,%d,%d,,%d,,,", pmvxg,
- 	    PMVXG_S_PORTCONF,
- 	    PMVXG_D_TRECOVUSEAGE, /* control port output block Label */
- 	    0,		/* clear current output control list (0=no) */
- 	    1,		/* add/delete sentences from list (1=add) */
- 			/* must be null */
- 	    INTERVAL*10); /* sentence output rate (sec) */
- 	    		/* precision for position output */
- 			/* nmea version for cga & gll output */
- 			/* pass-through control */
  
  	/*
  	 * "007" Control Port Configuration
--- 465,470 ----
***************
*** 455,468 ****
  	    PMVXG_S_PORTCONF,
  	    PMVXG_D_PHV, /* control port output block Label */
  	    0,		/* clear current output control list (0=no) */
! 	    1,		/* add/delete sentences from list (1=add) */
  			/* must be null */
  	    INTERVAL);	/* sentence output rate (sec) */
  	    		/* precision for position output */
  			/* nmea version for cga & gll output */
  			/* pass-through control */
- 
- 
  }
  
  /*
--- 474,485 ----
  	    PMVXG_S_PORTCONF,
  	    PMVXG_D_PHV, /* control port output block Label */
  	    0,		/* clear current output control list (0=no) */
! 	    add_mode,	/* add/delete sentences from list (1=add) */
  			/* must be null */
  	    INTERVAL);	/* sentence output rate (sec) */
  	    		/* precision for position output */
  			/* nmea version for cga & gll output */
  			/* pass-through control */
  }
  
  /*
***************
*** 481,486 ****
--- 498,511 ----
  	pp = peer->procptr;
  	up = (struct mx4200unit *)pp->unitptr;
  
+ 	/* Should never happen! */
+ 	if (up->moving) return;
+ 
+ 	/*
+ 	 * Set up to output status information in the near future
+ 	 */
+ 	up->log_time    = current_time + SLEEPTIME;
+ 
  	/*
  	 * "001" Initialization/Mode Control, Part B
  	 * Put receiver in fully-constrained 2d nav mode
***************
*** 549,557 ****
--- 574,614 ----
  	    alt,	/* height */
  	    1);		/* Altitude Reference 1=MSL */
  
+ 
+ 	/*
+ 	 * "007" Control Port Configuration
+ 	 * Stop outputting "022" DOPs
+ 	 */
+ 	mx4200_send(peer, "%s,%03d,%03d,%d,%d,,,,,", pmvxg,
+ 	    PMVXG_S_PORTCONF,
+ 	    PMVXG_D_DOPS, /* control port output block Label */
+ 	    0,		/* clear current output control list (0=no) */
+ 	    0);		/* add/delete sentences from list (0=delete) */
+ 			/* must be null */
+ 	    		/* sentence output rate (sec) */
+ 	    		/* precision for position output */
+ 			/* nmea version for cga & gll output */
+ 			/* pass-through control */
+ 
+ 	/*
+ 	 * "007" Control Port Configuration
+ 	 * Stop outputting "021" position, height, velocity reports
+ 	 */
+ 	mx4200_send(peer, "%s,%03d,%03d,%d,%d,,%d,,,", pmvxg,
+ 	    PMVXG_S_PORTCONF,
+ 	    PMVXG_D_PHV, /* control port output block Label */
+ 	    0,		/* clear current output control list (0=no) */
+ 	    0);		/* add/delete sentences from list (0=delete) */
+ 			/* must be null */
+ 	    		/* sentence output rate (sec) */
+ 	    		/* precision for position output */
+ 			/* nmea version for cga & gll output */
+ 			/* pass-through control */
+ 
  	msyslog(LOG_DEBUG,
  	    "mx4200_ref: reconfig to fixed location: %s %c, %s %c, %.2f m MSL",
  	    lats, nsc, lons, ewc, alt );
+ 
  }
  
  /*
***************
*** 597,602 ****
--- 654,673 ----
  	 */
  	up->polled = 1;
  	pp->polls++;
+ 
+ 	/*
+ 	 * Output receiver status information.
+ 	 */
+ 	if ((up->log_time > 0) && (current_time > up->log_time)) {
+ 		up->log_time = 0;
+ 		/*
+ 		 * Output the following messages once, for debugging.
+ 		 *    "004" Mode Data
+ 		 *    "523" Time Recovery Parameters
+ 		 */
+ 		mx4200_send(peer, "%s,%03d", "CDGPQ", PMVXG_D_MODEDATA);
+ 		mx4200_send(peer, "%s,%03d", "CDGPQ", PMVXG_D_TRECOVUSEAGE);
+ 	}
  }
  
  static char char2hex[] = "0123456789ABCDEF";
***************
*** 623,628 ****
--- 694,712 ----
  	up = (struct mx4200unit *)pp->unitptr;
  
  	/*
+ 	 * If operating mode has been changed, then reinitialize the receiver
+ 	 * before doing anything else.
+ 	 */
+ 	if ((pp->sloppyclockflag & CLK_FLAG2) !=
+ 	    (up->sloppyclockflag & CLK_FLAG2)) {
+ 		up->sloppyclockflag = pp->sloppyclockflag;
+ 		mx4200_debug(peer, "mx4200_receive: mode switch: reset receiver\n", cp);
+ 		mx4200_config(peer);
+ 		return;
+ 	}
+ 	up->sloppyclockflag = pp->sloppyclockflag;
+ 
+ 	/*
  	 * Read clock output.  Automatically handles STREAMS, CLKLDISC.
  	 */
  	pp->lencode = refclock_gtlin(rbufp, pp->lastcode, BMAX, &pp->lastrec);
***************
*** 705,710 ****
--- 789,798 ----
  		 * indicates the reciever needs to be initialized; thus, it is
  		 * not necessary to decode the status message.
  		 */
+ 		if ((cp = mx4200_parse_s(peer)) != NULL) {
+ 			mx4200_debug(peer,
+ 				"mx4200_receive: status: %s\n", cp);
+ 		}
  		mx4200_debug(peer, "mx4200_receive: reset receiver\n", cp);
  		mx4200_config(peer);
  		return;
***************
*** 755,765 ****
  	}
  
  	/*
  	 * "030" Software Configuration
  	 */
! 	if (sentence_type == PMVXG_D_SOFTCONF && !up->known) {
  		if ((cp = mx4200_parse_s(peer)) != NULL) {
! 			mx4200_debug(peer, "mx4200_receive: sw conf: %s\n", cp);
  			return;
  		}
  		return;
--- 843,859 ----
  	}
  
  	/*
+ 	 * Print to the syslog:
+ 	 * "004" Mode Data
  	 * "030" Software Configuration
+ 	 * "523" Time Recovery Parameters Currently in Use
  	 */
! 	if (sentence_type == PMVXG_D_MODEDATA ||
! 	    sentence_type == PMVXG_D_SOFTCONF ||
! 	    sentence_type == PMVXG_D_TRECOVUSEAGE ) {
  		if ((cp = mx4200_parse_s(peer)) != NULL) {
! 			mx4200_debug(peer,
! 				"mx4200_receive: multi-record: %s\n", cp);
  			return;
  		}
  		return;
***************
*** 972,982 ****
  	}
  
  	/*
! 	 * Now compute the offset estimate.  If the sloppy clock
! 	 * flag 1 is set, average the remainder, otherwise pick the
  	 * median.
  	 */
! 	if (pp->sloppyclockflag && CLK_FLAG1) {
  		L_CLR(&lftmp);
  		while (i < n) {
  			L_ADD(&lftmp, &off[i]);
--- 1066,1076 ----
  	}
  
  	/*
! 	 * Now compute the offset estimate.  If fudge flag 1
! 	 * is set, average the remainder, otherwise pick the
  	 * median.
  	 */
! 	if (pp->sloppyclockflag & CLK_FLAG1) {
  		L_CLR(&lftmp);
  		while (i < n) {
  			L_ADD(&lftmp, &off[i]);
***************
*** 1182,1193 ****
  		refclock_report(peer, CEVNT_BADTIME);
  		return ("bad time");
  	}
  
  	/*
  	 * Check for insane date
  	 */
  	if (monthday > 31 || month > 12 ||
! 	    monthday <  1 || month <  1 || year < 1996) {
  		mx4200_debug(peer,
  			"mx4200_parse_t: bad date (%4d-%02d-%02d)\n",
  			year, month, monthday);
--- 1276,1292 ----
  		refclock_report(peer, CEVNT_BADTIME);
  		return ("bad time");
  	}
+ 	if ( second == 60 ) {
+ 		msyslog(LOG_DEBUG, "mx4200_parse_t: leap second! %02d:%02d:%02d",
+ 			 hour, minute, second);
+ 	}
  
  	/*
  	 * Check for insane date
+ 	 * (Certainly can't be a year before this code was last altered!)
  	 */
  	if (monthday > 31 || month > 12 ||
! 	    monthday <  1 || month <  1 || year < 1997) {
  		mx4200_debug(peer,
  			"mx4200_parse_t: bad date (%4d-%02d-%02d)\n",
  			year, month, monthday);
***************
*** 1243,1248 ****
--- 1342,1357 ----
  		pp->leap = LEAP_NOTINSYNC;	/* shouldn't happen */
  
  	/*
+ 	 * Any change to the leap second warning status?
+ 	 */
+ 	if (leapsec != up->last_leap ) {
+ 		msyslog(LOG_DEBUG,
+ 			"mx4200_parse_t: leap second warning: %d to %d (%d)",
+ 			up->last_leap, leapsec, pp->leap);
+ 	}
+ 	up->last_leap = leapsec;
+ 
+ 	/*
  	 * Copy time data for billboard monitoring.
  	 */
  
***************
*** 1397,1402 ****
--- 1506,1514 ----
  	pp = peer->procptr;
  	up = (struct mx4200unit *)pp->unitptr;
  
+ 	/* Should never happen! */
+ 	if (up->moving) return ("mobile platform - no pos!");
+ 
  	cp = pp->lastcode;
  
  	if ((cp = strchr(cp, ',')) == NULL)
***************
*** 1513,1524 ****
  	up->filt_alt += weight;
  	up->avg_alt = up->avg_alt / up->filt_alt;
  
- 	/*
- 	 * Are we moving?
- 	 */
- 	if ((vele*vele + veln*veln) > MAX_VEL_SQUARED)
- 		up->moving++;
- 
  	return (NULL);
  }
  
--- 1625,1630 ----
***************
*** 1559,1564 ****
--- 1665,1673 ----
  	pp = peer->procptr;
  	up = (struct mx4200unit *)pp->unitptr;
  
+ 	/* Should never happen! */
+ 	if (up->moving) return ("mobile platform - no dop!");
+ 
  	cp = pp->lastcode;
  
  	if ((cp = strchr(cp, ',')) == NULL)
***************
*** 1607,1613 ****
--- 1716,1789 ----
  }
  
  /*
+  * Parse a mx4200 Status sentence
+  * Parse a mx4200 Mode Data sentence
   * Parse a mx4200 Software Configuration sentence
+  * Parse a mx4200 Time Recovery Parameters Currently in Use sentence
+  * (used only for logging raw strings)
+  *
+  * A typical message looks like this.  Checksum has already been stripped.
+  *
+  * $PMVXG,000,XXX,XX,X,HHMM,X
+  *
+  *	Field	Field Contents
+  *	-----	--------------
+  *		Block Label: $PMVXG
+  *		Sentence Type: 000=Status.
+  *			Returns status of the receiver to the controller.
+  *	1	Current Receiver Status:
+  *		ACQ = Satellite re-acquisition
+  *		ALT = Constellation selection
+  *		COR = Providing corrections (for reference stations only)
+  *		IAC = Initial acquisition
+  *		IDL = Idle, no satellites
+  *		NAV = Navigation
+  *		STS = Search the Sky (no almanac available)
+  *		TRK = Tracking
+  *	2	Number of satellites that should be visible
+  *	3	Number of satellites being tracked
+  *	4	Time since last navigation status if not currently navigating
+  *		(hours, minutes)
+  *	5	Initialization status:
+  *		0 = Waiting for initialization parameters
+  *		1 = Initialization completed
+  *
+  * A typical message looks like this.  Checksum has already been stripped.
+  *
+  * $PMVXG,004,C,R,D,H.HH,V.VV,TT,HHHH,VVVV,T
+  *
+  *	Field	Field Contents
+  *	-----	--------------
+  *		Block Label: $PMVXG
+  *		Sentence Type: 004=Software Configuration.
+  *			Defines the navigation mode and criteria for
+  *			acceptable navigation for the receiver.
+  *	1	Constrain Altitude Mode:
+  *		0 = Auto.  Constrain altitude (2-D solution) and use
+  *		    manual altitude input when 3 sats avalable.  Do
+  *		    not constrain altitude (3-D solution) when 4 sats
+  *		    available.
+  *		1 = Always constrain altitude (2-D solution).
+  *		2 = Never constrain altitude (3-D solution).
+  *		3 = Coast.  Constrain altitude (2-D solution) and use
+  *		    last GPS altitude calculation when 3 sats avalable.
+  *		    Do not constrain altitude (3-D solution) when 4 sats
+  *		    available.
+  *	2	Altitude Reference: (always 0 for MX4200)
+  *		0 = Ellipsoid
+  *		1 = Geoid (MSL)
+  *	3	Differential Navigation Control:
+  *		0 = Disabled
+  *		1 = Enabled
+  *	4	Horizontal Acceleration Constant (m/sec**2)
+  *	5	Vertical Acceleration Constant (m/sec**2) (0 for MX4200)
+  *	6	Tracking Elevation Limit (degrees)
+  *	7	HDOP Limit
+  *	8	VDOP Limit
+  *	9	Time Output Mode:
+  *		U = UTC
+  *		L = Local time
+  *	10	Local Time Offset (minutes) (absent on MX4200)
   *
   * A typical message looks like this.  Checksum has already been stripped.
   *
***************
*** 1621,1626 ****
--- 1797,1837 ----
   *			and baseband firmware version numbers.
   *	1	Nav Processor Version Number
   *	2	Baseband Firmware Version Number
+  *
+  * A typical message looks like this.  Checksum has already been stripped.
+  *
+  * $PMVXG,523,M,S,M,EEEE,BBBBBB,C,R
+  *
+  *	Field	Field Contents
+  *	-----	--------------
+  *		Block Label: $PMVXG
+  *		Sentence Type: 523=Time Recovery Parameters Currently in Use.
+  *			This sentence contains the configuration of the
+  *			time recovery feature of the receiver.
+  *	1	Time Recovery Mode:
+  *		D = Dynamic; solve for position and time while moving
+  *		S = Static; solve for position and time while stationary
+  *		K = Known position input, solve for time only
+  *		N = No time recovery
+  *	2	Time Synchronization:
+  *		U = UTC time
+  *		G = GPS time
+  *	3	Time Mark Mode:
+  *		A = Always output a time pulse
+  *		V = Only output time pulse if time is valid (as determined
+  *		    by Maximum Time Error)
+  *	4	Maximum Time Error - the maximum error (in nanoseconds) for
+  *		which a time mark will be considered valid.
+  *	5	User Time Bias - external bias in nanoseconds
+  *	6	Time Message Control:
+  *		0 = Do not output the time recovery message
+  *		1 = Output the time recovery message (record 830) to
+  *		    Control port
+  *		2 = Output the time recovery message (record 830) to
+  *		    Equipment port
+  *	7	Reserved
+  *	8	Position Known PRN (absent on MX 4200)
+  *
   */
  static char *
  mx4200_parse_s(peer)
***************
*** 1642,1655 ****
  
  	/* Sentence type */
  	sentence_type = strtol(cp, &cp, 10);
! 	if (sentence_type != PMVXG_D_SOFTCONF)
  		return ("wrong rec-type");
- 
- 	/* Log the software version */
  	cp++;
! 	msyslog(LOG_DEBUG, "mx4200_parse_s: firmware configuration: %s", cp);
  
! 	return 0;
  }
  
  /*
--- 1853,1890 ----
  
  	/* Sentence type */
  	sentence_type = strtol(cp, &cp, 10);
! 	if (sentence_type != PMVXG_D_STATUS &&
! 	    sentence_type != PMVXG_D_MODEDATA &&
! 	    sentence_type != PMVXG_D_SOFTCONF &&
! 	    sentence_type != PMVXG_D_TRECOVUSEAGE )
  		return ("wrong rec-type");
  	cp++;
! 
! 	/* Log the Status */
! 	if (sentence_type == PMVXG_D_STATUS) {
! 		msyslog(LOG_DEBUG,
! 		"mx4200_parse_s: status: %s", cp);
! 	}
! 
! 	/* Log the Mode Data */
! 	if (sentence_type == PMVXG_D_MODEDATA) {
! 		msyslog(LOG_DEBUG,
! 		"mx4200_parse_s: mode data: %s", cp);
! 	}
! 
! 	/* Log the Software Version */
! 	if (sentence_type == PMVXG_D_SOFTCONF) {
! 		msyslog(LOG_DEBUG,
! 		"mx4200_parse_s: firmware configuration: %s", cp);
! 	}
! 
! 	/* Log the Time Recovery Parameters */
! 	if (sentence_type == PMVXG_D_TRECOVUSEAGE) {
! 		msyslog(LOG_DEBUG,
! 		"mx4200_parse_s: time recovery parms: %s", cp);
! 	}
  
! 	return (NULL);
  }
  
  /*
***************
*** 1816,1835 ****
  #else /* not (REFCLOCK && MX4200 && PPS) */
  int refclock_mx4200_bs;
  #endif /* not (REFCLOCK && MX4200 && PPS) */
- 
- /*
-  * History:
-  *
-  * refclock_mx4200.c
-  *
-  * Author:	Craig Leres?
-  * Revised:	Marc Brett	1.10	1996-05-08
-  * - rewrote to "new-style" xntpd driver standard.
-  * - added position-averaging/fixed-location logic.
-  * Revised:	Marc Brett	1.20	1997-02-11
-  * - updated to xntp3-5.89.5 standards.
-  *
-  * Craig Leres	(leres@ee.lbl.gov)
-  * Marc Brett	(Marc.Brett@waii.com)
-  *
-  */
--- 2051,2053 ----

--PART-BOUNDARY=.19703181300.ZM17248.london.waii.com--

