]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
refclock_acts.c updates from Dave Mills
authorHarlan Stenn <stenn@ntp.org>
Fri, 31 Dec 2010 06:45:11 +0000 (01:45 -0500)
committerHarlan Stenn <stenn@ntp.org>
Fri, 31 Dec 2010 06:45:11 +0000 (01:45 -0500)
bk: 4d1d7bf7KpJ15hfKd6C7fh5m7RzQKg

ChangeLog
ntpd/refclock_acts.c

index 915f7d4af0b49dd35e5473317fea780cea28808d..061faceb8c55cd60c7e41e264a076ebfcca2fcaf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@
 * Move ntp_control.h variable IDs to ntp_control.c, remove their use by
   ntpq.  They are implementation details private to ntpd.  [Bug 597] was
   caused by ntpq's reliance on these IDs it need not know about.
+* refclock_acts.c updates from Dave Mills.
 (4.2.7p106) 2010/12/30 Released by Harlan Stenn <stenn@ntp.org>
 * from 4.2.6p3: Update genCommitLog for the bk-5 release.
 (4.2.7p105) 2010/12/29 Released by Harlan Stenn <stenn@ntp.org>
index 0429de60a8aa11c070a46853732aef7df01b3c6c..3a4d2f923d7bf48fed77974b02a177f6a4f27645 100644 (file)
  *
  * flag1       force a call in manual mode
  * flag2       enable port locking (not verified)
- * flag3       no modem; port is directly connected to device
+ * flag3       not used
  * flag4       not used
  *
  * time1       offset adjustment (s)
  *
- * Ordinarily, the serial port is connected to a modem; however, it can
- * be connected directly to a device or another computer for testing and
- * calibration. In this case set fudge flag3 and the driver will send a
- * single character 'T' at each poll event. In principle, fudge flag2
- * enables port locking, allowing the modem to be shared when not in use
- * by this driver. At least on Solaris with the current NTP I/O
- * routines, this results only in lots of ugly error messages.
+ * Ordinarily, the serial port is connected to a modem and the phones
+ * list is defined. If no phones list is defined, the port can be 
+ * connected directly to a device or another computer. In this case the
+ * driver will send a single character 'T' at each poll event. If
+ * fudge flag2 is enabled, port locking allows the modem to be shared
+ * when not in use by this driver.
  */
 /*
  * National Institute of Science and Technology (NIST)
 #define        DEVICE          "/dev/acts%d" /* device name and unit */
 #define        SPEED232        B9600   /* uart speed (9600 baud) */
 #define        PRECISION       (-10)   /* precision assumed (about 1 ms) */
-#define LOCKFILE       "/var/spool/locks/LCK..cua%d"
+#define LOCKFILE       "/var/spool/lock/LCK..cua%d"
 #define DESCRIPTION    "Automated Computer Time Service" /* WRU */
 #define REFID          "NONE"  /* default reference ID */
 #define MSGCNT         20      /* max message count */
-#define SMAX           256     /* max clockstats line length */
 #define        MAXPHONE        10      /* max number of phone numbers */
 
 /*
- * Calling program modes
+ * Calling program modes (mode)
  */
-#define MODE_AUTO      0       /* automatic mode */
-#define MODE_BACKUP    1       /* backup mode */
+#define MODE_BACKUP    0       /* backup mode */
+#define MODE_AUTO      1       /* automatic mode */
 #define MODE_MANUAL    2       /* manual mode */
 
 /*
- * Service identifiers.
+ * Service identifiers (message length)
  */
 #define REFACTS                "NIST"  /* NIST reference ID */
 #define LENACTS                50      /* NIST format */
  * &C0 disable carrier detect
  * &D2 hang up and return to command mode on DTR transition
  * E0  modem command echo disabled
- * l1  set modem speaker volume to low level
+ * L1  set modem speaker volume to low level
  * M1  speaker enabled until carrier detect
  * Q0  return result codes
  * V1  return result codes as English words
+ * Y1  enable long-space disconnect
  */
