diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 1ede703a41..15e853236d 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -56,6 +56,9 @@ #define FTDM_READ_TRACE_INDEX 0 #define FTDM_WRITE_TRACE_INDEX 1 +ftdm_time_t time_last_throttle_log = 0; +ftdm_time_t time_current_throttle_log = 0; + static int time_is_init = 0; static void time_init(void) 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 98b09e9305..5142de5211 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 @@ -242,10 +242,10 @@ 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) { + sngisdn_snd_event(span, 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; sngisdn_chan_data_t *sngisdn_info; @@ -267,9 +267,6 @@ static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_eve 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; @@ -327,7 +324,7 @@ static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj) len = 1000; status = ftdm_channel_read(dchan, data, &len); if (status == FTDM_SUCCESS) { - sngisdn_snd_data(span, data, len); + sngisdn_snd_data(dchan, data, len); } else { ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n"); } @@ -1019,7 +1016,8 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) 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.io.sng_data_req = sngisdn_rcv_data_req; + g_sngisdn_event_interface.io.sng_l1_data_req = sngisdn_rcv_l1_data_req; + g_sngisdn_event_interface.io.sng_l1_cmd_req = sngisdn_rcv_l1_cmd_req; for(i=1;i<=MAX_VARIANTS;i++) { ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex); 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 75262c9627..7c66c38acf 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 @@ -293,8 +293,8 @@ 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); +void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len); +void sngisdn_snd_event(ftdm_channel_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); @@ -314,7 +314,9 @@ 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); +int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_isdn_l1_frame_t *l1_frame); +int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd); + void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event); void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event); 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 eabaa7affc..6c75fb3a81 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 @@ -156,34 +156,34 @@ ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) ftdm_status_t sngisdn_stack_cfg_phy_gen(void) { /*local variables*/ - L1Mngmt cfg; /*configuration structure*/ - Pst pst; /*post structure*/ + L1Mngmt cfg; /*configuration structure*/ + Pst pst; /*post structure*/ - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTL1; + /* insert the destination Entity */ + pst.dstEnt = ENTL1; - /*clear the configuration structure*/ + /*clear the configuration structure*/ memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + /*fill in some general sections of the header*/ + stack_hdr_init(&cfg.hdr); - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTL1; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; + /*fill in the specific fields of the header*/ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTL1; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STGEN; - stack_pst_init(&cfg.t.cfg.s.l1Gen.sm ); - cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1; - cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM; + stack_pst_init(&cfg.t.cfg.s.l1Gen.sm ); + cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1; + cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM; - cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS+1; - cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */ - cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ + cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS; + cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */ + cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ if (sng_isdn_phy_config(&pst, &cfg)) { return FTDM_FAIL; @@ -193,38 +193,38 @@ ftdm_status_t sngisdn_stack_cfg_phy_gen(void) ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) { - L1Mngmt cfg; - Pst pst; + L1Mngmt cfg; + Pst pst; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTL1; + /* insert the destination Entity */ + pst.dstEnt = ENTL1; - /*clear the configuration structure*/ + /*clear the configuration structure*/ memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + /*fill in some general sections of the header*/ + stack_hdr_init(&cfg.hdr); - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTL1; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STPSAP; + /*fill in the specific fields of the header*/ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTL1; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STPSAP; cfg.hdr.elmId.elmntInst1 = signal_data->link_id; - + 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 = (int32_t)signal_data->dchan->sockfd; - + switch(span->trunk_type) { case FTDM_TRUNK_E1: cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI; @@ -240,9 +240,9 @@ ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) default: ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type); return FTDM_FAIL; - } - cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id; - + } + cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id; + if (sng_isdn_phy_config(&pst, &cfg)) { return FTDM_FAIL; } @@ -253,25 +253,25 @@ ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) ftdm_status_t sngisdn_stack_cfg_q921_gen(void) { BdMngmt cfg; - Pst pst; + Pst pst; - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); /* insert the destination Entity */ - pst.dstEnt = ENTLD; + pst.dstEnt = ENTLD; - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); + /*clear the configuration structure*/ + memset(&cfg, 0, sizeof(cfg)); /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTLD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - /* fill in the Gen Conf structures internal pst struct */ + stack_hdr_init(&cfg.hdr); - stack_pst_init(&cfg.t.cfg.s.bdGen.sm); + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTLD; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STGEN; + /* fill in the Gen Conf structures internal pst struct */ + + stack_pst_init(&cfg.t.cfg.s.bdGen.sm); cfg.t.cfg.s.bdGen.sm.dstEnt = ENTSM; /* entity */ @@ -284,8 +284,8 @@ ftdm_status_t sngisdn_stack_cfg_q921_gen(void) #ifdef LAPD_3_4 cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */ #endif - cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */ - cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */ + cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */ + cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */ if (sng_isdn_q921_config(&pst, &cfg)) { return FTDM_FAIL; @@ -296,27 +296,27 @@ ftdm_status_t sngisdn_stack_cfg_q921_gen(void) ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span) { BdMngmt cfg; - Pst pst; + Pst pst; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); /* insert the destination Entity */ - pst.dstEnt = ENTLD; + pst.dstEnt = ENTLD; - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); + /*clear the configuration structure*/ + memset(&cfg, 0, sizeof(cfg)); /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + stack_hdr_init(&cfg.hdr); cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTLD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STMSAP; + cfg.hdr.entId.ent = ENTLD; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STMSAP; cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id; - + cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */ cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */ cfg.t.cfg.s.bdMSAP.tQLowerTrs = 24; /* Tx Queue Lower Threshold */ @@ -328,7 +328,7 @@ ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span) cfg.t.cfg.s.bdMSAP.route = RTESPEC; /* Route */ cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */ cfg.t.cfg.s.bdMSAP.dstEnt = ENTL1; /* entity */ - cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */ + cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */ cfg.t.cfg.s.bdMSAP.t201Tmr = 1; /* T201 - should be equal to t200Tmr */ cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */ cfg.t.cfg.s.bdMSAP.bndRetryCnt = 2; /* bind retry counter */ @@ -377,7 +377,7 @@ ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span) if (signal_data->setup_arb == SNGISDN_OPT_TRUE) { cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE; } else if (signal_data->setup_arb == SNGISDN_OPT_FALSE) { - cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE; + cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE; } if (sng_isdn_q921_config(&pst, &cfg)) { @@ -389,24 +389,24 @@ 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) { BdMngmt cfg; - Pst pst; + Pst pst; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); /* insert the destination Entity */ - pst.dstEnt = ENTLD; + pst.dstEnt = ENTLD; - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); + /*clear the configuration structure*/ + memset(&cfg, 0, sizeof(cfg)); /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + stack_hdr_init(&cfg.hdr); /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTLD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLSAP; + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTLD; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STDLSAP; cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id; @@ -418,10 +418,10 @@ ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management } else { cfg.t.cfg.s.bdDLSAP.k = 7; /* k */ } - + cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */ cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */ - cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */ + cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */ cfg.t.cfg.s.bdDLSAP.t203Tmr = 10; /* t3 changed from 50 */ cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */ cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */ @@ -471,28 +471,28 @@ ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management ftdm_status_t sngisdn_stack_cfg_q931_gen(void) { InMngmt cfg; - Pst pst; + Pst pst; - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTIN; + /* insert the destination Entity */ + pst.dstEnt = ENTIN; - /*clear the configuration structure*/ + /*clear the configuration structure*/ memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + /*fill in some general sections of the header*/ + stack_hdr_init(&cfg.hdr); - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; + /*fill in the specific fields of the header*/ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTIN; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STGEN; - /* fill in the Gen Conf structures internal pst struct */ - stack_pst_init(&cfg.t.cfg.s.inGen.sm); + /* fill in the Gen Conf structures internal pst struct */ + stack_pst_init(&cfg.t.cfg.s.inGen.sm); cfg.t.cfg.s.inGen.nmbSaps = MAX_VARIANTS+1; /* Total number of variants supported */ @@ -526,26 +526,26 @@ ftdm_status_t sngisdn_stack_cfg_q931_gen(void) ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span) { InMngmt cfg; - Pst pst; + Pst pst; unsigned i; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTIN; + /* insert the destination Entity */ + pst.dstEnt = ENTIN; - /*clear the configuration structure*/ + /*clear the configuration structure*/ memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + /*fill in some general sections of the header*/ + stack_hdr_init(&cfg.hdr); - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STTSAP; + /*fill in the specific fields of the header*/ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTIN; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STTSAP; cfg.t.cfg.s.inTSAP.sapId = signal_data->cc_id; @@ -589,31 +589,31 @@ ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span) ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) { InMngmt cfg; - Pst pst; + Pst pst; unsigned i; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTIN; + /* insert the destination Entity */ + pst.dstEnt = ENTIN; - /*clear the configuration structure*/ + /*clear the configuration structure*/ memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + /*fill in some general sections of the header*/ + stack_hdr_init(&cfg.hdr); + + /*fill in the specific fields of the header*/ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTIN; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STDLSAP; - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLSAP; - cfg.hdr.response.selector=0; - + cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id; cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id; cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); @@ -659,7 +659,7 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1; } - cfg.t.cfg.s.inDLSAP.numRstInd = 255; + cfg.t.cfg.s.inDLSAP.numRstInd = 255; cfg.t.cfg.s.inDLSAP.relOpt = TRUE; #ifdef ISDN_SRV cfg.t.cfg.s.inDLSAP.bcas = FALSE; @@ -839,36 +839,36 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) { InMngmt cfg; - Pst pst; + Pst pst; uint8_t i; - uint8_t numCes=1; + uint8_t numCes=1; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && signal_data->signalling == SNGISDN_SIGNALING_NET) { numCes = 8; } - /* initalize the post structure */ - stack_pst_init(&pst); + /* initalize the post structure */ + stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTIN; + /* insert the destination Entity */ + pst.dstEnt = ENTIN; - /*clear the configuration structure*/ + /*clear the configuration structure*/ memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); + /*fill in some general sections of the header*/ + stack_hdr_init(&cfg.hdr); - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLC; + /*fill in the specific fields of the header*/ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTIN; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STDLC; cfg.hdr.response.selector=0; cfg.t.cfg.s.inLCe.sapId = signal_data->link_id; - + cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE; cfg.t.cfg.s.inLCe.tCon.enb = TRUE; @@ -877,7 +877,7 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) cfg.t.cfg.s.inLCe.tDisc.val = 35; cfg.t.cfg.s.inLCe.t314.enb = FALSE; /* if segmentation enabled, set to TRUE */ cfg.t.cfg.s.inLCe.t314.val = 35; - + cfg.t.cfg.s.inLCe.t332i.enb = FALSE; /* set to TRUE for NFAS */ #ifdef NFAS @@ -897,7 +897,6 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) cfg.t.cfg.s.inLCe.tRstAck.enb = TRUE; cfg.t.cfg.s.inLCe.tRstAck.val = 10; - cfg.t.cfg.s.inLCe.usid = 0; cfg.t.cfg.s.inLCe.tid = 0; @@ -983,11 +982,11 @@ ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span) cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST; cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId(); - cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0; - cfg.t.cfg.s.ccISAP.pst.route = RTESPEC; - cfg.t.cfg.s.ccISAP.pst.region = S_REG; - cfg.t.cfg.s.ccISAP.pst.pool = S_POOL; - cfg.t.cfg.s.ccISAP.pst.selector = 0; + cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0; + cfg.t.cfg.s.ccISAP.pst.route = RTESPEC; + cfg.t.cfg.s.ccISAP.pst.region = S_REG; + cfg.t.cfg.s.ccISAP.pst.pool = S_POOL; + cfg.t.cfg.s.ccISAP.pst.selector = 0; cfg.t.cfg.s.ccISAP.suId = signal_data->cc_id; cfg.t.cfg.s.ccISAP.spId = signal_data->cc_id; @@ -1005,19 +1004,19 @@ ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span) void stack_pst_init(Pst *pst) { memset(pst, 0, sizeof(Pst)); - /*fill in the post structure*/ - pst->dstProcId = SFndProcId(); - pst->dstInst = S_INST; + /*fill in the post structure*/ + pst->dstProcId = SFndProcId(); + pst->dstInst = S_INST; - pst->srcProcId = SFndProcId(); - pst->srcEnt = ENTSM; - pst->srcInst = S_INST; + pst->srcProcId = SFndProcId(); + pst->srcEnt = ENTSM; + pst->srcInst = S_INST; - pst->prior = PRIOR0; - pst->route = RTESPEC; - pst->region = S_REG; - pst->pool = S_POOL; - pst->selector = 0; + pst->prior = PRIOR0; + pst->route = RTESPEC; + pst->region = S_REG; + pst->pool = S_POOL; + pst->selector = 0; return; } @@ -1026,21 +1025,21 @@ void stack_pst_init(Pst *pst) void stack_hdr_init(Header *hdr) { hdr->msgType = 0; - hdr->msgLen = 0; - hdr->entId.ent = 0; - hdr->entId.inst = 0; - hdr->elmId.elmnt = 0; - hdr->elmId.elmntInst1 = 0; - hdr->elmId.elmntInst2 = 0; - hdr->elmId.elmntInst3 = 0; - hdr->seqNmb = 0; - hdr->version = 0; - hdr->response.prior = PRIOR0; - hdr->response.route = RTESPEC; - hdr->response.mem.region = S_REG; - hdr->response.mem.pool = S_POOL; - hdr->transId = 0; - hdr->response.selector = 0; + hdr->msgLen = 0; + hdr->entId.ent = 0; + hdr->entId.inst = 0; + hdr->elmId.elmnt = 0; + hdr->elmId.elmntInst1 = 0; + hdr->elmId.elmntInst2 = 0; + hdr->elmId.elmntInst3 = 0; + hdr->seqNmb = 0; + hdr->version = 0; + hdr->response.prior = PRIOR0; + hdr->response.route = RTESPEC; + hdr->response.mem.region = S_REG; + hdr->response.mem.pool = S_POOL; + hdr->transId = 0; + hdr->response.selector = 0; return; } 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 c0ee11d980..94bd6e23e1 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 @@ -595,16 +595,65 @@ 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) +/* We received an incoming frame on the d-channel, send data to the stack */ +void sngisdn_snd_data(ftdm_channel_t *dchan, 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); + l1_frame_t l1_frame; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data; + + memset(&l1_frame, 0, sizeof(l1_frame)); + l1_frame.len = len; + + memcpy(&l1_frame.data, data, len); + + if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_CRC)) { + l1_frame.flags |= SNG_L1FRAME_ERROR_CRC; + } + + if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FRAME)) { + l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME; + } + + if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_ABORT)) { + l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT; + } + + if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FIFO)) { + l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO; + } + + if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_DMA)) { + l1_frame.flags |= SNG_L1FRAME_ERROR_DMA; + } + + if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_QUEUE_THRES)) { + /* Should we trigger congestion here? */ + l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES; + } + + if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_QUEUE_FULL)) { + /* Should we trigger congestion here? */ + l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL; + } + + sng_isdn_data_ind(signal_data->link_id, &l1_frame); } -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); +void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data; + switch(event) { + case FTDM_OOB_ALARM_CLEAR: + sng_isdn_event_ind(signal_data->link_id, SNG_L1EVENT_ALARM_OFF); + break; + case FTDM_OOB_ALARM_TRAP: + sng_isdn_event_ind(signal_data->link_id, SNG_L1EVENT_ALARM_ON); + break; + default: + /* We do not care about the other OOB events for now */ + return; + } + return; } diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index f40f2b20c7..d6573ac2de 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -170,7 +170,7 @@ static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan) static __inline__ sng_fd_t __tdmv_api_open_span_chan(int span, int chan) { return __sangoma_open_tdmapi_span_chan(span, chan); -} +} #endif static ftdm_io_interface_t wanpipe_interface; @@ -759,6 +759,49 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) return FTDM_SUCCESS; } +static void wanpipe_read_stats(ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats) +{ + ftdmchan->iostats.s.rx.error_flags = 0; + if (rx_stats->rx_hdr_errors) { + wanpipe_reset_stats(ftdmchan); + ftdm_log_chan_msg_throttle(ftdmchan, "IO errors\n"); + } + + ftdmchan->iostats.s.rx_queue_size = rx_stats->rx_h.rx_h.max_rx_queue_length; + ftdmchan->iostats.s.rx_queue_len = rx_stats->rx_h.current_number_of_frames_in_rx_queue; + + if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_ABORT_ERROR_BIT)) { + ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_ABORT); + } + if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_DMA_ERROR_BIT)) { + ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_DMA); + } + if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_FIFO_ERROR_BIT)) { + ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FIFO); + } + if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_CRC_ERROR_BIT)) { + ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_CRC); + } + if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_FRAME_ERROR_BIT)) { + ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FRAME); + } + + if (ftdmchan->iostats.s.rx_queue_len >= (0.8*ftdmchan->iostats.s.rx_queue_size)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded threshold (%d/%d)\n", + ftdmchan->iostats.s.rx_queue_len, ftdmchan->iostats.s.rx_queue_size); + + ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES); + } + + if (ftdmchan->iostats.s.rx_queue_len >= ftdmchan->iostats.s.rx_queue_size) { + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n", + ftdmchan->iostats.s.rx_queue_len, ftdmchan->iostats.s.rx_queue_size); + + ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL); + } + return; +} + /** * \brief Reads data from a Wanpipe channel * \param ftdmchan Channel to read from @@ -787,9 +830,11 @@ static FIO_READ_FUNCTION(wanpipe_read) snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len); return FTDM_FAIL; - } - + } + if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) { + wanpipe_read_stats(ftdmchan, &hdrframe); + } return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index c5f3c4b821..6cbf589044 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -357,6 +357,7 @@ typedef struct { } ftdm_dtmf_debug_t; #endif + typedef struct { const char *file; const char *func; @@ -366,6 +367,33 @@ typedef struct { ftdm_time_t time; } ftdm_channel_history_entry_t; +typedef enum { + FTDM_IOSTATS_ERROR_CRC = (1<<0), + FTDM_IOSTATS_ERROR_FRAME = (1<<1), + FTDM_IOSTATS_ERROR_ABORT = (1<<2), + FTDM_IOSTATS_ERROR_FIFO = (1<<3), + FTDM_IOSTATS_ERROR_DMA = (1<<4), + FTDM_IOSTATS_ERROR_QUEUE_THRES = (1<<5), /* Queue reached high threshold */ + FTDM_IOSTATS_ERROR_QUEUE_FULL = (1<<6), /* Queue is full */ +} ftdm_iostats_error_type_t; + +typedef struct { + union { + struct { + uint32_t errors; + uint16_t flags; + uint8_t rx_queue_size; /* max queue size configured */ + uint8_t rx_queue_len; /* Current number of elements in queue */ + } rx; + struct { + uint32_t errors; + uint16_t flags; + uint8_t tx_queue_size; /* max queue size configured */ + uint8_t tx_queue_len; /* Current number of elements in queue */ + } tx; + } s; +} ftdm_channel_iostats_t; + /* 2^8 table size, one for each byte (sample) value */ #define FTDM_GAINS_TABLE_SIZE 256 struct ftdm_channel { @@ -438,6 +466,7 @@ struct ftdm_channel { int availability_rate; void *user_private; ftdm_timer_id_t hangup_timer; + ftdm_channel_iostats_t iostats; #ifdef FTDM_DEBUG_DTMF ftdm_dtmf_debug_t dtmfdbg; #endif @@ -632,10 +661,21 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); #define ftdm_channel_lock(chan) ftdm_mutex_lock(chan->mutex) #define ftdm_channel_unlock(chan) ftdm_mutex_unlock(chan->mutex) + +#define ftdm_log_throttle(level, ...) \ + time_current_throttle_log = ftdm_current_time_in_ms(); \ + if (time_current_throttle_log - time_last_throttle_log > FTDM_THROTTLE_LOG_INTERVAL) {\ + ftdm_log(level, __VA_ARGS__); \ + time_last_throttle_log = time_current_throttle_log; \ + } + #define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) #define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) #define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id) +#define ftdm_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) +#define ftdm_log_chan_msg_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) + #define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex) #define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex)