freetdm: added support for early-media-override

This commit is contained in:
David Yat Sin 2011-01-20 10:42:28 -05:00
parent 0cf1d54a05
commit 1da8339ffb
4 changed files with 63 additions and 12 deletions

View File

@ -676,6 +676,9 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm
/*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);
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
}
} else {
if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) {
/* By default, we do not send a progress indicator in the proceed */

View File

@ -112,6 +112,11 @@ typedef enum {
SNGISDN_OPT_FALSE = 2,
} sngisdn_opt_t;
typedef enum {
SNGISDN_EARLY_MEDIA_ON_PROCEED = (1 << 0),
SNGISDN_EARLY_MEDIA_ON_PROGRESS = (1 << 1),
SNGISDN_EARLY_MEDIA_ON_ALERT= (1 << 2),
} sngisdn_early_media_opt_t;
typedef enum {
SNGISDN_AVAIL_DOWN = 1,
@ -188,7 +193,8 @@ typedef struct sngisdn_span_data {
uint8_t span_id;
uint8_t tei;
uint8_t min_digits;
uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */
uint8_t trace_flags; /* TODO change to bit map of sngisdn_tracetype_t */
uint8_t early_media_flags; /* bit map of ftdm_sngisdn_early_media_opt_t */
uint8_t overlap_dial;
uint8_t setup_arb;
uint8_t facility_ie_decode;
@ -196,10 +202,10 @@ typedef struct sngisdn_span_data {
int8_t facility_timeout;
uint8_t num_local_numbers;
uint8_t ignore_cause_value;
uint8_t raw_trace_q931;
uint8_t raw_trace_q921;
uint8_t raw_trace_q931; /* TODO: combine with trace_flags */
uint8_t raw_trace_q921; /* TODO: combine with trace_flags */
uint8_t timer_t3;
uint8_t restart_opt;
uint8_t restart_opt;
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
ftdm_sched_t *sched;
ftdm_queue_t *event_queue;

View File

@ -192,6 +192,24 @@ static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span)
return FTDM_SUCCESS;
}
static ftdm_status_t parse_early_media(const char* opt, ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
if (!strcasecmp(opt, "on-proceed")) {
signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROCEED;
} else if (!strcasecmp(opt, "on-progress")) {
signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROGRESS;
} else if (!strcasecmp(opt, "on-alert")) {
signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_ALERT;
} else {
ftdm_log(FTDM_LOG_ERROR, "Unsupported early-media option %s\n", opt);
return FTDM_FAIL;
}
ftdm_log(FTDM_LOG_DEBUG, "Early media opt:0x%x\n", signal_data->early_media_flags);
return FTDM_SUCCESS;
}
static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
@ -249,6 +267,7 @@ static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span)
return FTDM_SUCCESS;
}
ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span)
{
unsigned paramindex;
@ -351,10 +370,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
parse_yesno(var, val, &signal_data->raw_trace_q931);
} else if (!strcasecmp(var, "q921-raw-trace")) {
parse_yesno(var, val, &signal_data->raw_trace_q921);
} else if (!strcasecmp(var, "early-media-override")) {
if (parse_early_media(val, span) != FTDM_SUCCESS) {
return FTDM_FAIL;
}
} else {
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
}
}
} /* for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) */
if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) {
ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name);

View File

@ -167,12 +167,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
char retrieved_str[255];
ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
/*
return values for "sng_isdn_retrieve_facility_information_following":
If there will be no information following, or fails to decode IE, returns -1
If there will be no information following, but current FACILITY IE contains a caller name, returns 0
If there will be information following, returns 1
*/
/*
return values for "sng_isdn_retrieve_facility_information_following":
If there will be no information following, or fails to decode IE, returns -1
If there will be no information following, but current FACILITY IE contains a caller name, returns 0
If there will be information following, returns 1
*/
if (ret_val == 1) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
@ -346,6 +346,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
@ -384,7 +385,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_DIALING:
case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_RINGING:
case FTDM_CHANNEL_STATE_RINGING:
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n");
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
@ -393,16 +394,34 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
}
switch (evntType) {
case MI_CALLPROC:
if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) &&
(signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROCEED)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on proceed\n");
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
}
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
}
break;
case MI_ALERTING:
if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) &&
(signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_ALERT)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on alert\n");
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
}
if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING);
}
break;
case MI_PROGRESS:
if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) &&
(signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROGRESS)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on progress\n");
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
}
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) {