From 1da8339ffb5719ba92ececeb27b6c335f3e6b4aa Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 20 Jan 2011 10:42:28 -0500 Subject: [PATCH] freetdm: added support for early-media-override --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 3 ++ .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 14 +++++--- .../ftmod_sangoma_isdn_cfg.c | 25 +++++++++++++- .../ftmod_sangoma_isdn_stack_hndl.c | 33 +++++++++++++++---- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index e7053c1d43..df528ae9c1 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -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 */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 58fcc07040..80dc73f0fa 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index aad68e15d1..afba96accc 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -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); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 7b7c748c7a..0b52011d42 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -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) {