wctdm24xxp: Fix FXO failure to detect battery CO disconnects.

In 2.6.2 I introduced an error in (41639330a "wctdm24xxp: Eliminate chance for
channel to be stuck in RED alarm.") which would get an FXO stuck in detecting an
ONHOOK event from the remote side.  An FXO port could go into the
BATTERY_DEBOUNCING_LOST_ALARM state and then back to the BATTERY_PRESENT state
without sending the dahdi_hooksig up to Asterisk.  Therefore, Asterisk would
never detect the state changes needed for a remote side disconnect.

This change adds two more states, BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM and
BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM so that the state machine does not
miss any needed transitions when going back to BATTERY_PRESENT or BATTERY_LOST
regardless of why the debounce was started.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
This commit is contained in:
Shaun Ruffell 2013-05-09 08:32:17 -05:00 committed by Russ Meyerriecks
parent bb5eeccef3
commit 244f621eb1
2 changed files with 24 additions and 8 deletions

View File

@ -1961,19 +1961,26 @@ wctdm_check_battery_lost(struct wctdm *wc, struct wctdm_module *const mod)
battery present or unknown, debounce timer (going to battery lost)
*/
switch (fxo->battery_state) {
case BATTERY_DEBOUNCING_PRESENT_ALARM:
fxo->battery_state = BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM;
fxo->battdebounce_timer = wc->framecount + battdebounce;
break;
case BATTERY_DEBOUNCING_PRESENT:
case BATTERY_DEBOUNCING_PRESENT_ALARM: /* intentional drop through */
/* we were going to BATTERY_PRESENT, but
* battery was lost again. */
fxo->battery_state = BATTERY_LOST;
break;
case BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM:
fxo->battery_state = BATTERY_DEBOUNCING_LOST_ALARM;
fxo->battdebounce_timer = wc->framecount +
battalarm - battdebounce;
break;
case BATTERY_UNKNOWN:
mod_hooksig(wc, mod, DAHDI_RXSIG_ONHOOK);
case BATTERY_PRESENT:
fxo->battery_state = BATTERY_DEBOUNCING_LOST;
fxo->battdebounce_timer = wc->framecount + battdebounce;
break;
case BATTERY_DEBOUNCING_LOST:
case BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM:
case BATTERY_DEBOUNCING_LOST: /* Intentional drop through */
if (time_after(wc->framecount, fxo->battdebounce_timer)) {
if (debug) {
dev_info(&wc->vb.pdev->dev,
@ -2022,7 +2029,8 @@ wctdm_check_battery_present(struct wctdm *wc, struct wctdm_module *const mod)
struct fxo *const fxo = &mod->mod.fxo;
switch (fxo->battery_state) {
case BATTERY_DEBOUNCING_PRESENT:
case BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM:
case BATTERY_DEBOUNCING_PRESENT: /* intentional drop through */
if (time_after(wc->framecount, fxo->battdebounce_timer)) {
if (debug) {
dev_info(&wc->vb.pdev->dev,
@ -2061,10 +2069,16 @@ wctdm_check_battery_present(struct wctdm *wc, struct wctdm_module *const mod)
break;
case BATTERY_PRESENT:
break;
case BATTERY_DEBOUNCING_LOST:
case BATTERY_DEBOUNCING_LOST_ALARM:
/* we were going to BATTERY_LOST, but battery appeared again,
* so clear the debounce timer */
fxo->battery_state = BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM;
fxo->battdebounce_timer = wc->framecount + battdebounce;
break;
case BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM:
fxo->battery_state = BATTERY_DEBOUNCING_PRESENT_ALARM;
fxo->battdebounce_timer = wc->framecount +
battalarm - battdebounce;
break;
case BATTERY_DEBOUNCING_LOST:
fxo->battery_state = BATTERY_PRESENT;
break;
case BATTERY_UNKNOWN:

View File

@ -106,9 +106,11 @@ struct calregs {
enum battery_state {
BATTERY_UNKNOWN = 0,
BATTERY_DEBOUNCING_PRESENT,
BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM,
BATTERY_DEBOUNCING_PRESENT_ALARM,
BATTERY_PRESENT,
BATTERY_DEBOUNCING_LOST,
BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM,
BATTERY_DEBOUNCING_LOST_ALARM,
BATTERY_LOST,
};