chan_dahdi: Allow autoreoriginating after hangup.

Currently, if an FXS channel is still off hook when
all calls on the line have hung up, the user is provided
reorder tone until going back on hook again.

In addition to not reflecting what most commercial switches
actually do, it's very common for switches to automatically
reoriginate for the user so that dial tone is provided without
the user having to depress and release the hookswitch manually.
This can increase convenience for users.

This behavior is now supported for kewlstart FXS channels.
It's supported only for kewlstart (FXOKS) mainly because the
behavior doesn't make any sense for ground start channels,
and loop start signalling doesn't provide the necessary DAHDI
event that makes this easy to implement. Likely almost everyone
is using FXOKS over FXOLS anyways since FXOLS is pretty useless
these days.

ASTERISK-30357 #close

Resolves: #224

UserNote: The autoreoriginate setting now allows for kewlstart FXS
channels to automatically reoriginate and provide dial tone to the
user again after all calls on the line have cleared. This saves users
from having to manually hang up and pick up the receiver again before
making another call.

(cherry picked from commit c16cc93a4b)
This commit is contained in:
Naveen Albert 2023-08-04 17:26:05 +00:00 committed by Asterisk Development Team
parent fcf7187cd6
commit 65a2bca074
3 changed files with 70 additions and 0 deletions

View File

@ -6565,6 +6565,36 @@ hangup_out:
ast_free(p->cidspill);
p->cidspill = NULL;
if (p->reoriginate && p->sig == SIG_FXOKS && dahdi_analog_lib_handles(p->sig, p->radio, 0)) {
/* Automatic reorigination: if all calls towards a user have hung up,
* give dial tone again, so user doesn't need to cycle the hook state manually. */
if (my_is_off_hook(p) && !p->owner) {
/* 2 important criteria: channel must be off-hook, with no calls remaining (no owner) */
ast_debug(1, "Queuing reorigination for channel %d\n", p->channel);
my_play_tone(p, SUB_REAL, -1); /* Stop any congestion tone that may be present. */
/* Must wait for the loop disconnect to end.
* Sadly, these definitions are in dahdi/kernel.h, not dahdi/user.h
* Calling usleep on an active DAHDI channel is a no-no, but this is okay.
*/
usleep(800000); /* DAHDI_KEWLTIME + DAHDI_AFTERKEWLTIME */
/* If the line is still off-hook and ownerless, actually queue the reorigination.
* do_monitor will actually go ahead and do it. */
if (!p->owner && my_is_off_hook(p)) {
p->doreoriginate = 1; /* Tell do_monitor to reoriginate this channel */
/* Note, my_off_hook will fail if called before the loop disconnect has finished
* (important for FXOKS signaled channels). This is because DAHDI will reject
* DAHDI_OFFHOOK while the channel is in TXSTATE_KEWL or TXSTATE_AFTERKEWL,
* so we have to wait for that to finish (see comment above).
* do_monitor itself cannot block, so make the blocking usleep call
* here in the channel thread instead.
*/
my_off_hook(p); /* Now, go ahead and take the channel back off hook (sig_analog put it on hook) */
} else {
ast_debug(1, "Channel %d is no longer eligible for reorigination (went back on hook or became in use)\n", p->channel);
}
}
}
ast_mutex_unlock(&p->lock);
ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast));
@ -11992,6 +12022,26 @@ static void *do_monitor(void *data)
else
doomed = handle_init_event(i, res);
}
if (i->doreoriginate && res == DAHDI_EVENT_HOOKCOMPLETE) {
/* Actually automatically reoriginate this FXS line, if directed to.
* We should get a DAHDI_EVENT_HOOKCOMPLETE from the loop disconnect
* doing its thing (one reason why this is for FXOKS only: FXOLS
* hangups don't give us any DAHDI events to piggyback off of)*/
i->doreoriginate = 0;
/* Double check the channel is still off-hook. There's only about a millisecond
* between when doreoriginate is set high and we see that here, but just to be safe. */
if (!my_is_off_hook(i)) {
ast_debug(1, "Woah! Went back on hook before reoriginate could happen on channel %d\n", i->channel);
} else {
ast_verb(3, "Automatic reorigination on channel %d\n", i->channel);
res = DAHDI_EVENT_RINGOFFHOOK; /* Pretend that the physical channel just went off hook */
if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res));
} else {
doomed = handle_init_event(i, res);
}
}
}
ast_mutex_lock(&iflock);
}
}
@ -13087,6 +13137,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
tmp->ani_wink_time = conf->chan.ani_wink_time;
tmp->ani_timeout = conf->chan.ani_timeout;
tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
tmp->reoriginate = conf->chan.reoriginate;
tmp->sendcalleridafter = conf->chan.sendcalleridafter;
ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params);
@ -18522,6 +18573,8 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
confp->chan.ani_timeout = atoi(v->value);
} else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
confp->chan.hanguponpolarityswitch = ast_true(v->value);
} else if (!strcasecmp(v->name, "autoreoriginate")) {
confp->chan.reoriginate = ast_true(v->value);
} else if (!strcasecmp(v->name, "sendcalleridafter")) {
confp->chan.sendcalleridafter = atoi(v->value);
} else if (!strcasecmp(v->name, "mwimonitornotify")) {

View File

@ -276,6 +276,14 @@ struct dahdi_pvt {
* \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
*/
unsigned int hanguponpolarityswitch:1;
/*!
* \brief TRUE if FXS (FXO-signalled) channel should reoriginate for user to make a new call.
*/
unsigned int reoriginate:1;
/*!
* \brief Internal flag for if we should actually process a reorigination.
*/
unsigned int doreoriginate:1;
/*! \brief TRUE if DTMF detection needs to be done by hardware. */
unsigned int hardwaredtmf:1;
/*!

View File

@ -1097,6 +1097,15 @@ pickupgroup=1
; polarity switch and hangup polarity switch.
; (default: 600ms)
;
; For kewlstart FXS (FXO signalled) ports only:
; When all calls towards a DAHDI channel have cleared, automatically
; reoriginate and provide dial tone to the user again, so s/he can
; make another call without having to cycle the hookswitch manually.
; This only works for kewlstart (fxo_ks) lines!
; Dial tone will be provided only after the loop disconnect has finished.
;
;autoreoriginate=yes
;
; On trunk interfaces (FXS) it can be useful to attempt to follow the progress
; of a call through RINGING, BUSY, and ANSWERING. If turned on, call
; progress attempts to determine answer, busy, and ringing on phone lines.