📄 dialer.c
字号:
/* FUNCTION: modem_linedown()
*
* Called when modem looses line or is unable to connect. This handles telling
* the upper (PPP) layers about the disconnect. It is currently called if:
*
* - we timeout while dialing
* - other guy disconnects
* - administrative (user cmd) hangup.
*
* PARAM1: MODEMP modemp
*
* RETURNS:
*/
void
modem_linedown(MODEMP modemp)
{
/* (yaxon add) */
int i;
for (i = 0; i < STATIC_NETS; i++)
{
netstatic[i].n_ipaddr = 0;
netstatic[i].snmask = 0;
netstatic[i].n_defgw = 0;
#ifdef IP_MULTICAST
/* Create a dummy entry for the Ethernet interface mcastlist */
/* If this entry is set to NULL, multicast is not supported */
/* on this interface */
netstatic[i].n_mcastlist = 0;
#endif /* IP_MULTICAST */
}
PPP_Broken();
/* (yaxon add) */
#ifdef USE_PPP
if(modemp->upperline &&
(modemp->upperline->upper_type == LN_PPP))
{
M_PPP mppp = (M_PPP)(modemp->upperline->upper_unit);
/* start PPP shutdown */
ppp_close(mppp, LCP_STATE);
/* tell PPP link is down */
ppp_lowerdown(mppp, LCP_STATE);
}
#endif
}
/* FUNCTION: ModemByLine()
*
* Get the modem structure which matches the pased line/
*
* PARAM1: LINEP line
*
* RETURNS: MODEMP pointer
*/
MODEMP
ModemByLine(LINEP line)
{
int i;
for(i = 0; i < NUM_MODEMS; i++)
{
if(modems[i].upperline == line)
return (&modems[i]);
}
return NULL; /* no found */
}
/* (yaxon add) */
int ModemIsIdle(int unit)
{
if (modems[unit].upperline->ln_state == D_IDLE)
return -1;
else
return 0;
}
/* (yaxon add) */
/* FUNCTION: ModemHangup(int unit)
*
* API to force a modem hangup.
* Called from user application. User App doesn't have access to modems[]
* and hence it passes a unit number.
* - Kill all existing sockets
* - Call modem_hangup() to being down PPP and hangup.
*
* PARAM1: int unit
*
* RETURNS:
*/
#ifdef MODEM_API /* requires extra ifdef to get this */
#ifdef MINI_IP
#error MODEM_API not compatible with MINI_IP option.
#endif /* MINI_IP */
void if_killsocks(NET ifp);
int
ModemHangup(int unit)
{
NET ifp;
/* kill all outstanding sockets on modems iface */
for (ifp = (NET)(netlist.q_head); ifp; ifp = ifp->n_next)
{
if(modems[unit].upperline == ifp->n_local)
{
if_killsocks(ifp);
break;
}
}
return modem_hangup(modems[unit].upperline);
}
#endif /* MODEM_API */
/* FUNCTION: modem_hangup()
*
* Force a modem hangup.
*
* PARAM1: LINEP line
*
* RETURNS:
*/
int
modem_hangup(LINEP line)
{
MODEMP modemp;
if((line == NULL) || (line->ln_state == LN_INITIAL))
{
dprintf("Modem not initialized\n");
return D_BROKEN;
}
modemp = ModemByLine(line);
if(modemp == NULL)
{
dtrap("dialer 2\n");
return D_BROKEN;
}
modem_linedown(modemp); /* tell upper line modem is down */
/* (yaxon add) */
modemp->upperline->ln_state = D_HANGINGUP;
modem_HangupPhone(PHONE_GPRS);
// ConPrintf("now, hang up\n\n");
return 0; /* no error detection in this port */
/* (yaxon add) */
/* (yaxon del) */
#if 0
/* dial_delay() in modem_reset() can result in a call to
* inet_timer()->uart_check()->dial_check_modem().
* Currently ln_state is D_CONNECTED. In such a state, the incoming
* char would be passed to PPP. PPP was just brought down by
* modem_linedown() and this would again try to bring PPP up.
* Hence set the state to D_RESETTING, so that dial_check_modem()
* ignores incoming chars.
*/
modemp->upperline->ln_state = D_RESETTING;
modem_reset(modemp);
modemp->upperline->ln_state = D_HANGINGUP;
return 0; /* no error detection in this port */
#endif
}
/* FUNCTION: dial_check()
*
* dial_check() - this routine drives the state of the dialer, It
* should be called periodicly by the OS so the dialer can advance
* from state to state without blocking. Usually calling this 10-20
* times per second provides fair performance on a 56K modem
* connection.
*
* PARAM1: none
*
* RETURNS: void
*/
int in_dialcheck = 0; /* prevent re-entry to dial_check() */
void dial_check_modem(MODEMP);
void
dial_check()
{
int i;
for(i = 0; i < NUM_MODEMS; i++)
{
if(modems[i].upperline)
dial_check_modem(&modems[i]);
}
}
/* FUNCTION: dial_check_modem()
*
* Per-unit subroutine for dial_check().
*
* PARAM1: MODEMP modemp
*
* RETURNS: void
*/
/* PPP character input callback, for line sanity test */
extern int ppp_direct_in(struct com_line * line, int chr);
void
dial_check_modem(MODEMP modemp)
{
int c; /* char read from uart */
/* (yaxon del) */
#if 0
int last_state; /* last upperline->ln_state */
unsigned long tmo; /* timeout timetick, for state timeouts */
char * cp;
#endif
#ifdef USE_PPP
M_PPP mppp;
#endif /* USE_PPP */
/* This bool value indicates whether we have received a "NO CARRIER"
* string from the modem or not. If we receive "NO CARRIER" string,
* then no_carrier=TRUE
*/
int no_carrier = FALSE ;
/* recursion check: */
if(in_dialcheck)
return;
in_dialcheck++;
#ifdef USE_PPP
mppp = (M_PPP)(modemp->upperline->upper_unit);
/* make sure line callback is set correctly for PPP links */
if((modemp->upperline->upper_type == LN_PPP) &&
(modemp->upperline->ln_getc != ppp_direct_in))
{
dtrap("dialer 3\n"); /* configuration problem? */
return;
}
#endif /* USE_PPP */
/* (yaxon add) */
switch(modemp->upperline->ln_state)
{
int curstatus;
case D_DIALING:
curstatus = modem_GetPhoneStatus(PHONE_GPRS);
if (curstatus == PHONE_TALKING) {
modemp->upperline->ln_state = D_CONNECTED;
ppp_lowerup(mppp, LCP_STATE);
// ConPrintf("Connect success!\n");
} else if (curstatus == PHONE_FREE) {
modem_linedown(modemp); /* tell upper line modem is down */
modemp->upperline->ln_state = D_IDLE;
//ConPrintf("fail to connecting!\n");
}
break;
case D_AUTOANS:
break;
case D_CONNECTED:
while((c = uart_getc(modemp->unit)) != -1)
{
modemp->upperline->ln_getc(modemp->upperline, c);
}
/* see if other guy hung up */
if(modem_GetPhoneStatus(PHONE_GPRS) != PHONE_TALKING)
{
//ConPrintf("lost carrier, cleaning up...\n");
modemp->upperline->ln_state = D_IDLE;
modem_linedown(modemp); /* tell upper line modem is down */
}
break;
case D_HANGINGUP:
if (modem_GetPhoneStatus(PHONE_GPRS) == PHONE_FREE) {
modemp->upperline->ln_state = D_IDLE;
modem_linedown(modemp); /* tell upper line modem is down */
//ConPrintf("hung up success\n");
}
break;
case D_IDLE:
break;
case D_BROKEN:
break;
case D_RESETTING:
break;
default:
// ConPrintf("ERROR: Bad dialer state\n");
dtrap("dialer 4\n");
modemp->upperline->ln_state = D_BROKEN;
break;
}
in_dialcheck--;
/* (yaxon add) */
#if 0 /* #if 0 */
/* get any modem AT responses here */
if(modemp->upperline->ln_state != D_CONNECTED)
{
modem_gets(modemp, 0); /* set any text from modem in modem_in[] */
}
switch(modemp->upperline->ln_state)
{
case D_DIALING: /* we just dialed, see if modem answered yet */
case D_AUTOANS:
if(strstr((char*)(modemp->modem_in), "CONNECT") != NULL) /* connected */
{
last_state = modemp->upperline->ln_state;
modemp->upperline->ln_state = D_CONNECTED;
/* figure out baud rate if we can */
cp = (char*)&(modemp->modem_in[7]); /* start looking for baud number */
if(cp)
{
while(*cp < '0' || *cp > '9') /* find baud rate digits */
cp++;
modemp->upperline->ln_speed = atol(cp); /* record new line speed */
}
modemp->modem_in[0] = 0; /* clean input buffer */
modemp->lastchar = cticks; /* reset traffic timeout value */
modemp->lastdial = cticks; /* reset last activity time */
if(last_state == D_AUTOANS)
{
ConPrintf("Connected to caller\n");
#ifdef USE_LOGINSCRIPT
logserver(); /* blocking call to run login script */
if(!loggedin) /* log server is unhappy, don't start PPP */
{
modem_hangup(modemp->unit); /* kill off the connection */
break;
}
#endif /* USE_LOGINSCRIPT */
#ifdef USE_PPP
if(modemp->upperline->upper_type == LN_PPP)
{
/* Indicate to PPP that server lower link has come up */
ppp_lowerup(mppp, LCP_STATE);
ppp_open(mppp, LCP_STATE);
}
#endif /* USE_PPP */
}
else /* we initiated the dialing, try to login */
{
ConPrintf("Connected to %s\n", mdm_dial_string);
#ifdef USE_LOGINSCRIPT
login(); /* see if we need to login */
if(!loggedin)
{
/* login failed, and a login is required... */
modem_hangup(modemp->unit); /* kill off the connection */
break;
}
#endif /* USE_LOGINSCRIPT */
#ifdef USE_PPP
/* Indicate to PPP that client lower link is now up */
ppp_lowerup(mppp, LCP_STATE);
#endif /* USE_PPP */
}
break;
}
if(modemp->upperline->ln_state == D_AUTOANS)
break; /* the rest of this only applies to D_DIALING errors */
cp = (char*)(modemp->modem_in);
if((strstr(cp, "BUSY") != NULL) || /* other side is busy */
(strstr(cp, "NO CARRIER") != NULL) || /* or not a modem */
(strstr(cp, "NO DIAL") != NULL)) /* or no dial tone */
{
#ifdef USE_PPP
/* Indicate to PPP that lower link failed */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -