isdn4k-utils/vbox/src/modem.c

1080 lines
25 KiB
C

/*
** $Id: modem.c,v 1.13 1998/06/10 14:31:08 michael Exp $
**
** Copyright (C) 1996, 1997 Michael 'Ghandi' Herold
*/
#include "config.h"
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <termio.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "modem.h"
#include "log.h"
#include "voice.h"
#include "libvbox.h"
/** Defines **************************************************************/
#define USE_NEW_MODEM_READER /* Define to use new modem read command */
#undef DBG_NEW_MODEM_READER /* Define to debug new modem read command */
#undef DBG_OLD_MODEM_READER /* Define to debug old modem read command */
/** Variables ************************************************************/
static int timeoutstatus = FALSE;
static int nocarrier = FALSE;
static int nocarrierpos = 0;
static char *nocarriertxt = "NO CARRIER";
static char modem_store_result[MODEM_BUFFER_LEN + 1];
#ifdef USE_NEW_MODEM_READER
static int modem_input_pos = 0;
static int modem_input_len = 0;
static char modem_input[MODEM_INPUT_LEN + 1];
#endif
/** Prototypes ***********************************************************/
static void modem_set_speed(TIO *);
static void modem_set_sane_mode(TIO *, int);
static void modem_set_raw_mode(TIO *);
static int modem_write(char *);
static int modem_read(char *, int);
static void modem_timeout_function(int);
static void modem_check_nocarrier(char);
static int modem_check_result(char *, char *);
static void modem_set_flowcontrol(TIO *);
static int modem_get_echo(char *);
static int modem_get_rawsequence(char *, int);
/*************************************************************************/
/** modem_open_port(): Opens the modem port. **/
/*************************************************************************/
int modem_open_port(void)
{
log(L_DEBUG, "Opening modem port \"%s\"...\n", setup.modem.device);
if (setup.modem.fd == -1)
{
if ((setup.modem.fd = open(setup.modem.device, O_RDWR|O_NDELAY)) == -1)
{
log(L_FATAL, "Can't open modem port \"%s\".\n", setup.modem.device);
returnerror();
}
if (fcntl(setup.modem.fd, F_SETFL, O_RDWR) == -1)
{
log(L_FATAL, "Can't call fcntl() to setup modem port.\n");
returnerror();
}
}
else log(L_WARN, "Found open modem port (%d).\n", setup.modem.fd);
returnok();
}
/*************************************************************************/
/** modem_set_speed(): Sets the modemport speed to 57600. **/
/*************************************************************************/
static void modem_set_speed(TIO *modemtio)
{
log(L_JUNK, "Setting modem speed to 57600...\n");
cfsetospeed(modemtio, B57600);
cfsetispeed(modemtio, B57600);
}
/*************************************************************************/
/** modem_set_termio(): Sets the modem terminal IO. **/
/*************************************************************************/
int modem_set_termio(TIO *modemtio)
{
if (tcsetattr(setup.modem.fd, TCSANOW, modemtio) >= 0) returnok();
returnerror();
}
/*************************************************************************/
/** modem_get_termio(): Gets the modem terminal IO. **/
/*************************************************************************/
int modem_get_termio(TIO *modemtio)
{
if (tcgetattr(setup.modem.fd, modemtio) >= 0) returnok();
returnerror();
}
/*************************************************************************/
/** modem_set_flowcontrol(): Sets modem flowcontrol to hardware hand- **/
/** shake. **/
/*************************************************************************/
static void modem_set_flowcontrol(TIO *modemtio)
{
log(L_JUNK, "Setting modem flow control (HARD)...\n");
modemtio->c_cflag &= ~(CRTSCTS);
modemtio->c_iflag &= ~(IXON|IXOFF|IXANY);
modemtio->c_cflag |= (CRTSCTS);
}
/*************************************************************************/
/** modem_hangup(): Toggles the data terminal ready line to hangup the **/
/** modem. **/
/*************************************************************************/
int modem_hangup(void)
{
TIO porttio;
TIO savetio;
log(L_DEBUG, "Hangup modem (drop dtr %d ms)...\n", setup.modem.toggle_dtr_time);
modem_flush(1);
if (!modem_get_termio(&porttio)) returnerror();
savetio = porttio;
cfsetospeed(&porttio, B0);
cfsetispeed(&porttio, B0);
modem_set_termio(&porttio);
xpause(setup.modem.toggle_dtr_time);
return(modem_set_termio(&savetio));
}
/*************************************************************************/
/** modem_set_sane_mode(): Sets modem terminal IO to sane mode. **/
/*************************************************************************/
static void modem_set_sane_mode(TIO *modemtio, int local)
{
modemtio->c_iflag = (BRKINT|IGNPAR|IXON|IXANY);
modemtio->c_oflag = (OPOST|TAB3);
modemtio->c_cflag &= ~(CSIZE|CSTOPB|PARENB|PARODD|CLOCAL);
modemtio->c_cflag |= (CS8|CREAD|HUPCL|(local ? CLOCAL : 0));
modemtio->c_lflag = (ECHOK|ECHOE|ECHO|ISIG|ICANON);
}
/*************************************************************************/
/** modem_set_raw_mode(): Sets modem terminal IO to raw mode. **/
/*************************************************************************/
static void modem_set_raw_mode(TIO *modemtio)
{
modemtio->c_iflag &= (IXON|IXOFF|IXANY);
modemtio->c_oflag = 0;
modemtio->c_lflag = 0;
modemtio->c_cc[VMIN] = 1;
modemtio->c_cc[VTIME] = 0;
}
/*************************************************************************/
/** modem_initialize(): Initialize the modem. **/
/*************************************************************************/
int modem_initialize(void)
{
TIO porttio;
log(L_INFO, "Initializing modem port (voice mode; %d ms)...\n", setup.modem.initpause);
xpause(setup.modem.initpause);
if (!modem_hangup()) log(L_WARN, "Can't hangup modem!\n");
if (!modem_get_termio(&porttio))
{
log(L_ERROR, "Can't get modem terminal IO settings (not initialized).\n");
returnerror();
}
modem_set_sane_mode(&porttio, TRUE);
modem_set_speed(&porttio);
modem_set_raw_mode(&porttio);
modem_set_flowcontrol(&porttio);
if (!modem_set_termio(&porttio))
{
log(L_ERROR, "Can't set modem terminal IO settings (not initialized).\n");
returnerror();
}
if (modem_command(setup.modem.init, "OK") <= 0) returnerror();
if (modem_command(setup.modem.interninita, "OK|VCON") <= 0) returnerror();
if (modem_command(setup.modem.interninitb, "OK|VCON") <= 0) returnerror();
returnok();
}
/*************************************************************************/
/** modem_close_port(): Close modem port. **/
/*************************************************************************/
void modem_close_port(void)
{
if (!modem_hangup()) log(L_WARN, "Can't hangup modem!\n");
log(L_DEBUG, "Closing modem port (%d)...\n", setup.modem.fd);
close(setup.modem.fd);
setup.modem.fd = -1;
}
/*************************************************************************/
/** modem_get_last_result(): Returns the last modem result. **/
/*************************************************************************/
char *modem_get_last_result(void)
{
return(modem_store_result);
}
/*************************************************************************/
/** modem_command(): Sends a command to the modem and waits for one or **/
/** more results. **/
/*************************************************************************/
int modem_command(char *command, char *result)
{
char line[MODEM_BUFFER_LEN + 1];
char commandsuffix[2];
int back;
*modem_store_result = '\0';
commandsuffix[0] = MODEM_COMMAND_SUFFIX;
commandsuffix[1] = 0;
if ((command) && (*command))
{
modem_flush(0);
log_line(L_DEBUG, "Sending \"");
log_code(L_DEBUG, command);
log_text(L_DEBUG, "\"...\n");
if (strcmp(command, commandsuffix) != 0)
{
if ((!modem_write(command)) || (!modem_write(commandsuffix)))
{
log(L_ERROR, "Can't send modem command.\n");
modem_flush(1);
returnerror();
}
if (!modem_get_echo(command))
{
log(L_ERROR, "Can't read modem command echo.\n");
modem_flush(1);
returnerror();
}
}
else
{
if (!modem_write(command))
{
log(L_ERROR, "Can't send modem command.\n");
modem_flush(1);
returnerror();
}
}
}
if ((result) && (*result))
{
if (!modem_read(line, setup.modem.timeout_cmd))
{
if ((command) && (*command))
{
log(L_ERROR, "Can't read modem command result.\n");
}
modem_flush(1);
returnerror();
}
strcpy(modem_store_result, line);
if (strcmp(result, "?") == 0) returnok();
if ((back = modem_check_result(line, result)) < 1)
{
log_line(L_ERROR, "Modem returns unneeded command \"");
log_code(L_ERROR, line);
log_text(L_ERROR, "\".\n");
modem_flush(1);
returnerror();
}
else return(back);
}
returnok();
}
/*************************************************************************/
/** modem_get_s_register(): Returns a s-register value. **/
/*************************************************************************/
char *modem_get_s_register(int r)
{
char temp[4];
char command[10];
if ((r >= MODEM_MIN_S_REGISTER) && (r <= MODEM_MAX_S_REGISTER))
{
sprintf(command, "ATS%d?", r);
if (modem_command(command, "?") == 1)
{
log(L_DEBUG, "Got s-register value \"%s\".\n", modem_get_last_result());
modem_raw_read(temp, 4);
return(modem_get_last_result());
}
}
return("ERROR");
}
/*************************************************************************/
/** modem_check_result(): Checks for a string in the modem result. **/
/*************************************************************************/
static int modem_check_result(char *have, char *need)
{
char line[MODEM_BUFFER_LEN + 1];
char *word;
char *more;
int nr;
log_line(L_DEBUG, "Waiting for \"");
log_code(L_DEBUG, need);
log_text(L_DEBUG, "\"... ");
xstrncpy(line, need, MODEM_BUFFER_LEN);
more = strchr(line, '|');
word = strtok(line, "|");
nr = 0;
while (word)
{
nr++;
if (strncmp(have, word, strlen(word)) == 0)
{
if (more)
{
log_text(L_DEBUG, "Got \"");
log_code(L_DEBUG, word);
log_text(L_DEBUG, "\" (%d).\n", nr);
}
else log_text(L_DEBUG, "Got it.\n");
return(nr);
}
word = strtok(NULL, "|");
}
log_text(L_DEBUG, "Oops!\n");
return(0);
}
/*************************************************************************/
/** modem_write(): Sends a null terminated string to the modem. **/
/*************************************************************************/
static int modem_write(char *s)
{
if (modem_raw_write(s, strlen(s)) == strlen(s)) returnok();
returnerror();
}
/*************************************************************************/
/** modem_raw_write(): Sends a string to the modem. **/
/*************************************************************************/
size_t modem_raw_write(char *string, int len)
{
return(write(setup.modem.fd, string, len));
}
/*************************************************************************/
/** modem_get_echo(): Reads modem echo. **/
/*************************************************************************/
static int modem_get_echo(char *echo)
{
return(modem_get_rawsequence(echo, TRUE));
}
/*************************************************************************/
/** modem_get_sequence(): Reads a specified sequence from the modem. **/
/*************************************************************************/
int modem_get_sequence(char *seq)
{
return(modem_get_rawsequence(seq, FALSE));
}
/*************************************************************************/
/** modem_get_rawsequence(): Reads a raw sequence from modem. This is**/
/** a subroutine for modem_get_sequence() & **/
/** modem_get_echo(). **/
/*************************************************************************/
static int modem_get_rawsequence(char *line, int echo)
{
char c;
int i;
int timeout;
timeout = (echo ? setup.modem.timeout_echo : setup.modem.timeout_cmd);
log(L_JUNK, "Reading modem %s (%d secs timeout)...\n", (echo ? "echo" : "sequence"), timeout);
modem_set_timeout(timeout);
for (i = 0; i < strlen(line); i++)
{
if ((modem_raw_read(&c, 1) != 1) || (modem_get_timeout()))
{
modem_set_timeout(0);
returnerror();
}
if (line[i] != c)
{
modem_set_timeout(0);
returnerror();
}
}
if (echo)
{
if ((modem_raw_read(&c, 1) != 1) || (modem_get_timeout()))
{
modem_set_timeout(0);
returnerror();
}
}
modem_set_timeout(0);
if (echo)
{
if (c != MODEM_COMMAND_SUFFIX) returnerror();
}
returnok();
}
/*************************************************************************/
/** modem_wait_sequence(): Reads a sequence from modem and breaks **/
/** on timeout or if the sequence was **/
/** matched. **/
/*************************************************************************/
int modem_wait_sequence(char *line)
{
char c;
int i=0;
int timeout;
timeout = setup.modem.timeout_cmd;
log_line(L_DEBUG, "Waiting (%d secs timeout) for sequence \"", timeout);
log_code(L_DEBUG, line);
log_text(L_DEBUG, "\"... ");
modem_set_timeout(timeout);
while (1)
{
if ((modem_raw_read(&c, 1) != 1) || (modem_get_timeout()))
{
modem_set_timeout(0);
log_text(L_DEBUG, " NOT FOUND\n");
returnerror();
}
if (line[i] == c)
{
i++;
if (i==strlen(line)) {
modem_set_timeout(0);
log_text(L_DEBUG, " GOT IT\n");
returnok();
}
} else {
i=0;
if (line[i] == c)
i++;
}
}
}
/*************************************************************************/
/** modem_read(): Reads a terminated string from the modem. **/
/*************************************************************************/
static int modem_read(char *line, int readtimeout)
{
char c;
int r;
int linelen = 0;
int havetxt = FALSE;
int timeout;
log(L_JUNK, "Reading modem input (%d secs timeout)...\n", readtimeout);
modem_set_timeout(readtimeout);
while (((r = modem_raw_read(&c, 1)) == 1) && (linelen < (MODEM_BUFFER_LEN - 1)))
{
if (c >= 32) havetxt = TRUE;
if (havetxt)
{
if (c == '\n') break;
if ((c != '\r') && (c != '\n'))
{
*line++ = c;
linelen++;
}
}
}
timeout = modem_get_timeout();
modem_set_timeout(0);
*line = 0;
if ((r != 1) || (timeout) || (linelen >= (MODEM_BUFFER_LEN - 1)) )
{
log(L_JUNK, "Can't read from modem [%d]%s.\n", r, (timeout ? " (timeout)" : ""));
returnerror();
}
returnok();
}
/*************************************************************************/
/** modem_raw_read(): Reads a raw string from modem. **/
/*************************************************************************/
int modem_raw_read(char *line, int len)
{
#ifdef USE_NEW_MODEM_READER
int use = 0;
int i;
#ifdef DBG_NEW_MODEM_READER
log(L_JUNK, "[READ] Function request %d byte(s) (now pos %d; len %d).\n", len, modem_input_pos, modem_input_len);
#endif
if (len > MODEM_INPUT_LEN)
{
log(L_FATAL, "Internal modem buffer overflow (size %d; request %d)!\n", MODEM_INPUT_LEN, len);
return(-1);
}
if (modem_input_len >= len)
{
memcpy(line, &modem_input[modem_input_pos], len);
modem_input_len -= len;
modem_input_pos += len;
#ifdef DBG_NEW_MODEM_READER
log(L_JUNK, "[READ] Return all %d bytes (now pos %d; len %d).\n", len, modem_input_pos, modem_input_len);
#endif
return(len);
}
if (modem_input_len > 0)
{
memcpy(line, &modem_input[modem_input_pos], modem_input_len);
#ifdef DBG_NEW_MODEM_READER
log(L_JUNK, "[READ] Store %d of %d bytes (now pos 0; len 0).\n", modem_input_len, len);
#endif
}
#ifdef DBG_NEW_MODEM_READER
else log(L_JUNK, "[READ] Store nothing (pos 0; len 0).\n");
#endif
len -= modem_input_len;
use += modem_input_len;
modem_input_pos = 0;
modem_input_len = 0;
if ((modem_input_len = read(setup.modem.fd, modem_input, MODEM_INPUT_LEN)) < 0)
{
modem_input_pos = 0;
modem_input_len = 0;
#ifdef DBG_NEW_MODEM_READER
log(L_JUNK, "[READ] Return only %d bytes (now pos %d; len %d).\n", use, modem_input_pos, modem_input_len);
#endif
return(use);
}
#ifdef DBG_NEW_MODEM_READER
log(L_JUNK, "[READ] Read %d bytes (now pos %d; len %d).\n", modem_input_len, modem_input_pos, modem_input_len);
#endif
for (i = 0; i < modem_input_len; i++)
{
#ifdef DBG_NEW_MODEM_READER
log_line(L_JUNK, "[READ] ");
log_char(L_JUNK, modem_input[i]);
log_text(L_JUNK, "\n");
#endif
modem_check_nocarrier(modem_input[i]);
}
if (modem_input_len < len) len = modem_input_len;
memcpy(&line[use], &modem_input[modem_input_pos], len);
modem_input_len -= len;
modem_input_pos += len;
#ifdef DBG_NEW_MODEM_READER
log(L_JUNK, "[READ] Return %d bytes (now pos %d; len %d.\n", use + len, modem_input_pos, modem_input_len);
#endif
return(use + len);
#else
int r;
int i;
if ((r = read(setup.modem.fd, line, len)) > 0)
{
for (i = 0; i < r; i++)
{
#ifdef DBG_OLD_MODEM_READER
log_line(L_JUNK, "[OLDREAD] ");
log_char(L_JUNK, line[i]);
log_text(L_JUNK, "\n");
#endif
modem_check_nocarrier(line[i]);
}
}
return(r);
#endif
}
/*************************************************************************/
/** modem_timeout_function(): **/
/*************************************************************************/
static void modem_timeout_function(int s)
{
alarm(0);
signal(SIGALRM, SIG_IGN);
log(L_JUNK, "Modem timeout function called...\n");
timeoutstatus = TRUE;
}
/*************************************************************************/
/** modem_set_timeout(): Sets the timeout for the modem functions. **/
/*************************************************************************/
void modem_set_timeout(int timeout)
{
if (timeout != 0)
{
timeoutstatus = FALSE;
signal(SIGALRM, modem_timeout_function);
siginterrupt(SIGALRM, 1);
alarm(timeout);
}
else
{
signal(SIGALRM, SIG_IGN);
alarm(0);
}
}
/*************************************************************************/
/** modem_get_timeout(): Returns the timeout status. **/
/*************************************************************************/
int modem_get_timeout(void)
{
return(timeoutstatus);
}
/*************************************************************************/
/** modem_check_nocarrier(): Watchs the modem input for NO CARRIER. **/
/*************************************************************************/
static void modem_check_nocarrier(char c)
{
if (c == nocarriertxt[nocarrierpos])
{
nocarrierpos++;
if (nocarrierpos >= strlen(nocarriertxt))
{
log(L_JUNK, "*** NO CARRIER ***\n");
nocarrier = TRUE;
nocarrierpos = 0;
}
}
else
{
nocarrierpos = 0;
if (c == nocarriertxt[0]) nocarrierpos++;
}
}
/*************************************************************************/
/** modem_flush(): Flushs modem input/output. **/
/*************************************************************************/
void modem_flush(int timeout)
{
TIO porttio;
TIO savetio;
long gotjunk = 0;
char onebyte = 0;
log(L_DEBUG, "Flushing modem%s...\n", (timeout ? " (timeout)" : ""));
if (modem_get_termio(&porttio))
{
savetio = porttio;
porttio.c_lflag &= ~ICANON;
porttio.c_cc[VMIN] = 0;
porttio.c_cc[VTIME] = timeout;
if (modem_set_termio(&porttio))
{
while (modem_raw_read(&onebyte, 1) == 1)
{
if (gotjunk++ < 20)
{
log_line(L_JUNK, "Junk: ");
log_char(L_JUNK, onebyte);
log_text(L_JUNK, "\n");
}
}
if (gotjunk > 20)
{
log(L_DEBUG, "Flush has junked %d bytes...\n", gotjunk);
}
modem_set_termio(&savetio);
}
}
tcflush(setup.modem.fd, TCIOFLUSH);
tcflush(setup.modem.fd, TCIOFLUSH);
}
/*************************************************************************/
/** modem_wait(): Waits for modem activity. **/
/*************************************************************************/
int modem_wait(void)
{
struct timeval timeout;
struct timeval *usetimeout;
fd_set fd;
int back;
log(L_INFO, "Waiting...\n");
FD_ZERO(&fd);
FD_SET(setup.modem.fd, &fd);
if (setup.modem.timeout_alive > 0)
{
timeout.tv_sec = setup.modem.timeout_alive;
timeout.tv_usec = setup.modem.timeout_alive * 1000;
usetimeout = &timeout;
}
else usetimeout = NULL;
back = select(FD_SETSIZE, &fd, NULL, NULL, usetimeout);
if (back <= 0)
{
if (back < 0)
{
log(L_ERROR, "Select returns with error (%d)...\n", back);
}
else log(L_JUNK, "Select returns with timeout...\n");
returnerror();
}
log(L_INFO, "Wakeup!\n");
returnok();
}
/*************************************************************************/
/** modem_count_rings(): Counts incoming rings. **/
/*************************************************************************/
int modem_count_rings(int needrings)
{
char line[MODEM_BUFFER_LEN + 1];
char *sreg;
int haverings;
int havesregs;
int havesetup;
int n;
voice_init_section();
haverings = 0;
havesregs = FALSE;
havesetup = FALSE;
while (modem_read(line, setup.modem.timeout_ring))
{
if (ctrl_ishere(setup.spool, CTRL_NAME_STOP))
{
log(L_INFO, "Control file \"%s\" exists - killing me now...\n", CTRL_NAME_STOP);
kill(getpid(), SIGTERM);
}
if (havesetup)
{
if (ctrl_ishere(setup.spool, CTRL_NAME_REJECT))
{
log(L_INFO, "Control file \"%s\" exists - rejecting call...\n", CTRL_NAME_REJECT);
if (!ctrl_remove(setup.spool, CTRL_NAME_REJECT))
{
log(L_WARN, "Can't remove control file \"%s\"!\n", CTRL_NAME_REJECT);
}
returnerror();
}
if (ctrl_ishere(setup.spool, CTRL_NAME_ANSWERNOW))
{
log(L_INFO, "Control file \"%s\" exists - answering now...\n", CTRL_NAME_ANSWERNOW);
if (!ctrl_remove(setup.spool, CTRL_NAME_ANSWERNOW))
{
log(L_WARN, "Can't remove control file \"%s\"!\n", CTRL_NAME_ANSWERNOW);
}
returnok();
}
if (ctrl_ishere(setup.spool, CTRL_NAME_ANSWERALL))
{
log(L_INFO, "Control file \"%s\" exists - answering now...\n", CTRL_NAME_ANSWERALL);
returnok();
}
if (!setup.voice.doanswer)
{
log(L_INFO, "Call will not be answered - disabled in \"vboxrc\"...\n");
returnerror();
}
if (needrings <= 0)
{
log(L_INFO, "Call will not be answered - no rings are set...\n");
returnerror();
}
}
if ((strncmp(line, "CALLER NUMBER: ", 15) == 0) && (!havesetup))
{
if ((sreg = modem_get_s_register(20)))
{
if (strcmp(sreg, "1") != 0)
{
log(L_INFO, "Incoming call is not voice - hanging up...\n");
returnerror();
}
}
else log(L_WARN, "Can't get incoming call type - I think it's voice...\n");
voice_init_section();
xstrncpy(setup.voice.callerid, &line[15], VOICE_MAX_CALLERID);
voice_user_section(setup.voice.callerid);
log(L_INFO, "[%2d/%2d] CALLER NUMBER: %s (%s)...\n", haverings, needrings, setup.voice.callerid, setup.voice.name);
if ((setup.voice.rings >= 0) && (setup.voice.rings != needrings))
{
log(L_DEBUG, "New number of rings from \"vboxrc\" are %d...\n", setup.voice.rings);
needrings = setup.voice.rings;
}
if ((setup.voice.ringsonnew >= 0) && (setup.voice.ringsonnew != needrings))
{
log(L_DEBUG, "Checking for new messages in \"%s\"...\n", setup.voice.checknewpath);
if ((n = get_nr_messages(setup.voice.checknewpath, TRUE)) > 0)
{
log(L_DEBUG, "Found %d new messages; new number of rings are %d...\n", n, setup.voice.ringsonnew);
needrings = setup.voice.ringsonnew;
}
}
havesetup = TRUE;
continue;
}
if ((haverings >= needrings) && (havesetup)) returnok();
if (strcmp(line, "RING") == 0)
{
haverings++;
log(L_INFO, "[%2d/%2d] RING...\n", haverings, needrings);
}
else
{
log_line(L_JUNK, "Got junk line \"");
log_code(L_JUNK, line);
log_text(L_JUNK, "\"...\n");
}
if ((haverings >= needrings) && (havesetup)) returnok();
}
returnerror();
}
/*************************************************************************/
/** modem_set_nocarrier_state(): Sets NO CARRIER state. **/
/*************************************************************************/
void modem_set_nocarrier_state(int state)
{
nocarrier = state;
}
/*************************************************************************/
/** modem_get_nocarrier_state(): Returns NO CARRIER state. **/
/*************************************************************************/
int modem_get_nocarrier_state(void)
{
return(nocarrier);
}
/*************************************************************************/
/** modem_check_input(): Checks for modem input. **/
/*************************************************************************/
int modem_check_input(void)
{
struct timeval timeout;
fd_set fd;
int result;
#ifdef USE_NEW_MODEM_READER
if (modem_input_len > 0) returnok();
#endif
FD_ZERO(&fd);
FD_SET(setup.modem.fd, &fd);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
result = select(FD_SETSIZE , &fd, NULL, NULL, &timeout);
if (result > 0) returnok();
returnerror();
}