-#define MODEM_SETUP    "ATB1&C0&D2E0L1M1Q0V1\r" /* modem setup */
-#define MODEM_HANGUP   "ATH\r" /* modem disconnect */
+#define MODEM_SETUP    "ATB1&C0&D2E0L1M1Q0V1Y1" /* modem setup */
 
 /*
  * Timeouts (all in seconds)
  */
 #define SETUP          3       /* setup timeout */
-#define        DTR             1       /* DTR timeout */
+#define        REDIAL          30      /* redial timeout */
 #define ANSWER         60      /* answer timeout */
-#define CONNECT                20      /* first valid message timeout */
-#define TIMECODE       30      /* all valid messages timeout */
+#define TIMECODE       60      /* message timeout */
+#define        MAXCODE         10      /* max timecodes */
 
 /*
  * State machine codes
  */
 #define S_IDLE         0       /* wait for poll */
-#define S_OK           1       /* wait for modem setup */
-#define S_DTR          2       /* wait for modem DTR */
-#define S_CONNECT      3       /* wait for answer*/
-#define S_FIRST                4       /* wait for first valid message */
-#define S_MSG          5       /* wait for all messages */
-#define S_CLOSE                6       /* wait after sending disconnect */
+#define        S_SETUP         1       /* send modem setup */
+#define S_CONNECT      2       /* wait for answer */
+#define S_MSG          3       /* wait for timecode */
 
 /*
  * Unit control structure
@@ -217,9 +212,9 @@ static      void    acts_receive    (struct recvbuf *);
 static void    acts_message    (struct peer *);
 static void    acts_timecode   (struct peer *, char *);
 static void    acts_poll       (int, struct peer *);
-static void    acts_timeout    (struct peer *);
-static void    acts_disc       (struct peer *);
+static void    acts_timeout    (struct peer *, int);
 static void    acts_timer      (int, struct peer *);
+static void    acts_close      (struct peer *);
 
 /*
  * Transfer vector (conditional structure name)
@@ -332,7 +327,8 @@ acts_receive (
                        *up->bufptr++ = *tptr;
                        if (*tptr == '*' || *tptr == '#') {
                                up->tstamp = pp->lastrec;
-                               write(pp->io.fd, tptr, 1);
+                               if (write(pp->io.fd, tptr, 1) < 0)
+                                       msyslog(LOG_ERR, "acts: write echo fails %m");
                        }
                }
        }
@@ -349,77 +345,342 @@ acts_message(
 {
        struct actsunit *up;
        struct refclockproc *pp;
-       int     dtr = TIOCM_DTR;
-       char    tbuf[SMAX];
-#ifdef DEBUG
-       u_int   modem;
-#endif
+       char    tbuf[BMAX];
+       int             dtr = TIOCM_DTR;
 
        /*
         * What to do depends on the state and the first token in the
-        * message.      */
+        * message.
+        */
        pp = peer->procptr;
        up = (struct actsunit *)pp->unitptr;
+
 #ifdef DEBUG
-       ioctl(pp->io.fd, TIOCMGET, (char *)&modem);
-       snprintf(tbuf, sizeof(tbuf), "acts: %04x (%d %d) %lu %s", modem,
-                up->state, up->timer, (u_long)strlen(pp->a_lastcode),
-                pp->a_lastcode);
        if (debug)
-               printf("%s\n", tbuf);
+               printf("acts: %d %s\n", strlen(pp->a_lastcode),
+                   pp->a_lastcode);
 #endif
 
        /*
-        * Extract the first token in the line. A NO token sends the
-        * message to the clockstats.
+        * Extract the first token in the line.
         */
-       strncpy(tbuf, pp->a_lastcode, SMAX);
+       strncpy(tbuf, pp->a_lastcode, BMAX);
        strtok(tbuf, " ");
