Skip to content

Commit d16046e

Browse files
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.
1 parent 8065155 commit d16046e

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

Diff for: channels/chan_dahdi.c

+53
Original file line numberDiff line numberDiff line change
@@ -6565,6 +6565,36 @@ static int dahdi_hangup(struct ast_channel *ast)
65656565
ast_free(p->cidspill);
65666566
p->cidspill = NULL;
65676567

6568+
if (p->reoriginate && p->sig == SIG_FXOKS && dahdi_analog_lib_handles(p->sig, p->radio, 0)) {
6569+
/* Automatic reorigination: if all calls towards a user have hung up,
6570+
* give dial tone again, so user doesn't need to cycle the hook state manually. */
6571+
if (my_is_off_hook(p) && !p->owner) {
6572+
/* 2 important criteria: channel must be off-hook, with no calls remaining (no owner) */
6573+
ast_debug(1, "Queuing reorigination for channel %d\n", p->channel);
6574+
my_play_tone(p, SUB_REAL, -1); /* Stop any congestion tone that may be present. */
6575+
/* Must wait for the loop disconnect to end.
6576+
* Sadly, these definitions are in dahdi/kernel.h, not dahdi/user.h
6577+
* Calling usleep on an active DAHDI channel is a no-no, but this is okay.
6578+
*/
6579+
usleep(800000); /* DAHDI_KEWLTIME + DAHDI_AFTERKEWLTIME */
6580+
/* If the line is still off-hook and ownerless, actually queue the reorigination.
6581+
* do_monitor will actually go ahead and do it. */
6582+
if (!p->owner && my_is_off_hook(p)) {
6583+
p->doreoriginate = 1; /* Tell do_monitor to reoriginate this channel */
6584+
/* Note, my_off_hook will fail if called before the loop disconnect has finished
6585+
* (important for FXOKS signaled channels). This is because DAHDI will reject
6586+
* DAHDI_OFFHOOK while the channel is in TXSTATE_KEWL or TXSTATE_AFTERKEWL,
6587+
* so we have to wait for that to finish (see comment above).
6588+
* do_monitor itself cannot block, so make the blocking usleep call
6589+
* here in the channel thread instead.
6590+
*/
6591+
my_off_hook(p); /* Now, go ahead and take the channel back off hook (sig_analog put it on hook) */
6592+
} else {
6593+
ast_debug(1, "Channel %d is no longer eligible for reorigination (went back on hook or became in use)\n", p->channel);
6594+
}
6595+
}
6596+
}
6597+
65686598
ast_mutex_unlock(&p->lock);
65696599
ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast));
65706600

@@ -11992,6 +12022,26 @@ static void *do_monitor(void *data)
1199212022
else
1199312023
doomed = handle_init_event(i, res);
1199412024
}
12025+
if (i->doreoriginate && res == DAHDI_EVENT_HOOKCOMPLETE) {
12026+
/* Actually automatically reoriginate this FXS line, if directed to.
12027+
* We should get a DAHDI_EVENT_HOOKCOMPLETE from the loop disconnect
12028+
* doing its thing (one reason why this is for FXOKS only: FXOLS
12029+
* hangups don't give us any DAHDI events to piggyback off of)*/
12030+
i->doreoriginate = 0;
12031+
/* Double check the channel is still off-hook. There's only about a millisecond
12032+
* between when doreoriginate is set high and we see that here, but just to be safe. */
12033+
if (!my_is_off_hook(i)) {
12034+
ast_debug(1, "Woah! Went back on hook before reoriginate could happen on channel %d\n", i->channel);
12035+
} else {
12036+
ast_verb(3, "Automatic reorigination on channel %d\n", i->channel);
12037+
res = DAHDI_EVENT_RINGOFFHOOK; /* Pretend that the physical channel just went off hook */
12038+
if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
12039+
doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res));
12040+
} else {
12041+
doomed = handle_init_event(i, res);
12042+
}
12043+
}
12044+
}
1199512045
ast_mutex_lock(&iflock);
1199612046
}
1199712047
}
@@ -13087,6 +13137,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
1308713137
tmp->ani_wink_time = conf->chan.ani_wink_time;
1308813138
tmp->ani_timeout = conf->chan.ani_timeout;
1308913139
tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
13140+
tmp->reoriginate = conf->chan.reoriginate;
1309013141
tmp->sendcalleridafter = conf->chan.sendcalleridafter;
1309113142
ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params);
1309213143

@@ -18522,6 +18573,8 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
1852218573
confp->chan.ani_timeout = atoi(v->value);
1852318574
} else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
1852418575
confp->chan.hanguponpolarityswitch = ast_true(v->value);
18576+
} else if (!strcasecmp(v->name, "autoreoriginate")) {
18577+
confp->chan.reoriginate = ast_true(v->value);
1852518578
} else if (!strcasecmp(v->name, "sendcalleridafter")) {
1852618579
confp->chan.sendcalleridafter = atoi(v->value);
1852718580
} else if (!strcasecmp(v->name, "mwimonitornotify")) {

Diff for: channels/chan_dahdi.h

+8
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,14 @@ struct dahdi_pvt {
276276
* \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
277277
*/
278278
unsigned int hanguponpolarityswitch:1;
279+
/*!
280+
* \brief TRUE if FXS (FXO-signalled) channel should reoriginate for user to make a new call.
281+
*/
282+
unsigned int reoriginate:1;
283+
/*!
284+
* \brief Internal flag for if we should actually process a reorigination.
285+
*/
286+
unsigned int doreoriginate:1;
279287
/*! \brief TRUE if DTMF detection needs to be done by hardware. */
280288
unsigned int hardwaredtmf:1;
281289
/*!

Diff for: configs/samples/chan_dahdi.conf.sample

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

0 commit comments

Comments
 (0)