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,
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;
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;
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;
return FTDM_SUCCESS;
}
+
ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span)
{
unsigned paramindex;
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);
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");
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;
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);
}
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) {