49 #if !defined(LIBSS7_ABI_COMPATIBILITY) 50 #error "Upgrade your libss7" 51 #elif LIBSS7_ABI_COMPATIBILITY != 2 52 #error "Your installed libss7 is not compatible" 78 static void sig_ss7_unlock_private(
struct sig_ss7_chan *p)
92 static void sig_ss7_deadlock_avoidance_private(
struct sig_ss7_chan *p)
98 sig_ss7_unlock_private(p);
100 sig_ss7_lock_private(p);
112 static void sig_ss7_set_dialing(
struct sig_ss7_chan *p,
int is_dialing)
119 static void sig_ss7_set_digital(
struct sig_ss7_chan *p,
int is_digital)
126 static void sig_ss7_set_outgoing(
struct sig_ss7_chan *p,
int is_outgoing)
134 static void sig_ss7_set_inservice(
struct sig_ss7_chan *p,
int is_inservice)
142 static void sig_ss7_set_locallyblocked(
struct sig_ss7_chan *p,
int is_blocked,
int type)
155 static void sig_ss7_set_remotelyblocked(
struct sig_ss7_chan *p,
int is_blocked,
int type)
193 static void sig_ss7_set_caller_id(
struct sig_ss7_chan *p)
202 caller.id.name.valid = 1;
204 caller.id.number.str = p->
cid_num;
205 caller.id.number.plan = p->
cid_ton;
207 caller.id.number.valid = 1;
210 caller.id.subaddress.valid = 1;
216 caller.ani.number.str = p->
cid_ani;
219 caller.ani.number.valid = 1;
236 static void sig_ss7_set_dnid(
struct sig_ss7_chan *p,
const char *dnid)
255 static int sig_ss7_set_echocanceller(
struct sig_ss7_chan *p,
int enable)
263 static void sig_ss7_loopback(
struct sig_ss7_chan *p,
int enable)
274 int ulaw,
int transfercapability,
char *
exten,
281 assignedids, requestor);
303 sig_ss7_set_digital(p, 1);
309 static void sig_ss7_handle_link_exception(
struct sig_ss7_linkset *linkset,
int which)
332 static int sig_ss7_is_chan_available(
struct sig_ss7_chan *pvt)
355 static void sig_ss7_lock_owner(
struct sig_ss7_linkset *ss7,
int chanpos)
368 sig_ss7_unlock_private(ss7->
pvts[chanpos]);
370 sig_ss7_lock_private(ss7->
pvts[chanpos]);
390 sig_ss7_lock_owner(ss7, chanpos);
411 static void sig_ss7_queue_control(
struct sig_ss7_linkset *ss7,
int chanpos,
int subclass)
421 sig_ss7_queue_frame(ss7, chanpos, &f);
438 static void ss7_queue_pvt_cause_data(
struct ast_channel *
owner,
const char *cause,
int ast_cause)
441 int datalen =
sizeof(*cause_code) + strlen(cause);
444 memset(cause_code, 0, datalen);
467 for (i = 0; i < linkset->
numchans; i++) {
468 if (linkset->
pvts[i] && (linkset->
pvts[i]->
dpc == dpc && linkset->
pvts[i]->
cic == cic)) {
488 static int ss7_find_cic_gripe(
struct sig_ss7_linkset *linkset,
int cic,
unsigned int dpc,
const char *msg_name)
495 linkset->
span, msg_name, cic, dpc);
501 static struct sig_ss7_chan *ss7_find_pvt(
struct ss7 *ss7,
int cic,
unsigned int dpc)
506 winner = sig_ss7_find_linkset(ss7);
508 return winner->
pvts[chanpos];
513 int sig_ss7_cb_hangup(
struct ss7 *ss7,
int cic,
unsigned int dpc,
int cause,
int do_hangup)
518 if (!(p = ss7_find_pvt(ss7, cic, dpc))) {
519 return SS7_CIC_NOT_EXISTS;
522 sig_ss7_lock_private(p);
531 sig_ss7_unlock_private(p);
541 winner = sig_ss7_find_linkset(ss7);
545 for (i = 0; i < winner->
numchans; i++) {
548 sig_ss7_lock_private(winner->
pvts[i]);
556 sig_ss7_unlock_private(winner->
pvts[i]);
567 if (!(p = ss7_find_pvt(ss7, cic, dpc))) {
571 sig_ss7_lock_private(p);
572 sig_ss7_set_inservice(p, 0);
573 sig_ss7_unlock_private(p);
589 static void ss7_check_range(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
unsigned int dpc,
unsigned char *state)
593 for (cic = startcic; cic <= endcic; cic++) {
595 state[cic - startcic] = 0;
600 static int ss7_match_range(
struct sig_ss7_chan *pvt,
int startcic,
int endcic,
unsigned int dpc)
602 if (pvt && pvt->
dpc == dpc && pvt->
cic >= startcic && pvt->
cic <= endcic) {
627 for (i = 0; i < linkset->
numchans; i++) {
628 if (ss7_match_range(linkset->
pvts[i], startcic, endcic, dpc)) {
633 if (found == endcic - startcic + 1) {
640 static void ss7_handle_cqm(
struct sig_ss7_linkset *linkset, ss7_event *e)
648 memset(status, 0,
sizeof(status));
649 for (i = 0; i < linkset->
numchans; i++) {
650 if (ss7_match_range(linkset->
pvts[i], e->cqm.startcic, e->cqm.endcic, e->cqm.opc)) {
651 p = linkset->
pvts[i];
652 sig_ss7_lock_private(p);
653 offset = p->
cic - e->cqm.startcic;
656 status[offset] |= (1 << 0) | (1 << 4);
659 status[offset] |= (1 << 1) | (1 << 5);
663 status[offset] |= (1 << 3);
665 status[offset] |= (1 << 2);
668 status[offset] |= 0x3 << 2;
670 sig_ss7_unlock_private(p);
675 isup_cqr(linkset->
ss7, e->cqm.startcic, e->cqm.endcic, e->cqm.opc, status);
682 isup_free_call(linkset->
ss7, e->cqm.call);
685 p = linkset->
pvts[chanpos];
686 sig_ss7_lock_private(p);
689 p->
ss7call = isup_free_call_if_clear(linkset->
ss7, e->cqm.call);
691 sig_ss7_unlock_private(p);
694 static inline void ss7_hangup_cics(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
unsigned int dpc)
698 for (i = 0; i < linkset->
numchans; i++) {
699 if (ss7_match_range(linkset->
pvts[i], startcic, endcic, dpc)) {
700 sig_ss7_lock_private(linkset->
pvts[i]);
701 sig_ss7_lock_owner(linkset, i);
706 sig_ss7_unlock_private(linkset->
pvts[i]);
726 static inline void ss7_block_cics(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
unsigned int dpc,
unsigned char state[],
int block,
int remotely,
int type)
730 for (i = 0; i < linkset->
numchans; i++) {
731 if (ss7_match_range(linkset->
pvts[i], startcic, endcic, dpc)) {
732 sig_ss7_lock_private(linkset->
pvts[i]);
734 if (state[linkset->
pvts[i]->
cic - startcic]) {
737 sig_ss7_set_remotelyblocked(linkset->
pvts[i], block, type);
739 sig_ss7_set_locallyblocked(linkset->
pvts[i], block, type);
742 sig_ss7_lock_owner(linkset, i);
753 sig_ss7_set_remotelyblocked(linkset->
pvts[i], block, type);
755 sig_ss7_set_locallyblocked(linkset->
pvts[i], block, type);
758 sig_ss7_unlock_private(linkset->
pvts[i]);
773 static void ss7_inservice(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
unsigned int dpc)
777 for (i = 0; i < linkset->
numchans; i++) {
778 if (ss7_match_range(linkset->
pvts[i], startcic, endcic, dpc)) {
779 sig_ss7_lock_private(linkset->
pvts[i]);
780 sig_ss7_set_inservice(linkset->
pvts[i], 1);
781 sig_ss7_unlock_private(linkset->
pvts[i]);
811 int i, startcic, endcic,
dpc;
818 startcic = linkset->
pvts[0]->
cic;
819 p = linkset->
pvts[0];
823 for (i = 0; i < linkset->
numchans; i++) {
824 if (linkset->
pvts[i+1]
825 && linkset->
pvts[i+1]->
dpc == dpc
827 && linkset->
pvts[i]->
cic - startcic < (linkset->
type == SS7_ANSI ? 24 : 31)) {
830 endcic = linkset->
pvts[i]->
cic;
831 ast_verb(1,
"Resetting CICs %d to %d\n", startcic, endcic);
833 sig_ss7_lock_private(p);
834 if (!ss7_find_alloc_call(p)) {
836 }
else if (!(endcic - startcic)) {
841 sig_ss7_unlock_private(p);
844 if (linkset->
pvts[i+1]) {
845 startcic = linkset->
pvts[i+1]->
cic;
847 p = linkset->
pvts[i+1];
895 if (!linkset->
pvts[which]) {
899 if (!ss7_find_alloc_call(linkset->
pvts[which])) {
904 sig_ss7_set_inservice(linkset->
pvts[which], 0);
905 sig_ss7_loopback(linkset->
pvts[which], 0);
907 sig_ss7_lock_owner(linkset, which);
914 ss7_do_rsc(linkset->
pvts[which]);
936 static void ss7_clear_channels(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
int dpc,
int do_hangup)
940 for (i = 0; i < linkset->
numchans; i++) {
941 if (ss7_match_range(linkset->
pvts[i], startcic, endcic, dpc)) {
942 sig_ss7_lock_private(linkset->
pvts[i]);
943 sig_ss7_set_inservice(linkset->
pvts[i], 0);
944 sig_ss7_lock_owner(linkset, i);
951 do_hangup : SS7_HANGUP_DO_NOTHING;
952 }
else if (linkset->
pvts[i] && linkset->
pvts[i]->
cic != startcic) {
956 sig_ss7_unlock_private(linkset->
pvts[i]);
974 struct ss7 *ss7 = linkset->
ss7;
990 if (linkset->
type == SS7_ITU) {
1004 sig_ss7_unlock_private(p);
1009 sig_ss7_lock_private(p);
1018 sig_ss7_lock_private(p);
1090 strp =
"NO_REDIRECTION";
1093 strp =
"CALL_REROUTED_PRES_ALLOWED";
1096 strp =
"CALL_REROUTED_INFO_RESTRICTED";
1099 strp =
"CALL_DIVERTED_PRES_ALLOWED";
1102 strp =
"CALL_DIVERTED_INFO_RESTRICTED";
1105 strp =
"CALL_REROUTED_PRES_RESTRICTED";
1108 strp =
"CALL_DIVERTED_PRES_RESTRICTED";
1114 strp =
"NO_REDIRECTION";
1201 redirecting.from.number.valid = 1;
1209 redirecting.from.name.valid = 1;
1217 redirecting.orig.number.valid = 1;
1220 }
else if (redirecting.count == 1) {
1236 case ISUP_CUG_OUTGOING_ALLOWED:
1237 strp =
"OUTGOING_ALLOWED";
1239 case ISUP_CUG_OUTGOING_NOT_ALLOWED:
1240 strp =
"OUTGOING_NOT_ALLOWED";
1257 sig_ss7_unlock_private(p);
1269 sig_ss7_lock_private(p);
1273 static void ss7_apply_plan_to_number(
char *
buf,
size_t size,
const struct sig_ss7_linkset *ss7,
const char *
number,
const unsigned nai)
1282 case SS7_NAI_INTERNATIONAL:
1285 case SS7_NAI_NATIONAL:
1288 case SS7_NAI_SUBSCRIBER:
1291 case SS7_NAI_UNKNOWN:
1294 case SS7_NAI_NETWORKROUTED:
1298 snprintf(buf, size,
"%s", number);
1303 static int ss7_pres_scr2cid_pres(
char presentation_ind,
char screening_ind)
1305 return ((presentation_ind & 0x3) << 5) | (screening_ind & 0x3);
1325 sig_ss7_lock_owner(linkset, chanpos);
1357 && linkset->
type == SS7_ITU
1359 && !isup_start_digittimeout(linkset->
ss7, p->
ss7call)) {
1366 sig_ss7_set_dnid(p, p->
exten);
1369 if ((e->e == ISUP_EVENT_IAM)
1370 ? !(e->iam.cot_check_required || e->iam.cot_performed_on_previous_cic)
1371 : (!(e->sam.cot_check_required || e->sam.cot_performed_on_previous_cic) || e->sam.cot_check_passed)) {
1372 ss7_start_call(p, linkset);
1377 ast_debug(1,
"Call on CIC for unconfigured extension %s\n", p->
exten);
1385 struct timeval *next =
NULL, tv;
1387 struct ss7 *ss7 = linkset->
ss7;
1388 ss7_event *e =
NULL;
1391 unsigned char mb_state[255];
1394 #define SS7_MAX_POLL 60000 1396 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
1405 if ((next = ss7_schedule_next(ss7))) {
1407 tv.tv_sec = next->tv_sec - tv.tv_sec;
1408 tv.tv_usec = next->tv_usec - tv.tv_usec;
1409 if (tv.tv_usec < 0) {
1410 tv.tv_usec += 1000000;
1413 if (tv.tv_sec < 0) {
1417 nextms = tv.tv_sec * 1000;
1418 nextms += tv.tv_usec / 1000;
1419 if (SS7_MAX_POLL < nextms) {
1420 nextms = SS7_MAX_POLL;
1423 nextms = SS7_MAX_POLL;
1427 pollers[i].fd = linkset->
fds[i];
1428 pollers[i].events = ss7_pollflags(ss7, linkset->
fds[i]);
1429 pollers[i].revents = 0;
1433 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
1434 pthread_testcancel();
1435 res = poll(pollers, linkset->
numsigchans, nextms);
1436 pthread_testcancel();
1437 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
1440 if ((res < 0) && (
errno != EINTR)) {
1443 ss7_schedule_run(ss7);
1447 if (pollers[i].revents & POLLPRI) {
1448 sig_ss7_handle_link_exception(linkset, i);
1450 if (pollers[i].revents & POLLIN) {
1451 res = ss7_read(ss7, pollers[i].fd);
1453 if (pollers[i].revents & POLLOUT) {
1454 res = ss7_write(ss7, pollers[i].fd);
1461 while ((e = ss7_check_event(ss7))) {
1466 if (linkset->
debug) {
1468 linkset->
span, ss7_event2str(e->e));
1473 if (linkset->
state != LINKSET_STATE_UP) {
1475 ss7_reset_linkset(linkset);
1477 linkset->
state = LINKSET_STATE_UP;
1479 case SS7_EVENT_DOWN:
1481 linkset->
state = LINKSET_STATE_DOWN;
1482 for (i = 0; i < linkset->
numchans; i++) {
1483 p = linkset->
pvts[i];
1485 sig_ss7_set_inservice(p, 0);
1493 ast_verb(1,
"MTP2 link up (SLC %d)\n", e->gen.data);
1495 case MTP2_LINK_DOWN:
1498 case ISUP_EVENT_CPG:
1499 chanpos = ss7_find_cic_gripe(linkset, e->cpg.cic, e->cpg.opc,
"CPG");
1501 isup_free_call(ss7, e->cpg.call);
1504 p = linkset->
pvts[chanpos];
1505 sig_ss7_lock_private(p);
1506 callid = func_ss7_linkset_callid(linkset, chanpos);
1508 switch (e->cpg.event) {
1509 case CPG_EVENT_ALERTING:
1513 sig_ss7_lock_owner(linkset, chanpos);
1521 ast_connected.id.number.presentation =
1522 ss7_pres_scr2cid_pres(e->cpg.connected_presentation_ind,
1523 e->cpg.connected_screening_ind);
1524 ss7_apply_plan_to_number(connected_num,
sizeof(connected_num),
1525 linkset, e->cpg.connected_num, e->cpg.connected_nai);
1526 ast_connected.id.number.str =
ast_strdup(connected_num);
1527 ast_connected.id.number.valid = 1;
1535 case CPG_EVENT_PROGRESS:
1536 case CPG_EVENT_INBANDINFO:
1538 ast_debug(1,
"Queuing frame PROGRESS on CIC %d\n", p->
cic);
1541 sig_ss7_set_dialing(p, 0);
1542 sig_ss7_open_media(p);
1546 ast_debug(1,
"Do not handle CPG with event type 0x%x\n", e->cpg.event);
1550 sig_ss7_unlock_private(p);
1552 case ISUP_EVENT_RSC:
1553 ast_verb(1,
"Resetting CIC %d\n", e->rsc.cic);
1554 chanpos = ss7_find_cic_gripe(linkset, e->rsc.cic, e->rsc.opc,
"RSC");
1556 isup_free_call(ss7, e->rsc.call);
1559 p = linkset->
pvts[chanpos];
1560 sig_ss7_lock_private(p);
1562 callid = func_ss7_linkset_callid(linkset, chanpos);
1563 sig_ss7_set_inservice(p, 1);
1567 isup_blo(ss7, e->rsc.call);
1572 isup_set_call_dpc(e->rsc.call, p->
dpc);
1573 sig_ss7_lock_owner(linkset, chanpos);
1576 if (!(e->rsc.got_sent_msg & ISUP_SENT_IAM)) {
1588 isup_rlc(ss7, e->rsc.call);
1589 p->
ss7call = isup_free_call_if_clear(ss7, e->rsc.call);
1592 sig_ss7_loopback(p, 0);
1594 sig_ss7_unlock_private(p);
1596 case ISUP_EVENT_GRS:
1600 e->grs.startcic, e->grs.endcic, e->grs.opc);
1603 isup_free_call(ss7, e->grs.call);
1606 p = linkset->
pvts[chanpos];
1607 sig_ss7_lock_private(p);
1608 p->
ss7call = isup_free_call_if_clear(ss7, e->grs.call);
1609 sig_ss7_unlock_private(p);
1614 for (i = e->grs.endcic - e->grs.startcic; 0 <= i; --i) {
1620 p = linkset->
pvts[chanpos];
1621 sig_ss7_lock_private(p);
1634 isup_gra(ss7, p->
ss7call, e->grs.endcic, mb_state);
1637 sig_ss7_lock_owner(linkset, chanpos);
1652 isup_free_call(ss7, p->
ss7call);
1655 sig_ss7_set_inservice(p, 1);
1656 sig_ss7_unlock_private(p);
1659 case ISUP_EVENT_CQM:
1660 ast_debug(1,
"Got Circuit group query message from CICs %d to %d\n",
1661 e->cqm.startcic, e->cqm.endcic);
1662 ss7_handle_cqm(linkset, e);
1664 case ISUP_EVENT_GRA:
1666 e->gra.endcic, e->gra.opc)) {
1668 e->gra.startcic, e->gra.endcic, e->gra.opc);
1669 isup_free_call(ss7, e->gra.call);
1672 ast_verb(1,
"Got reset acknowledgement from CIC %d to %d DPC: %d\n",
1673 e->gra.startcic, e->gra.endcic, e->gra.opc);
1674 ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc,
1676 ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc);
1680 isup_free_call(ss7, e->gra.call);
1684 p = linkset->
pvts[chanpos];
1685 sig_ss7_lock_private(p);
1688 p->
ss7call = isup_free_call_if_clear(ss7, e->gra.call);
1689 sig_ss7_unlock_private(p);
1691 case ISUP_EVENT_SAM:
1692 chanpos = ss7_find_cic_gripe(linkset, e->sam.cic, e->sam.opc,
"SAM");
1694 isup_free_call(ss7, e->sam.call);
1697 p = linkset->
pvts[chanpos];
1698 sig_ss7_lock_private(p);
1699 sig_ss7_lock_owner(linkset, chanpos);
1701 ast_log(
LOG_WARNING,
"SAM on CIC %d PC %d already have call\n", e->sam.cic, e->sam.opc);
1703 sig_ss7_unlock_private(p);
1709 strncat(p->
exten, e->sam.called_party_num,
sizeof(p->
exten) - strlen(p->
exten) - 1);
1710 st = strchr(p->
exten,
'#');
1715 ss7_match_extension(linkset, p, e);
1717 sig_ss7_unlock_private(p);
1719 case ISUP_EVENT_IAM:
1720 ast_debug(1,
"Got IAM for CIC %d and called number %s, calling number %s\n", e->iam.cic, e->iam.called_party_num, e->iam.calling_party_num);
1721 chanpos = ss7_find_cic_gripe(linkset, e->iam.cic, e->iam.opc,
"IAM");
1723 isup_free_call(ss7, e->iam.call);
1726 p = linkset->
pvts[chanpos];
1727 sig_ss7_lock_private(p);
1735 ast_log(
LOG_NOTICE,
"Got IAM on remotely blocked CIC %d DPC %d remove blocking\n", e->iam.cic, e->iam.opc);
1737 sig_ss7_set_inservice(p, 1);
1740 if (!sig_ss7_is_chan_available(p)) {
1744 isup_clear_callflags(ss7, e->iam.call, ISUP_GOT_IAM);
1745 p->
ss7call = isup_free_call_if_clear(ss7, e->iam.call);
1746 ast_log(
LOG_WARNING,
"Got IAM on locally blocked CIC %d DPC %d, ignore\n", e->iam.cic, e->iam.opc);
1748 sig_ss7_unlock_private(p);
1760 p->
callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind);
1763 if (e->iam.presentation_ind) {
1764 p->
callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind);
1774 ss7_apply_plan_to_number(p->
exten,
sizeof(p->
exten), linkset, e->iam.called_party_num, e->iam.
called_nai);
1775 st = strchr(p->
exten,
'#');
1805 p->
orig_called_presentation = ss7_pres_scr2cid_pres(e->iam.orig_called_pres_ind, e->iam.orig_called_screening_ind);
1809 p->
redirecting_presentation = ss7_pres_scr2cid_pres(e->iam.redirecting_num_presentation_ind, e->iam.redirecting_num_screening_ind);
1826 if (e->iam.cot_check_required) {
1827 sig_ss7_loopback(p, 1);
1831 sig_ss7_set_caller_id(p);
1832 ss7_match_extension(linkset, p, e);
1833 sig_ss7_unlock_private(p);
1835 if (e->iam.cot_performed_on_previous_cic) {
1839 ast_verb(1,
"COT request on previous nonexistent CIC %d in IAM PC %d\n", (e->iam.cic - 1), e->iam.opc);
1842 ast_verb(1,
"COT request on previous CIC %d in IAM PC %d\n", (e->iam.cic - 1), e->iam.opc);
1843 p = linkset->
pvts[chanpos];
1844 sig_ss7_lock_private(p);
1845 if (sig_ss7_is_chan_available(p)) {
1846 sig_ss7_set_inservice(p, 0);
1847 sig_ss7_loopback(p, 1);
1849 sig_ss7_unlock_private(p);
1852 case ISUP_EVENT_DIGITTIMEOUT:
1853 chanpos = ss7_find_cic_gripe(linkset, e->digittimeout.cic, e->digittimeout.opc,
"DIGITTIMEOUT");
1855 isup_free_call(ss7, e->digittimeout.call);
1858 p = linkset->
pvts[chanpos];
1859 sig_ss7_lock_private(p);
1860 ast_debug(1,
"Digittimeout on CIC: %d PC: %d\n", e->digittimeout.cic, e->digittimeout.opc);
1864 sig_ss7_set_dnid(p, p->
exten);
1867 if (!(e->digittimeout.cot_check_required || e->digittimeout.cot_performed_on_previous_cic) || e->digittimeout.cot_check_passed) {
1868 ss7_start_call(p, linkset);
1871 ast_debug(1,
"Call on CIC for unconfigured extension %s\n", p->
exten);
1874 sig_ss7_unlock_private(p);
1876 case ISUP_EVENT_COT:
1877 if (e->cot.cot_performed_on_previous_cic) {
1881 p = linkset->
pvts[chanpos];
1882 sig_ss7_lock_private(p);
1883 sig_ss7_set_inservice(p, 1);
1884 sig_ss7_loopback(p, 0);
1885 sig_ss7_unlock_private(p);;
1886 ast_verb(1,
"Loop turned off on CIC: %d PC: %d\n", (e->cot.cic - 1), e->cot.opc);
1890 chanpos = ss7_find_cic_gripe(linkset, e->cot.cic, e->cot.opc,
"COT");
1892 isup_free_call(ss7, e->cot.call);
1895 p = linkset->
pvts[chanpos];
1897 sig_ss7_lock_private(p);
1901 sig_ss7_loopback(p, 0);
1902 ast_verb(1,
"Loop turned off on CIC: %d PC: %d\n", e->cot.cic, e->cot.opc);
1906 if ((e->cot.got_sent_msg & ISUP_GOT_IAM) && e->cot.passed && p->
called_complete) {
1907 ss7_start_call(p, linkset);
1911 sig_ss7_unlock_private(p);
1913 case ISUP_EVENT_CCR:
1914 ast_debug(1,
"Got CCR request on CIC %d\n", e->ccr.cic);
1915 chanpos = ss7_find_cic_gripe(linkset, e->ccr.cic, e->ccr.opc,
"CCR");
1917 isup_free_call(ss7, e->ccr.call);
1921 p = linkset->
pvts[chanpos];
1923 sig_ss7_lock_private(p);
1925 sig_ss7_loopback(p, 1);
1926 if (linkset->
type == SS7_ANSI) {
1927 isup_lpa(linkset->
ss7, e->ccr.cic, p->
dpc);
1929 sig_ss7_unlock_private(p);
1931 case ISUP_EVENT_CVT:
1932 ast_debug(1,
"Got CVT request on CIC %d\n", e->cvt.cic);
1933 chanpos = ss7_find_cic_gripe(linkset, e->cvt.cic, e->cvt.opc,
"CVT");
1935 isup_free_call(ss7, e->cvt.call);
1939 p = linkset->
pvts[chanpos];
1941 sig_ss7_lock_private(p);
1943 sig_ss7_loopback(p, 1);
1945 p->
ss7call = isup_free_call_if_clear(ss7, e->cvt.call);
1947 isup_cvr(linkset->
ss7, e->cvt.cic, p->
dpc);
1948 sig_ss7_unlock_private(p);
1950 case ISUP_EVENT_REL:
1951 chanpos = ss7_find_cic_gripe(linkset, e->rel.cic, e->rel.opc,
"REL");
1953 isup_free_call(ss7, e->rel.call);
1956 p = linkset->
pvts[chanpos];
1957 sig_ss7_lock_private(p);
1959 callid = func_ss7_linkset_callid(linkset, chanpos);
1960 sig_ss7_lock_owner(linkset, chanpos);
1962 snprintf(cause_str,
sizeof(cause_str),
"SS7 ISUP_EVENT_REL (%d)", e->rel.cause);
1963 ss7_queue_pvt_cause_data(p->
owner, cause_str, e->rel.cause);
1970 ast_verb(1,
"REL on CIC %d DPC %d without owner!\n", p->
cic, p->
dpc);
1976 sig_ss7_loopback(p, 0);
1979 sig_ss7_unlock_private(p);
1981 case ISUP_EVENT_ACM:
1982 chanpos = ss7_find_cic_gripe(linkset, e->acm.cic, e->acm.opc,
"ACM");
1984 isup_free_call(ss7, e->acm.call);
1988 p = linkset->
pvts[chanpos];
1990 ast_debug(1,
"Queueing frame from SS7_EVENT_ACM on CIC %d\n", p->
cic);
1992 if (e->acm.call_ref_ident > 0) {
1996 sig_ss7_lock_private(p);
1998 callid = func_ss7_linkset_callid(linkset, chanpos);
2003 sig_ss7_set_dialing(p, 0);
2005 if (e->acm.called_party_status_ind == 1) {
2009 sig_ss7_lock_owner(linkset, chanpos);
2017 sig_ss7_unlock_private(p);
2019 case ISUP_EVENT_CGB:
2020 chanpos = ss7_find_cic_gripe(linkset, e->cgb.startcic, e->cgb.opc,
"CGB");
2022 isup_free_call(ss7, e->cgb.call);
2025 p = linkset->
pvts[chanpos];
2026 ss7_check_range(linkset, e->cgb.startcic, e->cgb.endcic,
2027 e->cgb.opc, e->cgb.status);
2028 ss7_block_cics(linkset, e->cgb.startcic, e->cgb.endcic,
2029 e->cgb.opc, e->cgb.status, 1, 1,
2032 sig_ss7_lock_private(p);
2035 isup_cgba(linkset->
ss7, p->
ss7call, e->cgb.endcic, e->cgb.status);
2037 p->
ss7call = isup_free_call_if_clear(ss7, e->cgb.call);
2039 sig_ss7_unlock_private(p);
2041 case ISUP_EVENT_CGU:
2042 chanpos = ss7_find_cic_gripe(linkset, e->cgu.startcic, e->cgu.opc,
"CGU");
2044 isup_free_call(ss7, e->cgu.call);
2047 p = linkset->
pvts[chanpos];
2048 ss7_check_range(linkset, e->cgu.startcic, e->cgu.endcic,
2049 e->cgu.opc, e->cgu.status);
2050 ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic,
2051 e->cgu.opc, e->cgu.status, 0, 1,
2054 sig_ss7_lock_private(p);
2057 isup_cgua(linkset->
ss7, p->
ss7call, e->cgu.endcic, e->cgu.status);
2059 p->
ss7call = isup_free_call_if_clear(ss7, e->cgu.call);
2061 sig_ss7_unlock_private(p);
2063 case ISUP_EVENT_UCIC:
2064 chanpos = ss7_find_cic_gripe(linkset, e->ucic.cic, e->ucic.opc,
"UCIC");
2066 isup_free_call(ss7, e->ucic.call);
2069 p = linkset->
pvts[chanpos];
2070 ast_debug(1,
"Unequiped Circuit Id Code on CIC %d\n", e->ucic.cic);
2071 sig_ss7_lock_private(p);
2072 sig_ss7_lock_owner(linkset, chanpos);
2078 sig_ss7_set_inservice(p, 0);
2080 isup_free_call(ss7, e->ucic.call);
2081 sig_ss7_unlock_private(p);
2083 case ISUP_EVENT_BLO:
2084 chanpos = ss7_find_cic_gripe(linkset, e->blo.cic, e->blo.opc,
"BLO");
2086 isup_free_call(ss7, e->blo.call);
2089 p = linkset->
pvts[chanpos];
2090 ast_debug(1,
"Blocking CIC %d\n", e->blo.cic);
2091 sig_ss7_lock_private(p);
2094 isup_bla(linkset->
ss7, e->blo.call);
2095 sig_ss7_lock_owner(linkset, chanpos);
2097 p->
ss7call = isup_free_call_if_clear(ss7, e->blo.call);
2099 if (e->blo.got_sent_msg & ISUP_SENT_IAM) {
2105 sig_ss7_unlock_private(p);
2107 case ISUP_EVENT_BLA:
2108 chanpos = ss7_find_cic_gripe(linkset, e->bla.cic, e->bla.opc,
"BLA");
2110 isup_free_call(ss7, e->bla.call);
2113 ast_debug(1,
"Locally blocking CIC %d\n", e->bla.cic);
2114 p = linkset->
pvts[chanpos];
2115 sig_ss7_lock_private(p);
2121 sig_ss7_unlock_private(p);
2123 case ISUP_EVENT_UBL:
2124 chanpos = ss7_find_cic_gripe(linkset, e->ubl.cic, e->ubl.opc,
"UBL");
2126 isup_free_call(ss7, e->ubl.call);
2129 p = linkset->
pvts[chanpos];
2130 ast_debug(1,
"Remotely unblocking CIC %d PC %d\n", e->ubl.cic, e->ubl.opc);
2131 sig_ss7_lock_private(p);
2134 isup_uba(linkset->
ss7, e->ubl.call);
2138 sig_ss7_unlock_private(p);
2140 case ISUP_EVENT_UBA:
2141 chanpos = ss7_find_cic_gripe(linkset, e->uba.cic, e->uba.opc,
"UBA");
2143 isup_free_call(ss7, e->uba.call);
2146 p = linkset->
pvts[chanpos];
2147 ast_debug(1,
"Locally unblocking CIC %d PC %d\n", e->uba.cic, e->uba.opc);
2148 sig_ss7_lock_private(p);
2154 sig_ss7_unlock_private(p);
2156 case ISUP_EVENT_CON:
2157 case ISUP_EVENT_ANM:
2158 if (e->e == ISUP_EVENT_CON) {
2159 chanpos = ss7_find_cic_gripe(linkset, e->con.cic, e->con.opc,
"CON");
2161 isup_free_call(ss7, e->con.call);
2165 chanpos = ss7_find_cic_gripe(linkset, e->anm.cic, e->anm.opc,
"ANM");
2167 isup_free_call(ss7, e->anm.call);
2172 p = linkset->
pvts[chanpos];
2173 sig_ss7_lock_private(p);
2174 p->
ss7call = (e->e == ISUP_EVENT_ANM) ? e->anm.call : e->con.call;
2175 callid = func_ss7_linkset_callid(linkset, chanpos);
2181 ? e->anm.connected_num : e->con.connected_num)) {
2182 sig_ss7_lock_owner(linkset, chanpos);
2188 if (e->e == ISUP_EVENT_ANM) {
2189 ast_connected.id.number.presentation = ss7_pres_scr2cid_pres(
2190 e->anm.connected_presentation_ind,
2191 e->anm.connected_screening_ind);
2192 ss7_apply_plan_to_number(connected_num,
sizeof(connected_num),
2193 linkset, e->anm.connected_num, e->anm.connected_nai);
2194 ast_connected.id.number.str =
ast_strdup(connected_num);
2196 ast_connected.id.number.presentation = ss7_pres_scr2cid_pres(
2197 e->con.connected_presentation_ind,
2198 e->con.connected_screening_ind);
2199 ss7_apply_plan_to_number(connected_num,
sizeof(connected_num),
2200 linkset, e->con.connected_num, e->con.connected_nai);
2201 ast_connected.id.number.str =
ast_strdup(connected_num);
2203 ast_connected.id.number.valid = 1;
2212 sig_ss7_set_dialing(p, 0);
2213 sig_ss7_open_media(p);
2214 if (((e->e == ISUP_EVENT_ANM) ? !e->anm.echocontrol_ind :
2216 sig_ss7_set_echocanceller(p, 1);
2218 sig_ss7_unlock_private(p);
2220 case ISUP_EVENT_RLC:
2221 chanpos = ss7_find_cic_gripe(linkset, e->rlc.cic, e->rlc.opc,
"RLC");
2223 isup_free_call(ss7, e->rlc.call);
2227 p = linkset->
pvts[chanpos];
2228 sig_ss7_lock_private(p);
2230 callid = func_ss7_linkset_callid(linkset, chanpos);
2231 if (e->rlc.got_sent_msg & (ISUP_SENT_RSC | ISUP_SENT_REL)) {
2232 sig_ss7_loopback(p, 0);
2233 if (e->rlc.got_sent_msg & ISUP_SENT_RSC) {
2234 sig_ss7_set_inservice(p, 1);
2237 sig_ss7_lock_owner(linkset, chanpos);
2239 p->
ss7call = isup_free_call_if_clear(ss7, e->rlc.call);
2246 sig_ss7_unlock_private(p);
2248 case ISUP_EVENT_FAA:
2253 chanpos = ss7_find_cic_gripe(linkset, e->faa.cic, e->faa.opc,
"FAA");
2255 isup_free_call(ss7, e->faa.call);
2260 p = linkset->
pvts[chanpos];
2261 sig_ss7_lock_private(p);
2262 callid = func_ss7_linkset_callid(linkset, chanpos);
2263 ast_debug(1,
"FAA received on CIC %d\n", e->faa.cic);
2264 p->
ss7call = isup_free_call_if_clear(ss7, e->faa.call);
2265 sig_ss7_unlock_private(p);
2267 case ISUP_EVENT_CGBA:
2268 chanpos = ss7_find_cic_gripe(linkset, e->cgba.startcic, e->cgba.opc,
"CGBA");
2270 isup_free_call(ss7, e->cgba.call);
2274 ss7_block_cics(linkset, e->cgba.startcic, e->cgba.endcic,
2275 e->cgba.opc, e->cgba.status, 1, 0,
2278 p = linkset->
pvts[chanpos];
2279 sig_ss7_lock_private(p);
2285 sig_ss7_unlock_private(p);
2287 case ISUP_EVENT_CGUA:
2288 chanpos = ss7_find_cic_gripe(linkset, e->cgua.startcic, e->cgua.opc,
"CGUA");
2290 isup_free_call(ss7, e->cgua.call);
2294 ss7_block_cics(linkset, e->cgua.startcic, e->cgua.endcic,
2295 e->cgua.opc, e->cgua.status, 0, 0,
2298 p = linkset->
pvts[chanpos];
2299 sig_ss7_lock_private(p);
2305 sig_ss7_unlock_private(p);
2307 case ISUP_EVENT_SUS:
2308 chanpos = ss7_find_cic_gripe(linkset, e->sus.cic, e->sus.opc,
"SUS");
2310 isup_free_call(ss7, e->sus.call);
2314 p = linkset->
pvts[chanpos];
2315 sig_ss7_lock_private(p);
2320 sig_ss7_unlock_private(p);
2322 case ISUP_EVENT_RES:
2323 chanpos = ss7_find_cic_gripe(linkset, e->res.cic, e->res.opc,
"RES");
2325 isup_free_call(ss7, e->res.call);
2329 p = linkset->
pvts[chanpos];
2330 sig_ss7_lock_private(p);
2335 sig_ss7_unlock_private(p);
2338 ast_debug(1,
"Unknown event %s\n", ss7_event2str(e->e));
2360 pthread_kill(ss7->
master, SIGURG);
2369 sig_ss7_deadlock_avoidance_private(pvt);
2388 for (i = 0; i < linkset->
numchans; i++) {
2389 if (linkset->
pvts[i] && linkset->
pvts[i]->
cic == cic && linkset->
pvts[i]->
dpc == dpc) {
2392 sig_ss7_lock_private(linkset->
pvts[i]);
2394 res = ss7_start_rsc(linkset, i);
2395 sig_ss7_unlock_private(linkset->
pvts[i]);
2418 sig_ss7_lock_private(linkset->
pvts[which]);
2419 if (!ss7_find_alloc_call(linkset->
pvts[which])) {
2420 sig_ss7_unlock_private(linkset->
pvts[which]);
2431 sig_ss7_unlock_private(linkset->
pvts[which]);
2454 sig_ss7_lock_private(linkset->
pvts[chanpos]);
2455 if (!ss7_find_alloc_call(linkset->
pvts[chanpos])) {
2456 sig_ss7_unlock_private(linkset->
pvts[chanpos]);
2461 isup_cgb(linkset->
ss7, linkset->
pvts[chanpos]->
ss7call, endcic, state, type);
2463 isup_cgu(linkset->
ss7, linkset->
pvts[chanpos]->
ss7call, endcic, state, type);
2466 sig_ss7_unlock_private(linkset->
pvts[chanpos]);
2487 for (i = 0; i < linkset->
numchans; i++) {
2488 if (linkset->
pvts[i] && linkset->
pvts[i]->
cic == cic && linkset->
pvts[i]->
dpc == dpc) {
2489 ss7_clear_channels(linkset, cic, cic + range, dpc, SS7_HANGUP_FREE_CALL);
2490 ss7_block_cics(linkset, cic, cic + range, dpc,
NULL, 0, 1,
2492 ss7_block_cics(linkset, cic, cic + range, dpc,
NULL, 0, 0,
2495 sig_ss7_lock_private(linkset->
pvts[i]);
2496 if (!ss7_find_alloc_call(linkset->
pvts[i])) {
2497 sig_ss7_unlock_private(linkset->
pvts[i]);
2501 sig_ss7_unlock_private(linkset->
pvts[i]);
2510 sig_ss7_lock_private(linkset->
pvts[channel]);
2515 sig_ss7_unlock_private(linkset->
pvts[channel]);
2518 static int ss7_parse_prefix(
struct sig_ss7_chan *p,
const char *number,
char *nai)
2524 *nai = SS7_NAI_INTERNATIONAL;
2527 *nai = SS7_NAI_NATIONAL;
2530 *nai = SS7_NAI_NETWORKROUTED;
2533 *nai = SS7_NAI_UNKNOWN;
2536 *nai = SS7_NAI_SUBSCRIBER;
2538 *nai = SS7_NAI_SUBSCRIBER;
2557 ss7_link_alarm(linkset->
ss7, linkset->
fds[which]);
2573 ss7_link_noalarm(linkset->
ss7, linkset->
fds[which]);
2592 int sig_ss7_add_sigchan(
struct sig_ss7_linkset *linkset,
int which,
int ss7type,
int transport,
int inalarm,
int networkindicator,
int pointcode,
int adjpointcode,
int cur_slc)
2594 if (!linkset->
ss7) {
2595 linkset->
type = ss7type;
2596 linkset->
ss7 = ss7_new(ss7type);
2597 if (!linkset->
ss7) {
2603 ss7_set_network_ind(linkset->
ss7, networkindicator);
2604 ss7_set_pc(linkset->
ss7, pointcode);
2606 if (ss7_add_link(linkset->
ss7, transport, linkset->
fds[which], cur_slc, adjpointcode)) {
2612 ss7_link_alarm(linkset->
ss7, linkset->
fds[which]);
2615 ss7_link_noalarm(linkset->
ss7, linkset->
fds[which]);
2640 available = sig_ss7_is_chan_available(p);
2655 static unsigned char cid_pres2ss7pres(
int cid_pres)
2657 return (cid_pres >> 5) & 0x03;
2660 static unsigned char cid_pres2ss7screen(
int cid_pres)
2662 return cid_pres & 0x03;
2667 int connected_strip = 0;
2669 unsigned char connected_pres;
2670 unsigned char connected_screen;
2671 const char *connected_num;
2679 connected_strip = ss7_parse_prefix(p, connected_num, &connected_nai);
2687 isup_set_connected(p->
ss7call, connected_num + connected_strip, connected_nai, connected_pres, connected_screen);
2721 static unsigned char ss7_redirect_info_ind(
struct ast_channel *ast)
2723 const char *redirect_info_ind;
2728 if (!strcasecmp(redirect_info_ind,
"CALL_REROUTED_PRES_ALLOWED")) {
2731 if (!strcasecmp(redirect_info_ind,
"CALL_REROUTED_INFO_RESTRICTED")) {
2734 if (!strcasecmp(redirect_info_ind,
"CALL_DIVERTED_PRES_ALLOWED")) {
2737 if (!strcasecmp(redirect_info_ind,
"CALL_DIVERTED_INFO_RESTRICTED")) {
2740 if (!strcasecmp(redirect_info_ind,
"CALL_REROUTED_PRES_RESTRICTED")) {
2743 if (!strcasecmp(redirect_info_ind,
"CALL_DIVERTED_PRES_RESTRICTED")) {
2746 if (!strcasecmp(redirect_info_ind,
"SPARE")) {
2773 int num_nai_strip = 0;
2776 if (!redirecting->
count) {
2780 isup_set_redirect_counter(p->
ss7call, redirecting->
count);
2787 num_nai_strip = ss7_parse_prefix(p, ss7_orig_called_num, &ss7_orig_called_nai);
2791 isup_set_orig_called_num(p->
ss7call, ss7_orig_called_num + num_nai_strip,
2792 ss7_orig_called_nai,
2802 num_nai_strip = ss7_parse_prefix(p, redirecting_number, &ss7_redirecting_num_nai);
2807 isup_set_redirecting_number(p->
ss7call, redirecting_number + num_nai_strip,
2808 ss7_redirecting_num_nai,
2813 isup_set_redirection_info(p->
ss7call, ss7_redirect_info_ind(ast),
2831 char ss7_called_nai;
2832 int called_nai_strip;
2833 char ss7_calling_nai;
2834 int calling_nai_strip;
2835 const char *col_req =
NULL;
2836 const char *ss7_cug_indicator_str;
2837 const char *ss7_cug_interlock_ni;
2838 const char *ss7_cug_interlock_code;
2839 const char *ss7_interworking_indicator;
2840 const char *ss7_forward_indicator_pmbits;
2841 unsigned char ss7_cug_indicator;
2842 const char *charge_str =
NULL;
2843 const char *gen_address =
NULL;
2844 const char *gen_digits =
NULL;
2845 const char *gen_dig_type =
NULL;
2846 const char *gen_dig_scheme =
NULL;
2847 const char *gen_name =
NULL;
2848 const char *jip_digits =
NULL;
2849 const char *lspi_ident =
NULL;
2850 const char *rlt_flag =
NULL;
2851 const char *call_ref_id =
NULL;
2852 const char *call_ref_pc =
NULL;
2853 const char *send_far =
NULL;
2854 const char *tmr =
NULL;
2861 c = strchr(dest,
'/');
2878 ss7_grab(p, p->
ss7);
2886 called_nai_strip = 0;
2889 called_nai_strip = ss7_parse_prefix(p, c + p->
stripmsd, &ss7_called_nai);
2893 calling_nai_strip = 0;
2896 calling_nai_strip = ss7_parse_prefix(p, l, &ss7_calling_nai);
2899 isup_set_calling(p->
ss7call, l ? (l + calling_nai_strip) :
NULL, ss7_calling_nai,
2901 : (l ? SS7_PRESENTATION_ALLOWED
2903 ? SS7_PRESENTATION_ADDR_NOT_AVAILABLE : SS7_PRESENTATION_RESTRICTED)),
2911 isup_set_charge(p->
ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
2921 isup_set_gen_digits(p->
ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme));
2925 isup_set_generic_name(p->
ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
2929 isup_set_jip_digits(p->
ss7call, jip_digits);
2933 isup_set_lspi(p->
ss7call, lspi_ident, 0x18, 0x7, 0x00);
2936 if ((rlt_flag) && ((strncmp(
"NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
2937 isup_set_lspi(p->
ss7call, rlt_flag, 0x18, 0x7, 0x00);
2942 if (call_ref_id && call_ref_pc) {
2943 isup_set_callref(p->
ss7call, atoi(call_ref_id),
2944 call_ref_pc ? atoi(call_ref_pc) : 0);
2948 if (send_far && strncmp(
"NO", send_far, strlen(send_far)) != 0) {
2954 isup_set_tmr(p->
ss7call, atoi(tmr));
2956 if (!strcasecmp(tmr,
"SPEECH")) {
2957 isup_set_tmr(p->
ss7call, SS7_TMR_SPEECH);
2958 }
else if (!strcasecmp(tmr,
"SPARE")) {
2959 isup_set_tmr(p->
ss7call, SS7_TMR_SPARE);
2960 }
else if (!strcasecmp(tmr,
"3K1_AUDIO")) {
2961 isup_set_tmr(p->
ss7call, SS7_TMR_3K1_AUDIO);
2962 }
else if (!strcasecmp(tmr,
"64K_UNRESTRICTED")) {
2963 isup_set_tmr(p->
ss7call, SS7_TMR_64K_UNRESTRICTED);
2965 isup_set_tmr(p->
ss7call, SS7_TMR_N64K_OR_SPARE);
2976 if (!strcasecmp(ss7_cug_indicator_str,
"OUTGOING_ALLOWED")) {
2977 ss7_cug_indicator = ISUP_CUG_OUTGOING_ALLOWED;
2978 }
else if (!strcasecmp(ss7_cug_indicator_str,
"OUTGOING_NOT_ALLOWED")) {
2979 ss7_cug_indicator = ISUP_CUG_OUTGOING_NOT_ALLOWED;
2981 ss7_cug_indicator = ISUP_CUG_NON;
2984 if (ss7_cug_indicator != ISUP_CUG_NON) {
2987 if (ss7_cug_interlock_code && ss7_cug_interlock_ni && strlen(ss7_cug_interlock_ni) == 4) {
2988 isup_set_cug(p->
ss7call, ss7_cug_indicator, ss7_cug_interlock_ni, atoi(ss7_cug_interlock_code));
2993 ss7_redirecting_update(p, ast);
2997 if (ss7_interworking_indicator) {
2998 isup_set_interworking_indicator(p->
ss7call,
ast_true(ss7_interworking_indicator));
3002 if (ss7_forward_indicator_pmbits) {
3003 isup_set_forward_indicator_pmbits(p->
ss7call, atoi(ss7_forward_indicator_pmbits));
3009 sig_ss7_set_dialing(p, 1);
3033 sig_ss7_set_dialing(p, 0);
3034 sig_ss7_set_outgoing(p, 0);
3039 ss7_grab(p, p->
ss7);
3043 case SS7_HANGUP_SEND_REL:
3050 icause = atoi(cause);
3061 case SS7_HANGUP_SEND_RSC:
3065 case SS7_HANGUP_SEND_RLC:
3070 case SS7_HANGUP_FREE_CALL:
3075 case SS7_HANGUP_REEVENT_IAM:
3079 case SS7_HANGUP_DO_NOTHING:
3103 ss7_grab(p, p->
ss7);
3112 sig_ss7_open_media(p);
3129 if (pchan->
owner == oldchan) {
3130 pchan->
owner = newchan;
3151 switch (condition) {
3162 ss7_grab(p, p->
ss7);
3189 ss7_grab(p, p->
ss7);
3207 ss7_grab(p, p->
ss7);
3214 sig_ss7_set_echocanceller(p, 1);
3254 ss7_redirecting_update(p, chan);
3258 res = sig_ss7_play_tone(p, -1);
3278 int transfercapability)
3283 if (p->
ss7->
type == SS7_ITU) {
3289 sig_ss7_set_outgoing(p, 1);
3291 p->
exten, assignedids, requestor);
3293 sig_ss7_set_outgoing(p, 0);
3317 #define SIG_SS7_SC_HEADER "%-4s %4s %-4s %-3s %-3s %-10s %-4s %s\n" 3318 #define SIG_SS7_SC_LINE "%4d %4d %-4s %-3s %-3s %-10s %-4s %s" 3321 ast_cli(fd, SIG_SS7_SC_HEADER,
"link",
"",
"Chan",
"Lcl",
"Rem",
"Call",
"SS7",
"Channel");
3322 ast_cli(fd, SIG_SS7_SC_HEADER,
"set",
"Chan",
"Idle",
"Blk",
"Blk",
"Level",
"Call",
"Name");
3332 for (idx = 0; idx < linkset->
numchans; ++idx) {
3333 if (!linkset->
pvts[idx]) {
3336 pvt = linkset->
pvts[idx];
3337 sig_ss7_lock_private(pvt);
3338 sig_ss7_lock_owner(linkset, idx);
3340 snprintf(line,
sizeof(line), SIG_SS7_SC_LINE,
3343 sig_ss7_is_chan_available(pvt) ?
"Yes" :
"No",
3353 sig_ss7_unlock_private(pvt);
3399 memset(ss7, 0,
sizeof(*ss7));
unsigned char gen_add_pres_ind
struct ast_channel * sig_ss7_request(struct sig_ss7_chan *p, enum sig_ss7_law law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int transfercapability)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
#define ast_channel_lock(chan)
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
General Asterisk channel transcoding definitions.
enum sig_ss7_call_level call_level
Asterisk main include file. File version handling, generic pbx functions.
int sig_ss7_available(struct sig_ss7_chan *p)
char chan_name[AST_CHANNEL_NAME]
unsigned char gen_dig_type
int sig_ss7_reset_cic(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc)
unsigned int outgoing
TRUE if this channel is being used for an outgoing call.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
void(*const lock_private)(void *pvt)
static struct ast_codec ulaw
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
int(*const set_echocanceller)(void *pvt, int enable)
int sig_ss7_indicate(struct sig_ss7_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
struct ast_party_id id
Connected party ID.
void(*const set_alarm)(void *pvt, int in_alarm)
unsigned char gen_add_num_plan
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
#define AST_CAUSE_SWITCH_CONGESTION
void sig_ss7_cli_show_channels(int fd, struct sig_ss7_linkset *linkset)
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
#define AST_CAUSE_UNALLOCATED
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Indicate that the redirecting id has changed.
unsigned char cug_indicator
Indication of the call being a CUG call and its permissions.
void(*const set_remotelyblocked)(void *pvt, int is_blocked)
enum sig_ss7_linkset::@164 state
#define DEADLOCK_AVOIDANCE(lock)
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
char cug_interlock_ni[5]
Network Identify Code as per Q.763 3.15.a.
void ast_callid_threadstorage_auto_clean(ast_callid callid, int callid_created)
Use in conjunction with ast_callid_threadstorage_auto. Cleans up the references and if the callid was...
unsigned char redirect_info_counter
unsigned short cug_interlock_code
Binari Code to uniquely identify a CUG inside the network.
#define LINKSET_FLAG_INITIALHWBLO
#define LINKSET_FLAG_USEECHOCONTROL
unsigned int loopedback
TRUE if this channel is in loopback.
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
struct sig_ss7_linkset * ss7
void(*const set_locallyblocked)(void *pvt, int is_blocked)
Structure to pass both assignedid values to channel drivers.
struct sig_ss7_callback sig_ss7_callbacks
Interface header for SS7 signaling module.
ast_channel_state
ast_channel states
struct ast_channel *(*const new_ast_channel)(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
unsigned int inalarm
TRUE if channel is associated with a link that is down.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int redirecting_presentation
#define ast_mutex_lock(a)
struct sig_ss7_linkset *(*const find_linkset)(struct ss7 *ss7)
void ast_verbose(const char *fmt,...)
#define ast_strdup(str)
A wrapper for strdup()
static int call(void *data)
void sig_ss7_cb_notinservice(struct ss7 *ss7, int cic, unsigned int dpc)
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
unsigned char gen_dig_scheme
void sig_ss7_free_isup_call(struct sig_ss7_linkset *linkset, int channel)
char exten[AST_MAX_EXTENSION]
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
void ast_cli(int fd, const char *fmt,...)
int sig_ss7_cic_blocking(struct sig_ss7_linkset *linkset, int do_block, int cic)
#define AST_CAUSE_INVALID_NUMBER_FORMAT
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define SS7_BLOCKED_HARDWARE
int code
enum AST_REDIRECTING_REASON value for redirection
#define ast_verb(level,...)
char cid_subaddr[AST_MAX_EXTENSION]
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
char cid_name[AST_MAX_EXTENSION]
int sig_ss7_reset_group(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc, int range)
unsigned char redirect_info_reas
#define ast_strlen_zero(foo)
struct ast_party_id orig
Who originally redirected the call (Sent to the party the call is redirected toward) ...
void(*const set_digital)(void *pvt, int is_digital)
unsigned int use_callingpres
TRUE if we will use the calling presentation setting from the Asterisk channel for outgoing calls...
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked.
#define LINKSTATE_INALARM
void(*const set_dnid)(void *pvt, const char *dnid)
char context[AST_MAX_CONTEXT]
#define ast_debug(level,...)
Log a DEBUG message.
unsigned char redirect_info_ind
void(*const set_dialing)(void *pvt, int is_dialing)
unsigned int use_callerid
TRUE if caller ID is used on this channel.
unsigned int progress
TRUE if the call has seen inband-information progress through the network.
void(*const set_outgoing)(void *pvt, int is_outgoing)
#define LINKSTATE_STARTING
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
unsigned char redirect_info
#define ast_mutex_trylock(a)
struct sig_ss7_chan * sig_ss7_chan_new(void *pvt_data, struct sig_ss7_linkset *ss7)
struct ast_party_redirecting_reason orig_reason
Reason for the redirection by the original party.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
#define AST_PTHREADT_NULL
void sig_ss7_link_noalarm(struct sig_ss7_linkset *linkset, int which)
#define LINKSET_FLAG_EXPLICITACM
#define AST_MAX_EXTENSION
int sig_ss7_find_cic(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc)
#define AST_CAUSE_NORMAL_CLEARING
void(*const open_media)(void *pvt)
void sig_ss7_cli_show_channels_header(int fd)
Caller Party information.
unsigned char redirect_info_orig_reas
void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
char mohinterpret[MAX_MUSICCLASS]
unsigned int inservice
TRUE if channel is in service.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
char subscriberprefix[20]
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
struct sig_ss7_chan * pvts[SIG_SS7_MAX_CHANNELS]
int sig_ss7_call(struct sig_ss7_chan *p, struct ast_channel *ast, const char *rdest)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
int fds[SIG_SS7_NUM_DCHANS]
void(*const set_loopback)(void *pvt, int enable)
#define SIG_SS7_NUM_DCHANS
int sig_ss7_find_cic_range(struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc)
Connected Line/Party information.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
unsigned int rlt
XXX BOOLEAN Purpose???
unsigned char gen_add_type
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
int linkstate[SIG_SS7_NUM_DCHANS]
void sig_ss7_init_linkset(struct sig_ss7_linkset *ss7)
#define ast_channel_unlock(chan)
int sig_ss7_group_blocking(struct sig_ss7_linkset *linkset, int do_block, int startcic, int endcic, unsigned char state[], int type)
unsigned int call_ref_ident
#define ast_calloc(num, len)
A wrapper for calloc()
int(*const play_tone)(void *pvt, enum sig_ss7_tone tone)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
int orig_called_presentation
#define SIG_SS7_DEBUG_DEFAULT
#define AST_CAUSE_INTERWORKING
struct ast_party_redirecting_reason reason
Reason for the redirection.
void sig_ss7_link_alarm(struct sig_ss7_linkset *linkset, int which)
char cid_num[AST_MAX_EXTENSION]
char networkroutedprefix[20]
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define AST_PRES_RESTRICTION
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
void sig_ss7_chan_delete(struct sig_ss7_chan *doomed)
void(*const queue_control)(void *pvt, int subclass)
int sig_ss7_hangup(struct sig_ss7_chan *p, struct ast_channel *ast)
int count
Number of times the call was redirected.
Standard Command Line Interface.
int sig_ss7_add_sigchan(struct sig_ss7_linkset *linkset, int which, int ss7type, int transport, int inalarm, int networkindicator, int pointcode, int adjpointcode, int cur_slc)
int ast_channel_hangupcause(const struct ast_channel *chan)
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
void(*const set_inservice)(void *pvt, int is_inservice)
const char * ast_channel_name(const struct ast_channel *chan)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
void(*const set_callerid)(void *pvt, const struct ast_party_caller *caller)
#define AST_CAUSE_USER_BUSY
int ast_callid_threadstorage_auto(ast_callid *callid)
Checks thread storage for a callid and stores a reference if it exists. If not, then a new one will b...
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
struct ast_channel * owner
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
char internationalprefix[10]
unsigned int called_complete
TRUE if the channel has completed collecting digits.
struct isup_call * ss7call
Opaque libss7 call control structure.
void(*const deadlock_avoidance_private)(void *pvt)
int sig_ss7_answer(struct sig_ss7_chan *p, struct ast_channel *ast)
char cid_ani[AST_MAX_EXTENSION]
void(*const handle_link_exception)(struct sig_ss7_linkset *linkset, int which)
#define AST_PRES_UNAVAILABLE
#define ast_mutex_init(pmutex)
#define ast_channel_trylock(chan)
#define LINKSET_FLAG_DEFAULTECHOCONTROL
void(*const unlock_private)(void *pvt)
void sig_ss7_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_ss7_chan *pchan)
unsigned char gen_add_nai
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
int sig_ss7_cb_hangup(struct ss7 *ss7, int cic, unsigned int dpc, int cause, int do_hangup)
#define SS7_BLOCKED_MAINTENANCE
unsigned char valid
TRUE if the number information is valid/present.
ast_callid ast_channel_callid(const struct ast_channel *chan)
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
unsigned int echocontrol_ind
#define AST_CAUSE_CONGESTION
void * ss7_linkset(void *data)
#define AST_TRANS_CAP_DIGITAL
#define LINKSET_FLAG_AUTOACM
unsigned char calling_party_cat
unsigned char redirect_counter
#define ast_mutex_unlock(a)
struct ast_party_number number
Subscriber phone number.
void sig_ss7_cb_call_null(struct ss7 *ss7, struct isup_call *c, int lock)