/* * 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_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 = 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); } }
/* * acts_poll - called by the transmit routine */ static void acts_poll( int unit, struct peer *peer ) { struct actsunit *up; struct refclockproc *pp; UNUSED_ARG(unit); /* * 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 = pp->unitptr; switch (peer->ttl) { /* * In manual mode the calling program is activated by the ntpq * program using the enable flag (fudge flag1), either manually * or by a cron job. */ case MODE_MANUAL: return; /* * In automatic mode the calling program runs continuously at * intervals determined by the poll event or specified timeout. */ 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; } pp->polls++; if (S_IDLE == up->state) { up->retry = 0; acts_timeout(peer, S_IDLE); } }
/* * acts_message - process message */ void acts_message( struct peer *peer, const char *msg ) { struct actsunit *up; struct refclockproc *pp; char tbuf[BMAX]; int dtr = TIOCM_DTR; DPRINTF(1, ("acts: %d %s\n", (int)strlen(msg), msg)); /* * What to do depends on the state and the first token in the * message. */ pp = peer->procptr; up = pp->unitptr; /* * Extract the first token in the line. */ strlcpy(tbuf, msg, sizeof(tbuf)); strtok(tbuf, " "); 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) { /* * We disable echo with MODEM_SETUP's E0 but * if the modem was previously E1, we will * see MODEM_SETUP echoed before the OK/ERROR. * Ignore it. */ if (!strcmp(tbuf, modem_setup)) return; break; } mprintf_event(PEVNT_CLOCK, peer, "DIAL #%d %s", up->retry, sys_phone[up->retry]); if (ioctl(pp->io.fd, TIOCMBIS, &dtr) < 0) msyslog(LOG_ERR, "acts: ioctl(TIOCMBIS) failed: %m"); 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, msg); 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, msg); if (up->msgcnt < MAXCODE) acts_timecode(peer, msg); else acts_timeout(peer, S_MSG); return; } /* * Other response. Tell us about it. */ report_event(PEVNT_CLOCK, peer, msg); acts_close(peer); }