Пример #1
0
/*
 * 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;
	}
}
Пример #2
0
/*
 * 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);
}