summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xpp/card_fxs.c24
-rw-r--r--xpp/xpp_zap.c21
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