Hookflash can be performed by hang-up or by dialing one pulse
This allows short hookflash.
This commit is contained in:
parent
9bf05e0bdb
commit
a70bff87fc
121
src/pstn/pstn.c
121
src/pstn/pstn.c
|
@ -1262,9 +1262,65 @@ static void swap_active_hold(pstn_t *pstn)
|
|||
jitter_reset(&pstn->tx_dejitter);
|
||||
}
|
||||
|
||||
/* process hookflash from various events: short hangup, off-hook-pulse, pulse digit 1 ... */
|
||||
static void hookflash(pstn_t *pstn)
|
||||
{
|
||||
/* stop tone (CW tone) */
|
||||
tone_off(pstn);
|
||||
/* clear dialing */
|
||||
pstn->dialing[0] = '\0';
|
||||
/* if call on hold, swap calls */
|
||||
if (pstn->call[PSTN_CALL_HOLD]->cc_callref) {
|
||||
PDEBUG(DTEL, DEBUG_INFO, "There is a call on hold, so swap both calls.\n");
|
||||
/* swap ACTIVE call and call on HOLD */
|
||||
swap_active_hold(pstn);
|
||||
/* send notify to call on hold */
|
||||
notify_ind(pstn->call[PSTN_CALL_HOLD], OSMO_CC_NOTIFY_REMOTE_HOLD);
|
||||
/* if waiting call, answer it */
|
||||
if (pstn->call[PSTN_CALL_ACTIVE]->state != CALL_STATE_ACTIVE
|
||||
&& pstn->call[PSTN_CALL_ACTIVE]->state != CALL_STATE_HOLD) {
|
||||
/* setup confirm */
|
||||
setup_cnf(pstn, PSTN_CALL_ACTIVE);
|
||||
}
|
||||
/* change state */
|
||||
pstn_call_state(pstn->call[PSTN_CALL_ACTIVE], CALL_STATE_ACTIVE);
|
||||
pstn_call_state(pstn->call[PSTN_CALL_HOLD], CALL_STATE_HOLD);
|
||||
/* send notify to active call */
|
||||
notify_ind(pstn->call[PSTN_CALL_ACTIVE], OSMO_CC_NOTIFY_REMOTE_RETRIEVAL);
|
||||
return;
|
||||
}
|
||||
/* if active call, put it on hold and setup new call, if not en-block dialing */
|
||||
if (pstn->call[PSTN_CALL_ACTIVE]->cc_callref) {
|
||||
PDEBUG(DTEL, DEBUG_INFO, "There is an active call only, so put it on hold and start a new one.\n");
|
||||
/* swap ACTIVE call and call on HOLD */
|
||||
swap_active_hold(pstn);
|
||||
/* change state */
|
||||
pstn_call_state(pstn->call[PSTN_CALL_HOLD], CALL_STATE_HOLD);
|
||||
/* send notify to call on hold */
|
||||
notify_ind(pstn->call[PSTN_CALL_HOLD], OSMO_CC_NOTIFY_REMOTE_HOLD);
|
||||
/* start DTMF */
|
||||
dtmf_on(pstn);
|
||||
/* start pulse */
|
||||
pulse_on(pstn);
|
||||
if (!pstn->enblock) {
|
||||
/* setup */
|
||||
setup_ind(pstn, PSTN_CALL_ACTIVE, "", 0);
|
||||
} else {
|
||||
/* start dial timer */
|
||||
timer_on(pstn, DIALTONE_TO, TIMER_IDENT_DIALING);
|
||||
/* dial tone */
|
||||
tone_on(pstn, TONE_DIALTONE, "dial");
|
||||
/* change state */
|
||||
pstn_call_state(pstn->call[PSTN_CALL_ACTIVE], CALL_STATE_ENBLOCK);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void v5_sig_ind(pstn_t *pstn, uint8_t *data, int len)
|
||||
{
|
||||
osmo_cc_msg_t *new_msg;
|
||||
int pulses;
|
||||
|
||||
if (len < 3 && data[1] < 1) {
|
||||
PDEBUG(DTEL, DEBUG_ERROR, "Received short V5 signal message, ignoring!\n");
|
||||
|
@ -1277,10 +1333,10 @@ static void v5_sig_ind(pstn_t *pstn, uint8_t *data, int len)
|
|||
case PSTN_V5_STEADY_SIGNAL_OFF_HOOK:
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Received steady off-kook signal.\n");
|
||||
if (timer_running(&pstn->timer) && pstn->timer_ident == TIMER_IDENT_HOOKFLASH) {
|
||||
PDEBUG(DTEL, DEBUG_INFO, "This was short, so this was a hookflash..\n");
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Performing hookflash, because on-hook was too short for hangup.\n");
|
||||
/* stop timer */
|
||||
timer_off(pstn);
|
||||
goto hookflash;
|
||||
hookflash(pstn);
|
||||
}
|
||||
/* clear dialing */
|
||||
pstn->dialing[0] = '\0';
|
||||
|
@ -1346,60 +1402,21 @@ static void v5_sig_ind(pstn_t *pstn, uint8_t *data, int len)
|
|||
switch ((data[2] & 0x7f)) {
|
||||
case PSTN_V5_PULSED_SIGNAL_ON_HOOK:
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Received pulsed on-kook signal.\n");
|
||||
hookflash:
|
||||
/* clear dialing */
|
||||
pstn->dialing[0] = '\0';
|
||||
/* if call on hold, swap calls */
|
||||
if (pstn->call[PSTN_CALL_HOLD]->cc_callref) {
|
||||
PDEBUG(DTEL, DEBUG_INFO, "There is a call on hold, so swap both calls.\n");
|
||||
/* swap ACTIVE call and call on HOLD */
|
||||
swap_active_hold(pstn);
|
||||
/* send notify to call on hold */
|
||||
notify_ind(pstn->call[PSTN_CALL_HOLD], OSMO_CC_NOTIFY_REMOTE_HOLD);
|
||||
/* if waiting call, answer it */
|
||||
if (pstn->call[PSTN_CALL_ACTIVE]->state != CALL_STATE_ACTIVE
|
||||
&& pstn->call[PSTN_CALL_ACTIVE]->state != CALL_STATE_HOLD) {
|
||||
/* setup confirm */
|
||||
setup_cnf(pstn, PSTN_CALL_ACTIVE);
|
||||
}
|
||||
/* change state */
|
||||
pstn_call_state(pstn->call[PSTN_CALL_ACTIVE], CALL_STATE_ACTIVE);
|
||||
pstn_call_state(pstn->call[PSTN_CALL_HOLD], CALL_STATE_HOLD);
|
||||
/* send notify to active call */
|
||||
notify_ind(pstn->call[PSTN_CALL_ACTIVE], OSMO_CC_NOTIFY_REMOTE_RETRIEVAL);
|
||||
break;
|
||||
}
|
||||
/* if active call, put it on hold and setup new call, if not en-block dialing */
|
||||
if (pstn->call[PSTN_CALL_ACTIVE]->cc_callref) {
|
||||
PDEBUG(DTEL, DEBUG_INFO, "There is a only an active call, so put it on hold and start a new one.\n");
|
||||
/* swap ACTIVE call and call on HOLD */
|
||||
swap_active_hold(pstn);
|
||||
/* change state */
|
||||
pstn_call_state(pstn->call[PSTN_CALL_HOLD], CALL_STATE_HOLD);
|
||||
/* send notify to call on hold */
|
||||
notify_ind(pstn->call[PSTN_CALL_HOLD], OSMO_CC_NOTIFY_REMOTE_HOLD);
|
||||
/* start DTMF */
|
||||
dtmf_on(pstn);
|
||||
/* start pulse */
|
||||
pulse_on(pstn);
|
||||
if (!pstn->enblock) {
|
||||
/* setup */
|
||||
setup_ind(pstn, PSTN_CALL_ACTIVE, "", 0);
|
||||
} else {
|
||||
/* start dial timer */
|
||||
timer_on(pstn, DIALTONE_TO, TIMER_IDENT_DIALING);
|
||||
/* dial tone */
|
||||
tone_on(pstn, TONE_DIALTONE, "dial");
|
||||
/* change state */
|
||||
pstn_call_state(pstn->call[PSTN_CALL_ACTIVE], CALL_STATE_ENBLOCK);
|
||||
}
|
||||
break;
|
||||
if (pstn->recall && pstn->call[PSTN_CALL_ACTIVE]->state == CALL_STATE_ACTIVE) {
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Performing hookflash, on-hook pulse was received.\n");
|
||||
hookflash(pstn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PSTN_V5_IE_DIGIT_SIGNAL:
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Received digit signal.\n");
|
||||
pulses = data[2] & 0x0f;
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Received digit signal: %d pulses\n", pulses);
|
||||
if (pulses == 1 && pstn->recall && pstn->call[PSTN_CALL_ACTIVE]->state == CALL_STATE_ACTIVE) {
|
||||
PDEBUG(DTEL, DEBUG_INFO, "Performing hookflash, because digit '1' was dialled. (short hookflash)\n");
|
||||
hookflash(pstn);
|
||||
break;
|
||||
}
|
||||
if (!pstn->pulse_on)
|
||||
break;
|
||||
/* stop timer */
|
||||
|
@ -1410,7 +1427,7 @@ hookflash:
|
|||
tone_off(pstn);
|
||||
/* convert pulses -> digit */
|
||||
char called[2] = { '\0', '\0' };
|
||||
switch (data[2] & 0x0f) {
|
||||
switch (pulses) {
|
||||
case 0:
|
||||
PDEBUG(DTEL, DEBUG_ERROR, "Received 0 pulses, ignoring!\n");
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue