mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-29 14:44:17 +00:00
Merge remote branch 'fsorig/master'
This commit is contained in:
commit
f1789ed5a2
39 files changed
+947
-332
No files matched your search
@@ -46,6 +46,7 @@ typedef enum {
|
||||
struct ftdm_analog_data {
|
||||
uint32_t flags;
|
||||
uint32_t max_dialstr;
|
||||
uint32_t wait_dialtone_timeout;
|
||||
uint32_t digit_timeout;
|
||||
char hotline[FTDM_MAX_HOTLINE_STR];
|
||||
};
|
||||
|
||||
@@ -49,13 +49,16 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj);
|
||||
*/
|
||||
static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxo_outgoing_call)
|
||||
{
|
||||
ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data;
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
|
||||
ftdm_channel_clear_needed_tones(ftdmchan);
|
||||
ftdm_channel_clear_detected_tones(ftdmchan);
|
||||
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL);
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_PROGRESS_DETECT, NULL);
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_DIAL] = 1;
|
||||
if (analog_data->wait_dialtone_timeout) {
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_DIAL] = 1;
|
||||
}
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
|
||||
ftdm_thread_create_detached(ftdm_analog_channel_run, ftdmchan);
|
||||
return FTDM_SUCCESS;
|
||||
@@ -157,6 +160,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
const char *tonemap = "us";
|
||||
const char *hotline = "";
|
||||
uint32_t digit_timeout = 10;
|
||||
uint32_t wait_dialtone_timeout = 30000;
|
||||
uint32_t max_dialstr = MAX_DTMF;
|
||||
const char *var, *val;
|
||||
int *intval;
|
||||
@@ -191,6 +195,15 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
break;
|
||||
}
|
||||
digit_timeout = *intval;
|
||||
} else if (!strcasecmp(var, "wait_dialtone_timeout")) {
|
||||
if (!(intval = va_arg(ap, int *))) {
|
||||
break;
|
||||
}
|
||||
wait_dialtone_timeout = *intval;
|
||||
if (wait_dialtone_timeout < 0) {
|
||||
wait_dialtone_timeout = 0;
|
||||
}
|
||||
ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Wait dial tone ms = %d\n", wait_dialtone_timeout);
|
||||
} else if (!strcasecmp(var, "enable_callerid")) {
|
||||
if (!(val = va_arg(ap, char *))) {
|
||||
break;
|
||||
@@ -221,7 +234,6 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (digit_timeout < 2000 || digit_timeout > 10000) {
|
||||
digit_timeout = 2000;
|
||||
}
|
||||
@@ -241,6 +253,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
|
||||
span->stop = ftdm_analog_stop;
|
||||
analog_data->flags = flags;
|
||||
analog_data->digit_timeout = digit_timeout;
|
||||
analog_data->wait_dialtone_timeout = wait_dialtone_timeout;
|
||||
analog_data->max_dialstr = max_dialstr;
|
||||
span->signal_cb = sig_cb;
|
||||
strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline));
|
||||
@@ -325,6 +338,27 @@ static void send_caller_id(ftdm_channel_t *ftdmchan)
|
||||
ftdm_channel_send_fsk_data(ftdmchan, &fsk_data, -14);
|
||||
}
|
||||
|
||||
static void analog_dial(ftdm_channel_t *ftdmchan, uint32_t *state_counter, uint32_t *dial_timeout)
|
||||
{
|
||||
if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No Digits to send!\n");
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
*state_counter = 0;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_RING] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_BUSY] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL1] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL2] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL3] = 1;
|
||||
*dial_timeout = ((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Main thread function for analog channel (outgoing call)
|
||||
* \param me Current thread
|
||||
@@ -342,7 +376,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_size_t dtmf_offset = 0;
|
||||
ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data;
|
||||
ftdm_channel_t *closed_chan;
|
||||
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000;
|
||||
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout;
|
||||
ftdm_sigmsg_t sig;
|
||||
ftdm_status_t status;
|
||||
|
||||
@@ -383,7 +417,11 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
|
||||
assert(interval != 0);
|
||||
ftdm_assert(interval != 0, NULL);
|
||||
|
||||
if (!dial_timeout) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Not waiting for dial tone to dial number %s\n", ftdmchan->caller_data.dnis.digits);
|
||||
}
|
||||
|
||||
while (ftdm_running() && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
|
||||
ftdm_wait_flag_t flags = FTDM_READ;
|
||||
@@ -412,7 +450,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
} else {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_GENRING:
|
||||
@@ -730,28 +768,15 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failure indication detected!\n");
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else if (ftdmchan->detected_tones[FTDM_TONEMAP_DIAL]) {
|
||||
if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No Digits to send!\n");
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
|
||||
} else {
|
||||
state_counter = 0;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_RING] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_BUSY] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL1] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL2] = 1;
|
||||
ftdmchan->needed_tones[FTDM_TONEMAP_FAIL3] = 1;
|
||||
dial_timeout = ((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000;
|
||||
}
|
||||
}
|
||||
analog_dial(ftdmchan, &state_counter, &dial_timeout);
|
||||
} else if (ftdmchan->detected_tones[FTDM_TONEMAP_RING]) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
}
|
||||
|
||||
ftdm_channel_clear_detected_tones(ftdmchan);
|
||||
} else if (!dial_timeout) {
|
||||
/* we were requested not to wait for dial tone, we can dial immediately */
|
||||
analog_dial(ftdmchan, &state_counter, &dial_timeout);
|
||||
}
|
||||
|
||||
if ((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) || (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer))) {
|
||||
|
||||
@@ -594,9 +594,10 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
|
||||
return;
|
||||
}
|
||||
|
||||
if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d not in DOWN state, cleaning up\n",
|
||||
ftdmchan->span_id, ftdmchan->chan_id);
|
||||
ftdm_channel_get_span_id(ftdmchan),
|
||||
ftdm_channel_get_id(ftdmchan));
|
||||
|
||||
/*
|
||||
* Send hangup signal to mod_openzap
|
||||
@@ -606,7 +607,7 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
|
||||
}
|
||||
|
||||
sig.event_id = FTDM_SIGEVENT_STOP;
|
||||
isdn_data->sig_cb(&sig);
|
||||
ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig);
|
||||
|
||||
/* Release zap channel */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
@@ -640,7 +641,9 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Call setup failed on channel %d:%d\n", ftdmchan->span_id, ftdmchan->chan_id);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Call setup failed on channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(ftdmchan),
|
||||
ftdm_channel_get_id(ftdmchan));
|
||||
|
||||
/*
|
||||
* Send signal to mod_openzap
|
||||
@@ -648,7 +651,7 @@ static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *
|
||||
sig.channel->caller_data.hangup_cause = FTDM_CAUSE_NETWORK_OUT_OF_ORDER;
|
||||
|
||||
sig.event_id = FTDM_SIGEVENT_STOP;
|
||||
isdn_data->sig_cb(&sig);
|
||||
ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig);
|
||||
|
||||
/* Release zap channel */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
@@ -908,7 +911,7 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
|
||||
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(span, &sig);
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Received %s in state %s, requested hangup for channel %d:%d\n", what,
|
||||
ftdm_channel_get_state_str(ftdmchan),
|
||||
@@ -1297,6 +1300,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
Q931mes_Generic *gen = (Q931mes_Generic *) ftdmchan->caller_data.raw_data;
|
||||
ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data;
|
||||
ftdm_span_t *span = ftdm_channel_get_span(ftdmchan);
|
||||
ftdm_sigmsg_t sig;
|
||||
ftdm_status_t status;
|
||||
|
||||
@@ -1328,7 +1332,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(ftdm_channel_get_span(ftdmchan), &sig) != FTDM_SUCCESS)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
} else {
|
||||
@@ -1376,7 +1380,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(span, &sig) != FTDM_SUCCESS)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
}
|
||||
@@ -1386,7 +1390,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(span, &sig);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
break;
|
||||
@@ -1394,7 +1398,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(span, &sig) != FTDM_SUCCESS)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
} else {
|
||||
@@ -1414,7 +1418,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(span, &sig) != FTDM_SUCCESS)) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
} else {
|
||||
@@ -1635,7 +1639,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(span, &sig);
|
||||
|
||||
gen->MesType = Q931mes_RELEASE;
|
||||
gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
|
||||
@@ -1672,7 +1676,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_isdn_data_t *isdn_data = span->signal_data;
|
||||
ftdm_alarm_flag_t alarmbits;
|
||||
ftdm_sigmsg_t sig;
|
||||
|
||||
@@ -1696,7 +1699,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
||||
}
|
||||
ftdm_set_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
|
||||
ftdm_channel_get_alarms(event->channel, &alarmbits);
|
||||
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",
|
||||
ftdm_channel_get_span_id(event->channel),
|
||||
@@ -1711,7 +1714,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e
|
||||
sig.event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
|
||||
ftdm_channel_get_alarms(event->channel, &alarmbits);
|
||||
isdn_data->sig_cb(&sig);
|
||||
ftdm_span_send_signal(span, &sig);
|
||||
}
|
||||
break;
|
||||
#ifdef __BROKEN_BY_FREETDM_CONVERSION__
|
||||
@@ -2056,8 +2059,7 @@ static void *ftdm_isdn_run(ftdm_thread_t *me, void *obj)
|
||||
}
|
||||
|
||||
done:
|
||||
// ftdm_channel_close(&isdn_data->dchans[0]);
|
||||
// ftdm_channel_close(&isdn_data->dchans[1]);
|
||||
ftdm_channel_close(&isdn_data->dchan);
|
||||
ftdm_clear_flag(isdn_data, FTDM_ISDN_RUNNING);
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -2744,8 +2746,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span)
|
||||
}
|
||||
}
|
||||
|
||||
isdn_data->sig_cb = sig_cb;
|
||||
isdn_data->dchan = dchan;
|
||||
isdn_data->dchan = dchan;
|
||||
isdn_data->digit_timeout = digit_timeout;
|
||||
|
||||
Q921_InitTrunk(&isdn_data->q921,
|
||||
@@ -2787,6 +2788,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span)
|
||||
span->state_map = &isdn_state_map;
|
||||
span->signal_data = isdn_data;
|
||||
span->signal_type = FTDM_SIGTYPE_ISDN;
|
||||
span->signal_cb = sig_cb;
|
||||
span->start = ftdm_isdn_start;
|
||||
span->stop = ftdm_isdn_stop;
|
||||
span->outgoing_call = isdn_outgoing_call;
|
||||
|
||||
@@ -63,9 +63,6 @@ struct ftdm_isdn_data {
|
||||
Q921Data_t q921;
|
||||
Q931_TrunkInfo_t q931;
|
||||
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;
|
||||
|
||||
@@ -503,15 +503,9 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
ftdm_status_t status;
|
||||
ftdm_sigmsg_t sig;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n",
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- %d:%d STATE [%s]\n",
|
||||
ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan), ftdm_channel_get_state_str(chan));
|
||||
|
||||
#if 0
|
||||
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND) && !call) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "NO CALL!!!!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&sig, 0, sizeof(sig));
|
||||
sig.chan_id = ftdm_channel_get_id(chan);
|
||||
sig.span_id = ftdm_channel_get_span_id(chan);
|
||||
@@ -522,6 +516,22 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
{
|
||||
chan->call_data = NULL;
|
||||
ftdm_channel_done(chan);
|
||||
|
||||
/*
|
||||
* Close channel completely, BRI PTMP will thank us
|
||||
*/
|
||||
if (ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_channel_t *chtmp = chan;
|
||||
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -548,6 +558,10 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
} else if (call) {
|
||||
/* make sure channel is open in this state (outbound handled in on_proceeding()) */
|
||||
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_channel_open_chan(chan);
|
||||
}
|
||||
pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
|
||||
} else {
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
|
||||
@@ -557,6 +571,10 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
{
|
||||
/*
|
||||
* This needs more auditing for BRI PTMP:
|
||||
* does pri_acknowledge() steal the call from other devices?
|
||||
*/
|
||||
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
if (call) {
|
||||
pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
|
||||
@@ -588,6 +606,10 @@ static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
} else if (call) {
|
||||
/* make sure channel is open in this state (outbound handled in on_answer()) */
|
||||
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_channel_open_chan(chan);
|
||||
}
|
||||
pri_answer(isdn_data->spri.pri, call, 0, 1);
|
||||
} else {
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
|
||||
@@ -795,34 +817,113 @@ static int on_answer(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
|
||||
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->answer.channel);
|
||||
|
||||
if (chan) {
|
||||
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Call answered, opening B-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
|
||||
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Answer on channel %d:%d\n", ftdm_span_get_id(span), pevent->answer.channel);
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_UP);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Answer on channel %d:%d but it's not in the span?\n",
|
||||
ftdm_span_get_id(span), pevent->answer.channel);
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handler for libpri proceed event
|
||||
* \brief Handler for libpri proceeding event
|
||||
* \param spri Pri wrapper structure (libpri, span, dchan)
|
||||
* \param event_type Event type (unused)
|
||||
* \param pevent Event
|
||||
* \return 0
|
||||
*/
|
||||
static int on_proceed(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent)
|
||||
static int on_proceeding(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent)
|
||||
{
|
||||
ftdm_span_t *span = spri->span;
|
||||
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->answer.channel);
|
||||
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->proceeding.channel);
|
||||
|
||||
if (chan) {
|
||||
/* Open channel if inband information is available */
|
||||
if ((pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) && !ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, opening B-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
|
||||
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d but it's not in the span?\n",
|
||||
ftdm_span_get_id(span), pevent->proceeding.channel);
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handler for libpri progress event
|
||||
* \param spri Pri wrapper structure (libpri, span, dchan)
|
||||
* \param event_type Event type (unused)
|
||||
* \param pevent Event
|
||||
* \return 0
|
||||
* \note also uses pri_event->proceeding
|
||||
*/
|
||||
static int on_progress(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent)
|
||||
{
|
||||
ftdm_span_t *span = spri->span;
|
||||
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->proceeding.channel);
|
||||
|
||||
if (chan) {
|
||||
/* Open channel if inband information is available */
|
||||
if ((pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) && !ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, opening B-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
|
||||
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d but it's not in the span?\n",
|
||||
ftdm_span_get_id(span), pevent->proceeding.channel);
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -840,17 +941,37 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve
|
||||
|
||||
if (chan) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d\n", ftdm_span_get_id(span), pevent->ringing.channel);
|
||||
|
||||
/* we may get on_ringing even when we're already in FTDM_CHANNEL_STATE_PROGRESS_MEDIA */
|
||||
if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
|
||||
/* dont try to move to STATE_PROGRESS to avoid annoying veto warning */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Open channel if inband information is available */
|
||||
if ((pevent->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) && !ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, opening B-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
|
||||
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d but it's not in the span?\n",
|
||||
ftdm_span_get_id(span), pevent->ringing.channel);
|
||||
}
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -868,16 +989,42 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
|
||||
ftdm_caller_data_t *caller_data = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!chan || ftdm_channel_get_state(chan) != FTDM_CHANNEL_STATE_DOWN || ftdm_test_flag(chan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "--Duplicate Ring on channel %d:%d (ignored)\n", ftdm_span_get_id(span), pevent->ring.channel);
|
||||
if (!chan) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "-- Unable to get channel %d:%d\n", ftdm_span_get_id(span), pevent->ring.channel);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "--Failure opening channel %d:%d (ignored)\n", ftdm_span_get_id(span), pevent->ring.channel);
|
||||
if (ftdm_channel_get_state(chan) != FTDM_CHANNEL_STATE_DOWN || ftdm_test_flag(chan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "-- Duplicate Ring on channel %d:%d (ignored)\n", ftdm_span_get_id(span), pevent->ring.channel);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((pevent->ring.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
|
||||
/* Open channel if inband information is available */
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, opening B-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN) && ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
|
||||
// ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
|
||||
|
||||
ftdm_log(FTDM_LOG_WARNING, "-- Error opening channel %d:%d (ignored)\n",
|
||||
ftdm_channel_get_span_id(chan),
|
||||
ftdm_channel_get_id(chan));
|
||||
|
||||
// caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
// ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
// goto done;
|
||||
}
|
||||
} else {
|
||||
/* Reserve channel, don't open it yet */
|
||||
if (ftdm_channel_use(chan) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "-- Error reserving channel %d:%d (ignored)\n",
|
||||
ftdm_span_get_id(span), pevent->ring.channel);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_NOTICE, "-- Ring on channel %d:%d (from %s to %s)\n", ftdm_span_get_id(span), pevent->ring.channel,
|
||||
pevent->ring.callingnum, pevent->ring.callednum);
|
||||
|
||||
@@ -901,7 +1048,7 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
|
||||
}
|
||||
|
||||
// scary to trust this pointer, you'd think they would give you a copy of the call data so you own it......
|
||||
/* hurr, this valid as along as nobody releases the call */
|
||||
/* hurr, this is valid as along as nobody releases the call */
|
||||
chan->call_data = pevent->ring.call;
|
||||
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RING);
|
||||
@@ -1300,7 +1447,7 @@ static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_
|
||||
*/
|
||||
static int on_anything(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent)
|
||||
{
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Caught Event span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Caught Event span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1313,7 +1460,7 @@ static int on_anything(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
|
||||
*/
|
||||
static int on_io_fail(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent)
|
||||
{
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Caught Event span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Caught Event span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1401,8 +1548,8 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_ANY, on_anything);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RING, on_ring);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RINGING, on_ringing);
|
||||
//LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_SETUP_ACK, on_proceed);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_PROCEEDING, on_proceed);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_PROCEEDING, on_proceeding);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_PROGRESS, on_progress);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_ANSWER, on_answer);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_UP, on_dchan_up);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_DOWN, on_dchan_down);
|
||||
|
||||
@@ -889,13 +889,18 @@ static FIO_WAIT_FUNCTION(zt_wait)
|
||||
inflags |= POLLPRI;
|
||||
}
|
||||
|
||||
|
||||
pollagain:
|
||||
memset(&pfds[0], 0, sizeof(pfds[0]));
|
||||
pfds[0].fd = ftdmchan->sockfd;
|
||||
pfds[0].events = inflags;
|
||||
result = poll(pfds, 1, to);
|
||||
*flags = 0;
|
||||
|
||||
if (result < 0 && errno == EINTR) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DAHDI wait got interrupted, trying again\n");
|
||||
goto pollagain;
|
||||
}
|
||||
|
||||
if (pfds[0].revents & POLLERR) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "DAHDI device got POLLERR\n");
|
||||
result = -1;
|
||||
|
||||
Reference in new issue
Block a user