From 6cbf8a0167d9a3d79ff3846e14bc90dbf4fe7371 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 10 Nov 2010 19:03:15 -0500 Subject: [PATCH] freetdm: ISDN - Changes to used ftdm IO for d-channel --- .../freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c | 1 - .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 8 +- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 168 ++++++++++++++---- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 51 +++--- .../ftmod_sangoma_isdn_cfg.c | 33 ++-- .../ftmod_sangoma_isdn_stack_cfg.c | 107 +++++------ .../ftmod_sangoma_isdn_stack_cntrl.c | 83 ++++++--- .../ftmod_sangoma_isdn_stack_hndl.c | 2 +- .../ftmod_sangoma_isdn_stack_out.c | 11 ++ .../ftmod_sangoma_isdn_stack_rcv.c | 24 ++- .../ftmod_sangoma_isdn_support.c | 35 +++- libs/freetdm/src/include/private/ftdm_core.h | 2 + libs/freetdm/src/include/private/ftdm_types.h | 3 +- 13 files changed, 369 insertions(+), 159 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index 65c9dfc11f..d64e711e73 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -53,7 +53,6 @@ //#define IODEBUG /* helper macros */ -#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP) #define FTDM_SPAN_IS_NT(x) (((ftdm_isdn_data_t *)(x)->signal_data)->mode == Q921_NT) 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 a975204b62..c9691e232b 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 @@ -1557,11 +1557,11 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name); ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits); if (strlen(ftdmchan->caller_data.rdnis.digits)) { - event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1; - event.rdnis.ton = ftdmchan->caller_data.rdnis.type; - event.rdnis.npi = ftdmchan->caller_data.rdnis.plan; + event.rdnis.digits_count = (uint8_t)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.screening_ind = ftdmchan->caller_data.screen; event.calling.presentation_ind = ftdmchan->caller_data.pres; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 22c89cb920..04c3b86c5e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -47,6 +47,8 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span); ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event); static void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan); +static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span); +static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event); static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan); static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event); @@ -56,7 +58,7 @@ static sng_isdn_event_interface_t g_sngisdn_event_interface; ftdm_sngisdn_data_t g_sngisdn_data; -extern ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); +extern ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); extern ftdm_status_t sngisdn_check_free_ids(void); ftdm_state_map_t sangoma_isdn_state_map = { @@ -238,6 +240,106 @@ static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftd } } +static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event) +{ + + switch (event) { + /* Check if the span woke up from power-saving mode */ + case FTDM_OOB_ALARM_CLEAR: + sngisdn_snd_event(span, SNG_L1EVENT_ALARM_OFF); + if (FTDM_SPAN_IS_BRI(span)) { + ftdm_channel_t *ftdmchan; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); + sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; + + if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) { + ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); + + ftdm_sched_timer(signal_data->sched, "delayed_setup", 1, sngisdn_delayed_setup, (void*) ftdmchan->call_data, NULL); + } + } + ftdm_iterator_free(chaniter); + } + break; + case FTDM_OOB_ALARM_TRAP: + sngisdn_snd_event(span, SNG_L1EVENT_ALARM_ON); + break; + default: + /* Ignore other events for now */ + break; + } +} + +static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span) +{ + ftdm_status_t ret_status; + ret_status = ftdm_span_poll_event(span, 0, NULL); + switch(ret_status) { + case FTDM_SUCCESS: + { + ftdm_event_t *event; + while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { + ftdm_sangoma_isdn_process_phy_events(span, event->enum_id); + } + } + break; + case FTDM_TIMEOUT: + /* No events pending */ + break; + default: + ftdm_log(FTDM_LOG_WARNING, "%s:Failed to poll span event\n", span->name); + } +} + +static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj) +{ + uint8_t data[1000]; + ftdm_status_t status = FTDM_SUCCESS; + ftdm_wait_flag_t wflags = FTDM_READ; + ftdm_span_t *span = (ftdm_span_t*) obj; + ftdm_channel_t *dchan = ((sngisdn_span_data_t*)span->signal_data)->dchan; + ftdm_size_t len = 0; + + + ftdm_assert(dchan, "Span does not have a dchannel"); + ftdm_channel_open_chan(dchan); + + while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) { + wflags = FTDM_READ; + status = ftdm_channel_wait(dchan, &wflags, 0); + switch(status) { + case FTDM_FAIL: + ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to wait for d-channel\n"); + break; + case FTDM_TIMEOUT: + break; + case FTDM_SUCCESS: + if ((wflags & FTDM_READ)) { + len = 1000; + status = ftdm_channel_read(dchan, data, &len); + if (status == FTDM_SUCCESS) { + sngisdn_snd_data(span, data, len); + } else { + ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n"); + } + } else { + ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Failed to poll for d-channel\n"); + } + break; + default: + ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Unhandled IO event\n"); + } + } + ftdm_channel_close(&dchan); + return NULL; +} + static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj) { ftdm_interrupt_t *ftdm_sangoma_isdn_int[2]; @@ -300,21 +402,8 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj) } /* Poll for events, e.g HW DTMF */ - ret_status = ftdm_span_poll_event(span, 0, NULL); - switch(ret_status) { - case FTDM_SUCCESS: - { - ftdm_event_t *event; - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS); - } - break; - case FTDM_TIMEOUT: - /* No events pending */ - break; - default: - ftdm_log(FTDM_LOG_WARNING, "%s:Failed to poll span event\n", span->name); - } - + ftdm_sangoma_isdn_poll_events(span); + if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) { if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) { sleep = SNGISDN_EVENT_POLL_RATE; @@ -498,8 +587,20 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) } break; case FTDM_CHANNEL_STATE_DIALING: /* outgoing call request */ - { - sngisdn_snd_setup(ftdmchan); + { + if (FTDM_SPAN_IS_BRI(ftdmchan->span) && + ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) && + ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) { + + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Line activation\n"); + sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING); + sngisdn_wake_up_phy(ftdmchan->span); + ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL); + } else { + sngisdn_snd_setup(ftdmchan); + } } break; case FTDM_CHANNEL_STATE_PROGRESS: @@ -592,7 +693,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) sngisdn_snd_release(ftdmchan, 0); if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); + sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); } } else { sngisdn_snd_disconnect(ftdmchan); @@ -747,7 +848,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status) static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) { ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id); - if (sng_isdn_stack_start(span) != FTDM_SUCCESS) { + if (sngisdn_stack_start(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name); return FTDM_FAIL; } @@ -761,6 +862,12 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) return FTDM_FAIL; } + /*start the dchan monitor thread*/ + if (ftdm_thread_create_detached(ftdm_sangoma_isdn_dchan_run, span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN d-channel Monitor Thread!\n"); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG,"Finished starting span %s\n", span->name); return FTDM_SUCCESS; } @@ -782,7 +889,7 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) ftdm_sleep(10); } - if (sng_isdn_stack_stop(span) != FTDM_SUCCESS) { + if (sngisdn_stack_stop(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name); } @@ -834,7 +941,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) return FTDM_FAIL; } - if (sng_isdn_stack_cfg(span) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Sangoma ISDN Stack configuration failed\n"); return FTDM_FAIL; } @@ -856,9 +963,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || span->trunk_type == FTDM_TRUNK_BRI) { - - ftdm_set_flag(span, FTDM_SPAN_USE_AV_RATE); - sng_isdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING); + + sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING); } /* Initialize scheduling context */ @@ -906,7 +1012,9 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) g_sngisdn_event_interface.sta.sng_q921_trc_ind = sngisdn_rcv_q921_trace; g_sngisdn_event_interface.sta.sng_q931_sta_ind = sngisdn_rcv_q931_ind; g_sngisdn_event_interface.sta.sng_q931_trc_ind = sngisdn_rcv_q931_trace; - g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind; + g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind; + + g_sngisdn_event_interface.io.sng_data_req = sngisdn_rcv_data_req; for(i=1;i<=MAX_VARIANTS;i++) { ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex); @@ -914,7 +1022,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) /* initalize sng_isdn library */ - ftdm_assert_return(!sng_isdn_init(&g_sngisdn_event_interface), FTDM_FAIL, "Failed to initialize stack\n"); + ftdm_assert_return(!sng_isdn_init(&g_sngisdn_event_interface), FTDM_FAIL, "Failed to initialize stack\n"); return FTDM_SUCCESS; } @@ -968,11 +1076,11 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) goto done; } if (!strcasecmp(trace_opt, "q921")) { - sng_isdn_activate_trace(span, SNGISDN_TRACE_Q921); + sngisdn_activate_trace(span, SNGISDN_TRACE_Q921); } else if (!strcasecmp(trace_opt, "q931")) { - sng_isdn_activate_trace(span, SNGISDN_TRACE_Q931); + sngisdn_activate_trace(span, SNGISDN_TRACE_Q931); } else if (!strcasecmp(trace_opt, "disable")) { - sng_isdn_activate_trace(span, SNGISDN_TRACE_DISABLE); + sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE); } else { stream->write_function(stream, "-ERR invalid trace option \n"); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index e84392e22a..75262c9627 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -74,6 +74,7 @@ typedef enum { FLAG_DELAYED_REL = (1 << 7), FLAG_SENT_PROCEED = (1 << 8), FLAG_SEND_DISC = (1 << 9), + FLAG_ACTIVATING = (1 << 10), /* Used for BRI only, flag is set after we request line CONNECTED */ } sngisdn_flag_t; @@ -167,6 +168,7 @@ typedef struct sngisdn_chan_data { /* Span specific data */ typedef struct sngisdn_span_data { ftdm_span_t *ftdm_span; + ftdm_channel_t *dchan; uint8_t link_id; uint8_t switchtype; uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */ @@ -181,6 +183,7 @@ typedef struct sngisdn_span_data { uint8_t facility; int8_t facility_timeout; uint8_t num_local_numbers; + uint8_t timer_t3; char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; ftdm_sched_t *sched; ftdm_queue_t *event_queue; @@ -275,7 +278,7 @@ void stack_hdr_init(Header *hdr); void stack_pst_init(Pst *pst); FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data); FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data); -FT_DECLARE_INLINE(ftdm_status_t) sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail); +FT_DECLARE_INLINE(ftdm_status_t) sngisdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail); /* Outbound Call Control functions */ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan); @@ -290,25 +293,28 @@ void sngisdn_snd_reset(ftdm_channel_t *ftdmchan); void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan); void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan); void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan); +void sngisdn_snd_data(ftdm_span_t *span, uint8_t *data, ftdm_size_t len); +void sngisdn_snd_event(ftdm_span_t *span, sng_isdn_l1_event_t l1_event); /* Inbound Call Control functions */ -void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces); -void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt); -void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt); -void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt); -void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action); -void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action); -void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action); -void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action); -void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt); -void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces); -void sngisdn_rcv_sta_cfm ( int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt); -void sngisdn_rcv_srv_ind ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_srv_cfm ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_rst_cfm ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); -void sngisdn_rcv_rst_ind ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); +void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces); +void sngisdn_rcv_con_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces); +void sngisdn_rcv_cnst_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces); +void sngisdn_rcv_disc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt); +void sngisdn_rcv_rel_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt); +void sngisdn_rcv_dat_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt); +void sngisdn_rcv_sshl_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action); +void sngisdn_rcv_sshl_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action); +void sngisdn_rcv_rmrt_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action); +void sngisdn_rcv_rmrt_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action); +void sngisdn_rcv_flc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt); +void sngisdn_rcv_fac_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces); +void sngisdn_rcv_sta_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt); +void sngisdn_rcv_srv_ind(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces); +void sngisdn_rcv_srv_cfm(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces); +void sngisdn_rcv_rst_cfm(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); +void sngisdn_rcv_rst_ind(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); +int16_t sngisdn_rcv_data_req(uint16_t spId, uint8_t *buff, uint32_t length); void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event); void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event); @@ -364,15 +370,18 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis void handle_sng_log(uint8_t level, char *fmt,...); void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status); +void sngisdn_delayed_setup(void* p_sngisdn_info); void sngisdn_delayed_release(void* p_sngisdn_info); void sngisdn_delayed_connect(void* p_sngisdn_info); void sngisdn_delayed_disconnect(void* p_sngisdn_info); void sngisdn_facility_timeout(void* p_sngisdn_info); +void sngisdn_t3_timeout(void* p_sngisdn_info); /* Stack management functions */ -ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_start(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span); +ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span); void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span); void sngisdn_print_spans(ftdm_stream_handle_t *stream); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index 64d7a2403f..43e35b6dfd 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -56,9 +56,11 @@ ftdm_status_t add_local_number(const char* val, ftdm_span_t *span) ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) { unsigned i; - + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; sngisdn_dchan_data_t *dchan_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + switch(span->trunk_type) { case FTDM_TRUNK_T1: if (!strcasecmp(switch_name, "ni2") || @@ -122,9 +124,9 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) /* add this span to its ent_cc */ signal_data->cc_id = i; - /* create a new dchan */ /* for NFAS - no-dchan on b-channels only links */ + /* create a new dchan */ /* for NFAS - no-dchan on b-channels-only links */ g_sngisdn_data.num_dchan++; - signal_data->dchan_id = g_sngisdn_data.num_dchan; + signal_data->dchan_id = g_sngisdn_data.num_dchan; dchan_data = &g_sngisdn_data.dchans[signal_data->dchan_id]; dchan_data->num_spans++; @@ -136,16 +138,23 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id); - /* Add the channels to the span */ - for (i=1;i<=span->chan_count;i++) { - unsigned chan_id; - ftdm_channel_t *ftdmchan = span->channels[i]; - /* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */ - chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id; - dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data; - dchan_data->num_chans++; + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + int32_t chan_id; + ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); + if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { + /* set the d-channel */ + signal_data->dchan = ftdmchan; + } else { + /* Add the channels to the span */ + /* NFAS is not supported on E1, so span_id will always be 1 for E1 so this will work for E1 as well */ + chan_id = ((signal_data->span_id-1)*NUM_T1_CHANNELS_PER_SPAN)+ftdmchan->physical_chan_id; + dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data; + dchan_data->num_chans++; + } } - + ftdm_iterator_free(chaniter); return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c index bb46fb7fba..eabaa7affc 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c @@ -38,52 +38,52 @@ extern ftdm_sngisdn_data_t g_sngisdn_data; uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype); -ftdm_status_t sng_isdn_cfg_phy(ftdm_span_t *span); -ftdm_status_t sng_isdn_cfg_q921(ftdm_span_t *span); -ftdm_status_t sng_isdn_cfg_q931(ftdm_span_t *span); -ftdm_status_t sng_isdn_cfg_cc(ftdm_span_t *span); +ftdm_status_t sngisdn_cfg_phy(ftdm_span_t *span); +ftdm_status_t sngisdn_cfg_q921(ftdm_span_t *span); +ftdm_status_t sngisdn_cfg_q931(ftdm_span_t *span); +ftdm_status_t sngisdn_cfg_cc(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_cfg_phy_gen(void); -ftdm_status_t sng_isdn_stack_cfg_q921_gen(void); -ftdm_status_t sng_isdn_stack_cfg_q931_gen(void); -ftdm_status_t sng_isdn_stack_cfg_cc_gen(void); +ftdm_status_t sngisdn_stack_cfg_phy_gen(void); +ftdm_status_t sngisdn_stack_cfg_q921_gen(void); +ftdm_status_t sngisdn_stack_cfg_q931_gen(void); +ftdm_status_t sngisdn_stack_cfg_cc_gen(void); -ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management); -ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management); +ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; if (!g_sngisdn_data.gen_config_done) { g_sngisdn_data.gen_config_done = 1; ftdm_log(FTDM_LOG_DEBUG, "Starting general stack configuration\n"); - if(sng_isdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) { + if(sngisdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed general physical configuration\n"); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "General stack physical done\n"); - if(sng_isdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) { + if(sngisdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n"); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "General stack q921 done\n"); - if(sng_isdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) { + if(sngisdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n"); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "General stack q931 done\n"); - if(sng_isdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) { + if(sngisdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed general CC configuration\n"); return FTDM_FAIL; } @@ -92,26 +92,26 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span) } /* TODO: for NFAS, should only call these function for spans with d-chans */ - if (sng_isdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:phy_psap configuration failed\n", span->name); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "%s:phy_psap configuration done\n", span->name); - if (sng_isdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:q921_msap configuration failed\n", span->name); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "%s:q921_msap configuration done\n", span->name); - if (sng_isdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap configuration failed\n", span->name); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap configuration done\n", span->name); if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - if (sng_isdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap management configuration failed\n", span->name); return FTDM_FAIL; } @@ -119,13 +119,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span) } - if (sng_isdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:q931_dlsap configuration failed\n", span->name); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "%s:q931_dlsap configuration done\n", span->name); - if (sng_isdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:q931_lce configuration failed\n", span->name); return FTDM_FAIL; } @@ -134,13 +134,13 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span) if (!g_sngisdn_data.ccs[signal_data->cc_id].config_done) { g_sngisdn_data.ccs[signal_data->cc_id].config_done = 1; /* if BRI, need to configure dlsap_mgmt */ - if (sng_isdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:q931_tsap configuration failed\n", span->name); return FTDM_FAIL; } ftdm_log(FTDM_LOG_DEBUG, "%s:q931_tsap configuration done\n", span->name); - if (sng_isdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) { + if (sngisdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "%s:cc_sap configuration failed\n", span->name); return FTDM_FAIL; } @@ -153,7 +153,7 @@ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span) -ftdm_status_t sng_isdn_stack_cfg_phy_gen(void) +ftdm_status_t sngisdn_stack_cfg_phy_gen(void) { /*local variables*/ L1Mngmt cfg; /*configuration structure*/ @@ -191,14 +191,11 @@ ftdm_status_t sng_isdn_stack_cfg_phy_gen(void) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span) -{ - ftdm_iterator_t *chaniter; - ftdm_iterator_t *curr; +ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) +{ L1Mngmt cfg; Pst pst; - int32_t d_channel_fd = -1; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; /* initalize the post structure */ @@ -220,25 +217,13 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span) cfg.hdr.elmId.elmnt = STPSAP; cfg.hdr.elmId.elmntInst1 = signal_data->link_id; - - - /* Find the d-channel */ - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - d_channel_fd = (int32_t)ftdmchan->sockfd; - break; - } - } - ftdm_iterator_free(chaniter); - - if(d_channel_fd < 0) { + + if (!signal_data->dchan) { ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name); return FTDM_FAIL; - } - - cfg.t.cfg.s.l1PSAP.sockfd = d_channel_fd; + } + + cfg.t.cfg.s.l1PSAP.sockfd = (int32_t)signal_data->dchan->sockfd; switch(span->trunk_type) { case FTDM_TRUNK_E1: @@ -257,7 +242,7 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span) return FTDM_FAIL; } cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id; - + if (sng_isdn_phy_config(&pst, &cfg)) { return FTDM_FAIL; } @@ -265,7 +250,7 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span) } -ftdm_status_t sng_isdn_stack_cfg_q921_gen(void) +ftdm_status_t sngisdn_stack_cfg_q921_gen(void) { BdMngmt cfg; Pst pst; @@ -308,7 +293,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span) { BdMngmt cfg; Pst pst; @@ -401,7 +386,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management) +ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management) { BdMngmt cfg; Pst pst; @@ -483,7 +468,7 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_cfg_q931_gen(void) +ftdm_status_t sngisdn_stack_cfg_q931_gen(void) { InMngmt cfg; Pst pst; @@ -538,7 +523,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_gen(void) } /* Link between CC and q931 */ -ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span) { InMngmt cfg; Pst pst; @@ -601,7 +586,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_tsap(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) { InMngmt cfg; Pst pst; @@ -851,7 +836,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) { InMngmt cfg; Pst pst; @@ -927,7 +912,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_lce(ftdm_span_t *span) } -ftdm_status_t sng_isdn_stack_cfg_cc_gen(void) +ftdm_status_t sngisdn_stack_cfg_cc_gen(void) { CcMngmt cfg; Pst pst; @@ -966,7 +951,7 @@ ftdm_status_t sng_isdn_stack_cfg_cc_gen(void) } -ftdm_status_t sng_isdn_stack_cfg_cc_sap(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span) { CcMngmt cfg; Pst pst; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c index 27c16c2a51..d8e6c8e00d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c @@ -37,27 +37,27 @@ void stack_resp_hdr_init(Header *hdr); -ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span); -ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span); +ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span); +ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span); -ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span); -ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); +ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span); +ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); -ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction); -ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction); +ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction); +ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction); extern ftdm_sngisdn_data_t g_sngisdn_data; -ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span); +ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_start(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - if (sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name); return FTDM_FAIL; } @@ -72,7 +72,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span) ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name); if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) { g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1; - if (sng_isdn_activate_cc(span) != FTDM_SUCCESS) { + if (sngisdn_activate_cc(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack CC\n", span->name); return FTDM_FAIL; } @@ -80,7 +80,7 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span) } - if (sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name); return FTDM_FAIL; } @@ -90,20 +90,20 @@ ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span) +ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span) { /* Stop L1 first, so we do not receive any more frames */ - if (sng_isdn_deactivate_phy(span) != FTDM_SUCCESS) { + if (sngisdn_deactivate_phy(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name); return FTDM_FAIL; } - if (sng_isdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name); return FTDM_FAIL; } - if (sng_isdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name); return FTDM_FAIL; } @@ -113,7 +113,7 @@ ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span) } -ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span) +ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span) { /* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */ @@ -121,7 +121,7 @@ ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span) +ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span) { L1Mngmt cntrl; Pst pst; @@ -155,8 +155,41 @@ ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span) return FTDM_SUCCESS; } +ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span) +{ + L1Mngmt cntrl; + Pst pst; -ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span) + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; + + /* initalize the post structure */ + stack_pst_init(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTL1; + + /* initalize the control structure */ + memset(&cntrl, 0, sizeof(cntrl)); + + /* initalize the control header */ + stack_hdr_init(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* configuration */ + cntrl.hdr.entId.ent = ENTL1; /* entity */ + cntrl.hdr.entId.inst = S_INST; /* instance */ + cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */ + + cntrl.t.cntrl.action = AENA; + cntrl.t.cntrl.subAction = SAELMNT; + cntrl.t.cntrl.sapId = signal_data->link_id; + + if (sng_isdn_phy_cntrl(&pst, &cntrl)) { + return FTDM_FAIL; + } + return FTDM_SUCCESS; +} + +ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span) { CcMngmt cntrl; Pst pst; @@ -190,7 +223,7 @@ ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt) +ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; switch (trace_opt) { @@ -199,7 +232,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id); sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921); - if (sng_isdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n"); } } @@ -207,7 +240,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra ftdm_log(FTDM_LOG_INFO, "s%d Disabling q931 trace\n", signal_data->link_id); sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q931); - if (sng_isdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q931(span, ADISIMM, SATRC) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q931 trace\n"); } } @@ -217,7 +250,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra ftdm_log(FTDM_LOG_INFO, "s%d Enabling q921 trace\n", signal_data->link_id); sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q921); - if (sng_isdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q921(span, AENA, SATRC) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q921 trace\n"); } } @@ -227,7 +260,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra ftdm_log(FTDM_LOG_INFO, "s%d Enabling q931 trace\n", signal_data->link_id); sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q931); - if (sng_isdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) { + if (sngisdn_cntrl_q931(span, AENA, SATRC) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "s%d Failed to enable q931 trace\n"); } } @@ -237,7 +270,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra } -ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction) +ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction) { InMngmt cntrl; Pst pst; @@ -276,7 +309,7 @@ ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t sub } -ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction) +ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction) { BdMngmt cntrl; Pst pst; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 7ca408538a..37613cc33d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -539,7 +539,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_DIALING: /* Remote side rejected our SETUP message on outbound call */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); + sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); } /* fall-through */ case FTDM_CHANNEL_STATE_PROGRESS: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 3284d54165..bf44cb2e0a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -600,6 +600,17 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) return; } +void sngisdn_snd_data(ftdm_span_t *span, uint8_t *data, ftdm_size_t len) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + sng_isdn_data_ind(signal_data->link_id, data, len); +} + +void sngisdn_snd_event(ftdm_span_t *span, sng_isdn_l1_event_t l1_event) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + sng_isdn_event_ind(signal_data->link_id, l1_event); +} /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index 5580f3a950..e7ebc8f20b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -736,7 +736,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status) DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); - sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); + sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); } else { ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", status->t.usta.suId, @@ -745,7 +745,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status) DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); - sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); + sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); } } break; @@ -866,6 +866,26 @@ end_of_trace: return; } +int16_t sngisdn_rcv_data_req(uint16_t spId, uint8_t *buff, uint32_t length) +{ + ftdm_status_t status; + ftdm_wait_flag_t flags = FTDM_WRITE; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; + ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); + + status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 10); + if (status != FTDM_SUCCESS) { + ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "transmit timed-out\n"); + return -1; + } + status = signal_data->dchan->fio->write(signal_data->dchan, buff, (ftdm_size_t*)&length); + if (status != FTDM_SUCCESS) { + ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n"); + return -1; + } + return 0; +} + void sngisdn_rcv_sng_assert(char *message) { ftdm_assert(0, message); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index f54f7db61c..a418103bed 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -137,7 +137,7 @@ FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_spInstId(int16_t cc_id, uint32_ return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) +ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) { if (span->trunk_type == FTDM_TRUNK_BRI || @@ -382,6 +382,39 @@ ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmc return FTDM_SUCCESS; } +void sngisdn_t3_timeout(void* p_sngisdn_info) +{ + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; + ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Timer T3 expired (suId:%d suInstId:%u spInstId:%u)\n", + signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); + ftdm_mutex_lock(ftdmchan->mutex); + if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)){ + /* PHY layer timed-out, need to clear the call */ + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Failed to Wake-Up line (suId:%d suInstId:%u spInstId:%u)\n", + signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); + + ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NO_ROUTE_DESTINATION; + ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); + ftdm_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + } + ftdm_mutex_unlock(ftdmchan->mutex); +} + +void sngisdn_delayed_setup(void* p_sngisdn_info) +{ + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; + ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + + ftdm_mutex_lock(ftdmchan->mutex); + sngisdn_snd_setup(ftdmchan); + ftdm_mutex_unlock(ftdmchan->mutex); + return; +} + void sngisdn_delayed_release(void* p_sngisdn_info) { sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 8bdbdd60f8..239eb4a3d9 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -222,6 +222,8 @@ extern "C" { #define ftdm_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119) +#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP) + /*! \brief Copy flags from one arbitrary object to another \command dest the object to copy the flags to diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index bddefd9be6..78ac8f63eb 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -176,10 +176,11 @@ typedef enum { FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6), FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7), FTDM_SPAN_USE_AV_RATE = (1 << 8), + FTDM_SPAN_PWR_SAVING = (1 << 9), /* If you use this flag, you MUST call ftdm_span_trigger_signals to deliver the user signals * after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal * for later delivery */ - FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 9), + FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10), } ftdm_span_flag_t; /*! \brief Channel supported features */