freetdm: Changes for FTDM IO commands

This commit is contained in:
David Yat Sin 2010-11-15 14:13:01 -05:00
parent d0b6117325
commit caacb24500
7 changed files with 329 additions and 193 deletions

View File

@ -56,6 +56,9 @@
#define FTDM_READ_TRACE_INDEX 0 #define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1 #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 int time_is_init = 0;
static void time_init(void) static void time_init(void)

View File

@ -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) static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event)
{ {
sngisdn_snd_event(span, event);
switch (event) { switch (event) {
/* Check if the span woke up from power-saving mode */ /* Check if the span woke up from power-saving mode */
case FTDM_OOB_ALARM_CLEAR: case FTDM_OOB_ALARM_CLEAR:
sngisdn_snd_event(span, SNG_L1EVENT_ALARM_OFF);
if (FTDM_SPAN_IS_BRI(span)) { if (FTDM_SPAN_IS_BRI(span)) {
ftdm_channel_t *ftdmchan; ftdm_channel_t *ftdmchan;
sngisdn_chan_data_t *sngisdn_info; 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); ftdm_iterator_free(chaniter);
} }
break; break;
case FTDM_OOB_ALARM_TRAP:
sngisdn_snd_event(span, SNG_L1EVENT_ALARM_ON);
break;
default: default:
/* Ignore other events for now */ /* Ignore other events for now */
break; break;
@ -327,7 +324,7 @@ static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj)
len = 1000; len = 1000;
status = ftdm_channel_read(dchan, data, &len); status = ftdm_channel_read(dchan, data, &len);
if (status == FTDM_SUCCESS) { if (status == FTDM_SUCCESS) {
sngisdn_snd_data(span, data, len); sngisdn_snd_data(dchan, data, len);
} else { } else {
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n"); 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_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; 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++) { for(i=1;i<=MAX_VARIANTS;i++) {
ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex); ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex);

View File

@ -293,8 +293,8 @@ void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
void sngisdn_snd_con_complete(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_info_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_status_enq(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_data(ftdm_channel_t *dchan, 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_event(ftdm_channel_t *span, sng_isdn_l1_event_t l1_event);
/* Inbound Call Control functions */ /* 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_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_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_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_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_ind (sngisdn_event_data_t *sngisdn_event);
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event); void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event);

View File

@ -156,34 +156,34 @@ ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span)
ftdm_status_t sngisdn_stack_cfg_phy_gen(void) ftdm_status_t sngisdn_stack_cfg_phy_gen(void)
{ {
/*local variables*/ /*local variables*/
L1Mngmt cfg; /*configuration structure*/ L1Mngmt cfg; /*configuration structure*/
Pst pst; /*post structure*/ Pst pst; /*post structure*/
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTL1; pst.dstEnt = ENTL1;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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*/ /*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG; cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTL1; cfg.hdr.entId.ent = ENTL1;
cfg.hdr.entId.inst = S_INST; cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN; cfg.hdr.elmId.elmnt = STGEN;
stack_pst_init(&cfg.t.cfg.s.l1Gen.sm ); stack_pst_init(&cfg.t.cfg.s.l1Gen.sm );
cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1; cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM; cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS+1; 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.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
if (sng_isdn_phy_config(&pst, &cfg)) { if (sng_isdn_phy_config(&pst, &cfg)) {
return FTDM_FAIL; 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) ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span)
{ {
L1Mngmt cfg; L1Mngmt cfg;
Pst pst; Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTL1; pst.dstEnt = ENTL1;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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*/ /*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG; cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTL1; cfg.hdr.entId.ent = ENTL1;
cfg.hdr.entId.inst = S_INST; cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STPSAP; cfg.hdr.elmId.elmnt = STPSAP;
cfg.hdr.elmId.elmntInst1 = signal_data->link_id; cfg.hdr.elmId.elmntInst1 = signal_data->link_id;
if (!signal_data->dchan) { if (!signal_data->dchan) {
ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name); ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name);
return FTDM_FAIL; return FTDM_FAIL;
} }
cfg.t.cfg.s.l1PSAP.sockfd = (int32_t)signal_data->dchan->sockfd; cfg.t.cfg.s.l1PSAP.sockfd = (int32_t)signal_data->dchan->sockfd;
switch(span->trunk_type) { switch(span->trunk_type) {
case FTDM_TRUNK_E1: case FTDM_TRUNK_E1:
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI; 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: default:
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type); ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type);
return FTDM_FAIL; 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)) { if (sng_isdn_phy_config(&pst, &cfg)) {
return FTDM_FAIL; 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) ftdm_status_t sngisdn_stack_cfg_q921_gen(void)
{ {
BdMngmt cfg; BdMngmt cfg;
Pst pst; Pst pst;
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTLD; pst.dstEnt = ENTLD;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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 = STGEN;
/* fill in the Gen Conf structures internal pst struct */
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 */ 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 #ifdef LAPD_3_4
cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */ cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */
#endif #endif
cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */ 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.poolTrLower = 1; /* lower pool threshold */
if (sng_isdn_q921_config(&pst, &cfg)) { if (sng_isdn_q921_config(&pst, &cfg)) {
return FTDM_FAIL; 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) ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span)
{ {
BdMngmt cfg; BdMngmt cfg;
Pst pst; Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTLD; pst.dstEnt = ENTLD;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*fill in some general sections of the header*/
stack_hdr_init(&cfg.hdr); stack_hdr_init(&cfg.hdr);
cfg.hdr.msgType = TCFG; cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTLD; cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST; cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STMSAP; cfg.hdr.elmId.elmnt = STMSAP;
cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id; cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id;
cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */ 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.tQUpperTrs = 32; /* Tx Queue Upper Threshold */
cfg.t.cfg.s.bdMSAP.tQLowerTrs = 24; /* Tx Queue Lower 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.route = RTESPEC; /* Route */
cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */ cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */
cfg.t.cfg.s.bdMSAP.dstEnt = ENTL1; /* entity */ 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.t201Tmr = 1; /* T201 - should be equal to t200Tmr */
cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */ cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */
cfg.t.cfg.s.bdMSAP.bndRetryCnt = 2; /* bind retry counter */ 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) { if (signal_data->setup_arb == SNGISDN_OPT_TRUE) {
cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE; cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE;
} else if (signal_data->setup_arb == SNGISDN_OPT_FALSE) { } 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)) { 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) ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management)
{ {
BdMngmt cfg; BdMngmt cfg;
Pst pst; Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTLD; pst.dstEnt = ENTLD;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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*/ /*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG; cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTLD; cfg.hdr.entId.ent = ENTLD;
cfg.hdr.entId.inst = S_INST; cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLSAP; cfg.hdr.elmId.elmnt = STDLSAP;
cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id; 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 { } else {
cfg.t.cfg.s.bdDLSAP.k = 7; /* k */ cfg.t.cfg.s.bdDLSAP.k = 7; /* k */
} }
cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */ cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */
cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */ 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.t203Tmr = 10; /* t3 changed from 50 */
cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */ cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */
cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */ 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) ftdm_status_t sngisdn_stack_cfg_q931_gen(void)
{ {
InMngmt cfg; InMngmt cfg;
Pst pst; Pst pst;
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTIN; pst.dstEnt = ENTIN;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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*/ /*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG; cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN; cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST; cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STGEN; cfg.hdr.elmId.elmnt = STGEN;
/* fill in the Gen Conf structures internal pst struct */ /* fill in the Gen Conf structures internal pst struct */
stack_pst_init(&cfg.t.cfg.s.inGen.sm); stack_pst_init(&cfg.t.cfg.s.inGen.sm);
cfg.t.cfg.s.inGen.nmbSaps = MAX_VARIANTS+1; /* Total number of variants supported */ 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) ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span)
{ {
InMngmt cfg; InMngmt cfg;
Pst pst; Pst pst;
unsigned i; unsigned i;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTIN; pst.dstEnt = ENTIN;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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*/ /*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG; cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN; cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST; cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STTSAP; cfg.hdr.elmId.elmnt = STTSAP;
cfg.t.cfg.s.inTSAP.sapId = signal_data->cc_id; 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) ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
{ {
InMngmt cfg; InMngmt cfg;
Pst pst; Pst pst;
unsigned i; unsigned i;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTIN; pst.dstEnt = ENTIN;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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 = 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.hdr.response.selector=0;
cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id; 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.spId = signal_data->link_id;
cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); 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.ctldInt[1] = 1;
} }
cfg.t.cfg.s.inDLSAP.numRstInd = 255; cfg.t.cfg.s.inDLSAP.numRstInd = 255;
cfg.t.cfg.s.inDLSAP.relOpt = TRUE; cfg.t.cfg.s.inDLSAP.relOpt = TRUE;
#ifdef ISDN_SRV #ifdef ISDN_SRV
cfg.t.cfg.s.inDLSAP.bcas = FALSE; 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) ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span)
{ {
InMngmt cfg; InMngmt cfg;
Pst pst; Pst pst;
uint8_t i; uint8_t i;
uint8_t numCes=1; uint8_t numCes=1;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; 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) { if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && signal_data->signalling == SNGISDN_SIGNALING_NET) {
numCes = 8; numCes = 8;
} }
/* initalize the post structure */ /* initalize the post structure */
stack_pst_init(&pst); stack_pst_init(&pst);
/* insert the destination Entity */ /* insert the destination Entity */
pst.dstEnt = ENTIN; pst.dstEnt = ENTIN;
/*clear the configuration structure*/ /*clear the configuration structure*/
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
/*fill in some general sections of the header*/ /*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*/ /*fill in the specific fields of the header*/
cfg.hdr.msgType = TCFG; cfg.hdr.msgType = TCFG;
cfg.hdr.entId.ent = ENTIN; cfg.hdr.entId.ent = ENTIN;
cfg.hdr.entId.inst = S_INST; cfg.hdr.entId.inst = S_INST;
cfg.hdr.elmId.elmnt = STDLC; cfg.hdr.elmId.elmnt = STDLC;
cfg.hdr.response.selector=0; cfg.hdr.response.selector=0;
cfg.t.cfg.s.inLCe.sapId = signal_data->link_id; cfg.t.cfg.s.inLCe.sapId = signal_data->link_id;
cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE; cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE;
cfg.t.cfg.s.inLCe.tCon.enb = 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.tDisc.val = 35;
cfg.t.cfg.s.inLCe.t314.enb = FALSE; /* if segmentation enabled, set to TRUE */ 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.t314.val = 35;
cfg.t.cfg.s.inLCe.t332i.enb = FALSE; /* set to TRUE for NFAS */ cfg.t.cfg.s.inLCe.t332i.enb = FALSE; /* set to TRUE for NFAS */
#ifdef 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.enb = TRUE;
cfg.t.cfg.s.inLCe.tRstAck.val = 10; cfg.t.cfg.s.inLCe.tRstAck.val = 10;
cfg.t.cfg.s.inLCe.usid = 0; cfg.t.cfg.s.inLCe.usid = 0;
cfg.t.cfg.s.inLCe.tid = 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.dstInst = S_INST;
cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId(); cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId();
cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0; cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0;
cfg.t.cfg.s.ccISAP.pst.route = RTESPEC; cfg.t.cfg.s.ccISAP.pst.route = RTESPEC;
cfg.t.cfg.s.ccISAP.pst.region = S_REG; cfg.t.cfg.s.ccISAP.pst.region = S_REG;
cfg.t.cfg.s.ccISAP.pst.pool = S_POOL; cfg.t.cfg.s.ccISAP.pst.pool = S_POOL;
cfg.t.cfg.s.ccISAP.pst.selector = 0; cfg.t.cfg.s.ccISAP.pst.selector = 0;
cfg.t.cfg.s.ccISAP.suId = signal_data->cc_id; cfg.t.cfg.s.ccISAP.suId = signal_data->cc_id;
cfg.t.cfg.s.ccISAP.spId = 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) void stack_pst_init(Pst *pst)
{ {
memset(pst, 0, sizeof(Pst)); memset(pst, 0, sizeof(Pst));
/*fill in the post structure*/ /*fill in the post structure*/
pst->dstProcId = SFndProcId(); pst->dstProcId = SFndProcId();
pst->dstInst = S_INST; pst->dstInst = S_INST;
pst->srcProcId = SFndProcId(); pst->srcProcId = SFndProcId();
pst->srcEnt = ENTSM; pst->srcEnt = ENTSM;
pst->srcInst = S_INST; pst->srcInst = S_INST;
pst->prior = PRIOR0; pst->prior = PRIOR0;
pst->route = RTESPEC; pst->route = RTESPEC;
pst->region = S_REG; pst->region = S_REG;
pst->pool = S_POOL; pst->pool = S_POOL;
pst->selector = 0; pst->selector = 0;
return; return;
} }
@ -1026,21 +1025,21 @@ void stack_pst_init(Pst *pst)
void stack_hdr_init(Header *hdr) void stack_hdr_init(Header *hdr)
{ {
hdr->msgType = 0; hdr->msgType = 0;
hdr->msgLen = 0; hdr->msgLen = 0;
hdr->entId.ent = 0; hdr->entId.ent = 0;
hdr->entId.inst = 0; hdr->entId.inst = 0;
hdr->elmId.elmnt = 0; hdr->elmId.elmnt = 0;
hdr->elmId.elmntInst1 = 0; hdr->elmId.elmntInst1 = 0;
hdr->elmId.elmntInst2 = 0; hdr->elmId.elmntInst2 = 0;
hdr->elmId.elmntInst3 = 0; hdr->elmId.elmntInst3 = 0;
hdr->seqNmb = 0; hdr->seqNmb = 0;
hdr->version = 0; hdr->version = 0;
hdr->response.prior = PRIOR0; hdr->response.prior = PRIOR0;
hdr->response.route = RTESPEC; hdr->response.route = RTESPEC;
hdr->response.mem.region = S_REG; hdr->response.mem.region = S_REG;
hdr->response.mem.pool = S_POOL; hdr->response.mem.pool = S_POOL;
hdr->transId = 0; hdr->transId = 0;
hdr->response.selector = 0; hdr->response.selector = 0;
return; return;
} }

View File

@ -595,16 +595,65 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
return; 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; l1_frame_t l1_frame;
sng_isdn_data_ind(signal_data->link_id, data, len); 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) void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event)
{ {
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
sng_isdn_event_ind(signal_data->link_id, l1_event); 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;
} }

View File

@ -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) static __inline__ sng_fd_t __tdmv_api_open_span_chan(int span, int chan)
{ {
return __sangoma_open_tdmapi_span_chan(span, chan); return __sangoma_open_tdmapi_span_chan(span, chan);
} }
#endif #endif
static ftdm_io_interface_t wanpipe_interface; static ftdm_io_interface_t wanpipe_interface;
@ -759,6 +759,49 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
return FTDM_SUCCESS; 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 * \brief Reads data from a Wanpipe channel
* \param ftdmchan Channel to read from * \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)); 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); ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
return FTDM_FAIL; return FTDM_FAIL;
} }
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
wanpipe_read_stats(ftdmchan, &hdrframe);
}
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }

