diff options
-rw-r--r-- | xpp/card_fxs.c | 24 | ||||
-rw-r--r-- | xpp/xpp_zap.c | 21 |
2 files changed, 24 insertions, 21 deletions
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c index 1264348..0050348 100644 --- a/xpp/card_fxs.c +++ b/xpp/card_fxs.c @@ -768,21 +768,17 @@ HANDLER_DEF(FXS, SIG_CHANGED) if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i)) continue; if(IS_SET(sig_toggles, i)) { - struct zt_chan *chan = &xpd->span.chans[i]; - xpd->ringing[i] = 0; // No more ringing... do_chan_power(xpd->xbus, xpd, BIT(i), 0); // When not ringing, VBAT is always Low MARK_BLINK(priv,i,LED_GREEN,0); if(IS_SET(sig_status, i)) { - DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, chan->channo); + DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, i); MARK_LED(priv,i,LED_GREEN,LED_ON); - BIT_SET(xpd->hookstate, i); - zt_hooksig(chan, ZT_RXSIG_OFFHOOK); + update_line_status(xpd, i, 1); } else { - DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, chan->channo); + DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, i); MARK_LED(priv,i,LED_GREEN,LED_OFF); - BIT_CLR(xpd->hookstate, i); - zt_hooksig(chan, ZT_RXSIG_ONHOOK); + update_line_status(xpd, i, 0); } } } @@ -819,22 +815,18 @@ HANDLER_DEF(FXS, SLIC_REPLY) for(i = 0; i < ARRAY_SIZE(input_channels); i++) { int channo = input_channels[i]; int newchanno; - struct zt_chan *chan; if(IS_SET(lines, channo)) { newchanno = LINES_REGULAR + LINES_DIGI_OUT + i; BIT_CLR(lines, channo); BIT_SET(lines, newchanno); - chan = &xpd->span.chans[newchanno]; xpd->ringing[newchanno] = 0; // Stop ringing. No leds for digital inputs. if(offhook && !IS_SET(xpd->hookstate, newchanno)) { // OFFHOOK - DBG("OFFHOOK: channo=%d\n", chan->channo); - BIT_SET(xpd->hookstate, newchanno); - zt_hooksig(chan, ZT_RXSIG_OFFHOOK); + DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, newchanno); + update_line_status(xpd, newchanno, 1); } else if(!offhook && IS_SET(xpd->hookstate, newchanno)) { // ONHOOK - DBG("ONHOOK channo=%d\n", chan->channo); - BIT_CLR(xpd->hookstate, newchanno); - zt_hooksig(chan, ZT_RXSIG_ONHOOK); + DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, newchanno); + update_line_status(xpd, newchanno, 0); } } } diff --git a/xpp/xpp_zap.c b/xpp/xpp_zap.c index 02604f5..b805075 100644 --- a/xpp/xpp_zap.c +++ b/xpp/xpp_zap.c @@ -619,7 +619,7 @@ void update_xpd_status(xpd_t *xpd, int alarm_flag) DBG("Update XPD alarms: %s -> %02X\n", xpd->span.name, alarm_flag); } -void update_line_status(xpd_t *xpd, int pos, bool good) +void update_line_status(xpd_t *xpd, int pos, bool to_offhook) { struct zt_chan *chan; @@ -627,14 +627,20 @@ void update_line_status(xpd_t *xpd, int pos, bool good) if(!SPAN_REGISTERED(xpd)) return; chan = &xpd->chans[pos]; - if(good) + /* + * We should not spinlock before calling zt_hooksig() as + * it may call back into our xpp_hooksig() and cause + * a nested spinlock scenario + */ + if(to_offhook) { + BIT_SET(xpd->hookstate, pos); zt_hooksig(chan, ZT_RXSIG_OFFHOOK); - else + } else { + BIT_CLR(xpd->hookstate, pos); zt_hooksig(chan, ZT_RXSIG_ONHOOK); + } } -#define RING_TIME 15 /* in ticks */ - void update_zap_ring(xpd_t *xpd, int pos, bool on) { struct zt_chan *chan; @@ -643,6 +649,11 @@ void update_zap_ring(xpd_t *xpd, int pos, bool on) if(!SPAN_REGISTERED(xpd)) return; chan = &xpd->chans[pos]; + /* + * We should not spinlock before calling zt_hooksig() as + * it may call back into our xpp_hooksig() and cause + * a nested spinlock scenario + */ if(on) zt_hooksig(chan, ZT_RXSIG_RING); else |