-       if (strcmp(tbuf, "NO") == 0) {
+       switch(up->state) {
+
+       /*
+        * We are waiting for the OK response to the modem setup
+        * command. When this happens, dial the number followed.
+        * If anything other than OK is received, just ignore it
+        * and wait for timeoue.
+        */
+       case S_SETUP:
+               if (strcmp(tbuf, "OK") != 0)
+                       break;
+
+               snprintf(tbuf, sizeof(tbuf), "DIAL #%d %s", up->retry,
+                   sys_phone[up->retry]);
+               report_event(PEVNT_CLOCK, peer, tbuf);
+               ioctl(pp->io.fd, TIOCMBIS, &dtr);
+               if (write(pp->io.fd, sys_phone[up->retry],
+                   strlen(sys_phone[up->retry])) < 0)
+                       msyslog(LOG_ERR, "acts: write DIAL fails %m");
+               write(pp->io.fd, "\r", 1);
+               up->retry++;
+               up->state = S_CONNECT;
+               up->timer = ANSWER;
+               return;
+
+       /*
+        * We are waiting for the CONNECT response to the dial
+        * command. When this happens, listen for timecodes. If
+        * somthing other than CONNECT is received, like BUSY
+        * or NO CARRIER, abort the call.
+        */
+       case S_CONNECT:
+               if (strcmp(tbuf, "CONNECT") != 0)
+                       break;
+
                report_event(PEVNT_CLOCK, peer, pp->a_lastcode);
+               up->state = S_MSG;
+               up->timer = TIMECODE;
+               return;
+
+       /*
+        * We are waiting for a timecode response. Pass it to
+        * the parser. If NO CARRIER is received, save the
+        * messages and abort the call.
+        */
+       case S_MSG:
+               if (strcmp(tbuf, "NO") == 0)
+                       report_event(PEVNT_CLOCK, peer, pp->a_lastcode);
+               if (up->msgcnt < MAXCODE)
+                       acts_timecode(peer, pp->a_lastcode);
+               else
+                       acts_timeout(peer, S_MSG);
                return;
        }
-       switch(up->state) {
 
        /*
-        * We are waiting for the OK response to the modem setup
-        * command. When this happens, raise DTR and dial the number
-        * followed by \r.
+        * Other response. Tell us about it.
         */
-       case S_OK:
-               if (strcmp(tbuf, "OK") != 0) {
-                       msyslog(LOG_ERR, "acts: setup error %s",
-                           pp->a_lastcode);
-                       acts_disc(peer);
+       report_event(PEVNT_CLOCK, peer, pp->a_lastcode);
+       acts_close(peer);
+}
+
+
+/*
+ * acts_timeout - called on timeout
+ */
+static void
+acts_timeout(
+       struct peer *peer,
+       int     dstate
+       )
+{
+       struct actsunit *up;
+       struct refclockproc *pp;
+       int     fd;
+       char    device[20];
+       char    lockfile[128], pidbuf[8];
+       char    tbuf[BMAX];
+
+       /*
+        * The state machine is driven by messages from the modem,
+        * when first stated and at timeout.
+        */
+       pp = peer->procptr;
+       up = (struct actsunit *)pp->unitptr;
+       switch(dstate) {
+
+       /*
+        * System poll event. Lock the modem port, open the device
+        * and send the setup command.
+        */
+       case S_IDLE:
+
+               /*
+                * Lock the modem port. If busy, retry later. Note: if
+                * something fails between here and the close, the lock
+                * file may not be removed.
+                */
+               if (pp->sloppyclockflag & CLK_FLAG2) {
+                       snprintf(lockfile, sizeof(lockfile), LOCKFILE,
+                           up->unit);
+                       fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL,
+                           0644);
+                       if (fd < 0) {
+                               report_event(PEVNT_CLOCK, peer, "acts: port busy");
+                               return;
+                       }
+                       snprintf(pidbuf, sizeof(pidbuf), "%d\n",
+                           (u_int)getpid());
+                       if (write(fd, pidbuf, strlen(pidbuf)) < 0)
+                               msyslog(LOG_ERR, "acts: write lock fails %m");
+                       close(fd);
+               }
+
+               /*
+                * Open the device in raw mode and link the I/O.
+                */
+               snprintf(device, sizeof(device), DEVICE,
+                   up->unit);
+               fd = refclock_open(device, SPEED232,LDISC_ACTS |
+                   LDISC_RAW | LDISC_REMOTE);
+               if (fd < 0) {
+                       msyslog(LOG_ERR, "acts: open fails %m");
                        return;
                }
-               ioctl(pp->io.fd, TIOCMBIS, (char *)&dtr);
-               up->state = S_DTR;
-               up->timer = DTR;
+               pp->io.fd = fd;
+               if (!io_addclock(&pp->io)) {
+                       msyslog(LOG_ERR, "acts: addclock fails");
+                       return;
+               }
+               tcflush(pp->io.fd, TIOCFLUSH);
+               up->msgcnt = 0;
+               up->bufptr = pp->a_lastcode;
+
+               /*
+                * If the port is directly connected to the device, skip
+                * the modem business and send 'T' for Spectrabum.
+                */
+               if (sys_phone[up->retry] == NULL) {
+                       if (write(pp->io.fd, "T", 1) < 0)
+                               msyslog(LOG_ERR, "acts: write T fails %m");
+                       up->state = S_MSG;
+                       up->timer = TIMECODE;
+                       return;
+               }
+
+               /*
+                * Initialize the modem. This works with Hayes comapatible
+                * modems.
+                */
+               snprintf(tbuf, sizeof(tbuf), "SETUP %s", MODEM_SETUP); 
+               report_event(PEVNT_CLOCK, peer, tbuf);
+               if (write(pp->io.fd, MODEM_SETUP, strlen(MODEM_SETUP)) < 0)
+                       msyslog(LOG_ERR, "acts: write SETUP fails %m");
+               write(pp->io.fd, "\r", 1);
+               up->state = S_SETUP;
+               up->timer = SETUP;
                return;
 
        /*
-        * We are waiting for the call to be answered. All we care about
-        * here is token CONNECT. Send the message to the clockstats.
+        * In SETUP state the modem did not respond to setup.
+        * the call.
+        */
+       case S_SETUP:
+               report_event(PEVNT_CLOCK, peer, "no modem");
+               break;
+
+       /*
+        * In CONNECT state the call did not complete. Abort
+        * the call.
         */
        case S_CONNECT:
-               report_event(PEVNT_CLOCK, peer, pp->a_lastcode);
-               if (strcmp(tbuf, "CONNECT") != 0) {
-                       acts_disc(peer);
+               report_event(PEVNT_CLOCK, peer, "no answer");
+               break;
+
+       /*
+        * In MSG states no further timecoees are expected. If any
+        * timecodes have arrived, update the clock. In any case,
+        * ternuabte the cakk.
+        */
+       case S_MSG:
+               if (up->msgcnt == 0)
+                       report_event(PEVNT_CLOCK, peer, "no timecodes");
+               else
+                       refclock_receive(peer);
+               break;
+       }
+       acts_close(peer);
+}
+
+
+/*
+ * acts_close - close and prepare for next call.
+ *
+ * In ClOSE state no further protocol actions are required
+ * other than to close and release the device and prepare to
+ * dial the next number if necessary.
+ */
+void
+acts_close(
+       struct peer *peer
+       )
+{
+       struct actsunit *up;
+       struct refclockproc *pp;
+       char    lockfile[128];
+       int             dtr = TIOCM_DTR;
+
+       pp = peer->procptr;
+       up = (struct actsunit *)pp->unitptr;
+       if (pp->io.fd != 0) {
+               report_event(PEVNT_CLOCK, peer, "close");
+               ioctl(pp->io.fd, TIOCMBIC, &dtr);
+               tcflush(pp->io.fd, TIOCFLUSH);
+               io_closeclock(&pp->io);
+               pp->io.fd = 0;
+       }
+       if (pp->sloppyclockflag & CLK_FLAG2) {
+               snprintf(lockfile, sizeof(lockfile),
+                   LOCKFILE, up->unit);
+               unlink(lockfile);
+       }
+       if (up->msgcnt == 0 && up->retry > 0) {
+           if (sys_phone[up->retry] != NULL) {
+                       up->state = S_IDLE;
+                       up->timer = REDIAL;
                        return;
                }
-               up->state = S_FIRST;
-               up->timer = CONNECT;
+       }
+       up->state = S_IDLE;
+       up->timer = 0;
+}
+
+
+/*
+ * acts_poll - called by the transmit routine
+ */
+static void
+acts_poll (
+       int     unit,
+       struct peer *peer
+       )
+{
+       struct actsunit *up;
+       struct refclockproc *pp;
+
+       /*
+        * This routine is called at every system poll. All it does is
+        * set flag1 under certain conditions. The real work is done by
+        * the timeout routine and state machine.
+        */
+       pp = peer->procptr;
+       up = (struct actsunit *)pp->unitptr;
+       switch (peer->ttl) {
+
+       /*
+        * In manual mode the calling program is activated by the ntpdc
+        * program using the enable flag (fudge flag1), either manually
+        * or by a cron job.
+        */
+       case MODE_MANUAL:
                return;
 
        /*
-        * We are waiting for a timecode. Pass it to the parser.
+        * In automatic mode the calling program runs continuously at
+        * intervals determined by the poll event or specified timeout.
         */
-       case S_FIRST:
-       case S_MSG:
-               acts_timecode(peer, pp->a_lastcode);
+       case MODE_AUTO:
+               break;
+
+       /*
+        * In backup mode the calling program runs continuously as long
+        * as either no peers are available or this peer is selected.
+        */
+       case MODE_BACKUP:
+               if (!(sys_peer == NULL || sys_peer == peer))
+                       return;
+
                break;
        }
+       up->retry = 0;
+       acts_timeout(peer, S_IDLE);
+}
+
+
+/*
+ * acts_timer - called at one-second intervals
+ */
+static void
+acts_timer(
+       int     unit,
+       struct peer *peer
+       )
+{
+       struct actsunit *up;
+       struct refclockproc *pp;
+
+       /*
+        * This routine implments a timeout which runs for a programmed
+        * interval. The counter is initialized by the state machine and
+        * counts down to zero. Upon reaching zero, the state machine is
+        * called. If flag1 is set while timer is zero, force a call.
+        */
+       pp = peer->procptr;
+       up = (struct actsunit *)pp->unitptr;
+       if (up->timer == 0) {
+               if (pp->sloppyclockflag & CLK_FLAG1) {
+                       pp->sloppyclockflag &= ~CLK_FLAG1;
+                       acts_timeout(peer, S_IDLE);
+               }
+       } else {
+               up->timer--;
+               if (up->timer == 0)
+                       acts_timeout(peer, up->state);
+       }
 }
 
 /*
@@ -492,9 +753,10 @@ acts_timecode(
                 * We don't need to do anything, as ACTS adjusts the
                 * on-time epoch.
                 */
-               if (flag != '#')
+/*
+if (flag != '#')
                        return;
-
+*/
                pp->day = ymd2yd(pp->year, month, day);
                pp->leap = LEAP_NOWARNING;
                if (leap == 1)
@@ -528,7 +790,7 @@ acts_timecode(
                if (up->msgcnt == 0)
                        record_clock_stats(&peer->srcadr, str);
                up->msgcnt++;
-               return;
+               break;
 
        /*
         * PTB/NPL format: "yyyy-mm-dd hh:mm:ss MEZ" 
@@ -615,321 +877,14 @@ acts_timecode(
         */
        peer->refid = pp->refid;
        pp->lastrec = up->tstamp;
+       if (up->msgcnt == 0)
+               return;
+
        if (!refclock_process(pp)) {
                refclock_report(peer, CEVNT_BADTIME);
                return;
        }
        pp->lastref = pp->lastrec;
-       if (up->state != S_MSG) {
-               up->state = S_MSG;
-               up->timer = TIMECODE;
-       }
-}
-
-
-/*
- * acts_poll - called by the transmit routine
- */
-static void
-acts_poll (
-       int     unit,
-       struct peer *peer
-       )
-{
-       struct actsunit *up;
-       struct refclockproc *pp;
-
-       /*
-        * This routine is called at every system poll. All it does is
-        * set flag1 under certain conditions. The real work is done by
-        * the timeout routine and state machine.
-        */
-       pp = peer->procptr;
-       up = (struct actsunit *)pp->unitptr;
-       switch (peer->ttl) {
-
-       /*
-        * In manual mode the calling program is activated by the ntpdc
-        * program using the enable flag (fudge flag1), either manually
-        * or by a cron job.
-        */
-       case MODE_MANUAL:
-               /* fall through */
-               break;
-
-       /*
-        * In automatic mode the calling program runs continuously at
-        * intervals determined by the poll event or specified timeout.
-        */
-       case MODE_AUTO:
-               pp->sloppyclockflag |= CLK_FLAG1;
-               break;
-
-       /*
-        * In backup mode the calling program runs continuously as long
-        * as either no peers are available or this peer is selected.
-        */
-       case MODE_BACKUP:
-               if (sys_peer == NULL || sys_peer == peer)
-                       pp->sloppyclockflag |= CLK_FLAG1;
-               break;
-       }
-}
-
-
-/*
- * acts_timer - called at one-second intervals
- */
-static void
-acts_timer(
-       int     unit,
-       struct peer *peer
-       )
-{
-       struct actsunit *up;
-       struct refclockproc *pp;
-
-       /*
-        * This routine implments a timeout which runs for a programmed
-        * interval. The counter is initialized by the state machine and
-        * counts down to zero. Upon reaching zero, the state machine is
-        * called. If flag1 is set while in S_IDLE state, force a
-        * timeout.
-        */
-       pp = peer->procptr;
-       up = (struct actsunit *)pp->unitptr;
-       if (pp->sloppyclockflag & CLK_FLAG1 && up->state == S_IDLE) {
-               acts_timeout(peer);
-               return;
-       }
-       if (up->timer == 0)
-               return;
-
-       up->timer--;
-       if (up->timer == 0)
-               acts_timeout(peer);
-}
-
-
-/*
- * acts_timeout - called on timeout
- */
-static void
-acts_timeout(
-       struct peer *peer
-       )
-{
-       struct actsunit *up;
-       struct refclockproc *pp;
-       int     fd;
-       char    device[20];
-       char    lockfile[128], pidbuf[8];
-       char    tbuf[SMAX];
-
-       /*
-        * The state machine is driven by messages from the modem, when
-        * first stated and at timeout.
-        */
-       pp = peer->procptr;
-       up = (struct actsunit *)pp->unitptr;
-       pp->sloppyclockflag &= ~CLK_FLAG1;
-       if (sys_phone[up->retry] == NULL && !(pp->sloppyclockflag &
-           CLK_FLAG3)) {
-               msyslog(LOG_ERR, "acts: no phones");
-               return;
-       }
-       switch(up->state) {
-
-       /*
-        * System poll event. Lock the modem port and open the device.
-        */
-       case S_IDLE:
-
-               /*
-                * Lock the modem port. If busy, retry later. Note: if
-                * something fails between here and the close, the lock
-                * file may not be removed.
-                */
-               if (pp->sloppyclockflag & CLK_FLAG2) {
-                       snprintf(lockfile, sizeof(lockfile), LOCKFILE,
-                           up->unit);
-                       fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL,
-                           0644);
-                       if (fd < 0) {
-                               msyslog(LOG_ERR, "acts: port busy");
-                               return;
-                       }
-                       snprintf(pidbuf, sizeof(pidbuf), "%d\n",
-                           (u_int)getpid());
-                       write(fd, pidbuf, strlen(pidbuf));
-                       close(fd);
-               }
-
-               /*
-                * Open the device in raw mode and link the I/O.
-                */
-               if (!pp->io.fd) {
-                       snprintf(device, sizeof(device), DEVICE,
-                           up->unit);
-                       fd = refclock_open(device, SPEED232,
-                           LDISC_ACTS | LDISC_RAW | LDISC_REMOTE);
-                       if (fd == 0) {
-                               msyslog(LOG_ERR,
-                                   "acts: open fails");
-                               return;
-                       }
-                       pp->io.fd = fd;
-                       if (!io_addclock(&pp->io)) {
-                               msyslog(LOG_ERR,
-                                   "acts: addclock fails");
-                               close(fd);
-                               pp->io.fd = 0;
-                               return;
-                       }
-               }
-
-               /*
-                * If the port is directly connected to the device, skip
-                * the modem business and send 'T' for Spectrabum.
-                */
-               if (pp->sloppyclockflag & CLK_FLAG3) {
-                       if (write(pp->io.fd, "T", 1) < 0) {
-                               msyslog(LOG_ERR, "acts: write %m");
-                               return;
-                       }
-                       up->state = S_FIRST;
-                       up->timer = CONNECT;
-                       return;
-               }
-
-               /*
-                * Initialize the modem. This works with Hayes commands.
-                */
-#ifdef DEBUG
-               if (debug)
-                       printf("acts: setup %s\n", MODEM_SETUP);
-#endif
-               if (write(pp->io.fd, MODEM_SETUP, strlen(MODEM_SETUP)) <
-                   0) {
-                       msyslog(LOG_ERR, "acts: write %m");
-                       return;
-               }
-               up->state = S_OK;
-               up->timer = SETUP;
-               return;
-
-       /*
-        * In OK state the modem did not respond to setup.
-        */
-       case S_OK:
-               msyslog(LOG_ERR, "acts: no modem");
-               break;
-
-       /*
-        * In DTR state we are waiting for the modem to settle down
-        * before hammering it with a dial command.
-        */
-       case S_DTR:
-               snprintf(tbuf, sizeof(tbuf), "DIAL #%d %s", up->retry,
-                   sys_phone[up->retry]);
-               report_event(PEVNT_CLOCK, peer, tbuf);
-#ifdef DEBUG
-               if (debug)
-                       printf("%s\n", tbuf);
-#endif
-               write(pp->io.fd, sys_phone[up->retry],
-                   strlen(sys_phone[up->retry]));
-               write(pp->io.fd, "\r", 1);
-               up->state = S_CONNECT;
-               up->timer = ANSWER;
-               return;
-
-       /*
-        * In CONNECT state the call did not complete.
-        */
-       case S_CONNECT:
-               msyslog(LOG_ERR, "acts: no answer");
-               break;
-
-       /*
-        * In FIRST state no messages were received.
-        */
-       case S_FIRST:
-               msyslog(LOG_ERR, "acts: no messages");
-               break;
-
-       /*
-        * In CLOSE state hangup is complete. Close the doors and
-        * windows and get some air.
-        */
-       case S_CLOSE:
-
-               /*
-                * Close the device and unlock a shared modem.
-                */
-               if (pp->io.fd) {
-                       io_closeclock(&pp->io);
-                       close(pp->io.fd);
-                       if (pp->sloppyclockflag & CLK_FLAG2) {
-                               snprintf(lockfile, sizeof(lockfile),
-                                   LOCKFILE, up->unit);
-                               unlink(lockfile);
-                       }
-                       pp->io.fd = 0;
-               }
-
-               /*
-                * If messages were received, fold the tent and wait for
-                * the next poll. If no messages and there are more
-                * numbers to dial, retry after a short wait.
-                */
-               up->bufptr = pp->a_lastcode;
-               up->timer = 0;
-               up->state = S_IDLE;
-               if ( up->msgcnt == 0) {
-                       up->retry++;
-                       if (sys_phone[up->retry] == NULL)
-                               up->retry = 0;
-                       else
-                               up->timer = SETUP;
-               } else {
-                       up->retry = 0;
-               }
-               up->msgcnt = 0;
-               return;
-       }
-       acts_disc(peer);
-}
-
-
-/*
- * acts_disc - disconnect the call and clean the place up.
- */
-static void
-acts_disc (
-       struct peer *peer
-       )
-{
-       struct actsunit *up;
-       struct refclockproc *pp;
-       int     dtr = TIOCM_DTR;
-
-       /*
-        * We get here if the call terminated successfully or if an
-        * error occured. If the median filter has something in it,
-        * feed the data to the clock filter. If a modem port, drop DTR
-        * to force command mode and send modem hangup.
-        */
-       pp = peer->procptr;
-       up = (struct actsunit *)pp->unitptr;
-       if (up->msgcnt > 0)
-               refclock_receive(peer);
-       if (!(pp->sloppyclockflag & CLK_FLAG3)) {
-               ioctl(pp->io.fd, TIOCMBIC, (char *)&dtr);
-               write(pp->io.fd, MODEM_HANGUP, strlen(MODEM_HANGUP));
-       }
-       up->timer = SETUP;
-       up->state = S_CLOSE;
 }
 #else
 int refclock_acts_bs;