home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume26
/
modempool
/
part01
/
modem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-05
|
6KB
|
285 lines
/*******************************************************************
*
* Module: @(#)modem.c 4.2 92/04/16
*
* Description:
* Handle various modem functions.
*
* Revision:
* Date By Reason
* ---- -- ------
* 920306 Lars Berntzon Created
*
*******************************************************************/
static char SccsId[] = "@(#)modem.c 4.2 92/04/16";
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include "modempool.h"
#define N_MOD_CMDS (sizeof mod_cmds / sizeof mod_cmds[0])
static char *mod_cmds[] = {
"*", "CONNECT\r", "CONNECT 300\r", "CONNECT 1200\r", "CONNECT 2400\r",
"RING\r", "BUSY\r", "ERROR\r", "NO CARRIER\r", "OK\r",
"CONNECT 4800\r", "CONNECT 9600\r"
};
static char *cmd_str(int n);
/*
* Routines.
*/
/*******************************************************************
*
* M O D _ S E T U P
* -----------------
*
* Description:
* Sets the modem to a correct state.
*
*******************************************************************/
int
mod_setup(void)
{
int retry;
int rc = 0;
for(retry = 0; retry < 2; retry++) {
if ((rc = mod_put(initstr)) == E_OK &&
(rc = mod_put("\r")) == E_OK &&
(rc = mod_exp(MOD_OK, 0)) == E_OK) return E_OK;
}
logerr("setup_modem: failed ( %d)", rc);
return rc;
}
/*******************************************************************
* M O D _ P U T
* -------------
*
* Description:
* Initialize the modem (hayes commands).
*
*******************************************************************/
mod_put(char *msg)
{
int rc;
debug("mod_put(\"%s\")", msg);
trig(2);
rc = tty_write(msg, strlen(msg));
if (istimeout()) {
return E_TMOUT;
}
if (rc < 0) {
logerr("mod_put: failed to write");
return E_WRITE;
}
return E_OK;
}
/*******************************************************************
* M O D _ E X P
* -------------
*
* Description:
* Expect answer from modem.
*
* Arguments:
* expected - Answer type (integern enumeration)
* tmout - Timeout (0 means default)
*
*******************************************************************/
mod_exp(int expected, int tmout)
{
va_list arg = NULL;
int exp_len = 0;
char buf[MATCH_SIZE];
int buf_len;
int pos = 0;
int i = 0;
/* Used default timeout if none specified */
if (tmout == 0) tmout = MODEM_TMOUT;
debug("expecting(\"%s\")", cmd_str(expected));
/* Read until text matches but not more than can fit into bufer */
while(pos < MATCH_SIZE)
{
buf[pos] = 0;
/* Read with timeout */
trig(tmout);
buf_len = tty_read(buf + pos++, 1);
if(istimeout()) {
return E_TMOUT;
}
/*
* Some one called us ?.
*/
if (buf_len <= 0 && signalled) {
return E_TMOUT;
}
if (buf_len < 0) return E_READ;
if (!isprint(buf[pos - 1])) {
debugnonl("(0x%X)", buf[pos - 1]);
}
else {
debugnonl("%c", buf[pos - 1]);
}
/* Check if any was right */
for(i = 0; i < N_MOD_CMDS; i++)
{
exp_len = strlen(mod_cmds[i]);
if (pos < exp_len) continue;
if (memcmp(mod_cmds[i], buf + pos - exp_len, exp_len) == 0) break;
}
if (i < N_MOD_CMDS)
{
buf[pos + 1] = 0;
debug("gotten(\"%s\")", cmd_str(i));
if (expected == MOD_ANY || expected == i)
{
/* Return what arrived if awaited for any */
if (expected == MOD_ANY) return i;
/*
* Otherwise just return that what had been awaited for
* has arrived OK.
*/
return E_OK;
}
}
}
logerr("mod_exp: never got any sane answer from modem (%s)", buf);
return E_FAIL;
}
/************************************************************************
*
* MOD_DIAL
* --------
* Description:
* Dials a number
*
* Arguments:
* prefix - Prefix telephone number, like '0w' to get external line.
* phone - The phone number.
*
************************************************************************/
mod_dial(char *prefix, char *phone)
{
int rc;
int i;
/* Retry 3 times*/
for(i = 0; i < 5; i++)
{
/* Dialup */
mod_put("ATDT");
mod_put(prefix);
mod_put(phone);
mod_put("\r");
/* Wait for answer */
switch(mod_exp(MOD_ANY, 15))
{
case MOD_CONNECT:
case MOD_CONNECT_1200:
case MOD_CONNECT_2400:
log("dialup: succeded to dial '%s'", phone);
return E_OK;
case MOD_BUSY:
log("dialup: busy");
break;
case MOD_NO_CARRIER:
logerr("dialup: no carrier for phone '%s'", phone);
}
}
}
/*******************************************************************
*
* PROMPT
* ------
*
* Description:
* Writes prompt to port and reads line.
*
* Arguments:
* msg - Prompt message.
* dest - Where to store answer.
* size - Dont read more than this.
* tmout - Timeout, 0 means no timeout.
*
*******************************************************************/
int prompt(char *msg, char *dest, int size, int tmout)
{
int i;
if (mod_put(msg) < 0)
{
logerr("prompt: failed to write to port");
return E_FAIL;
}
trig(tmout);
size = tty_read(dest, size);
if (istimeout()) {
return E_TMOUT;
}
if (size < 0) {
logerr("prompt: failed to read");
return E_READ;
}
/* User pressed EOF */
if (size == 0)
{
mod_put(MSG_ABORTED);
return E_FAIL;
}
/* Remove leading blanks */
for(i = 0; i < size && isspace(dest[i]); i++)
;
memcpy(dest, dest + i, size -= i);
/* Remove trailing blanks */
for(i = size - 1; i >= 0 && isspace(dest[i]); i--,size --)
;
dest[i + 1] = 0;
return E_OK;
}
/***************************************
* Return ascii value for modem answers.
***************************************/
static char *cmd_str(int n)
{
if (n < 0 || n > N_MOD_CMDS) {
return "[unknown]";
}
return mod_cmds[n];
}