Commit 34f57d0b authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Reorganize isdn_net_stat_callback

Order actions to be taken by current dialstate primarily and received
status messages secondarily.
parent 2d392056
...@@ -411,6 +411,47 @@ static void isdn_net_lp_disconnected(isdn_net_local *lp) ...@@ -411,6 +411,47 @@ static void isdn_net_lp_disconnected(isdn_net_local *lp)
isdn_net_rm_from_bundle(lp); isdn_net_rm_from_bundle(lp);
} }
static void isdn_net_connected(isdn_net_local *lp)
{
#ifdef CONFIG_ISDN_X25
struct concap_proto *cprot = lp -> netdev -> cprot;
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
#endif
lp->dialstate = ST_0;
isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
isdn_net_ciscohdlck_connected(lp);
if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
if (lp->master) { /* is lp a slave? */
isdn_net_dev *nd = ((isdn_net_local *)lp->master->priv)->netdev;
isdn_net_add_to_bundle(nd, lp);
}
}
printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
/* If first Chargeinfo comes before B-Channel connect,
* we correct the timestamp here.
*/
lp->chargetime = jiffies;
/* reset dial-timeout */
lp->dialstarted = 0;
lp->dialwait_timer = 0;
#ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
isdn_ppp_wakeup_daemon(lp);
#endif
#ifdef CONFIG_ISDN_X25
/* try if there are generic concap receiver routines */
if( pops )
if( pops->connect_ind)
pops->connect_ind(cprot);
#endif /* CONFIG_ISDN_X25 */
/* ppp needs to do negotiations first */
if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
isdn_net_device_wake_queue(lp);
}
/* /*
* Handle status-messages from ISDN-interfacecard. * Handle status-messages from ISDN-interfacecard.
* This function is called from within the main-status-dispatcher * This function is called from within the main-status-dispatcher
...@@ -421,158 +462,169 @@ int ...@@ -421,158 +462,169 @@ int
isdn_net_stat_callback(int idx, isdn_ctrl *c) isdn_net_stat_callback(int idx, isdn_ctrl *c)
{ {
isdn_net_dev *p = isdn_slot_st_netdev(idx); isdn_net_dev *p = isdn_slot_st_netdev(idx);
isdn_net_local *lp;
#ifdef CONFIG_ISDN_X25
struct concap_proto *cprot;
struct concap_proto_ops *pops;
#endif
int cmd = c->command; int cmd = c->command;
if (p) { if (!p)
isdn_net_local *lp = p->local; return 0;
lp = p->local;
#ifdef CONFIG_ISDN_X25 #ifdef CONFIG_ISDN_X25
struct concap_proto *cprot = lp -> netdev -> cprot; cprot = lp -> netdev -> cprot;
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0; pops = cprot ? cprot -> pops : 0;
#endif #endif
switch (lp->dialstate) {
case ST_0:
switch (cmd) { switch (cmd) {
case ISDN_STAT_BSENT: case ISDN_STAT_BSENT:
/* A packet has successfully been sent out */ /* A packet has successfully been sent out */
if ((lp->flags & ISDN_NET_CONNECTED) && if (lp->flags & ISDN_NET_CONNECTED) {
(lp->dialstate == ST_0)) { isdn_net_dec_frame_cnt(lp);
isdn_net_dec_frame_cnt(lp); lp->stats.tx_packets++;
lp->stats.tx_packets++; lp->stats.tx_bytes += c->parm.length;
lp->stats.tx_bytes += c->parm.length;
}
return 1; return 1;
case ISDN_STAT_DCONN: }
/* D-Channel is up */ break;
switch (lp->dialstate) { case ISDN_STAT_DHUP:
case ST_4: /* Either D-Channel-hangup or error during dialout */
lp->dialstate = ST_5; #ifdef CONFIG_ISDN_X25 // FIXME handle != ST_0?
return 1; /* If we are not connencted then dialing had
case ST_7: failed. If there are generic encap protocol
lp->dialstate = ST_8; receiver routines signal the closure of
return 1; the link*/
case ST_8:
lp->dialstate = ST_9; if (!(lp->flags & ISDN_NET_CONNECTED)
return 1; && pops && pops->disconn_ind)
case 12: pops -> disconn_ind(cprot);
lp->dialstate = ST_5;
return 1;
}
break;
case ISDN_STAT_DHUP:
/* Either D-Channel-hangup or error during dialout */
#ifdef CONFIG_ISDN_X25
/* If we are not connencted then dialing had
failed. If there are generic encap protocol
receiver routines signal the closure of
the link*/
if( !(lp->flags & ISDN_NET_CONNECTED)
&& pops && pops -> disconn_ind )
pops -> disconn_ind(cprot);
#endif /* CONFIG_ISDN_X25 */
if ((lp->dialstate == ST_0) && (lp->flags & ISDN_NET_CONNECTED)) {
if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
isdn_net_ciscohdlck_disconnected(lp);
#ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
isdn_ppp_free(lp);
#endif
isdn_net_lp_disconnected(lp);
isdn_slot_all_eaz(lp->isdn_slot);
printk(KERN_INFO "%s: remote hangup\n", lp->name);
printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
lp->charge);
isdn_net_unbind_channel(lp);
return 1;
}
break;
#ifdef CONFIG_ISDN_X25
case ISDN_STAT_BHUP:
/* B-Channel-hangup */
/* try if there are generic encap protocol
receiver routines and signal the closure of
the link */
if( pops && pops -> disconn_ind ){
pops -> disconn_ind(cprot);
return 1;
}
break;
#endif /* CONFIG_ISDN_X25 */ #endif /* CONFIG_ISDN_X25 */
case ISDN_STAT_BCONN: if (lp->flags & ISDN_NET_CONNECTED) {
/* B-Channel is up */ if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
isdn_net_zero_frame_cnt(lp); isdn_net_ciscohdlck_disconnected(lp);
switch (lp->dialstate) {
case ST_5:
case ST_6:
case ST_7:
case ST_8:
case ST_9:
case ST_10:
case ST_12:
if (lp->dialstate == ST_5 || lp->dialstate == ST_6)
isdn_slot_set_usage(idx, isdn_slot_usage(idx) | ISDN_USAGE_OUTGOING);
else
isdn_slot_set_rx_netdev(idx, p);
lp->dialstate = ST_0;
isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
isdn_net_ciscohdlck_connected(lp);
if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
if (lp->master) { /* is lp a slave? */
isdn_net_dev *nd = ((isdn_net_local *)lp->master->priv)->netdev;
isdn_net_add_to_bundle(nd, lp);
}
}
printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
/* If first Chargeinfo comes before B-Channel connect,
* we correct the timestamp here.
*/
lp->chargetime = jiffies;
/* reset dial-timeout */
lp->dialstarted = 0;
lp->dialwait_timer = 0;
#ifdef CONFIG_ISDN_PPP #ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
isdn_ppp_wakeup_daemon(lp); isdn_ppp_free(lp);
#endif #endif
#ifdef CONFIG_ISDN_X25 isdn_net_lp_disconnected(lp);
/* try if there are generic concap receiver routines */ isdn_slot_all_eaz(lp->isdn_slot);
if( pops ) printk(KERN_INFO "%s: remote hangup\n", lp->name);
if( pops->connect_ind) printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
pops->connect_ind(cprot); lp->charge);
#endif /* CONFIG_ISDN_X25 */ isdn_net_unbind_channel(lp);
/* ppp needs to do negotiations first */ return 1;
if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) }
isdn_net_device_wake_queue(lp); break;
return 1; #ifdef CONFIG_ISDN_X25 // FIXME handle != ST_0?
} case ISDN_STAT_BHUP:
break; /* B-Channel-hangup */
case ISDN_STAT_NODCH: /* try if there are generic encap protocol
/* No D-Channel avail. */ receiver routines and signal the closure of
if (lp->dialstate == ST_4) { the link */
lp->dialstate = ST_3; if( pops && pops -> disconn_ind ){
return 1; pops -> disconn_ind(cprot);
}
break;
case ISDN_STAT_CINF:
/* Charge-info from TelCo. Calculate interval between
* charge-infos and set timestamp for last info for
* usage by isdn_net_autohup()
*/
lp->charge++;
if (lp->hupflags & ISDN_HAVECHARGE) {
lp->hupflags &= ~ISDN_WAITCHARGE;
lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
}
if (lp->hupflags & ISDN_WAITCHARGE)
lp->hupflags |= ISDN_HAVECHARGE;
lp->chargetime = jiffies;
printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
lp->name, lp->chargetime);
return 1; return 1;
}
break;
#endif /* CONFIG_ISDN_X25 */
case ISDN_STAT_CINF:
/* Charge-info from TelCo. Calculate interval between
* charge-infos and set timestamp for last info for
* usage by isdn_net_autohup()
*/
lp->charge++;
if (lp->hupflags & ISDN_HAVECHARGE) {
lp->hupflags &= ~ISDN_WAITCHARGE;
lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
}
if (lp->hupflags & ISDN_WAITCHARGE)
lp->hupflags |= ISDN_HAVECHARGE;
lp->chargetime = jiffies;
printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
lp->name, lp->chargetime);
return 1;
} }
break;
case ST_4:
switch (cmd) {
case ISDN_STAT_NODCH:
/* No D-Channel avail. */
lp->dialstate = ST_3;
return 1;
case ISDN_STAT_DCONN:
lp->dialstate = ST_5;
return 1;
}
break;
case ST_5:
switch (cmd) {
case ISDN_STAT_BCONN:
isdn_slot_set_usage(idx, isdn_slot_usage(idx) | ISDN_USAGE_OUTGOING);
isdn_net_connected(lp);
return 1;
}
break;
case ST_6:
switch (cmd) {
case ISDN_STAT_BCONN:
isdn_slot_set_usage(idx, isdn_slot_usage(idx) | ISDN_USAGE_OUTGOING);
isdn_net_connected(lp);
return 1;
}
break;
case ST_7:
switch (cmd) {
case ISDN_STAT_DCONN:
lp->dialstate = ST_8;
return 1;
case ISDN_STAT_BCONN:
isdn_slot_set_rx_netdev(idx, p);
isdn_net_connected(lp);
return 1;
}
break;
case ST_8:
switch (cmd) {
case ISDN_STAT_DCONN:
lp->dialstate = ST_9;
return 1;
case ISDN_STAT_BCONN:
isdn_slot_set_rx_netdev(idx, p);
isdn_net_connected(lp);
return 1;
}
break;
case ST_9:
switch (cmd) {
case ISDN_STAT_BCONN:
isdn_slot_set_rx_netdev(idx, p);
isdn_net_connected(lp);
return 1;
}
break;
case ST_10:
switch (cmd) {
case ISDN_STAT_BCONN:
isdn_slot_set_rx_netdev(idx, p);
isdn_net_connected(lp);
return 1;
}
break;
case ST_12:
switch (cmd) {
case ISDN_STAT_DCONN:
lp->dialstate = ST_5;
return 1;
case ISDN_STAT_BCONN:
isdn_slot_set_rx_netdev(idx, p);
isdn_net_connected(lp);
return 1;
}
break;
} }
return 0;
} }
/* Initiate dialout. Set phone-number-pointer to first number /* Initiate dialout. Set phone-number-pointer to first number
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment