hayes.c revision 8d489c7a815fcac696803219572e95aa01532b0f
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "tip.h"
static int hayes_sync(int);
static void sigALRM(void);
static sigjmp_buf timeoutbuf;
void hayes_disconnect(void);
/*
* Dial up on a Hayes Smart Modem 1200 or 2400
*/
/* ARGSUSED */
int
hayes_dialer(char *num, char *acu)
{
char code = 0, cr = 0;
sig_handler_t f;
struct termios buf;
f = signal(SIGALRM, (sig_handler_t)sigALRM);
if (!hayes_sync(FD)) {
(void) printf("can't synchronize with hayes\n");
#ifdef ACULOG
logent(value(HOST), num, "hayes", "can't synch up");
#endif
(void) signal(SIGALRM, f);
return (0);
}
if (boolean(value(VERBOSE)))
(void) printf("\ndialing...");
(void) fflush(stdout);
(void) ioctl(FD, TCGETS, &buf);
buf.c_cflag |= HUPCL;
(void) ioctl(FD, TCSETS, &buf);
(void) ioctl(FD, TCFLSH, TCIOFLUSH);
if (sigsetjmp(timeoutbuf, 1)) {
#ifdef ACULOG
char line[80];
(void) sprintf(line, "%d second dial timeout",
number(value(DIALTIMEOUT)));
logent(value(HOST), num, "hayes", line);
#endif
hayes_disconnect();
(void) signal(SIGALRM, f);
return (0);
}
(void) alarm(number(value(DIALTIMEOUT)));
(void) ioctl(FD, TCFLSH, TCIOFLUSH);
if (*num == 'S')
(void) write(FD, "AT", 2);
else
(void) write(FD, "ATDT", 4); /* use tone dialing */
(void) write(FD, num, strlen(num));
(void) write(FD, "\r", 1);
(void) read(FD, &code, 1);
(void) read(FD, &cr, 1);
if (code == '1' && cr == '0')
(void) read(FD, &cr, 1);
(void) alarm(0);
(void) signal(SIGALRM, f);
if ((code == '1' || code == '5') && cr == '\r')
return (1);
return (0);
}
void
hayes_disconnect(void)
{
(void) close(FD);
}
void
hayes_abort(void)
{
int dtr = TIOCM_DTR;
(void) alarm(0);
(void) ioctl(FD, TIOCMBIC, &dtr);
(void) sleep(2);
(void) ioctl(FD, TCFLSH, TCIOFLUSH);
(void) close(FD);
}
static void
sigALRM(void)
{
siglongjmp(timeoutbuf, 1);
}
/*
* This piece of code attempts to get the hayes in sync.
*/
static int
hayes_sync(int fd)
{
int tries;
char code = 0, cr = 0;
int dtr = TIOCM_DTR;
/*
* Toggle DTR to force anyone off that might have left
* the modem connected, and insure a consistent state
* to start from.
*/
(void) ioctl(fd, TIOCMBIC, &dtr);
(void) sleep(1);
(void) ioctl(fd, TIOCMBIS, &dtr);
for (tries = 0; tries < 3; tries++) {
/*
* After reseting the modem, initialize all
* parameters to required vaules:
*
* V0 - result codes are single digits
* Q0 - result codes ARE sent
* E0 - do not echo
* S0=1 - automatically answer phone
* S2=255 - disable escape character
* S12=255 - longest possible escape guard time
*/
(void) write(fd, "ATV0Q0E0S0=1S2=255S12=255\r", 26);
(void) sleep(1);
/* flush any echoes or return codes */
(void) ioctl(fd, TCFLSH, TCIOFLUSH);
/* now see if the modem is talking to us properly */
(void) write(fd, "AT\r", 3);
if (sigsetjmp(timeoutbuf, 1) == 0) {
(void) alarm(2);
(void) read(FD, &code, 1);
(void) read(FD, &cr, 1);
if (code == '0' && cr == '\r')
return (1);
}
}
return (0);
}