l4isup.c
来自「asterisk1.4.6版本下 7#信令驱动 源码」· C语言 代码 · 共 2,056 行 · 第 1/5 页
C
2,056 行
}
ast_mutex_lock(&pvt->lock);
chan = ss7_new(pvt, AST_STATE_DOWN, NULL, sep ? sep+1 : arg);
if(!chan) {
ast_mutex_unlock(&pvt->lock);
unlock_global();
*cause = AST_CAUSE_CONGESTION;
ast_log(LOG_WARNING, "Unable to allocate SS7 channel structure.\n");
return NULL;
}
ast_mutex_unlock(&pvt->lock);
unlock_global();
ast_update_use_count();
ast_log(LOG_DEBUG, "SS7 channel %s/%s allocated successfully.\n", type, arg);
return chan;
}
static int ss7_send_digit_begin(struct ast_channel *chan, char digit) {
struct ss7_chan *pvt = chan->tech_pvt;
ast_mutex_lock(&pvt->lock);
if (!io_send_dtmf(pvt->zaptel_fd, pvt->cic, digit))
pvt->sending_dtmf = 1;
ast_mutex_unlock(&pvt->lock);
return 0;
}
static int ss7_send_digit_end(struct ast_channel *chan, char digit, unsigned int duration) {
return 0;
}
static void ss7_send_call_progress(struct ss7_chan *pvt, int value) {
unsigned char msg[MTP_MAX_PCK_SIZE];
int current, varptr;
unsigned char param[1];
unsigned char param_backward_ind[2];
unsigned char param_opt_backw_ind[1];
isup_msg_init(msg, sizeof(msg), variant(pvt), this_host->opc, peerpc(pvt), pvt->cic, ISUP_CPR, ¤t);
param[0] = value; /* Event information */
param_backward_ind[0] = 0x16; /* Charge, subscriber free, ordinary subscriber, no end-to-end */
param_backward_ind[1] = 0x14; /* No interworking, no end-to-end, ISDN all the way, no hold, terminating access ISDN, no echo control */
param_opt_backw_ind[0] = 0x01;
isup_msg_add_fixed(msg, sizeof(msg), ¤t, param, 1);
isup_msg_start_variable_part(msg, sizeof(msg), &varptr, ¤t, 0, 1);
isup_msg_start_optional_part(msg, sizeof(msg), &varptr, ¤t);
isup_msg_add_optional(msg, sizeof(msg), ¤t, IP_BACKWARD_CALL_INDICATORS,
param_backward_ind, 2);
isup_msg_add_optional(msg, sizeof(msg), ¤t, IP_OPTIONAL_BACKWARD_CALL_INDICATORS,
param_opt_backw_ind, 1);
isup_msg_end_optional_part(msg, sizeof(msg), ¤t);
mtp_enqueue_isup(pvt, msg, current);
}
#ifdef USE_ASTERISK_1_2
static int ss7_indicate(struct ast_channel *chan, int condition) {
#else
static int ss7_indicate(struct ast_channel *chan, int condition, const void* data, size_t datalen) {
#endif
struct ss7_chan *pvt = chan->tech_pvt;
int res;
ast_mutex_lock(&pvt->lock);
ast_log(LOG_DEBUG, "SS7 indicate CIC=%d.\n", pvt->cic);
switch(condition) {
case AST_CONTROL_RINGING:
ast_log(LOG_DEBUG, "Sending ALERTING call progress for CIC=%d in-band ind=%d.\n",
pvt->cic, pvt->has_inband_ind);
ss7_send_call_progress(pvt, 0x01);
ast_setstate(chan, AST_STATE_RINGING);
res = !pvt->has_inband_ind && !pvt->is_digital; /* If there is no indication of in-band information, tell asterisk to generate ringing indication tone */
break;
case AST_CONTROL_PROGRESS:
ast_log(LOG_DEBUG, "Sending in-band information available call progress for CIC=%d..\n",
pvt->cic);
ss7_send_call_progress(pvt, 0x03);
ast_playtones_stop(chan);
res = 0;
break;
default:
/* Not supported. */
res = !pvt->has_inband_ind && !pvt->is_digital; /* If there is no indication of in-band information, tell asterisk to generate ringing indication tone */
}
ast_mutex_unlock(&pvt->lock);
if (!res)
ast_log(LOG_DEBUG, "Generating in-band indication tones for CIC=%d, condition=%d.\n", pvt->cic, condition);
return res;
}
static int t1_timeout(void *arg) {
struct ss7_chan *pvt = arg;
ast_log(LOG_NOTICE, "T1 timeout (waiting for RLC) CIC=%d.\n", pvt->cic);
isup_send_rel(pvt, pvt->hangupcause);
return 1; /* Run us again the next period */
}
/* This should be called with pvt->lock held. */
static void t1_clear(struct ss7_chan *pvt) {
if(pvt->t1 != -1) {
stop_timer(pvt->t1);
pvt->t1 = -1;
}
}
/* This should be called with pvt->lock held. */
static void t1_start(struct ss7_chan *pvt) {
t1_clear(pvt);
pvt->t1 = start_timer(30000, t1_timeout, pvt);
}
static int t2_timeout(void *arg) {
struct ss7_chan *pvt = arg;
ast_log(LOG_NOTICE, "T2 timeout (waiting for RES, user) CIC=%d.\n", pvt->cic);
isup_send_rel(pvt, AST_CAUSE_NORMAL_CLEARING); /* Q.764 2.4.3 and Annex A */
pvt->t2 = -1;
return 0; /* Remove us from sched */
}
/* This should be called with pvt->lock held. */
static void t2_clear(struct ss7_chan *pvt) {
if(pvt->t2 != -1) {
stop_timer(pvt->t2);
pvt->t2 = -1;
}
}
/* This should be called with pvt->lock held. */
static void t2_start(struct ss7_chan *pvt) {
t2_clear(pvt);
pvt->t2 = start_timer(180000, t2_timeout, pvt);
}
/* This should be called with pvt->lock held. */
static void t5_clear(struct ss7_chan *pvt) {
if(pvt->t5 != -1) {
stop_timer(pvt->t5);
pvt->t5 = -1;
}
}
static int t5_timeout(void *arg) {
struct ss7_chan *pvt = arg;
/* For the long T5 timeout, alert maintenance, and switch to sending
"reset circuit". */
ast_log(LOG_WARNING, "T5 timeout (No \"release complete\" from peer) CIC=%d.\n", pvt->cic);
t1_clear(pvt);
isup_send_rsc(pvt);
t17_start(pvt);
pvt->t5 = -1;
return 0; /* Remove us from sched */
}
/* This should be called with pvt->lock held. */
static void t5_start(struct ss7_chan *pvt) {
t5_clear(pvt);
pvt->t5 = start_timer(600000, t5_timeout, pvt);
}
static int t6_timeout(void *arg) {
struct ss7_chan *pvt = arg;
ast_log(LOG_NOTICE, "T6 timeout (waiting for RES, network) CIC=%d.\n", pvt->cic);
isup_send_rel(pvt, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE);
pvt->t6 = -1;
return 0; /* Remove us from sched */
}
/* This should be called with pvt->lock held. */
static void t6_clear(struct ss7_chan *pvt) {
if(pvt->t6 != -1) {
stop_timer(pvt->t6);
pvt->t6 = -1;
}
}
/* This should be called with pvt->lock held. */
static void t6_start(struct ss7_chan *pvt) {
t6_clear(pvt);
pvt->t6 = start_timer(60000, t6_timeout, pvt);
}
static int t7_timeout(void *arg) {
struct ast_channel *chan = arg;
struct ss7_chan *pvt = chan->tech_pvt;
ast_log(LOG_NOTICE, "T7 timeout (waiting for ACM or CON) CIC=%d.\n", pvt->cic);
/* Q.764 2.4.3 */
request_hangup(chan, AST_CAUSE_NORMAL_CLEARING);
pvt->t7 = -1;
/* asterisk sometimes fail to call ss7_hangup ... */
return 0; /* Remove us from sched */
}
/* This should be called with pvt->lock held. */
static void t7_clear(struct ss7_chan *pvt) {
if(pvt->t7 != -1) {
stop_timer(pvt->t7);
pvt->t7 = -1;
}
}
/* This should be called with pvt->lock held. */
static void t7_start(struct ast_channel *chan) {
struct ss7_chan *pvt = chan->tech_pvt;
t7_clear(pvt);
pvt->t7 = start_timer(25000, t7_timeout, chan);
}
static int t9_timeout(void *arg) {
struct ast_channel *chan = arg;
struct ss7_chan *pvt = chan->tech_pvt;
ast_log(LOG_NOTICE, "T9 timeout (waiting for ANM).\n");
request_hangup(chan, AST_CAUSE_NETWORK_OUT_OF_ORDER);
pvt->t9 = -1;
return 0; /* Remove us from sched */
}
/* This should be called with pvt->lock held. */
static void t9_clear(struct ss7_chan *pvt) {
if(pvt->t9 != -1) {
stop_timer(pvt->t9);
pvt->t9 = -1;
}
}
/* This should be called with pvt->lock held. */
static void t9_start(struct ast_channel *chan) {
struct ss7_chan *pvt = chan->tech_pvt;
t9_clear(pvt);
pvt->t9 = start_timer(90000, t9_timeout, chan);
}
/* This should be called with pvt->lock held. */
static void t16_clear(struct ss7_chan *pvt) {
if(pvt->t16 != -1) {
stop_timer(pvt->t16);
pvt->t16 = -1;
}
}
static int t16_timeout(void *arg) {
struct ss7_chan *pvt = arg;
/* For the long T16 timeout, alert maintenance, and switch to sending
"reset circuit". */
ast_log(LOG_WARNING, "T16 timeout (No \"release complete\" from peer) CIC=%d, sent RSC.\n", pvt->cic);
isup_send_rsc(pvt);
return 1; /* Run us again the next period */
}
/* This should be called with pvt->lock held. */
static void t16_start(struct ss7_chan *pvt) {
t16_clear(pvt);
pvt->t16 = start_timer(30000, t16_timeout, pvt);
}
/* This should be called with pvt->lock held. */
static void t17_clear(struct ss7_chan *pvt) {
if(pvt->t17 != -1) {
stop_timer(pvt->t17);
pvt->t17 = -1;
}
}
static int t17_timeout(void *arg) {
struct ss7_chan *pvt = arg;
/* For the long T17 timeout, alert maintenance, and switch to sending
"reset circuit". */
ast_log(LOG_WARNING, "T17 timeout (No \"release complete\" from peer) CIC=%d.\n", pvt->cic);
isup_send_rsc(pvt);
return 1; /* Run us again the next period */
}
/* This should be called with pvt->lock held. */
static void t17_start(struct ss7_chan *pvt) {
t17_clear(pvt);
pvt->t17 = start_timer(600000, t17_timeout, pvt);
}
/* This should be called with pvt->lock held. */
static void t18_clear(struct ss7_chan *pvt) {
if(pvt->t18 != -1) {
stop_timer(pvt->t18);
pvt->t18 = -1;
}
}
static int t18_timeout(void *arg) {
struct ss7_chan *pvt = arg;
/* For the long T18 timeout, alert maintenance, and switch to sending
"reset circuit". */
ast_log(LOG_WARNING, "T18 timeout (No \"circuit group blocking acknowledge\" from peer) CIC=%d.\n", pvt->cic);
isup_send_cgb(pvt, pvt->cgb_mask);
pvt->t18 = -1;
t19_start(pvt);
return 0; /* Remove us from sched */
}
/* This should be called with pvt->lock held. */
static void t18_start(struct ss7_chan *pvt) {
t18_clear(pvt);
pvt->t18 = start_timer(30000, t18_timeout, pvt);
}
/* This should be called with pvt->lock held. */
static void t19_clear(struct ss7_chan *pvt) {
if(pvt->t19 != -1) {
stop_timer(pvt->t19);
pvt->t19 = -1;
}
}
static int t19_timeout(void *arg) {
struct ss7_chan *pvt = arg;
/* For the long T19 timeout, alert maintenance, and switch to sending
"reset circuit". */
ast_log(LOG_WARNING, "T19 timeout (No \"circuit group blocking acknowledge\" from peer) CIC=%d.\n", pvt->cic);
isup_send_cgb(pvt, pvt->cgb_mask);
return 1; /* Run us again the next period */
}
/* This should be called with pvt->lock held. */
static void t19_start(struct ss7_chan *pvt) {
t19_clear(pvt);
pvt->t19 = start_timer(600000, t19_timeout, pvt);
}
/* This should be called with pvt->lock held. */
static void t20_clear(struct ss7_chan *pvt) {
if(pvt->t20 != -1) {
stop_timer(pvt->t20);
pvt->t20 = -1;
}
}
static int t20_timeout(void *arg) {
struct ss7_chan *pvt = arg;
/* For the long T20 timeout, alert maintenance, and switch to sending
"reset circuit". */
ast_log(LOG_WARNING, "T20 timeout (No \"circuit group unblocking acknowledge\" from peer) CIC=%d.\n", pvt->cic);
isup_send_cgu(pvt, pvt->cgb_mask);
pvt->t20 = -1;
t21_start(pvt);
return 0; /* Remove us from sched */
}
/* This should be called with pvt->lock held. */
static void t20_start(struct ss7_chan *pvt) {
t20_clear(pvt);
pvt->t20 = start_timer(30000, t20_timeout, pvt);
}
/* This should be called with pvt->lock held. */
static void t21_clear(struct ss7_chan *pvt) {
if(pvt->t21 != -1) {
stop_timer(pvt->t21);
pvt->t21 = -1;
}
}
static int t21_timeout(void *arg) {
struct ss7_chan *pvt = arg;
/* For the long T21 timeout, alert maintenance, and switch to sending
"reset circuit". */
ast_log(LOG_WARNING, "T21 timeout (No \"circuit group blocking acknowledge\" from peer) CIC=%d.\n", pvt->cic);
isup_send_cgu(pvt, pvt->cgb_mask);
return 1; /* Run us again the next period */
}
/* This should be called with pvt->lock held. */
static void t21_start(struct ss7_chan *pvt) {
t21_clear(pvt);
pvt->t21 = start_timer(600000, t21_timeout, pvt);
}
/* This should be called with pvt->lock held. */
static void t22_clear(struct ss7_chan *pvt) {
if(pvt->t22 != -1) {
stop_timer(pvt->t22);
pvt->t22 = -1;
}
}
static int t22_timeout(void *arg) {
struct ss7_chan *pvt = arg;
ast_log(LOG_NOTICE, "T22 timeout (No \"circuit group reset acknowledge\" from peer) CIC=%d.\n", pvt->cic);
isup_send_grs(pvt, pvt->grs_count, 0);
return 1; /* Run us again the next period */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?