提交 b814dc17 authored 作者: David Yat Sin's avatar David Yat Sin

freetdm: ISDN Changes to better match SIP-to-TDM states

上级 473a0465
...@@ -425,8 +425,11 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) ...@@ -425,8 +425,11 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
tech_pvt = switch_core_session_get_private(session); tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL); assert(tech_pvt != NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel)); assert(tech_pvt->ftdmchan != NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
...@@ -852,7 +855,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, ...@@ -852,7 +855,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
switch (msg->message_id) { switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_RINGING: case SWITCH_MESSAGE_INDICATE_RINGING:
{ {
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS); ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
} }
break; break;
case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_PROGRESS:
...@@ -935,7 +938,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio ...@@ -935,7 +938,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio
!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_EARLY_MEDIA) &&
!switch_channel_test_flag(channel, CF_RING_READY) !switch_channel_test_flag(channel, CF_RING_READY)
) { ) {
ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RING); ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
switch_channel_mark_ring_ready(channel); switch_channel_mark_ring_ready(channel);
} }
break; break;
...@@ -2133,7 +2136,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) ...@@ -2133,7 +2136,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
spanid, chanid, (uuid) ? uuid : "N/A"); spanid, chanid, (uuid) ? uuid : "N/A");
} }
} }
break; break;
case FTDM_SIGEVENT_SIGSTATUS_CHANGED: case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
{ {
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus; ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
...@@ -2141,6 +2144,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) ...@@ -2141,6 +2144,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
spanid, chanid, ftdm_signaling_status2str(sigstatus)); spanid, chanid, ftdm_signaling_status2str(sigstatus));
} }
break; break;
case FTDM_SIGEVENT_PROCEED:
case FTDM_SIGEVENT_MSG:
/* FS does not have handlers for these messages, so ignore them for now */
break;
default: default:
{ {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
......
...@@ -2033,7 +2033,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char ...@@ -2033,7 +2033,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
goto done; goto done;
} }
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
} }
...@@ -2202,14 +2201,19 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch ...@@ -2202,14 +2201,19 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
switch (indication) { switch (indication) {
/* FIXME: ring and busy cannot be used with all signaling stacks /* FIXME: ring and busy cannot be used with all signaling stacks
* (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */ * (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */
case FTDM_CHANNEL_INDICATE_RING: case FTDM_CHANNEL_INDICATE_RINGING:
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RING, 1); ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RINGING, 1);
break; break;
case FTDM_CHANNEL_INDICATE_BUSY: case FTDM_CHANNEL_INDICATE_BUSY:
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1); ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1);
break; break;
case FTDM_CHANNEL_INDICATE_PROCEED:
if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE)) {
if (ftdmchan->state == FTDM_CHANNEL_STATE_RING) {
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROCEED, 1);
}
}
break;
case FTDM_CHANNEL_INDICATE_PROGRESS: case FTDM_CHANNEL_INDICATE_PROGRESS:
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS); ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
...@@ -2217,7 +2221,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch ...@@ -2217,7 +2221,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
} }
break; break;
case FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA: case FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA:
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS); ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
...@@ -2236,7 +2239,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch ...@@ -2236,7 +2239,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
} }
break; break;
default: default:
ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Do not know how to indicate %d\n", indication); ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Do not know how to indicate %d\n", indication);
status = FTDM_FAIL; status = FTDM_FAIL;
......
...@@ -438,7 +438,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ...@@ -438,7 +438,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
{ {
if (state_counter > 5000 || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) { if (state_counter > 5000 || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) {
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_CALLERID_DETECT, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_CALLERID_DETECT, NULL);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
} }
} }
break; break;
...@@ -492,8 +492,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ...@@ -492,8 +492,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
} }
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
(ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
|| ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) { || ftdmchan->last_state >= FTDM_CHANNEL_STATE_RING)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
} else { } else {
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
...@@ -535,7 +535,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ...@@ -535,7 +535,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
} }
} }
case FTDM_CHANNEL_STATE_UP: case FTDM_CHANNEL_STATE_UP:
case FTDM_CHANNEL_STATE_IDLE: case FTDM_CHANNEL_STATE_RING:
{ {
ftdm_sleep(interval); ftdm_sleep(interval);
continue; continue;
...@@ -599,7 +599,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ...@@ -599,7 +599,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
ftdm_channel_use(ftdmchan); ftdm_channel_use(ftdmchan);
} }
break; break;
case FTDM_CHANNEL_STATE_IDLE: case FTDM_CHANNEL_STATE_RING:
{ {
ftdm_channel_use(ftdmchan); ftdm_channel_use(ftdmchan);
sig.event_id = FTDM_SIGEVENT_START; sig.event_id = FTDM_SIGEVENT_START;
...@@ -669,7 +669,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ...@@ -669,7 +669,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
continue; continue;
} }
break; break;
case FTDM_CHANNEL_STATE_RING: case FTDM_CHANNEL_STATE_RINGING:
{ {
ftdm_buffer_zero(dt_buffer); ftdm_buffer_zero(dt_buffer);
teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]); teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
...@@ -732,7 +732,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ...@@ -732,7 +732,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) { if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
last_digit = 0; last_digit = 0;
collecting = 0; collecting = 0;
} }
...@@ -890,7 +890,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ...@@ -890,7 +890,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) { if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) {
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID); ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
} else { } else {
ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_IDLE); ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RING);
} }
event->channel->ring_count = 1; event->channel->ring_count = 1;
ftdm_mutex_unlock(event->channel->mutex); ftdm_mutex_unlock(event->channel->mutex);
......
...@@ -115,7 +115,19 @@ ftdm_state_map_t sangoma_isdn_state_map = { ...@@ -115,7 +115,19 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSD_INBOUND, ZSD_INBOUND,
ZSM_UNACCEPTABLE, ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RING, FTDM_END}, {FTDM_CHANNEL_STATE_RING, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END} {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RINGING, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
}, },
{ {
ZSD_INBOUND, ZSD_INBOUND,
...@@ -189,9 +201,17 @@ ftdm_state_map_t sangoma_isdn_state_map = { ...@@ -189,9 +201,17 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSD_OUTBOUND, ZSD_OUTBOUND,
ZSM_UNACCEPTABLE, ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DIALING, FTDM_END}, {FTDM_CHANNEL_STATE_DIALING, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END} FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
FTDM_CHANNEL_STATE_DOWN, FTDM_END}
}, },
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{ {
ZSD_OUTBOUND, ZSD_OUTBOUND,
ZSM_UNACCEPTABLE, ZSM_UNACCEPTABLE,
...@@ -604,13 +624,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) ...@@ -604,13 +624,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
break; break;
case FTDM_CHANNEL_STATE_GET_CALLERID: case FTDM_CHANNEL_STATE_GET_CALLERID:
{ {
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
sngisdn_snd_proceed(ftdmchan); sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
sngisdn_snd_proceed(ftdmchan);
}
/* Wait in this state until we get FACILITY msg */ /* Wait in this state until we get FACILITY msg */
} }
break; break;
case FTDM_CHANNEL_STATE_RING: /* incoming call request */ case FTDM_CHANNEL_STATE_RING: /* incoming call request */
{ {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits);
/* we have enough information to inform FTDM of the call*/ /* we have enough information to inform FTDM of the call*/
...@@ -635,6 +657,25 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) ...@@ -635,6 +657,25 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
} }
} }
break; break;
case FTDM_CHANNEL_STATE_PROCEED:
{
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
/*OUTBOUND...so we were told by the line of this so noifiy the user*/
sigev.event_id = FTDM_SIGEVENT_PROCEED;
ftdm_span_send_signal(ftdmchan->span, &sigev);
} else {
if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED);
sngisdn_snd_proceed(ftdmchan);
}
}
}
break;
case FTDM_CHANNEL_STATE_RINGING:
{
sngisdn_snd_alert(ftdmchan, SNGISDN_PROGIND_NETE_ISDN);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS:
{ {
/*check if the channel is inbound or outbound*/ /*check if the channel is inbound or outbound*/
...@@ -642,9 +683,12 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) ...@@ -642,9 +683,12 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
/*OUTBOUND...so we were told by the line of this so noifiy the user*/ /*OUTBOUND...so we were told by the line of this so noifiy the user*/
sigev.event_id = FTDM_SIGEVENT_PROGRESS; sigev.event_id = FTDM_SIGEVENT_PROGRESS;
ftdm_span_send_signal(ftdmchan->span, &sigev); ftdm_span_send_signal(ftdmchan->span, &sigev);
} else if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { } else {
sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); /* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */
sngisdn_snd_proceed(ftdmchan); if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) {
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
sngisdn_snd_progress(ftdmchan, SNGISDN_PROGIND_NETE_ISDN);
}
} }
} }
break; break;
...@@ -654,7 +698,8 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) ...@@ -654,7 +698,8 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
ftdm_span_send_signal(ftdmchan->span, &sigev); ftdm_span_send_signal(ftdmchan->span, &sigev);
} else { } else {
sngisdn_snd_progress(ftdmchan); /* Send a progress message, indicating: In-band information/pattern available */
sngisdn_snd_progress(ftdmchan, SNGISDN_PROGIND_IB_AVAIL);
} }
} }
break; break;
...@@ -992,6 +1037,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) ...@@ -992,6 +1037,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
span->state_map = &sangoma_isdn_state_map; span->state_map = &sangoma_isdn_state_map;
ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);
ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE);
ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
span->trunk_type == FTDM_TRUNK_BRI) { span->trunk_type == FTDM_TRUNK_BRI) {
......
...@@ -75,7 +75,8 @@ typedef enum { ...@@ -75,7 +75,8 @@ typedef enum {
FLAG_DELAYED_REL = (1 << 7), FLAG_DELAYED_REL = (1 << 7),
FLAG_SENT_PROCEED = (1 << 8), FLAG_SENT_PROCEED = (1 << 8),
FLAG_SEND_DISC = (1 << 9), FLAG_SEND_DISC = (1 << 9),
FLAG_ACTIVATING = (1 << 10), /* Used for BRI only, flag is set after we request line CONNECTED */ /* Used for BRI only, flag is set after we request line CONNECTED */
FLAG_ACTIVATING = (1 << 10),
} sngisdn_flag_t; } sngisdn_flag_t;
...@@ -135,6 +136,21 @@ typedef enum { ...@@ -135,6 +136,21 @@ typedef enum {
SNGISDN_EVENT_RST_IND, SNGISDN_EVENT_RST_IND,
} ftdm_sngisdn_event_id_t; } ftdm_sngisdn_event_id_t;
typedef enum {
/* Call is not end-to-end ISDN */
SNGISDN_PROGIND_NETE_ISDN = 1,
/* Destination address is non-ISDN */
SNGISDN_PROGIND_DEST_NISDN,
/* Origination address is non-ISDN */
SNGISDN_PROGIND_ORIG_NISDN,
/* Call has returned to the ISDN */
SNGISDN_PROGIND_RET_ISDN,
/* Interworking as occured and has resulted in a telecommunication service change */
SNGISDN_PROGIND_SERV_CHANGE,
/* In-band information or an appropriate pattern is now available */
SNGISDN_PROGIND_IB_AVAIL,
} ftdm_sngisdn_progind_t;
/* Only timers that can be cancelled are listed here */ /* Only timers that can be cancelled are listed here */
#define SNGISDN_NUM_TIMERS 1 #define SNGISDN_NUM_TIMERS 1
/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */ /* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */
...@@ -181,6 +197,7 @@ typedef struct sngisdn_span_data { ...@@ -181,6 +197,7 @@ typedef struct sngisdn_span_data {
uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */ uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */
uint8_t overlap_dial; uint8_t overlap_dial;
uint8_t setup_arb; uint8_t setup_arb;
uint8_t facility_ie_decode;
uint8_t facility; uint8_t facility;
int8_t facility_timeout; int8_t facility_timeout;
uint8_t num_local_numbers; uint8_t num_local_numbers;
...@@ -288,13 +305,14 @@ void stack_pst_init(Pst *pst); ...@@ -288,13 +305,14 @@ void stack_pst_init(Pst *pst);
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan); void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan); void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan);
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan); void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan); void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan); void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind);
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan); void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan); void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare); void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
void sngisdn_snd_reset(ftdm_channel_t *ftdmchan); void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan); void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan); void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan); void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len); void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
...@@ -362,6 +380,8 @@ ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgP ...@@ -362,6 +380,8 @@ ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgP
ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb); ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb); ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display); ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
ftdm_status_t cpy_facility_ie_from_stack(ftdm_caller_data_t *ftdm, uint8_t *data, uint32_t data_len);
ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm); ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm); ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm); ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
......
...@@ -190,6 +190,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ...@@ -190,6 +190,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
signal_data->min_digits = 8; signal_data->min_digits = 8;
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT; signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
signal_data->setup_arb = SNGISDN_OPT_DEFAULT; signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
signal_data->facility_ie_decode = SNGISDN_OPT_TRUE;
signal_data->timer_t3 = 8; signal_data->timer_t3 = 8;
signal_data->link_id = span->span_id; signal_data->link_id = span->span_id;
...@@ -289,6 +290,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ...@@ -289,6 +290,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
if (signal_data->facility_timeout < 0) { if (signal_data->facility_timeout < 0) {
signal_data->facility_timeout = 0; signal_data->facility_timeout = 0;
} }
} else if (!strcasecmp(var, "facility-ie-decode")) {
if (!strcasecmp(val, "yes")) {
signal_data->facility_ie_decode = SNGISDN_OPT_TRUE;
} else if (!strcasecmp(val, "no")) {
signal_data->facility_ie_decode = SNGISDN_OPT_FALSE;
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
}
} else { } else {
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
} }
......
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
#include "ftmod_sangoma_isdn.h" #include "ftmod_sangoma_isdn.h"
static void sngisdn_set_prog_desc(ProgInd *progInd, ftdm_sngisdn_progind_t prod_ind);
static void sngisdn_set_facilityStr(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
{ {
ConEvnt conEvnt; ConEvnt conEvnt;
...@@ -138,6 +141,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) ...@@ -138,6 +141,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
cpy_redir_num_from_user(&conEvnt.redirNmb, &ftdmchan->caller_data); cpy_redir_num_from_user(&conEvnt.redirNmb, &ftdmchan->caller_data);
cpy_calling_name_from_user(&conEvnt, ftdmchan); cpy_calling_name_from_user(&conEvnt, ftdmchan);
sngisdn_set_facilityStr(ftdmchan, &conEvnt.facilityStr);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, signal_data->dchan_id, sngisdn_info->ces)) { if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
...@@ -323,14 +328,14 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan) ...@@ -323,14 +328,14 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
return; return;
} }
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan) void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
{ {
CnStEvnt cnStEvnt; CnStEvnt cnStEvnt;
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
...@@ -351,7 +356,8 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan) ...@@ -351,7 +356,8 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF; cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF; cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
cnStEvnt.progInd.progDesc.val = IN_PD_IBAVAIL;
sngisdn_set_prog_desc(&cnStEvnt.progInd, prog_ind);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) { if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) {
...@@ -360,14 +366,14 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan) ...@@ -360,14 +366,14 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
return; return;
} }
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan) void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
{ {
CnStEvnt cnStEvnt; CnStEvnt cnStEvnt;
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
...@@ -382,7 +388,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan) ...@@ -382,7 +388,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF; cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF; cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; sngisdn_set_prog_desc(&cnStEvnt.progInd, prog_ind);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
...@@ -456,6 +462,27 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) ...@@ -456,6 +462,27 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
return; return;
} }
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan)
{
FacEvnt facEvnt;
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending FACILITY, but no call data, ignoring (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
return;
}
memset(&facEvnt, 0, sizeof(facEvnt));
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, signal_data->dchan_id, sngisdn_info->ces)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused FACILITY request\n");
}
return;
}
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan) void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan)
{ {
...@@ -510,7 +537,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan) ...@@ -510,7 +537,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
...@@ -531,6 +558,8 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan) ...@@ -531,6 +558,8 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
discEvnt.causeDgn[0].recommend.pres = NOTPRSNT; discEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT; discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
sngisdn_set_facilityStr(ftdmchan, &discEvnt.facilityStr);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) { if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n"); ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n");
...@@ -575,6 +604,8 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) ...@@ -575,6 +604,8 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
spInstId = sngisdn_info->spInstId; spInstId = sngisdn_info->spInstId;
} }
sngisdn_set_facilityStr(ftdmchan, &relEvnt.facilityStr);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);
if (glare) { if (glare) {
...@@ -589,6 +620,46 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) ...@@ -589,6 +620,46 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
return; return;
} }
static void sngisdn_set_prog_desc(ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind)
{
switch(prog_ind) {
case SNGISDN_PROGIND_NETE_ISDN:
progInd->progDesc.val = IN_PD_NOTETEISDN;
break;
case SNGISDN_PROGIND_DEST_NISDN:
progInd->progDesc.val = IN_PD_DSTNOTISDN;
break;
case SNGISDN_PROGIND_ORIG_NISDN:
progInd->progDesc.val = IN_PD_ORGNOTISDN;
break;
case SNGISDN_PROGIND_RET_ISDN:
progInd->progDesc.val = IN_PD_CALLRET;
break;
case SNGISDN_PROGIND_SERV_CHANGE:
/* Trillium defines do not match ITU-T Q931 Progress descriptions,
indicate a delayed response for now */
progInd->progDesc.val = IN_PD_DELRESP;
break;
case SNGISDN_PROGIND_IB_AVAIL:
progInd->progDesc.val = IN_PD_IBAVAIL;
break;
}
return;
}
static void sngisdn_set_facilityStr(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
{
const char *facility_str = NULL;
facility_str = ftdm_channel_get_var(ftdmchan, "isdn.facility.val");
if (facility_str) {
facilityStr->eh.pres = PRSNT_NODEF;
facilityStr->facilityStr.len = strlen(facility_str);
memcpy(facilityStr->facilityStr.val, facility_str, facilityStr->facilityStr.len);
}
return;
}
/* We received an incoming frame on the d-channel, send data to the stack */ /* We received an incoming frame on the d-channel, send data to the stack */
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len) void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
{ {
......
...@@ -229,6 +229,24 @@ ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *dis ...@@ -229,6 +229,24 @@ ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *dis
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }
ftdm_status_t cpy_facility_ie_from_stack(ftdm_caller_data_t *caller_data, uint8_t *data, uint32_t data_len)
{
if (data_len > sizeof(caller_data->raw_data)-2) {
ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n");
return FTDM_FAIL;
}
memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data));
/* Always include Facility IE identifier + len so this can be used as a sanity check by the user */
caller_data->raw_data[0] = 0x1C;
caller_data->raw_data[1] = data_len;
memcpy(&caller_data->raw_data[2], data, data_len);
caller_data->raw_data_len = data_len+2;
return FTDM_SUCCESS;
}
ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm) ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
{ {
uint8_t len = strlen(ftdm->cid_num.digits); uint8_t len = strlen(ftdm->cid_num.digits);
......
...@@ -289,7 +289,8 @@ typedef enum { ...@@ -289,7 +289,8 @@ typedef enum {
FTDM_SIGEVENT_STOP, /*!< Hangup */ FTDM_SIGEVENT_STOP, /*!< Hangup */
FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */ FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */
FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */ FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */
FTDM_SIGEVENT_FLASH, /*< Flash event (typically on-hook/off-hook for analog devices) */ FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */ FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */
FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */ FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */
FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */ FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */
...@@ -299,9 +300,10 @@ typedef enum { ...@@ -299,9 +300,10 @@ typedef enum {
FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */ FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */
FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */ FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */
FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */ FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */
FTDM_SIGEVENT_MSG, /* !< We received an in-call msg */
FTDM_SIGEVENT_INVALID FTDM_SIGEVENT_INVALID
} ftdm_signal_event_t; } ftdm_signal_event_t;
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROGRESS", \ #define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \ "PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "INVALID" "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "INVALID"
...@@ -581,7 +583,7 @@ typedef enum { ...@@ -581,7 +583,7 @@ typedef enum {
* This is used during incoming calls when you want to request the signaling stack * This is used during incoming calls when you want to request the signaling stack
* to notify about indications occurring locally */ * to notify about indications occurring locally */
typedef enum { typedef enum {
FTDM_CHANNEL_INDICATE_RING, FTDM_CHANNEL_INDICATE_RINGING,
FTDM_CHANNEL_INDICATE_PROCEED, FTDM_CHANNEL_INDICATE_PROCEED,
FTDM_CHANNEL_INDICATE_PROGRESS, FTDM_CHANNEL_INDICATE_PROGRESS,
FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA,
......
...@@ -181,6 +181,8 @@ typedef enum { ...@@ -181,6 +181,8 @@ typedef enum {
* after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal * after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal
* for later delivery */ * for later delivery */
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10), FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10),
/* If this flag is set, channel will be moved to proceed state when calls goes to routing */
FTDM_SPAN_USE_PROCEED_STATE = (1 << 11),
} ftdm_span_flag_t; } ftdm_span_flag_t;
/*! \brief Channel supported features */ /*! \brief Channel supported features */
...@@ -204,6 +206,7 @@ typedef enum { ...@@ -204,6 +206,7 @@ typedef enum {
FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_DIALTONE,
FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_COLLECT,
FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_RING,
FTDM_CHANNEL_STATE_RINGING,
FTDM_CHANNEL_STATE_BUSY, FTDM_CHANNEL_STATE_BUSY,
FTDM_CHANNEL_STATE_ATTN, FTDM_CHANNEL_STATE_ATTN,
FTDM_CHANNEL_STATE_GENRING, FTDM_CHANNEL_STATE_GENRING,
...@@ -211,6 +214,7 @@ typedef enum { ...@@ -211,6 +214,7 @@ typedef enum {
FTDM_CHANNEL_STATE_GET_CALLERID, FTDM_CHANNEL_STATE_GET_CALLERID,
FTDM_CHANNEL_STATE_CALLWAITING, FTDM_CHANNEL_STATE_CALLWAITING,
FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_RESTART,
FTDM_CHANNEL_STATE_PROCEED,
FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS,
FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_UP,
...@@ -223,8 +227,8 @@ typedef enum { ...@@ -223,8 +227,8 @@ typedef enum {
FTDM_CHANNEL_STATE_INVALID FTDM_CHANNEL_STATE_INVALID
} ftdm_channel_state_t; } ftdm_channel_state_t;
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \ #define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
"RING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \ "RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
"RESTART", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \ "RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID" "HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID"
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t) FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
......
...@@ -50,7 +50,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_signal) ...@@ -50,7 +50,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_signal)
switch(sigmsg->event_id) { switch(sigmsg->event_id) {
case FTDM_SIGEVENT_START: case FTDM_SIGEVENT_START:
ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_RING); ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_RINGING);
ftdm_log(FTDM_LOG_DEBUG, "launching thread and indicating ring\n"); ftdm_log(FTDM_LOG_DEBUG, "launching thread and indicating ring\n");
ftdm_thread_create_detached(test_call, sigmsg->channel); ftdm_thread_create_detached(test_call, sigmsg->channel);
break; break;
......
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论