View File

@ -357,6 +357,7 @@ typedef struct {
} ftdm_dtmf_debug_t; } ftdm_dtmf_debug_t;
#endif #endif
typedef struct { typedef struct {
const char *file; const char *file;
const char *func; const char *func;
@ -366,6 +367,33 @@ typedef struct {
ftdm_time_t time; ftdm_time_t time;
} ftdm_channel_history_entry_t; } 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 */ /* 2^8 table size, one for each byte (sample) value */
#define FTDM_GAINS_TABLE_SIZE 256 #define FTDM_GAINS_TABLE_SIZE 256
struct ftdm_channel { struct ftdm_channel {
@ -438,6 +466,7 @@ struct ftdm_channel {
int availability_rate; int availability_rate;
void *user_private; void *user_private;
ftdm_timer_id_t hangup_timer; ftdm_timer_id_t hangup_timer;
ftdm_channel_iostats_t iostats;
#ifdef FTDM_DEBUG_DTMF #ifdef FTDM_DEBUG_DTMF
ftdm_dtmf_debug_t dtmfdbg; ftdm_dtmf_debug_t dtmfdbg;
#endif #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_lock(chan) ftdm_mutex_lock(chan->mutex)
#define ftdm_channel_unlock(chan) ftdm_mutex_unlock(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_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(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_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_lock(span) ftdm_mutex_lock(span->mutex)
#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex) #define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex)