From 66bc2e43c8ad41c9b24c79b766e52b0cbaacafe2 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 10 Mar 2010 20:06:31 +0000 Subject: [PATCH] merged 1039:1053 openzap/trunk git-svn-id: http://svn.openzap.org/svn/openzap/branches/sangoma_boost@1054 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/freetdm/mod_freetdm/mod_freetdm.c | 112 ++++++++++++-- libs/freetdm/src/ftdm_io.c | 51 ++++++- .../src/ftmod/ftmod_analog/ftmod_analog.c | 8 + .../freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c | 13 -- .../src/ftmod/ftmod_libpri/ftmod_libpri.c | 13 -- .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 143 ++++++++++++++---- .../src/ftmod/ftmod_sangoma_boost/sigboost.h | 54 +++++-- .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 82 +++++++++- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 16 ++ libs/freetdm/src/include/freetdm.h | 19 ++- 10 files changed, 422 insertions(+), 89 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 8a19d3d725..ea59263b08 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -61,7 +61,7 @@ struct span_config { char dial_regex[256]; char fail_dial_regex[256]; char hold_music[256]; - char type[256]; + char type[256]; analog_option_t analog_options; }; @@ -133,7 +133,6 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream); void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream); - static switch_core_session_t *ftdm_channel_get_session(ftdm_channel_t *channel, int32_t id) { switch_core_session_t *session = NULL; @@ -1108,7 +1107,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi char *argv[3]; int argc = 0; const char *var; - + const char *dest_num = NULL, *callerid_num = NULL; if (!outbound_profile) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n"); @@ -1123,8 +1122,18 @@ 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 (!zstr(outbound_profile->destination_number)) { + dest_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number)); + } + if (!zstr(outbound_profile->caller_id_number)) { + callerid_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->caller_id_number)); + } + + if (!zstr(callerid_num) && !strcmp(callerid_num, "0000000000")) { + callerid_num = NULL; + } + 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; @@ -1206,15 +1215,15 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_data.dnis.plan = outbound_profile->destination_number_numplan; - -#if 0 - if (!zstr(outbound_profile->rdnis)) { - ftdm_set_string(caller_data.rdnis.digits, outbound_profile->rdnis); - } -#endif + /* blindly copy data from outbound_profile. They will be overwritten + * by calling ftdm_caller_data if needed after */ + caller_data.cid_num.type = outbound_profile->caller_ton; + caller_data.cid_num.plan = outbound_profile->caller_numplan; + caller_data.rdnis.type = outbound_profile->rdnis_ton; + caller_data.rdnis.plan = outbound_profile->rdnis_numplan; ftdm_set_string(caller_data.cid_name, outbound_profile->caller_id_name); - ftdm_set_string(caller_data.cid_num.digits, outbound_profile->caller_id_number); + ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(outbound_profile->caller_id_number)); if (group_id >= 0) { status = ftdm_channel_open_by_group(group_id, direction, &caller_data, &ftdmchan); @@ -1269,8 +1278,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi switch_channel_set_variable(channel, "freetdm_span_name", ftdmchan->span->name); switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", ftdmchan->span_id); switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", ftdmchan->chan_id); - ftdmchan->caller_data = caller_data; + ftdm_channel_set_caller_data(ftdmchan, &caller_data); caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); + caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num)); + caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, switch_str_nil(callerid_num)); switch_channel_set_caller_profile(channel, caller_profile); tech_pvt->caller_profile = caller_profile; @@ -1400,6 +1411,70 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session return FTDM_SUCCESS; } +static FIO_SIGNAL_CB_FUNCTION(on_common_signal) +{ + switch_event_t *event = NULL; + + switch (sigmsg->event_id) { + + case FTDM_SIGEVENT_ALARM_CLEAR: + case FTDM_SIGEVENT_ALARM_TRAP: + { + if (ftdm_channel_get_alarms(sigmsg->channel) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n"); + return FTDM_FAIL; + } + if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n"); + return FTDM_FAIL; + } + if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear"); + } else { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap"); + } + } + break; + default: + return FTDM_SUCCESS; + break; + } + + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", sigmsg->channel->span->name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", sigmsg->channel->span_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", sigmsg->channel->chan_id); + + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_RECOVER)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "recover"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_LOOPBACK)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "loopback"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_YELLOW)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_RED)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_BLUE)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_NOTOPEN)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "notopen"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_AIS)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_RAI)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai"); + } + if (ftdm_test_alarm_flag(sigmsg->channel, FTDM_ALARM_GENERAL)) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general"); + } + switch_event_fire(&event); + + return FTDM_BREAK; +} static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) { @@ -1682,6 +1757,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel %d\n", ftdm_signal_event2str(sigmsg->event_id), sigmsg->channel->physical_chan_id); + if (on_common_signal(sigmsg) == FTDM_BREAK) { + return FTDM_SUCCESS; + } + switch(sigmsg->event_id) { /* on_call_disconnect from the R2 side */ case FTDM_SIGEVENT_STOP: @@ -1784,6 +1863,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) ftdm_log(FTDM_LOG_DEBUG, "got clear channel sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id)); + if (on_common_signal(sigmsg) == FTDM_BREAK) { + return FTDM_SUCCESS; + } + switch(sigmsg->event_id) { case FTDM_SIGEVENT_START: { @@ -1870,6 +1953,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_analog_signal) { switch_status_t status = SWITCH_STATUS_FALSE; + if (on_common_signal(sigmsg) == FTDM_BREAK) { + return FTDM_SUCCESS; + } + switch (sigmsg->channel->type) { case FTDM_CHAN_TYPE_FXO: case FTDM_CHAN_TYPE_EM: @@ -2210,6 +2297,7 @@ static switch_status_t load_config(void) uint32_t to = 0; int q921loglevel = -1; int q931loglevel = -1; + // quick debug //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ID: '%s', Name:'%s'\n",id,name); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 2ea9ad7d77..b7d2a36e20 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -219,6 +219,53 @@ FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler = FT_DECLARE_DATA ftdm_crash_policy_t g_ftdm_crash_policy = FTDM_CRASH_NEVER; +static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t *caller_data) +{ + if (!caller_data) { + ftdm_log(FTDM_LOG_CRIT, "Error: trying to set caller data, but no caller_data!\n"); + return FTDM_FAIL; + } + + if (caller_data->cid_num.plan == FTDM_NPI_INVALID) { + caller_data->cid_num.plan = span->default_caller_data.cid_num.plan; + } + + if (caller_data->cid_num.type == FTDM_TON_INVALID) { + caller_data->cid_num.type = span->default_caller_data.cid_num.type; + } + + if (caller_data->ani.plan == FTDM_NPI_INVALID) { + caller_data->ani.plan = span->default_caller_data.ani.plan; + } + + if (caller_data->ani.type == FTDM_TON_INVALID) { + caller_data->ani.type = span->default_caller_data.ani.type; + } + + if (caller_data->rdnis.plan == FTDM_NPI_INVALID) { + caller_data->rdnis.plan = span->default_caller_data.rdnis.plan; + } + + if (caller_data->rdnis.type == FTDM_NPI_INVALID) { + caller_data->rdnis.type = span->default_caller_data.rdnis.type; + } + return FTDM_SUCCESS; +} + +FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data) +{ + ftdm_status_t err = FTDM_SUCCESS; + if (!ftdmchan) { + ftdm_log(FTDM_LOG_CRIT, "Error: trying to set caller data, but no ftdmchan!\n"); + return FTDM_FAIL; + } + if ((err = ftdm_set_caller_data(ftdmchan->span, caller_data)) != FTDM_SUCCESS) { + return err; + } + ftdmchan->caller_data = *caller_data; + return FTDM_SUCCESS; +} + FT_DECLARE_DATA ftdm_logger_t ftdm_log = null_logger; FT_DECLARE(void) ftdm_global_set_crash_policy(ftdm_crash_policy_t policy) @@ -1238,8 +1285,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc *ftdmchan = NULL; return FTDM_FAIL; } - + if (span->channel_request && !span->suggest_chan_id) { + ftdm_set_caller_data(span, caller_data); return span->channel_request(span, 0, direction, caller_data, ftdmchan); } @@ -1284,6 +1332,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc ) { if (span && span->channel_request) { + ftdm_set_caller_data(span, caller_data); status = span->channel_request(span, i, direction, caller_data, ftdmchan); break; } diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index c71b19d202..26c26e3a02 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -872,6 +872,14 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN); } } + case FTDM_OOB_ALARM_TRAP: + { + ftdm_set_flag_locked(event->channel, FTDM_CHANNEL_SUSPENDED); + } + case FTDM_OOB_ALARM_CLEAR: + { + ftdm_clear_flag_locked(event->channel, FTDM_CHANNEL_SUSPENDED); + } } end: diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index 547c6feaa0..3445599d13 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -1512,21 +1512,12 @@ 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; - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = event->channel->chan_id; - sig.span_id = event->channel->span_id; - sig.channel = event->channel; - ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n", ftdm_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, ftdm_channel_state2str(event->channel->state)); switch(event->enum_id) { case FTDM_OOB_ALARM_TRAP: { - sig.event_id = FTDM_SIGEVENT_HWSTATUS_CHANGED; - sig.raw_data = (void *)FTDM_HW_LINK_DISCONNECTED; if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) { if (event->channel->type == FTDM_CHAN_TYPE_B) { ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RESTART); @@ -1538,7 +1529,6 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_channel_get_alarms(event->channel); - 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, @@ -1551,11 +1541,8 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) alarms Cleared!\n", event->channel->span_id, event->channel->chan_id, event->channel->physical_span_id, event->channel->physical_chan_id); - sig.event_id = FTDM_SIGEVENT_HWSTATUS_CHANGED; - sig.raw_data = (void *)FTDM_HW_LINK_CONNECTED; ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED); ftdm_channel_get_alarms(event->channel); - ftdm_span_send_signal(span, &sig); } break; } diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index a3885ff856..929a874657 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -806,21 +806,12 @@ 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; - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = event->channel->chan_id; - sig.span_id = event->channel->span_id; - sig.channel = event->channel; - ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d][%d:%d] STATE [%s]\n", ftdm_oob_event2str(event->enum_id), event->enum_id, event->channel->span_id, event->channel->chan_id, ftdm_channel_state2str(event->channel->state)); switch(event->enum_id) { case FTDM_OOB_ALARM_TRAP: { - sig.event_id = FTDM_SIGEVENT_HWSTATUS_CHANGED; - sig.raw_data = (void *)FTDM_HW_LINK_CONNECTED; if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) { if (event->channel->type == FTDM_CHAN_TYPE_B) { ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RESTART); @@ -832,7 +823,6 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_channel_get_alarms(event->channel); - 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, @@ -845,11 +835,8 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) alarms Cleared!\n", event->channel->span_id, event->channel->chan_id, event->channel->physical_span_id, event->channel->physical_chan_id); - sig.event_id = FTDM_SIGEVENT_HWSTATUS_CHANGED; - sig.raw_data = (void *)FTDM_HW_LINK_CONNECTED; ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED); ftdm_channel_get_alarms(event->channel); - ftdm_span_send_signal(span, &sig); } break; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index 48b8efebaf..d60732a589 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -351,13 +351,21 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request) } ftdm_set_string(event.calling_name, caller_data->cid_name); - ftdm_set_string(event.isup_in_rdnis, caller_data->rdnis.digits); + ftdm_set_string(event.rdnis.digits, caller_data->rdnis.digits); if (strlen(caller_data->rdnis.digits)) { - event.isup_in_rdnis_size = (uint16_t)strlen(caller_data->rdnis.digits)+1; + event.rdnis.digits_count = strlen(caller_data->rdnis.digits)+1; + event.rdnis.ton = caller_data->rdnis.type; + event.rdnis.npi = caller_data->rdnis.plan; } - event.calling_number_screening_ind = caller_data->screen; - event.calling_number_presentation = caller_data->pres; + event.calling.screening_ind = caller_data->screen; + event.calling.presentation_ind = caller_data->pres; + + event.calling.ton = caller_data->cid_num.type; + event.calling.npi = caller_data->cid_num.plan; + + event.called.ton = caller_data->dnis.type; + event.called.npi = caller_data->dnis.plan; OUTBOUND_REQUESTS[r].status = BST_WAITING; OUTBOUND_REQUESTS[r].span = span; @@ -459,14 +467,23 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(sangoma_boost_outgoing_call) event.span = (uint8_t)ftdmchan->physical_span_id; event.chan = (uint8_t)ftdmchan->physical_chan_id; + ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name); - ftdm_set_string(event.isup_in_rdnis, ftdmchan->caller_data.rdnis.digits); + ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits); if (strlen(ftdmchan->caller_data.rdnis.digits)) { - event.isup_in_rdnis_size = (uint16_t)strlen(ftdmchan->caller_data.rdnis.digits)+1; + event.rdnis.digits_count = strlen(ftdmchan->caller_data.rdnis.digits)+1; + event.rdnis.ton = ftdmchan->caller_data.rdnis.type; + event.rdnis.npi = ftdmchan->caller_data.rdnis.plan; } - event.calling_number_screening_ind = ftdmchan->caller_data.screen; - event.calling_number_presentation = ftdmchan->caller_data.pres; + event.calling.screening_ind = ftdmchan->caller_data.screen; + event.calling.presentation_ind = ftdmchan->caller_data.pres; + + event.calling.ton = ftdmchan->caller_data.cid_num.type; + event.calling.npi = ftdmchan->caller_data.cid_num.plan; + + event.called.ton = ftdmchan->caller_data.dnis.type; + event.called.npi = ftdmchan->caller_data.dnis.plan; OUTBOUND_REQUESTS[r].status = BST_WAITING; OUTBOUND_REQUESTS[r].span = ftdmchan->span; @@ -866,6 +883,21 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s ftdm_channel_t *ftdmchan; if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) { + if ((ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) { + int r; + if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) { + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); + ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r); + } else if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); + ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); + } else { + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); + + } + ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); + ftdmchan=NULL; + } ftdm_log(FTDM_LOG_CRIT, "START CANT FIND CHAN %d:%d\n", event->span+1,event->chan+1); goto error; } @@ -881,35 +913,42 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s ftdmchan->physical_span_id, ftdmchan->physical_chan_id); ftdmchan->sflags = 0; - ftdm_set_string(ftdmchan->caller_data.cid_num.digits, (char *)event->calling_number_digits); - ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)event->calling_number_digits); + ftdm_set_string(ftdmchan->caller_data.cid_num.digits, (char *)event->calling.digits); + ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)event->calling.digits); + ftdm_set_string(ftdmchan->caller_data.ani.digits, (char *)event->calling.digits); + ftdm_set_string(ftdmchan->caller_data.dnis.digits, (char *)event->called.digits); + ftdm_set_string(ftdmchan->caller_data.rdnis.digits, (char *)event->rdnis.digits); + if (strlen(event->calling_name)) { ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)event->calling_name); } - ftdm_set_string(ftdmchan->caller_data.ani.digits, (char *)event->calling_number_digits); - ftdm_set_string(ftdmchan->caller_data.dnis.digits, (char *)event->called_number_digits); - if (event->isup_in_rdnis_size) { - char* p; - //Set value of rdnis.digis in case prot daemon is still using older style RDNIS - if (atoi((char *)event->isup_in_rdnis) > 0) { - ftdm_set_string(ftdmchan->caller_data.rdnis.digits, (char *)event->isup_in_rdnis); - } + ftdmchan->caller_data.cid_num.plan = event->calling.npi; + ftdmchan->caller_data.cid_num.type = event->calling.ton; - p = strstr((char*)event->isup_in_rdnis,"PRI001-ANI2-"); + ftdmchan->caller_data.ani.plan = event->calling.npi; + ftdmchan->caller_data.ani.type = event->calling.ton; + + ftdmchan->caller_data.dnis.plan = event->called.npi; + ftdmchan->caller_data.dnis.type = event->called.ton; + + ftdmchan->caller_data.rdnis.plan = event->rdnis.npi; + ftdmchan->caller_data.rdnis.type = event->rdnis.ton; + + ftdmchan->caller_data.screen = event->calling.screening_ind; + ftdmchan->caller_data.pres = event->calling.presentation_ind; + + if (event->custom_data_size) { + char* p = NULL; + + p = strstr((char*)event->custom_data,"PRI001-ANI2-"); if (p!=NULL) { int ani2 = 0; sscanf(p, "PRI001-ANI2-%d", &ani2); snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", ani2); } - p = strstr((char*)event->isup_in_rdnis,"RDNIS-"); - if (p!=NULL) { - sscanf(p, "RDNIS-%s", &ftdmchan->caller_data.rdnis.digits[0]); - } - } - ftdmchan->caller_data.screen = event->calling_number_screening_ind; - ftdmchan->caller_data.pres = event->calling_number_presentation; + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); return; @@ -2050,6 +2089,46 @@ static FIO_SPAN_GET_SIG_STATUS_FUNCTION(sangoma_boost_get_span_sig_status) return sangoma_boost_data->sigmod->get_span_sig_status(span, status); } +/* TODO: move these ones to a common private header so other ISDN mods can use them */ +static void ftdm_span_set_npi(const char *npi_string, uint8_t *target) +{ + if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) { + *target = FTDM_NPI_ISDN; + } else if (!strcasecmp(npi_string, "data")) { + *target = FTDM_NPI_DATA; + } else if (!strcasecmp(npi_string, "telex")) { + *target = FTDM_NPI_TELEX; + } else if (!strcasecmp(npi_string, "national")) { + *target = FTDM_NPI_NATIONAL; + } else if (!strcasecmp(npi_string, "private")) { + *target = FTDM_NPI_PRIVATE; + } else if (!strcasecmp(npi_string, "reserved")) { + *target = FTDM_NPI_RESERVED; + } else if (!strcasecmp(npi_string, "unknown")) { + *target = FTDM_NPI_UNKNOWN; + } else { + ftdm_log(FTDM_LOG_WARNING, "Invalid NPI value (%s)\n", npi_string); + *target = FTDM_NPI_UNKNOWN; + } +} + +static void ftdm_span_set_ton(const char *ton_string, uint8_t *target) +{ + if (!strcasecmp(ton_string, "national")) { + *target = FTDM_TON_NATIONAL; + } else if (!strcasecmp(ton_string, "international")) { + *target = FTDM_TON_INTERNATIONAL; + } else if (!strcasecmp(ton_string, "local")) { + *target = FTDM_TON_SUBSCRIBER_NUMBER; + } else if (!strcasecmp(ton_string, "unknown")) { + *target = FTDM_TON_UNKNOWN; + } else { + ftdm_log(FTDM_LOG_WARNING, "Invalid TON value (%s)\n", ton_string); + *target = FTDM_TON_UNKNOWN; + } +} + + /** * \brief Initialises an sangoma boost span from configuration variables * \param span Span to configure @@ -2096,6 +2175,18 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span) local_port = atoi(val); } else if (!strcasecmp(var, "remote_port")) { remote_port = atoi(val); + } else if (!strcasecmp(var, "outbound-called-ton")) { + ftdm_span_set_ton(val, &span->default_caller_data.dnis.type); + } else if (!strcasecmp(var, "outbound-called-npi")) { + ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan); + } else if (!strcasecmp(var, "outbound-calling-ton")) { + ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type); + } else if (!strcasecmp(var, "outbound-calling-npi")) { + ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan); + } else if (!strcasecmp(var, "outbound-rdnis-ton")) { + ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type); + } else if (!strcasecmp(var, "outbound-rdnis-npi")) { + ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan); } else if (!sigmod) { snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var); FAIL_CONFIG_RETURN(FTDM_FAIL); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h index 9c3be35260..05ca52a487 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sigboost.h @@ -14,7 +14,7 @@ #ifndef _SIGBOOST_H_ #define _SIGBOOST_H_ -#define SIGBOOST_VERSION 102 +#define SIGBOOST_VERSION 103 // handy to define integer types that actually work on both Lin and Win #include @@ -104,7 +104,12 @@ enum e_sigboost_progress_flags #define CORE_MAX_CHAN_PER_SPAN 32 #define MAX_PENDING_CALLS CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN /* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */ -#define SIZE_RDNIS 900 + +/* Should only be used by server */ +#define MAX_CALL_SETUP_ID 0xFFFF + +#define SIZE_CUSTOM 900 +#define SIZE_RDNIS SIZE_CUSTOM #pragma pack(1) @@ -113,7 +118,17 @@ typedef struct { uint8_t capability; uint8_t uil1p; -}t_sigboost_bearer; +} t_sigboost_bearer; + +typedef struct +{ + uint8_t digits_count; + char digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ + uint8_t npi; + uint8_t ton; + uint8_t screening_ind; + uint8_t presentation_ind; +}t_sigboost_digits; typedef struct { @@ -128,21 +143,30 @@ typedef struct uint8_t chan; uint32_t flags; /* struct timeval tv; */ - uint8_t called_number_digits_count; - char called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ - uint8_t calling_number_digits_count; /* it's an array */ - char calling_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */ + t_sigboost_digits called; + t_sigboost_digits calling; + t_sigboost_digits rdnis; /* ref. Q.931 Table 4-11 and Q.951 Section 3 */ - uint8_t calling_number_screening_ind; - uint8_t calling_number_presentation; char calling_name[MAX_DIALED_DIGITS + 1]; t_sigboost_bearer bearer; uint8_t hunt_group; - uint16_t isup_in_rdnis_size; - char isup_in_rdnis [SIZE_RDNIS]; /* it's a null terminated string */ + uint16_t custom_data_size; + char custom_data[SIZE_CUSTOM]; /* it's a null terminated string */ + } t_sigboost_callstart; -#define MIN_SIZE_CALLSTART_MSG sizeof(t_sigboost_callstart) - SIZE_RDNIS +#define called_number_digits_count called.digits_count +#define called_number_digits called.digits +#define calling_number_digits_count calling.digits_count +#define calling_number_digits calling.digits +#define calling_number_screening_ind calling.screening_ind +#define calling_number_presentation calling.presentation_ind + +#define isup_in_rdnis_size custom_data_size +#define isup_in_rdnis custom_data + + +#define MIN_SIZE_CALLSTART_MSG sizeof(t_sigboost_callstart) - SIZE_CUSTOM typedef struct { @@ -167,10 +191,10 @@ static __inline__ int boost_full_event(int event_id) switch (event_id) { case SIGBOOST_EVENT_CALL_START: case SIGBOOST_EVENT_DIGIT_IN: - case SIGBOOST_EVENT_CALL_PROGRESS: - return 1; + case SIGBOOST_EVENT_CALL_PROGRESS: + return 1; default: - break; + break; } return 0; diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index c7723e94a9..4ad3ea79a0 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -601,21 +601,41 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) break; case FTDM_COMMAND_ENABLE_ECHOCANCEL: { - //code me + err=sangoma_tdm_enable_hwec(ftdmchan->sockfd, &tdm_api); + if (err) { + snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed"); + return FTDM_FAIL; + } } break; case FTDM_COMMAND_DISABLE_ECHOCANCEL: { - //code me + err=sangoma_tdm_disable_hwec(ftdmchan->sockfd, &tdm_api); + if (err) { + snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed"); + return FTDM_FAIL; + } } break; case FTDM_COMMAND_ENABLE_LOOP: { - // code me +#ifdef WP_API_FEATURE_LOOP + err=sangoma_tdm_enable_loop(ftdmchan->sockfd, &tdm_api); + if (err) { + snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Loop Enable Failed"); + return FTDM_FAIL; + } +#endif } case FTDM_COMMAND_DISABLE_LOOP: { - // code me +#ifdef WP_API_FEATURE_LOOP + err=sangoma_tdm_disable_loop(ftdmchan->sockfd, &tdm_api); + if (err) { + snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Loop Disable Failed"); + return FTDM_FAIL; + } +#endif } case FTDM_COMMAND_SET_INTERVAL: { @@ -719,6 +739,9 @@ static FIO_WRITE_FUNCTION(wanpipe_write) /* Do we even need the headerframe here? on windows, we don't even pass it to the driver */ memset(&hdrframe, 0, sizeof(hdrframe)); + if (*datalen == 0) { + return FTDM_SUCCESS; + } bsent = sangoma_writemsg_tdm(ftdmchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (unsigned short)(*datalen),0); /* should we be checking if bsent == *datalen here? */ @@ -921,11 +944,38 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) } alarms = tdm_api.wp_tdm_cmd.fe_alarms; #endif + ftdmchan->alarm_flags = FTDM_ALARM_NONE; - - ftdmchan->alarm_flags = alarms ? FTDM_ALARM_RED : FTDM_ALARM_NONE; + if (alarms & WAN_TE_BIT_ALARM_RED) { + ftdmchan->alarm_flags |= FTDM_ALARM_RED; + alarms &= ~WAN_TE_BIT_ALARM_RED; + } - return FTDM_SUCCESS; + if (alarms & WAN_TE_BIT_ALARM_AIS) { + ftdmchan->alarm_flags |= FTDM_ALARM_AIS; + ftdmchan->alarm_flags |= FTDM_ALARM_BLUE; + alarms &= ~WAN_TE_BIT_ALARM_AIS; + } + + if (alarms & WAN_TE_BIT_ALARM_RAI) { + ftdmchan->alarm_flags |= FTDM_ALARM_RAI; + ftdmchan->alarm_flags |= FTDM_ALARM_YELLOW; + alarms &= ~WAN_TE_BIT_ALARM_RAI; + } + + /* still missing to map: + * FTDM_ALARM_RECOVER + * FTDM_ALARM_LOOPBACK + * FTDM_ALARM_NOTOPEN + * */ + + /* if we still have alarms that we did not map, set the general alarm */ + if (alarms) { + ftdm_log(FTDM_LOG_DEBUG, "Unmapped wanpipe alarms: %d\n", alarms); + ftdmchan->alarm_flags |= FTDM_ALARM_GENERAL; + } + + return FTDM_SUCCESS; } /** @@ -986,6 +1036,8 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) case WP_TDMAPI_EVENT_LINK_STATUS: { + ftdm_sigmsg_t sigmsg; + memset(&sigmsg, 0, sizeof(sigmsg)); switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) { case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: event_id = FTDM_OOB_ALARM_CLEAR; @@ -994,6 +1046,11 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) event_id = FTDM_OOB_ALARM_TRAP; break; }; + sigmsg.chan_id = ftdmchan->chan_id; + sigmsg.span_id = ftdmchan->span_id; + sigmsg.channel = ftdmchan; + sigmsg.event_id = (event_id == FTDM_OOB_ALARM_CLEAR) ? FTDM_SIGEVENT_ALARM_CLEAR : FTDM_SIGEVENT_ALARM_TRAP; + ftdm_span_send_signal(ftdmchan->span, &sigmsg); } break; @@ -1071,7 +1128,16 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) break; case WP_TDMAPI_EVENT_ALARM: { - event_id = FTDM_OOB_NOOP; + ftdm_log(FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm); + ftdm_sigmsg_t sigmsg; + memset(&sigmsg, 0, sizeof(sigmsg)); + /* FIXME: is this always alarm trap? what about clearing? */ + event_id = FTDM_OOB_ALARM_TRAP; + sigmsg.chan_id = ftdmchan->chan_id; + sigmsg.span_id = ftdmchan->span_id; + sigmsg.channel = ftdmchan; + sigmsg.event_id = (event_id == FTDM_OOB_ALARM_CLEAR) ? FTDM_SIGEVENT_ALARM_CLEAR : FTDM_SIGEVENT_ALARM_TRAP; + ftdm_span_send_signal(ftdmchan->span, &sigmsg); } break; default: diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 0ab9553307..c8fc9bd003 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -1027,12 +1027,28 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) break; case ZT_EVENT_ALARM: { + ftdm_sigmsg_t sigmsg; + ftdm_channel_t *ftdmchan = span->channels[i]; event_id = FTDM_OOB_ALARM_TRAP; + memset(&sigmsg, 0, sizeof(sigmsg)); + sigmsg.chan_id = ftdmchan->chan_id; + sigmsg.span_id = ftdmchan->span_id; + sigmsg.channel = ftdmchan; + sigmsg.event_id = FTDM_SIGEVENT_ALARM_TRAP; + ftdm_span_send_signal(ftdmchan->span, &sigmsg); } break; case ZT_EVENT_NOALARM: { + ftdm_sigmsg_t sigmsg; + ftdm_channel_t *ftdmchan = span->channels[i]; event_id = FTDM_OOB_ALARM_CLEAR; + memset(&sigmsg, 0, sizeof(sigmsg)); + sigmsg.chan_id = ftdmchan->chan_id; + sigmsg.span_id = ftdmchan->span_id; + sigmsg.channel = ftdmchan; + sigmsg.event_id = FTDM_SIGEVENT_ALARM_CLEAR; + ftdm_span_send_signal(ftdmchan->span, &sigmsg); } break; case ZT_EVENT_BITSCHANGED: diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 2113f1d347..aa1da3af56 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -450,9 +450,24 @@ typedef enum { FTDM_TON_NETWORK_SPECIFIC, FTDM_TON_SUBSCRIBER_NUMBER, FTDM_TON_ABBREVIATED_NUMBER, - FTDM_TON_RESERVED + FTDM_TON_RESERVED, + FTDM_TON_INVALID = 255 } ftdm_ton_t; +/** + * Numbering Plan Identification (NPI) + */ +typedef enum { + FTDM_NPI_UNKNOWN = 0, + FTDM_NPI_ISDN = 1, + FTDM_NPI_DATA = 3, + FTDM_NPI_TELEX = 4, + FTDM_NPI_NATIONAL = 8, + FTDM_NPI_PRIVATE = 9, + FTDM_NPI_RESERVED = 10, + FTDM_NPI_INVALID = 255 +} ftdm_npi_t; + typedef struct { char digits[25]; uint8_t type; @@ -605,6 +620,7 @@ struct ftdm_span { size_t dtmf_hangup_len; int suggest_chan_id; ftdm_state_map_t *state_map; + ftdm_caller_data_t default_caller_data; struct ftdm_span *next; }; @@ -801,6 +817,7 @@ FT_DECLARE(int) ftdm_load_module_assume(const char *name); FT_DECLARE(ftdm_status_t) ftdm_span_find_by_name(const char *name, ftdm_span_t **span); FT_DECLARE(char *) ftdm_api_execute(const char *type, const char *cmd); FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap); +FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data); FIO_CODEC_FUNCTION(fio_slin2ulaw); FIO_CODEC_FUNCTION(fio_ulaw2slin);