diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-08-10 03:12:25 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-08-10 03:12:25 +0000 |
commit | 7d33e1eca2cc193bd0127816c7d487e3ef73e5bb (patch) | |
tree | 69d148d2587518cd5e04f173a593eb7a0c497203 /xpp | |
parent | 4ab762499c932cb80394ec1ec6b93879004a5214 (diff) |
* New SOFT_RING detection in FXO:
- Poll register 0x05 on each DAA
- When enough energy (value of 0x20|0x40 occurs enough times), raise
the ringing[] flag.
- When the value show no energy, lower the ringing[] flag.
- When we get SIG_CHANGED of stop ringing -- stop polling.
* More debugging messages for proc files
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1285 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp')
-rw-r--r-- | xpp/Makefile | 2 | ||||
-rw-r--r-- | xpp/card_fxo.c | 97 | ||||
-rw-r--r-- | xpp/xpp_zap.c | 6 |
3 files changed, 89 insertions, 16 deletions
diff --git a/xpp/Makefile b/xpp/Makefile index cce22ad..aa8d712 100644 --- a/xpp/Makefile +++ b/xpp/Makefile @@ -1,4 +1,4 @@ -EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION -DWITH_RBS +EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION -DWITH_RBS -DSOFT_RING obj-m = xpp.o xpp_usb.o xpd_fxs.o xpd_fxo.o xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c index 2627e21..89bec14 100644 --- a/xpp/card_fxo.c +++ b/xpp/card_fxo.c @@ -70,6 +70,12 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline); #define PROC_DAA_FNAME "slics" #define PROC_FXO_INFO_FNAME "fxo_info" +#ifdef SOFT_RING +#define POLL_RING_INTERVAL 1 +#define RING_THRESHOLD 5 +#define DAA_RING_REGISTER 0x05 +#endif + struct FXO_priv_data { struct proc_dir_entry *xpd_slic; struct proc_dir_entry *fxo_info; @@ -79,6 +85,9 @@ struct FXO_priv_data { xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */ xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */ int blinking[NUM_LEDS][CHANNELS_PERXPD]; +#ifdef SOFT_RING + ushort ring_thresh[CHANNELS_PERXPD]; +#endif }; /*---------------- FXO: Static functions ----------------------------------*/ @@ -174,6 +183,24 @@ static void handle_fxo_leds(xpd_t *xpd) spin_unlock_irqrestore(&xpd->lock, flags); } +static void mark_ring(xpd_t *xpd, lineno_t pos, bool on) +{ + struct FXO_priv_data *priv; + + priv = xpd->priv; + BUG_ON(!priv); + if(on && !xpd->ringing[pos]) { + DBG("%s/%s/%d: START\n", xpd->xbus->busname, xpd->xpdname, pos); + xpd->ringing[pos] = 1; + MARK_BLINK(priv, pos, LED_GREEN, LED_BLINK); + } else if(!on && xpd->ringing[pos]) { + DBG("%s/%s/%d: STOP\n", xpd->xbus->busname, xpd->xpdname, pos); + xpd->ringing[pos] = 0; + if(IS_BLINKING(priv, pos, LED_GREEN)) + MARK_BLINK(priv, pos, LED_GREEN, 0); + } +} + static void do_sethook(xpd_t *xpd, int pos, bool offhook) { unsigned long flags; @@ -187,7 +214,7 @@ static void do_sethook(xpd_t *xpd, int pos, bool offhook) DBG("%s/%s/%d: WARNING: called while battery is off\n", xpd->xbus->busname, xpd->xpdname, pos); } spin_lock_irqsave(&xpd->lock, flags); - xpd->ringing[pos] = 0; // No more rings + mark_ring(xpd, pos, 0); // No more rings CALL_XMETHOD(SETHOOK, xpd->xbus, xpd, pos, offhook); if(offhook) { BIT_SET(xpd->hookstate, pos); @@ -413,6 +440,21 @@ static void poll_battery(xbus_t *xbus, xpd_t *xpd) } } +#ifdef SOFT_RING + +static void poll_ring(xbus_t *xbus, xpd_t *xpd) +{ + int i; + struct FXO_priv_data *priv; + + priv = xpd->priv; + BUG_ON(!priv); + for_each_line(xpd, i) { + if(priv->ring_thresh[i] > 0) + CALL_PROTO(FXO, DAA_QUERY, xbus, xpd, i, DAA_RING_REGISTER); + } +} +#endif static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd) { @@ -426,6 +468,10 @@ static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd) if(poll_battery_interval != 0 && (rate_limit % poll_battery_interval) == 0) { poll_battery(xbus, xpd); } +#ifdef SOFT_RING + if((rate_limit % POLL_RING_INTERVAL) == 0) + poll_ring(xbus, xpd); +#endif handle_fxo_leds(xpd); return 0; } @@ -552,7 +598,6 @@ static /* 0x0F */ HOSTCMD(FXO, SETHOOK, int pos, bool offhook) xpacket_t *pack; slic_cmd_t *sc; int len; - unsigned long flags; bool value; BUG_ON(!xbus); @@ -560,7 +605,6 @@ static /* 0x0F */ HOSTCMD(FXO, SETHOOK, int pos, bool offhook) value = (offhook) ? 0x09 : 0x08; // value |= BIT(3); /* Bit 3 is for CID */ DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (offhook)?"OFFHOOK":"ONHOOK"); - spin_lock_irqsave(&xpd->lock, flags); MARK_LED(xpd, pos, LED_GREEN, (offhook)?LED_ON:LED_OFF); XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id); sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd); @@ -568,8 +612,7 @@ static /* 0x0F */ HOSTCMD(FXO, SETHOOK, int pos, bool offhook) pack->datalen = len; packet_send(xbus, pack); if(!offhook) - xpd->ringing[pos] = 0; - spin_unlock_irqrestore(&xpd->lock, flags); + mark_ring(xpd, pos, 0); // No more rings return ret; } @@ -619,17 +662,18 @@ HANDLER_DEF(FXO, SIG_CHANGED) spin_lock_irqsave(&xpd->lock, flags); for_each_line(xpd, i) { if(IS_SET(sig_toggles, i)) { - struct zt_chan *chan = &xpd->span.chans[i]; - if(IS_SET(sig_status, i)) { - DBG("%s/%s/%d: RING-ON\n", xbus->busname, xpd->xpdname, chan->channo); - xpd->ringing[i] = 1; - MARK_BLINK(priv, i, LED_GREEN, LED_BLINK); +#ifdef SOFT_RING + priv->ring_thresh[i]++; /* trigger register polling */ +#else + mark_ring(xpd, i, 1); +#endif } else { - DBG("%s/%s/%d: RING-OFF\n", xbus->busname, xpd->xpdname, chan->channo); - xpd->ringing[i] = 0; - if(IS_BLINKING(priv, i, LED_GREEN)) - MARK_BLINK(priv, i, LED_GREEN, 0); +#ifdef SOFT_RING + priv->ring_thresh[i] = 0; +#else + mark_ring(xpd, i, 0); +#endif } } } @@ -671,6 +715,24 @@ HANDLER_DEF(FXO, DAA_REPLY) } } } +#ifdef SOFT_RING + if(!info->indirect && info->reg_num == DAA_RING_REGISTER) { + bool ringit = (info->data_low & (0x20 | 0x40)) ? 1 : 0; /* Ring positive | Ring negative */ + int i; + + for_each_line(xpd, i) { + if(IS_SET(lines, i)) { + if(ringit) { + if(priv->ring_thresh[i]++ > RING_THRESHOLD) { + mark_ring(xpd, i, 1); + } + } else { + mark_ring(xpd, i, 0); + } + } + } + } +#endif #if 0 DBG("DAA_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n", xpd->id, (info->indirect)?"I":"D", @@ -772,6 +834,13 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) len += sprintf(page + len, "%d ", IS_BLINKING(priv,i,LED_GREEN)); } +#ifdef SOFT_RING + len += sprintf(page + len, "\n\t%-17s: ", "ring_thresh"); + for_each_line(xpd, i) { + if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) + len += sprintf(page + len, "%d ", priv->ring_thresh[i]); + } +#endif len += sprintf(page + len, "\n\t%-17s: ", "battery"); for_each_line(xpd, i) { len += sprintf(page + len, "%d ", IS_SET(priv->battery, i)); diff --git a/xpp/xpp_zap.c b/xpp/xpp_zap.c index e1d15ed..e992144 100644 --- a/xpp/xpp_zap.c +++ b/xpp/xpp_zap.c @@ -634,6 +634,8 @@ void update_line_status(xpd_t *xpd, int pos, bool good) zt_hooksig(chan, ZT_RXSIG_ONHOOK); } +#define RING_TIME 15 /* in ticks */ + static void xpp_ring_generate(xpd_t *xpd) { int i; @@ -658,7 +660,7 @@ static void xpp_ring_generate(xpd_t *xpd) for_each_line(xpd, i) { if(xpd->ringing[i] || xpd->ringer_on[i]) { // ring state is only changed once per second: - if((xpd->timer_count % 1000) == 0) { + if((xpd->timer_count % RING_TIME) == 0) { DBG("pos=%d ringing=%d ringer_on=%d\n", i, xpd->ringing[i], xpd->ringer_on[i]); if(xpd->ringer_on[i]) { zt_hooksig(&xpd->chans[i], ZT_RXSIG_OFFHOOK); @@ -1488,8 +1490,10 @@ static void do_cleanup(void) unregister_chrdev(XPP_CTL_MAJOR, THIS_MODULE->name); #endif #ifdef CONFIG_PROC_FS + DBG("Removing '%s' from proc\n", PROC_SYNC); remove_proc_entry(PROC_SYNC, xpp_proc_toplevel); if(xpp_proc_toplevel) { + DBG("Removing '%s' from proc\n", PROC_DIR); remove_proc_entry(PROC_DIR, NULL); xpp_proc_toplevel = NULL; } |