diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index ba34f8db86..496131a213 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -385,6 +385,10 @@ static switch_status_t channel_on_init(switch_core_session_t *session) channel = switch_core_session_get_channel(session); assert(channel != NULL); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_SUCCESS; + } /* Move channel's state machine to ROUTING */ switch_channel_set_state(channel, CS_ROUTING); @@ -462,6 +466,9 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); + if (!tech_pvt->ftdmchan) { + goto end; + } ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session)); @@ -505,6 +512,8 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) break; } + end: + switch_clear_flag_locked(tech_pvt, TFLAG_IO); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); @@ -564,6 +573,11 @@ static switch_status_t channel_send_dtmf(switch_core_session_t *session, const s tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_FALSE; + } + tmp[0] = dtmf->digit; ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_SEND_DTMF, tmp); @@ -585,11 +599,13 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch channel = switch_core_session_get_channel(session); assert(channel != NULL); - + tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - assert(tech_pvt->ftdmchan != NULL); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + return SWITCH_STATUS_FALSE; + } /* Digium Cards sometimes timeout several times in a row here. Yes, we support digium cards, ain't we nice....... @@ -597,10 +613,6 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch chunk = tech_pvt->ftdmchan->effective_interval * 2; total_to = chunk * 6; - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - return SWITCH_STATUS_FALSE; - } - top: if (switch_channel_test_flag(channel, CF_SUSPEND)) { @@ -698,7 +710,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - assert(tech_pvt->ftdmchan != NULL); + if (!tech_pvt->ftdmchan) { + return SWITCH_STATUS_FALSE; + } if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { return SWITCH_STATUS_FALSE; @@ -758,6 +772,11 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio tech_pvt = (private_t *) switch_core_session_get_private(session); assert(tech_pvt != NULL); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_FALSE; + } + ftdm_log(FTDM_LOG_DEBUG, "Got Freeswitch message in R2 channel %d [%d]\n", tech_pvt->ftdmchan->physical_chan_id, msg->message_id); @@ -817,9 +836,12 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, tech_pvt = (private_t *) switch_core_session_get_private(session); assert(tech_pvt != NULL); - assert(tech_pvt->ftdmchan != NULL); - ftdm_mutex_lock(tech_pvt->ftdmchan->mutex); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_FALSE; + } + if (tech_pvt->ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { ftdm_mutex_unlock(tech_pvt->ftdmchan->mutex); return SWITCH_STATUS_SUCCESS; @@ -875,7 +897,6 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, break; } - ftdm_mutex_unlock(tech_pvt->ftdmchan->mutex); return SWITCH_STATUS_SUCCESS; } @@ -890,6 +911,11 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio tech_pvt = (private_t *) switch_core_session_get_private(session); assert(tech_pvt != NULL); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_FALSE; + } + switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: @@ -919,6 +945,11 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio tech_pvt = (private_t *) switch_core_session_get_private(session); assert(tech_pvt != NULL); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_FALSE; + } + switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: @@ -955,12 +986,31 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s switch_status_t status; switch_channel_t *channel; const char *var; + ftdm_channel_t *ftdmchan = NULL; tech_pvt = (private_t *) switch_core_session_get_private(session); assert(tech_pvt != NULL); channel = switch_core_session_get_channel(session); + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_FALSE; + } + + if (!(ftdmchan = tech_pvt->ftdmchan)) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + return SWITCH_STATUS_FALSE; + } + + ftdm_mutex_lock(ftdmchan->mutex); + + if (!tech_pvt->ftdmchan) { + switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); + status = SWITCH_STATUS_FALSE; + goto end; + } + switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: @@ -1001,6 +1051,10 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s break; } + end: + + ftdm_mutex_unlock(ftdmchan->mutex); + return status; } @@ -1068,6 +1122,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi data = switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number); + outbound_profile->destination_number = switch_sanitize_number(outbound_profile->destination_number); + if ((argc = switch_separate_string(data, '/', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n"); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; @@ -1168,8 +1224,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } if (status != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channels available\n"); - return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; + if (caller_data.hangup_cause == SWITCH_CAUSE_NONE) { + caller_data.hangup_cause = SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; + } + return caller_data.hangup_cause; } if ((var = switch_event_get_header(var_event, "freetdm_pre_buffer_size"))) { @@ -1363,7 +1421,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) break; case FTDM_SIGEVENT_STOP: { + private_t *tech_pvt = NULL; while((session = ftdm_channel_get_session(sigmsg->channel, 0))) { + tech_pvt = switch_core_session_get_private(session); + switch_set_flag_locked(tech_pvt, TFLAG_DEAD); ftdm_channel_clear_token(sigmsg->channel, 0); channel = switch_core_session_get_channel(session); switch_channel_hangup(channel, sigmsg->channel->caller_data.hangup_cause); @@ -1440,6 +1501,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) break; case FTDM_SIGEVENT_STOP: { + private_t *tech_pvt = NULL; switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; if (sigmsg->channel->token_count) { switch_core_session_t *session_a, *session_b, *session_t = NULL; @@ -1495,6 +1557,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) } while((session = ftdm_channel_get_session(sigmsg->channel, 0))) { + tech_pvt = switch_core_session_get_private(session); + switch_set_flag_locked(tech_pvt, TFLAG_DEAD); channel = switch_core_session_get_channel(session); switch_channel_hangup(channel, cause); ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); @@ -1621,7 +1685,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) /* on_call_disconnect from the R2 side */ case FTDM_SIGEVENT_STOP: { + private_t *tech_pvt = NULL; while((session = ftdm_channel_get_session(sigmsg->channel, 0))) { + tech_pvt = switch_core_session_get_private(session); + switch_set_flag_locked(tech_pvt, TFLAG_DEAD); channel = switch_core_session_get_channel(session); switch_channel_hangup(channel, sigmsg->channel->caller_data.hangup_cause); ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); @@ -1731,7 +1798,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) case FTDM_SIGEVENT_STOP: case FTDM_SIGEVENT_RESTART: { + private_t *tech_pvt = NULL; while((session = ftdm_channel_get_session(sigmsg->channel, 0))) { + tech_pvt = switch_core_session_get_private(session); + switch_set_flag_locked(tech_pvt, TFLAG_DEAD); channel = switch_core_session_get_channel(session); switch_channel_hangup(channel, sigmsg->channel->caller_data.hangup_cause); ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); @@ -2959,6 +3029,12 @@ SWITCH_STANDARD_APP(disable_ec_function) } tech_pvt = switch_core_session_get_private(session); + + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE); + return; + } + ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOCANCEL, &x); ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOTRAIN, &x); ftdm_log(FTDM_LOG_INFO, "Echo Canceller Disabled\n"); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index a1fee89395..7c6ca108ec 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3356,6 +3356,25 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na return status; } +FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) +{ + ftdm_status_t status = FTDM_FAIL; + + if (span->signal_cb) { + if (sigmsg->channel) { + ftdm_mutex_lock(sigmsg->channel->mutex); + } + + status = span->signal_cb(sigmsg); + + if (sigmsg->channel) { + ftdm_mutex_unlock(sigmsg->channel->mutex); + } + } + + return status; +} + FT_DECLARE(ftdm_status_t) ftdm_global_init(void) { memset(&globals, 0, sizeof(globals)); diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h b/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h index 4b9f02e16c..487829fd7b 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h @@ -48,7 +48,6 @@ struct ftdm_analog_data { uint32_t max_dialstr; uint32_t digit_timeout; char hotline[FTDM_MAX_HOTLINE_STR]; - fio_signal_cb_t sig_cb; }; diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 4ef3d2a13e..c71b19d202 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -176,7 +176,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span) analog_data->flags = flags; analog_data->digit_timeout = digit_timeout; analog_data->max_dialstr = max_dialstr; - analog_data->sig_cb = sig_cb; + span->signal_cb = sig_cb; strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline)); span->signal_type = FTDM_SIGTYPE_ANALOG; span->signal_data = analog_data; @@ -481,7 +481,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) sig.event_id = FTDM_SIGEVENT_UP; } - analog_data->sig_cb(&sig); + ftdm_span_send_signal(ftdmchan->span, &sig); continue; } break; @@ -501,14 +501,14 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ftdm_set_string(ftdmchan->caller_data.dnis.digits, dtmf); } - analog_data->sig_cb(&sig); + ftdm_span_send_signal(ftdmchan->span, &sig); continue; } break; case FTDM_CHANNEL_STATE_DOWN: { sig.event_id = FTDM_SIGEVENT_STOP; - analog_data->sig_cb(&sig); + ftdm_span_send_signal(ftdmchan->span, &sig); goto done; } break; @@ -549,7 +549,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) sig.span_id = ftdmchan->span_id; sig.channel = ftdmchan; sig.event_id = FTDM_SIGEVENT_PROGRESS; - analog_data->sig_cb(&sig); + ftdm_span_send_signal(ftdmchan->span, &sig); } break; @@ -608,7 +608,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) last_digit = elapsed; sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; sig.raw_data = dtmf; - if (analog_data->sig_cb(&sig) == FTDM_BREAK) { + if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) { collecting = 0; } } @@ -654,9 +654,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) if (ftdmchan->detected_tones[i]) { ftdm_log(FTDM_LOG_DEBUG, "Detected tone %s on %d:%d\n", ftdm_tonemap2str(i), ftdmchan->span_id, ftdmchan->chan_id); sig.raw_data = &i; - if (analog_data->sig_cb) { - analog_data->sig_cb(&sig); - } + ftdm_span_send_signal(ftdmchan->span, &sig); } } @@ -843,7 +841,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP); } else { sig.event_id = FTDM_SIGEVENT_FLASH; - analog_data->sig_cb(&sig); + ftdm_span_send_signal(span, &sig); } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h b/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h index 353ea108d6..83d5bb31d9 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h @@ -51,7 +51,6 @@ struct ftdm_analog_data { uint32_t flags; uint32_t max_dialstr; uint32_t digit_timeout; - fio_signal_cb_t sig_cb; }; static void *ftdm_analog_em_run(ftdm_thread_t *me, void *obj); diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 42e1ab1ee8..bb11798c68 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -145,7 +145,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) span->start = ftdm_analog_em_start; analog_data->digit_timeout = digit_timeout; analog_data->max_dialstr = max_dialstr; - analog_data->sig_cb = sig_cb; + span->signal_cb = sig_cb; span->signal_type = FTDM_SIGTYPE_ANALOG; span->signal_data = analog_data; span->outgoing_call = analog_em_outgoing_call; @@ -349,7 +349,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) sig.event_id = FTDM_SIGEVENT_UP; - analog_data->sig_cb(&sig); + ftdm_span_send_signal(ftdmchan->span, &sig); continue; } break; @@ -370,14 +370,14 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) sig.event_id = FTDM_SIGEVENT_START; - analog_data->sig_cb(&sig); + ftdm_span_send_signal(ftdmchan->span, &sig); continue; } break; case FTDM_CHANNEL_STATE_DOWN: { sig.event_id = FTDM_SIGEVENT_STOP; - analog_data->sig_cb(&sig); + ftdm_span_send_signal(ftdmchan->span, &sig); goto done; } break; @@ -440,7 +440,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) last_digit = elapsed; sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; sig.raw_data = dtmf; - if (analog_data->sig_cb(&sig) == FTDM_BREAK) { + if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) { collecting = 0; } } @@ -480,9 +480,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) if (ftdmchan->detected_tones[i]) { ftdm_log(FTDM_LOG_DEBUG, "Detected tone %s on %d:%d\n", ftdm_tonemap2str(i), ftdmchan->span_id, ftdmchan->chan_id); sig.raw_data = &i; - if (analog_data->sig_cb) { - analog_data->sig_cb(&sig); - } + ftdm_span_send_signal(ftdmchan->span, &sig); } } diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftdm_isdn.h b/libs/freetdm/src/ftmod/ftmod_isdn/ftdm_isdn.h index d550f01557..7168abeb3b 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftdm_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftdm_isdn.h @@ -60,7 +60,6 @@ struct ftdm_isdn_data { ftdm_channel_t *dchan; ftdm_channel_t *dchans[2]; struct ftdm_sigmsg sigmsg; - fio_signal_cb_t sig_cb; uint32_t flags; int32_t mode; int32_t digit_timeout; diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index fe9009da58..547c6feaa0 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -699,7 +699,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen) sig.channel->caller_data.hangup_cause = (cause) ? cause->Value : FTDM_CAUSE_NORMAL_UNSPECIFIED; sig.event_id = FTDM_SIGEVENT_STOP; - status = isdn_data->sig_cb(&sig); + status = ftdm_span_send_signal(ftdmchan->span, &sig); ftdm_log(FTDM_LOG_DEBUG, "Received %s in state %s, requested hangup for channel %d:%d\n", what, ftdm_channel_state2str(ftdmchan->state), ftdmchan->span_id, chan_id); } @@ -1186,7 +1186,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_PROGRESS; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } else { @@ -1230,7 +1230,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_START; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } @@ -1240,7 +1240,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED; sig.event_id = FTDM_SIGEVENT_RESTART; - status = isdn_data->sig_cb(&sig); + status = ftdm_span_send_signal(ftdmchan->span, &sig); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); } break; @@ -1248,7 +1248,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } else { @@ -1268,7 +1268,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_UP; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } else { @@ -1473,7 +1473,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) ftdm_log(FTDM_LOG_DEBUG, "Terminating: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound"); sig.event_id = FTDM_SIGEVENT_STOP; - status = isdn_data->sig_cb(&sig); + status = ftdm_span_send_signal(ftdmchan->span, &sig); gen->MesType = Q931mes_RELEASE; gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1; Q931Rx43(&isdn_data->q931, (void *)gen, gen->Size); @@ -1513,7 +1513,6 @@ static __inline__ void check_state(ftdm_span_t *span) static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event) { ftdm_sigmsg_t sig; - ftdm_isdn_data_t *isdn_data = span->signal_data; memset(&sig, 0, sizeof(sig)); sig.chan_id = event->channel->chan_id; @@ -1539,7 +1538,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_channel_get_alarms(event->channel); - isdn_data->sig_cb(&sig); + ftdm_span_send_signal(span, &sig); ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) has alarms! [%s]\n", event->channel->span_id, event->channel->chan_id, event->channel->physical_span_id, event->channel->physical_chan_id, @@ -1556,7 +1555,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e sig.raw_data = (void *)FTDM_HW_LINK_CONNECTED; ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED); ftdm_channel_get_alarms(event->channel); - isdn_data->sig_cb(&sig); + ftdm_span_send_signal(span, &sig); } break; } @@ -2357,7 +2356,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_isdn_configure_span) span->start = ftdm_isdn_start; span->stop = ftdm_isdn_stop; - isdn_data->sig_cb = sig_cb; + span->signal_cb = sig_cb; isdn_data->dchans[0] = dchans[0]; isdn_data->dchans[1] = dchans[1]; isdn_data->dchan = isdn_data->dchans[0]; diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 0874bfafa1..a3885ff856 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -454,7 +454,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_PROGRESS; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } else if (call) { @@ -468,7 +468,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } else if (call) { @@ -484,7 +484,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) if (call) { pri_acknowledge(isdn_data->spri.pri, call, ftdmchan->chan_id, 0); sig.event_id = FTDM_SIGEVENT_START; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } else { @@ -497,7 +497,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED; sig.event_id = FTDM_SIGEVENT_RESTART; - status = isdn_data->sig_cb(&sig); + status = ftdm_span_send_signal(ftdmchan->span, &sig); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); } break; @@ -505,7 +505,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_UP; - if ((status = isdn_data->sig_cb(&sig) != FTDM_SUCCESS)) { + if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } else if (call) { @@ -579,7 +579,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_TERMINATING: { sig.event_id = FTDM_SIGEVENT_STOP; - status = isdn_data->sig_cb(&sig); + status = ftdm_span_send_signal(ftdmchan->span, &sig); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); } @@ -807,7 +807,6 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event) { ftdm_sigmsg_t sig; - ftdm_libpri_data_t *isdn_data = span->signal_data; memset(&sig, 0, sizeof(sig)); sig.chan_id = event->channel->chan_id; @@ -833,7 +832,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_channel_get_alarms(event->channel); - isdn_data->sig_cb(&sig); + ftdm_span_send_signal(span, &sig); ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) has alarms! [%s]\n", event->channel->span_id, event->channel->chan_id, event->channel->physical_span_id, event->channel->physical_chan_id, @@ -850,7 +849,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e sig.raw_data = (void *)FTDM_HW_LINK_CONNECTED; ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED); ftdm_channel_get_alarms(event->channel); - isdn_data->sig_cb(&sig); + ftdm_span_send_signal(span, &sig); } break; } @@ -1331,7 +1330,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_libpri_configure_span) span->start = ftdm_libpri_start; span->stop = ftdm_libpri_stop; - isdn_data->sig_cb = sig_cb; + span->signal_cb = sig_cb; //isdn_data->dchans[0] = dchans[0]; //isdn_data->dchans[1] = dchans[1]; //isdn_data->dchan = isdn_data->dchans[0]; diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h index 534bd9896b..0bf8c46817 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h @@ -55,7 +55,6 @@ struct ftdm_libpri_data { ftdm_channel_t *dchan; ftdm_channel_t *dchans[2]; struct ftdm_sigmsg sigmsg; - fio_signal_cb_t sig_cb; uint32_t flags; int32_t mode; ftdm_isdn_opts_t opts; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 4453bce887..758942452e 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -90,8 +90,6 @@ typedef struct ft_r2_conf_s { /* r2 configuration stored in span->signal_data */ typedef struct ftdm_r2_data_s { - /* signaling callback */ - fio_signal_cb_t sig_cb; /* span flags */ ftdm_r2_flag_t flags; /* openr2 handle for the R2 variant context */ @@ -253,7 +251,7 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons sigev.channel = ftdmchan; sigev.event_id = FTDM_SIGEVENT_START; - if (r2data->sig_cb(&sigev) != FTDM_SUCCESS) { + if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_NOTICE, "Failed to handle call offered on chan %d\n", openr2_chan_get_number(r2chan)); openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); @@ -323,7 +321,7 @@ static void ftdm_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_discon sigev.event_id = FTDM_SIGEVENT_STOP; r2data = ftdmchan->span->signal_data; - r2data->sig_cb(&sigev); + ftdm_span_send_signal(ftdmchan->span, &sigev); } static void ftdm_r2_on_call_end(openr2_chan_t *r2chan) @@ -377,7 +375,7 @@ static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_err sigev.event_id = FTDM_SIGEVENT_STOP; r2data = ftdmchan->span->signal_data; - r2data->sig_cb(&sigev); + ftdm_span_send_signal(ftdmchan->span, &sigev); } static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan) @@ -460,7 +458,7 @@ static int ftdm_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit) sigev.channel = ftdmchan; sigev.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; r2data = ftdmchan->span->signal_data; - if (r2data->sig_cb(&sigev) == FTDM_BREAK) { + if (ftdm_span_send_signal(ftdmchan->span, &sigev) == FTDM_BREAK) { ftdm_log(FTDM_LOG_NOTICE, "Requested to stop getting DNIS. Current DNIS = %s on chan %d\n", ftdmchan->caller_data.dnis.digits, openr2_chan_get_number(r2chan)); return OR2_STOP_DNIS_REQUEST; } @@ -884,7 +882,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_r2_configure_span) span->start = ftdm_r2_start; r2data->flags = 0; - r2data->sig_cb = sig_cb; + span->signal_cb = sig_cb; span->signal_type = FTDM_SIGTYPE_R2; span->signal_data = r2data; span->outgoing_call = r2_outgoing_call; @@ -1004,7 +1002,7 @@ static void *ftdm_r2_channel_run(ftdm_thread_t *me, void *obj) } else { ftdm_log(FTDM_LOG_DEBUG, "PROGRESS: Notifying progress in channel %d\n", ftdmchan->physical_chan_id); sigev.event_id = FTDM_SIGEVENT_PROGRESS; - if (r2data->sig_cb(&sigev) != FTDM_SUCCESS) { + if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } @@ -1027,7 +1025,7 @@ static void *ftdm_r2_channel_run(ftdm_thread_t *me, void *obj) } else { ftdm_log(FTDM_LOG_DEBUG, "UP: Notifying of call answered in channel %d\n", ftdmchan->physical_chan_id); sigev.event_id = FTDM_SIGEVENT_UP; - if (r2data->sig_cb(&sigev) != FTDM_SUCCESS) { + if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } } diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 27c13d716a..9e66d8ec53 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -285,6 +285,15 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start //} } +#ifdef LIBSANGOMA_VERSION + if (type == FTDM_CHAN_TYPE_FXS) { + if (sangoma_tdm_disable_ring_trip_detect_events(chan->sockfd, &tdm_api)) { + /* we had problems of on-hook/off-hook detection due to how ring trip events were handled + * if this fails, I believe we will still work ok as long as we dont handle them incorrectly */ + ftdm_log(FTDM_LOG_WARNING, "Failed to disable ring trip events in channel s%dc%d\n", spanno, x); + } + } +#endif #if 0 if (type == FTDM_CHAN_TYPE_FXS || type == FTDM_CHAN_TYPE_FXO) { /* Enable FLASH/Wink Events */ @@ -379,6 +388,20 @@ static FIO_CONFIGURE_FUNCTION(wanpipe_configure) } else { wp_globals.flash_ms = num; } + } else if (!strcasecmp(var, "ring_on_ms")) { + num = atoi(val); + if (num < 500 || num > 5000) { + ftdm_log(FTDM_LOG_WARNING, "invalid ring_on_ms at line %d (valid range 500 to 5000)\n", lineno); + } else { + wp_globals.ring_on_ms = num; + } + } else if (!strcasecmp(var, "ring_off_ms")) { + num = atoi(val); + if (num < 500 || num > 5000) { + ftdm_log(FTDM_LOG_WARNING, "invalid ring_off_ms at line %d (valid range 500 to 5000)\n", lineno); + } else { + wp_globals.ring_off_ms = num; + } } } @@ -1003,11 +1026,14 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP; } break; + /* + disabled this ones when configuring, we don't need them, do we? case WP_TDMAPI_EVENT_RING_TRIP_DETECT: { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK; } break; + */ case WP_TDMAPI_EVENT_RBS: { event_id = FTDM_OOB_CAS_BITS_CHANGE; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 2d3e9d861c..6c66759ef8 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -329,12 +329,12 @@ typedef enum { } ftdm_state_change_result_t; #define ftdm_set_state_r(obj, s, l, r) if ( obj->state == s ) { \ - ftdm_log(FTDM_LOG_WARNING, "Why bother changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(obj->state), ftdm_channel_state2str(s)); r = FTDM_STATE_CHANGE_SAME; \ + if (s != FTDM_CHANNEL_STATE_HANGUP) ftdm_log(FTDM_LOG_WARNING, "Why bother changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(obj->state), ftdm_channel_state2str(s)); r = FTDM_STATE_CHANGE_SAME; \ } else if (ftdm_test_flag(obj, FTDM_CHANNEL_READY)) { \ int st = obj->state; \ r = (ftdm_channel_set_state(obj, s, l) == FTDM_SUCCESS) ? FTDM_STATE_CHANGE_SUCCESS : FTDM_STATE_CHANGE_FAIL; \ if (obj->state == s) {ftdm_log(FTDM_LOG_DEBUG, "Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s));} \ - else {ftdm_log(FTDM_LOG_WARNING, "VETO Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s)); } \ + else { if (!((obj->state == FTDM_CHANNEL_STATE_HANGUP && s == FTDM_CHANNEL_STATE_TERMINATING) || (obj->state == FTDM_CHANNEL_STATE_HANGUP_COMPLETE && s == FTDM_CHANNEL_STATE_HANGUP) || (obj->state == FTDM_CHANNEL_STATE_TERMINATING && s == FTDM_CHANNEL_STATE_HANGUP))) ftdm_log(FTDM_LOG_WARNING, "VETO Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s)); } \ } @@ -584,6 +584,7 @@ struct ftdm_span { ftdm_analog_start_type_t start_type; ftdm_signal_type_t signal_type; void *signal_data; + fio_signal_cb_t signal_cb; ftdm_event_t event_header; char last_error[256]; char tone_map[FTDM_TONEMAP_INVALID+1][FTDM_TONEMAP_LEN]; @@ -792,6 +793,7 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span(const char *type, ftdm_span_t *spa FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(const char *type, ftdm_span_t *span, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *parameters); FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span); FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span); +FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg); FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len); FT_DECLARE(ftdm_status_t) ftdm_global_add_io_interface(ftdm_io_interface_t *io_interface); FT_DECLARE(int) ftdm_load_module(const char *name);