📄 dialer.c
字号:
/*
* FILENAME: dialer.c
*
* Copyright 1997- 2001 By InterNiche Technologies Inc. All rights reserved
* Copyright 1995, 1996 by NetPort Software.
*
* MODULE: MODEM
*
* Hayes command set dialer. This code supports Hayes modems as an InterNiche
* com_line device. This file assumes contact with the modem via
* four primitives:
*
* uart_init() - get it ready, set speed etc,
* uart_getc() - getchar from uart
* uart_putc() - put char to uart
* uart_stats() - output uart stats
*
* ROUTINES: modem_init(), modem_state(), modem_getc(),
* ROUTINES: modem_gets(), modem_cmd(), dial(), modem_linedown(),
* ROUTINES: ModemByLine(), modem_hangup(), dial_check(), dial_check_modem(),
* ROUTINES: modem_putc(), dialer_status(), modem_connect(), modem_reset(),
* modem_no_carrier(),
*
* PORTABLE: yes
*/
#include "mdmport.h"
/* (yaxon add) */
#include "includes.h"
#include "phonedrv.h"
/* (yaxon add) */
#ifdef USE_MODEM /* whole file can be ifdeffed out */
void modem_gets(MODEMP, int wait);
void dial_delay(unsigned long ticks);
int modem_cmd(MODEMP, char * data);
struct atmodem modems[NUM_MODEMS];
char mdm_init_string[MODEM_STRING_SIZE];
char mdm_dial_string[TELNUM_SIZE];
unsigned answer_rings = 1; /* number of rings before autoanswer */
/* FUNCTION: modem_init()
*
* Initiazation for each line device which is mapped
* to a modem. This may be called multiple times, even for a single
* modem. We should detect the re-init calls and maintain the unit to
* modems[] links. For initial init calls we should assign the next
* available entry in modems[].
*
* PARAM1: LINEP line
*
* RETURNS: 0 if OK, non-zero if modem failure.
*/
int
modem_init(LINEP line)
{
int e;
int unit;
struct atmodem * modemp;
/* We need to select a modem structre to map to the upper layer line. We
* want this process to be flexible, but not require complex setup by
* applications which just want a simple default. To acheive this we check
* the passed line to see if it has already been cross mapped to a modem
* by the caller. If not, then we select the next unused modem slot and
* map it to the passed line.
*/
unit = line->lower_unit;
if(modems[unit].upperline != line) /* not matched */
{
/* find the next available modems[] entry */
for(unit = 0; unit < NUM_MODEMS; unit++)
{
if(modems[unit].upperline == NULL)
break;
}
if(unit == NUM_MODEMS)
return ENP_RESOURCE;
MEMSET(&modems[unit], 0, sizeof (struct atmodem)); /* clear modem struct */
/* cross map free modems[] entry to passed line */
modems[unit].upperline = line;
line->lower_unit = unit;
}
//ConPrintf("Initializing modem unit %d", unit);
modemp = &modems[unit]; /* set pointer to modem struct to use */
modemp->upperline->ln_state = D_BROKEN;
modemp->upperline->ln_speed = 0;
modemp->unit = unit;
/* set the idle timeout from nvparms "Idle Line Timeout" */
#ifdef INCLUDE_NVPARMS
modemp->IdleDialTmo = ppp_nvparms.line_tmo;
#else
/* (yaxon modify) */
/* modemp->IdleDialTmo = 120; default timeout (in seconds) */
modemp->IdleDialTmo = 0; /* default timeout (in seconds) */
#endif /* INCLUDE_NVPARMS */
if((e = uart_init(modemp->unit)) != 0) /* init the UART driver */
return e;
/* (yaxon add) */
strcpy(mdm_dial_string, "*99#");
modemp->upperline->ln_state = D_IDLE;
// ConPrintf("modem ready.\n");
return 0;
/* (yaxon add) */
/* (yaxon del) */
#if 0 /* #if 0 */
modem_reset(modemp); /* reset the modem hardware */
/* Send modem init string from parameters file to modem */
if(modem_cmd(modemp, mdm_init_string) == 0)
{
modemp->upperline->ln_state = D_IDLE;
ConPrintf("modem ready.\n");
return 0;
}
else
{
ConPrintf("Error initializing modem\n");
return -1;
}
#endif /* #if 0 */
}
/* FUNCTION: modem_state()
*
* Return a string indicatinf the current state of the modem.
*
* PARAM1: MODEMP modemp
*
* RETURNS: string.
*/
char *
modem_state(MODEMP modemp) /* report which of the modem states, in text */
{
/* If not set, use first modem as default */
if(modemp == NULL)
modemp = &modems[0];
switch(modemp->upperline->ln_state)
{
case D_IDLE:
return("IDLE");
case D_AUTOANS:
return("AUTOANS");
case D_DIALING:
return("DIALING");
case D_CONNECTED:
return("CONNECTED");
case D_HANGINGUP:
return("HANGINGUP");
case D_BROKEN:
return("BROKEN");
case D_RESETTING:
return("RESETTING");
default:
dtrap("dialer 0\n");
return ("Bogus state");
}
}
/* (yaxon del) */
#if 0 /* #if 0 */
/* FUNCTION: modem_getc()
*
* modem_getc(int tmo) - get a char from modem. This is expected to be
* a reply to or an echo of a command. This is not designed for general
* data stream gathering.
*
* Returns the next char from the modem if one appears within the
* specified number of seconds.
*
* PARAM1: MODEMP modemp
* PARAM2: unsigned tmo
*
* RETURNS: -1 if modem times out without a char.
*/
int
modem_getc(MODEMP modemp, unsigned tmo)
{
unsigned long stop;
int uchr;
stop = cticks + ((unsigned long)tmo * TPS);
while(cticks < stop)
{
uchr = uart_getc(modemp->unit);
if(uchr != -1)
return uchr;
/* on SUPERLOOP systems, calling tk_yield() at this point can
* get us into recursion trouble; otherwise we should let
* system spin...
*/
#ifndef SUPERLOOP
tk_yield(); /* let rest of system run */
#endif
}
return -1; /* timeout return */
}
/* FUNCTION: modem_gets()
*
* modem_gets() - get a line of input from the modem.
* Returns immediatly if modem is connected.
* Returns if no input comes in 'wait' ticks. Wait can be 0
* for immediate return if input is not waiting.
*
* Leaves input in modem_in[] buffer & modem_index set.
* This is designed to get responses to "AT" commands.
*
* PARAM1: MODEMP modemp
* PARAM2: int wait
*
* RETURNS: void
*/
void
modem_gets(MODEMP modemp, int wait) /* ticks to wait for input */
{
int c; /* last char read from modem */
int i;
if(modemp->upperline->ln_state != D_CONNECTED)
{
/* wait for first char from uart */
c = uart_getc(modemp->unit);
while((c == -1) && (wait))
{
dial_delay(1); /* wait 1 tick for uart char */
c = uart_getc(modemp->unit); /* try uart again */
wait--; /* countdown the tick */
}
if(c != -1) /* got first char, try to extract whole string */
{
modemp->modem_in[0] = (u_char)c;
/* receive upto MODEM_BUF_SIZE-1 chars, so that we can form
* a null-terminated string */
for(i = 1; i < MODEM_BUF_SIZE-1; i++)
{
/* (yaxon del) */
#if 0
/* return to caller on newlines */
if ((c == 0x0d) || (c == 0x0a))
break;
#endif
c = modem_getc(modemp, 1); /* give uart 1 sec to get next char */
if(c == -1) /* quit if uart buffer is empty */
break;
modemp->modem_in[i] = (u_char)c; /* save uart char in modem buffer */
}
modemp->modem_in[i] = 0; /* null terminate modem string */
ConPrintf("modem_gets: %s\n", modemp->modem_in);
}
/* now leave modem_in[] for caller */
}
}
/* FUNCTION: modem_cmd()
*
* send an AT command to the modem.
*
* PARAM1: MODEMP modemp
* PARAM2: char * data
*
* RETURNS: 0 if no error detected (ie modem took the command)
* or -1 if there was some kind of error
*/
int
modem_cmd(MODEMP modemp, char * data)
{
char * cp; /* scratch data pointer */
u_long tmo;
int modem_unit;
int retval = -1; /* return value */
ConPrintf("modem_cmd: %s\n", data);
modem_gets(modemp, 0); /* clear out any pending message from modem */
modemp->modem_in[0] = 0; /* clear modem reply text before we issue cmd */
modem_unit = modemp->unit;
/* write command string to modem via UART */
cp = data;
while(*cp)
uart_putc(modem_unit, *cp++);
if(*(cp-1) != '\r') /* make sure command ends with <CR> */
uart_putc(modem_unit, '\r');
/* wait for echo of command from modem */
tmo = cticks + (3*TPS); /* set echo timeout */
while(tmo > cticks)
{
modem_gets(modemp, TPS); /* get echo of command */
if(modemp->modem_in[0] == 0)
{
dial_delay(1); /* wait 1 tick for uart char */
continue;
}
if((strstr((char*)(modemp->modem_in), data) != NULL) ||
((modemp->modem_in[0] == 'O') && (modemp->modem_in[1] == 'K')))
{
retval = 0; /* got echo of command or 'OK' string */
break;
}
else /* got some text, but not an echo */
{
ConPrintf("modem_cmd: extra input: %s\n", modemp->modem_in);
modemp->modem_in[0] = 0; /* clear input buffer */
}
}
if(modemp->modem_in[0] == 0)
ConPrintf("modem_cmd timeout.\n");
modemp->modem_in[0] = 0; /* clear input buffer */
return retval;
}
#endif /* #if 0 */
/* FUNCTION: dial()
*
* do the actual ATDT dialing
*
* PARAM1: MODEMP modemp
* PARAM2: char * phone_num
*
* RETURNS:
*/
void
dial(MODEMP modemp, char * phone_num) /* initate phone dialing */
{
if(modemp->upperline->ln_state != D_IDLE && modemp->upperline->ln_state != D_AUTOANS)
{
// ConPrintf("Modem is unavailable. state: %s\n", modem_state(modemp));
return;
}
#ifdef NPDEBUG /* sanity check state */
if((modemp->upperline->ln_state != D_IDLE) &&
(modemp->upperline->ln_state != D_AUTOANS))
{
dtrap("dialer 1\n");
}
#endif /* NPDEBUG */
//ConPrintf("dialing %s...\n", phone_num);
/* yaxon add */
if (modem_RingupPhone(PHONE_GPRS, (INT8U *)phone_num, strlen(phone_num))) {
modemp->upperline->ln_state = D_DIALING; /* push state machine to dialing */
} else {
dtrap("dialer 12\n");
}
/* yaxon add */
/* (yaxon del) */
#if 0
sprintf((char*)(modemp->modem_out), "ATDT%s\r", phone_num );
if(modem_cmd(modemp, (char*)(modemp->modem_out)) == 0)
{
modemp->upperline->ln_state = D_DIALING; /* push state machine to dialing */
modemp->lastdial = cticks;
}
else
{
//ConPrintf("Error dialing modem\n");
}
#endif
}
/* (yaxon add) */
extern void PPP_Broken(void);
extern struct net netstatic[STATIC_NETS];
/* (yaxon add) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -