/* * acts_message - process message */ void acts_message( struct peer *peer ) { struct actsunit *up; struct refclockproc *pp; int dtr = TIOCM_DTR; char tbuf[SMAX]; #ifdef DEBUG u_int modem; #endif /* * What to do depends on the state and the first token in the * 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) %zu %s", modem, up->state, up->timer, strlen(pp->a_lastcode), pp->a_lastcode); if (debug) printf("%s\n", tbuf); #endif /* * Extract the first token in the line. A NO token sends the * message to the clockstats. */ strncpy(tbuf, pp->a_lastcode, SMAX); strtok(tbuf, " "); if (strcmp(tbuf, "NO") == 0) { report_event(PEVNT_CLOCK, peer, pp->a_lastcode); 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. */ case S_OK: if (strcmp(tbuf, "OK") != 0) { msyslog(LOG_ERR, "acts: setup error %s", pp->a_lastcode); acts_disc(peer); return; } ioctl(pp->io.fd, TIOCMBIS, (char *)&dtr); up->state = S_DTR; up->timer = DTR; return; /* * We are waiting for the call to be answered. All we care about * here is token CONNECT. Send the message to the clockstats. */ case S_CONNECT: report_event(PEVNT_CLOCK, peer, pp->a_lastcode); if (strcmp(tbuf, "CONNECT") != 0) { acts_disc(peer); return; } up->state = S_FIRST; up->timer = CONNECT; return; /* * We are waiting for a timecode. Pass it to the parser. */ case S_FIRST: case S_MSG: acts_timecode(peer, pp->a_lastcode); break; } }
/* * 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); }