summaryrefslogtreecommitdiff
path: root/kernel/xpp/card_fxs.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-08-04 15:52:49 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-08-04 15:52:49 +0000
commit64f72ae8855f0eb7985a1b4b09c0eda769d739c8 (patch)
tree87de502479311b224f6c52bca5f3128f7504768d /kernel/xpp/card_fxs.c
parenteeff62d36576880696ca8c64e415a13ca7437386 (diff)
Merged revisions 4451-4455 via svnmerge from
http://svn.digium.com/svn/zaptel/branches/1.2 ........ r4451 | tzafrir | 2008-08-04 18:11:01 +0300 (Mon, 04 Aug 2008) | 9 lines Firmware update: 5959 (DTMF and BRI ID) (From DAHDI rev. 4695) * Fix some cases of double digits. * Fix some rare cases of a BRI unit providing incorrect directionality. * Extra debugging code in card_fxs.c to trace future DTMF issues. * Properly note DAHDI (as opposed to Zaptel) ioctls. ........ r4452 | tzafrir | 2008-08-04 18:36:19 +0300 (Mon, 04 Aug 2008) | 2 lines Make it formally bashism. ........ r4453 | tzafrir | 2008-08-04 18:38:10 +0300 (Mon, 04 Aug 2008) | 2 lines Kbuild: A more robust check for the bri_dchan patch. ........ r4454 | tzafrir | 2008-08-04 18:39:01 +0300 (Mon, 04 Aug 2008) | 2 lines Minor BRI initlization improvements. ........ r4455 | tzafrir | 2008-08-04 18:43:32 +0300 (Mon, 04 Aug 2008) | 7 lines Add channel alarms in Zaptel-perl and lszaptel specifically. * Zaptel::Chans now provides a method alarms() for a list (or number of) alarms. * lszaptel uses it for a more correct display of channel status. * Also update PCI hardware list. ........ git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4456 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'kernel/xpp/card_fxs.c')
-rw-r--r--kernel/xpp/card_fxs.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/kernel/xpp/card_fxs.c b/kernel/xpp/card_fxs.c
index 24b278f..b45db4a 100644
--- a/kernel/xpp/card_fxs.c
+++ b/kernel/xpp/card_fxs.c
@@ -132,6 +132,8 @@ struct FXS_priv_data {
xpp_line_t update_offhook_state;
xpp_line_t want_dtmf_events; /* what zaptel want */
xpp_line_t want_dtmf_mute; /* what zaptel want */
+ xpp_line_t prev_key_down; /* DTMF down sets the bit */
+ struct timeval prev_key_time[CHANNELS_PERXPD];
int led_counter[NUM_LEDS][CHANNELS_PERXPD];
int ohttimer[CHANNELS_PERXPD];
#define OHT_TIMER 6000 /* How long after RING to retain OHT */
@@ -1117,6 +1119,11 @@ static void process_hookstate(xpd_t *xpd, xpp_line_t offhook, xpp_line_t change_
metering_gen(xpd, i, 0); /* Stop metering... */
#endif
MARK_BLINK(priv, i, LED_GREEN, 0);
+ /*
+ * Reset our previous DTMF memories...
+ */
+ BIT_CLR(priv->prev_key_down, i);
+ priv->prev_key_time[i].tv_sec = priv->prev_key_time[i].tv_usec = 0L;
if(IS_SET(offhook, i)) {
LINE_DBG(SIGNAL, xpd, i, "OFFHOOK\n");
MARK_ON(priv, i, LED_GREEN);
@@ -1194,12 +1201,15 @@ static const char dtmf_digits[] = {
/*
* This function is called with spinlocked XPD
*/
-static void process_dtmf(xpd_t *xpd, xpp_line_t lines, byte val)
+static void process_dtmf(xpd_t *xpd, uint portnum, byte val)
{
- int i;
byte digit;
- bool is_down = val & 0x10;
+ bool key_down = val & 0x10;
+ bool want_mute;
+ bool want_event;
struct FXS_priv_data *priv;
+ struct timeval now;
+ int msec = 0;
if(!dtmf_detection)
return;
@@ -1208,42 +1218,46 @@ static void process_dtmf(xpd_t *xpd, xpp_line_t lines, byte val)
priv = xpd->priv;
val &= 0xF;
if(val <= 0) {
- if(is_down)
+ if(key_down)
XPD_NOTICE(xpd, "Bad DTMF value %d. Ignored\n", val);
return;
}
val--;
digit = dtmf_digits[val];
- for_each_line(xpd, i) {
- if(IS_SET(lines, i)) {
- int event = (is_down) ? ZT_EVENT_DTMFDOWN : ZT_EVENT_DTMFUP;
- bool want_mute = IS_SET(priv->want_dtmf_mute, i);
- bool want_event = IS_SET(priv->want_dtmf_events, i);
-
- if(want_event) {
- LINE_DBG(SIGNAL, xpd, i,
- "DTMF digit %s (val=%d) '%c' (want_mute=%s)\n",
- (is_down)?"DOWN":"UP", val, digit,
- (want_mute) ? "yes" : "no");
- } else {
- LINE_DBG(SIGNAL, xpd, i,
- "Ignored DTMF digit %s '%c'\n",
- (is_down)?"DOWN":"UP", digit);
- }
- /*
- * FIXME: we currently don't use the want_dtmf_mute until
- * we are sure about the logic in Asterisk native bridging.
- * Meanwhile, simply mute it on button press.
- */
- if(is_down && want_mute)
- __do_mute_dtmf(xpd, i, 1);
- else
- __do_mute_dtmf(xpd, i, 0);
- __pcm_recompute(xpd, 0); /* XPD is locked */
- if(want_event)
- zt_qevent_lock(&xpd->chans[i], event | digit);
- break;
- }
+ want_mute = IS_SET(priv->want_dtmf_mute, portnum);
+ want_event = IS_SET(priv->want_dtmf_events, portnum);
+ if(!IS_SET(priv->prev_key_down, portnum) && !key_down) {
+ LINE_NOTICE(xpd, portnum, "DTMF: duplicate UP (%c)\n", digit);
+ }
+ if(key_down)
+ BIT_SET(priv->prev_key_down, portnum);
+ else
+ BIT_CLR(priv->prev_key_down, portnum);
+ do_gettimeofday(&now);
+ if(priv->prev_key_time[portnum].tv_sec != 0)
+ msec = usec_diff(&now, &priv->prev_key_time[portnum]) / 1000;
+ priv->prev_key_time[portnum] = now;
+ LINE_DBG(SIGNAL, xpd, portnum,
+ "[%lu.%06lu] DTMF digit %-4s '%c' (val=%d, want_mute=%s want_event=%s, delta=%d msec)\n",
+ now.tv_sec, now.tv_usec,
+ (key_down)?"DOWN":"UP", digit, val,
+ (want_mute) ? "yes" : "no",
+ (want_event) ? "yes" : "no",
+ msec);
+ /*
+ * FIXME: we currently don't use the want_dtmf_mute until
+ * we are sure about the logic in Asterisk native bridging.
+ * Meanwhile, simply mute it on button press.
+ */
+ if(key_down && want_mute)
+ __do_mute_dtmf(xpd, portnum, 1);
+ else
+ __do_mute_dtmf(xpd, portnum, 0);
+ __pcm_recompute(xpd, 0); /* XPD is locked */
+ if(want_event) {
+ int event = (key_down) ? ZT_EVENT_DTMFDOWN : ZT_EVENT_DTMFUP;
+
+ zt_qevent_lock(&xpd->chans[portnum], event | digit);
}
}
@@ -1264,9 +1278,8 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
regnum, REG_FIELD(info, data_low), REG_FIELD(info, data_high));
if(!indirect && regnum == REG_DTMF_DECODE) {
byte val = REG_FIELD(info, data_low);
- xpp_line_t lines = BIT(info->portnum);
- process_dtmf(xpd, lines, val);
+ process_dtmf(xpd, info->portnum, val);
}
#ifdef POLL_DIGITAL_INPUTS
/*