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"
78static void sig_ss7_unlock_private(
struct sig_ss7_chan *p)
92static void sig_ss7_deadlock_avoidance_private(
struct sig_ss7_chan *p)
98 sig_ss7_unlock_private(p);
100 sig_ss7_lock_private(p);
112static void sig_ss7_set_dialing(
struct sig_ss7_chan *p,
int is_dialing)
119static void sig_ss7_set_digital(
struct sig_ss7_chan *p,
int is_digital)
126static void sig_ss7_set_outgoing(
struct sig_ss7_chan *p,
int is_outgoing)
134static void sig_ss7_set_inservice(
struct sig_ss7_chan *p,
int is_inservice)
142static void sig_ss7_set_locallyblocked(
struct sig_ss7_chan *p,
int is_blocked,
int type)
155static void sig_ss7_set_remotelyblocked(
struct sig_ss7_chan *p,
int is_blocked,
int type)
189static void sig_ss7_set_caller_id(
struct sig_ss7_chan *p)
198 caller.id.name.valid = 1;
200 caller.id.number.str = p->
cid_num;
201 caller.id.number.plan = p->
cid_ton;
203 caller.id.number.valid = 1;
206 caller.id.subaddress.valid = 1;
212 caller.ani.number.str = p->
cid_ani;
215 caller.ani.number.valid = 1;
230static void sig_ss7_set_dnid(
struct sig_ss7_chan *p,
const char *dnid)
249static int sig_ss7_set_echocanceller(
struct sig_ss7_chan *p,
int enable)
257static void sig_ss7_loopback(
struct sig_ss7_chan *p,
int enable)
275 assignedids, requestor);
297 sig_ss7_set_digital(p, 1);
303static void sig_ss7_handle_link_exception(
struct sig_ss7_linkset *linkset,
int which)
326static int sig_ss7_is_chan_available(
struct sig_ss7_chan *pvt)
350 if (!
ss7->pvts[chanpos]->owner) {
360 sig_ss7_unlock_private(
ss7->pvts[chanpos]);
362 sig_ss7_lock_private(
ss7->pvts[chanpos]);
380 sig_ss7_lock_owner(
ss7, chanpos);
381 if (
ss7->pvts[chanpos]->owner) {
399static void sig_ss7_queue_control(
struct sig_ss7_linkset *
ss7,
int chanpos,
int subclass)
409 sig_ss7_queue_frame(
ss7, chanpos, &f);
425static void ss7_queue_pvt_cause_data(
struct ast_channel *
owner,
const char *cause,
int ast_cause)
428 int datalen =
sizeof(*cause_code) + strlen(cause);
431 memset(cause_code, 0, datalen);
454 for (i = 0; i < linkset->
numchans; i++) {
455 if (linkset->
pvts[i] && (linkset->
pvts[i]->
dpc == dpc && linkset->
pvts[i]->
cic == cic)) {
475static int ss7_find_cic_gripe(
struct sig_ss7_linkset *linkset,
int cic,
unsigned int dpc,
const char *msg_name)
482 linkset->
span, msg_name, cic, dpc);
493 winner = sig_ss7_find_linkset(
ss7);
495 return winner->
pvts[chanpos];
505 if (!(p = ss7_find_pvt(
ss7,
cic,
dpc))) {
506 return SS7_CIC_NOT_EXISTS;
509 sig_ss7_lock_private(p);
518 sig_ss7_unlock_private(p);
528 winner = sig_ss7_find_linkset(
ss7);
532 for (i = 0; i < winner->
numchans; i++) {
535 sig_ss7_lock_private(winner->
pvts[i]);
543 sig_ss7_unlock_private(winner->
pvts[i]);
554 if (!(p = ss7_find_pvt(
ss7,
cic,
dpc))) {
558 sig_ss7_lock_private(p);
559 sig_ss7_set_inservice(p, 0);
560 sig_ss7_unlock_private(p);
574static void ss7_check_range(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
unsigned int dpc,
unsigned char *
state)
578 for (
cic = startcic;
cic <= endcic;
cic++) {
585static int ss7_match_range(
struct sig_ss7_chan *pvt,
int startcic,
int endcic,
unsigned int dpc)
587 if (pvt && pvt->
dpc ==
dpc && pvt->
cic >= startcic && pvt->
cic <= endcic) {
612 for (i = 0; i < linkset->
numchans; i++) {
613 if (ss7_match_range(linkset->
pvts[i], startcic, endcic,
dpc)) {
618 if (found == endcic - startcic + 1) {
625static void ss7_handle_cqm(
struct sig_ss7_linkset *linkset, ss7_event *e)
634 for (i = 0; i < linkset->
numchans; i++) {
635 if (ss7_match_range(linkset->
pvts[i], e->cqm.startcic, e->cqm.endcic, e->cqm.opc)) {
636 p = linkset->
pvts[i];
637 sig_ss7_lock_private(p);
638 offset = p->
cic - e->cqm.startcic;
641 status[offset] |= (1 << 0) | (1 << 4);
644 status[offset] |= (1 << 1) | (1 << 5);
648 status[offset] |= (1 << 3);
650 status[offset] |= (1 << 2);
653 status[offset] |= 0x3 << 2;
655 sig_ss7_unlock_private(p);
660 isup_cqr(linkset->
ss7, e->cqm.startcic, e->cqm.endcic, e->cqm.opc,
status);
667 isup_free_call(linkset->
ss7, e->cqm.call);
670 p = linkset->
pvts[chanpos];
671 sig_ss7_lock_private(p);
674 p->
ss7call = isup_free_call_if_clear(linkset->
ss7, e->cqm.call);
676 sig_ss7_unlock_private(p);
679static inline void ss7_hangup_cics(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
unsigned int dpc)
683 for (i = 0; i < linkset->
numchans; i++) {
684 if (ss7_match_range(linkset->
pvts[i], startcic, endcic,
dpc)) {
685 sig_ss7_lock_private(linkset->
pvts[i]);
686 sig_ss7_lock_owner(linkset, i);
691 sig_ss7_unlock_private(linkset->
pvts[i]);
709static 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)
713 for (i = 0; i < linkset->
numchans; i++) {
714 if (ss7_match_range(linkset->
pvts[i], startcic, endcic,
dpc)) {
715 sig_ss7_lock_private(linkset->
pvts[i]);
720 sig_ss7_set_remotelyblocked(linkset->
pvts[i], block,
type);
722 sig_ss7_set_locallyblocked(linkset->
pvts[i], block,
type);
725 sig_ss7_lock_owner(linkset, i);
736 sig_ss7_set_remotelyblocked(linkset->
pvts[i], block,
type);
738 sig_ss7_set_locallyblocked(linkset->
pvts[i], block,
type);
741 sig_ss7_unlock_private(linkset->
pvts[i]);
754static void ss7_inservice(
struct sig_ss7_linkset *linkset,
int startcic,
int endcic,
unsigned int dpc)
758 for (i = 0; i < linkset->
numchans; i++) {
759 if (ss7_match_range(linkset->
pvts[i], startcic, endcic,
dpc)) {
760 sig_ss7_lock_private(linkset->
pvts[i]);
761 sig_ss7_set_inservice(linkset->
pvts[i], 1);
762 sig_ss7_unlock_private(linkset->
pvts[i]);
792 int i, startcic, endcic,
dpc;
799 startcic = linkset->
pvts[0]->
cic;
800 p = linkset->
pvts[0];
804 for (i = 0; i < linkset->
numchans; i++) {
805 if (linkset->
pvts[i+1]
808 && linkset->
pvts[i]->
cic - startcic < (linkset->
type == SS7_ANSI ? 24 : 31)) {
811 endcic = linkset->
pvts[i]->
cic;
812 ast_verb(1,
"Resetting CICs %d to %d\n", startcic, endcic);
814 sig_ss7_lock_private(p);
815 if (!ss7_find_alloc_call(p)) {
817 }
else if (!(endcic - startcic)) {
822 sig_ss7_unlock_private(p);
825 if (linkset->
pvts[i+1]) {
826 startcic = linkset->
pvts[i+1]->
cic;
828 p = linkset->
pvts[i+1];
874 if (!linkset->
pvts[which]) {
878 if (!ss7_find_alloc_call(linkset->
pvts[which])) {
883 sig_ss7_set_inservice(linkset->
pvts[which], 0);
884 sig_ss7_loopback(linkset->
pvts[which], 0);
886 sig_ss7_lock_owner(linkset, which);
893 ss7_do_rsc(linkset->
pvts[which]);
917 for (i = 0; i < linkset->
numchans; i++) {
918 if (ss7_match_range(linkset->
pvts[i], startcic, endcic,
dpc)) {
919 sig_ss7_lock_private(linkset->
pvts[i]);
920 sig_ss7_set_inservice(linkset->
pvts[i], 0);
921 sig_ss7_lock_owner(linkset, i);
929 }
else if (linkset->
pvts[i] && linkset->
pvts[i]->
cic != startcic) {
933 sig_ss7_unlock_private(linkset->
pvts[i]);
949 struct ss7 *ss7 = linkset->
ss7;
965 if (linkset->
type == SS7_ITU) {
979 sig_ss7_unlock_private(p);
984 sig_ss7_lock_private(p);
993 sig_ss7_lock_private(p);
1065 strp =
"NO_REDIRECTION";
1068 strp =
"CALL_REROUTED_PRES_ALLOWED";
1071 strp =
"CALL_REROUTED_INFO_RESTRICTED";
1074 strp =
"CALL_DIVERTED_PRES_ALLOWED";
1077 strp =
"CALL_DIVERTED_INFO_RESTRICTED";
1080 strp =
"CALL_REROUTED_PRES_RESTRICTED";
1083 strp =
"CALL_DIVERTED_PRES_RESTRICTED";
1089 strp =
"NO_REDIRECTION";
1176 redirecting.from.number.valid = 1;
1184 redirecting.from.name.valid = 1;
1192 redirecting.orig.number.valid = 1;
1195 }
else if (redirecting.count == 1) {
1211 case ISUP_CUG_OUTGOING_ALLOWED:
1212 strp =
"OUTGOING_ALLOWED";
1214 case ISUP_CUG_OUTGOING_NOT_ALLOWED:
1215 strp =
"OUTGOING_NOT_ALLOWED";
1232 sig_ss7_unlock_private(p);
1244 sig_ss7_lock_private(p);
1248static void ss7_apply_plan_to_number(
char *
buf,
size_t size,
const struct sig_ss7_linkset *ss7,
const char *
number,
const unsigned nai)
1257 case SS7_NAI_INTERNATIONAL:
1260 case SS7_NAI_NATIONAL:
1263 case SS7_NAI_SUBSCRIBER:
1266 case SS7_NAI_UNKNOWN:
1269 case SS7_NAI_NETWORKROUTED:
1278static int ss7_pres_scr2cid_pres(
char presentation_ind,
char screening_ind)
1280 return ((presentation_ind & 0x3) << 5) | (screening_ind & 0x3);
1300 sig_ss7_lock_owner(linkset, chanpos);
1330 && linkset->
type == SS7_ITU
1332 && !isup_start_digittimeout(linkset->
ss7, p->
ss7call)) {
1339 sig_ss7_set_dnid(p, p->
exten);
1342 if ((e->e == ISUP_EVENT_IAM)
1343 ? !(e->iam.cot_check_required || e->iam.cot_performed_on_previous_cic)
1344 : (!(e->sam.cot_check_required || e->sam.cot_performed_on_previous_cic) || e->sam.cot_check_passed)) {
1345 ss7_start_call(p, linkset);
1350 ast_debug(1,
"Call on CIC for unconfigured extension %s\n", p->
exten);
1358 struct timeval *next =
NULL, tv;
1360 struct ss7 *ss7 = linkset->
ss7;
1361 ss7_event *e =
NULL;
1364 unsigned char mb_state[255];
1367#define SS7_MAX_POLL 60000
1369 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
1378 if ((next = ss7_schedule_next(ss7))) {
1380 tv.tv_sec = next->tv_sec - tv.tv_sec;
1381 tv.tv_usec = next->tv_usec - tv.tv_usec;
1382 if (tv.tv_usec < 0) {
1383 tv.tv_usec += 1000000;
1386 if (tv.tv_sec < 0) {
1390 nextms = tv.tv_sec * 1000;
1391 nextms += tv.tv_usec / 1000;
1392 if (SS7_MAX_POLL < nextms) {
1393 nextms = SS7_MAX_POLL;
1396 nextms = SS7_MAX_POLL;
1400 pollers[i].fd = linkset->
fds[i];
1401 pollers[i].events = ss7_pollflags(ss7, linkset->
fds[i]);
1402 pollers[i].revents = 0;
1406 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
1407 pthread_testcancel();
1408 res = poll(pollers, linkset->
numsigchans, nextms);
1409 pthread_testcancel();
1410 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
1413 if ((res < 0) && (
errno != EINTR)) {
1416 ss7_schedule_run(ss7);
1420 if (pollers[i].revents & POLLPRI) {
1421 sig_ss7_handle_link_exception(linkset, i);
1423 if (pollers[i].revents & POLLIN) {
1424 res = ss7_read(ss7, pollers[i].fd);
1426 if (pollers[i].revents & POLLOUT) {
1427 res = ss7_write(ss7, pollers[i].fd);
1434 while ((e = ss7_check_event(ss7))) {
1439 if (linkset->
debug) {
1441 linkset->
span, ss7_event2str(e->e));
1446 if (linkset->
state != LINKSET_STATE_UP) {
1448 ss7_reset_linkset(linkset);
1450 linkset->
state = LINKSET_STATE_UP;
1452 case SS7_EVENT_DOWN:
1454 linkset->
state = LINKSET_STATE_DOWN;
1455 for (i = 0; i < linkset->
numchans; i++) {
1456 p = linkset->
pvts[i];
1458 sig_ss7_set_inservice(p, 0);
1466 ast_verb(1,
"MTP2 link up (SLC %d)\n", e->gen.data);
1468 case MTP2_LINK_DOWN:
1471 case ISUP_EVENT_CPG:
1472 chanpos = ss7_find_cic_gripe(linkset, e->cpg.cic, e->cpg.opc,
"CPG");
1474 isup_free_call(ss7, e->cpg.call);
1477 p = linkset->
pvts[chanpos];
1478 sig_ss7_lock_private(p);
1479 callid = func_ss7_linkset_callid(linkset, chanpos);
1481 switch (e->cpg.event) {
1482 case CPG_EVENT_ALERTING:
1486 sig_ss7_lock_owner(linkset, chanpos);
1494 ast_connected.id.number.presentation =
1495 ss7_pres_scr2cid_pres(e->cpg.connected_presentation_ind,
1496 e->cpg.connected_screening_ind);
1497 ss7_apply_plan_to_number(connected_num,
sizeof(connected_num),
1498 linkset, e->cpg.connected_num, e->cpg.connected_nai);
1499 ast_connected.id.number.str =
ast_strdup(connected_num);
1500 ast_connected.id.number.valid = 1;
1508 case CPG_EVENT_PROGRESS:
1509 case CPG_EVENT_INBANDINFO:
1511 ast_debug(1,
"Queuing frame PROGRESS on CIC %d\n", p->
cic);
1514 sig_ss7_set_dialing(p, 0);
1515 sig_ss7_open_media(p);
1519 ast_debug(1,
"Do not handle CPG with event type 0x%x\n", e->cpg.event);
1523 sig_ss7_unlock_private(p);
1525 case ISUP_EVENT_RSC:
1526 ast_verb(1,
"Resetting CIC %d\n", e->rsc.cic);
1527 chanpos = ss7_find_cic_gripe(linkset, e->rsc.cic, e->rsc.opc,
"RSC");
1529 isup_free_call(ss7, e->rsc.call);
1532 p = linkset->
pvts[chanpos];
1533 sig_ss7_lock_private(p);
1535 callid = func_ss7_linkset_callid(linkset, chanpos);
1536 sig_ss7_set_inservice(p, 1);
1540 isup_blo(ss7, e->rsc.call);
1545 isup_set_call_dpc(e->rsc.call, p->
dpc);
1546 sig_ss7_lock_owner(linkset, chanpos);
1549 if (!(e->rsc.got_sent_msg & ISUP_SENT_IAM)) {
1561 isup_rlc(ss7, e->rsc.call);
1562 p->
ss7call = isup_free_call_if_clear(ss7, e->rsc.call);
1565 sig_ss7_loopback(p, 0);
1567 sig_ss7_unlock_private(p);
1569 case ISUP_EVENT_GRS:
1573 e->grs.startcic, e->grs.endcic, e->grs.opc);
1576 isup_free_call(ss7, e->grs.call);
1579 p = linkset->
pvts[chanpos];
1580 sig_ss7_lock_private(p);
1581 p->
ss7call = isup_free_call_if_clear(ss7, e->grs.call);
1582 sig_ss7_unlock_private(p);
1587 for (i = e->grs.endcic - e->grs.startcic; 0 <= i; --i) {
1593 p = linkset->
pvts[chanpos];
1594 sig_ss7_lock_private(p);
1607 isup_gra(ss7, p->
ss7call, e->grs.endcic, mb_state);
1610 sig_ss7_lock_owner(linkset, chanpos);
1625 isup_free_call(ss7, p->
ss7call);
1628 sig_ss7_set_inservice(p, 1);
1629 sig_ss7_unlock_private(p);
1632 case ISUP_EVENT_CQM:
1633 ast_debug(1,
"Got Circuit group query message from CICs %d to %d\n",
1634 e->cqm.startcic, e->cqm.endcic);
1635 ss7_handle_cqm(linkset, e);
1637 case ISUP_EVENT_GRA:
1639 e->gra.endcic, e->gra.opc)) {
1641 e->gra.startcic, e->gra.endcic, e->gra.opc);
1642 isup_free_call(ss7, e->gra.call);
1645 ast_verb(1,
"Got reset acknowledgement from CIC %d to %d DPC: %d\n",
1646 e->gra.startcic, e->gra.endcic, e->gra.opc);
1647 ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc,
1649 ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc);
1653 isup_free_call(ss7, e->gra.call);
1657 p = linkset->
pvts[chanpos];
1658 sig_ss7_lock_private(p);
1661 p->
ss7call = isup_free_call_if_clear(ss7, e->gra.call);
1662 sig_ss7_unlock_private(p);
1664 case ISUP_EVENT_SAM:
1665 chanpos = ss7_find_cic_gripe(linkset, e->sam.cic, e->sam.opc,
"SAM");
1667 isup_free_call(ss7, e->sam.call);
1670 p = linkset->
pvts[chanpos];
1671 sig_ss7_lock_private(p);
1672 sig_ss7_lock_owner(linkset, chanpos);
1674 ast_log(
LOG_WARNING,
"SAM on CIC %d PC %d already have call\n", e->sam.cic, e->sam.opc);
1676 sig_ss7_unlock_private(p);
1682 strncat(p->
exten, e->sam.called_party_num,
sizeof(p->
exten) - strlen(p->
exten) - 1);
1683 st = strchr(p->
exten,
'#');
1688 ss7_match_extension(linkset, p, e);
1690 sig_ss7_unlock_private(p);
1692 case ISUP_EVENT_IAM:
1693 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);
1694 chanpos = ss7_find_cic_gripe(linkset, e->iam.cic, e->iam.opc,
"IAM");
1696 isup_free_call(ss7, e->iam.call);
1699 p = linkset->
pvts[chanpos];
1700 sig_ss7_lock_private(p);
1708 ast_log(
LOG_NOTICE,
"Got IAM on remotely blocked CIC %d DPC %d remove blocking\n", e->iam.cic, e->iam.opc);
1710 sig_ss7_set_inservice(p, 1);
1713 if (!sig_ss7_is_chan_available(p)) {
1717 isup_clear_callflags(ss7, e->iam.call, ISUP_GOT_IAM);
1718 p->
ss7call = isup_free_call_if_clear(ss7, e->iam.call);
1719 ast_log(
LOG_WARNING,
"Got IAM on locally blocked CIC %d DPC %d, ignore\n", e->iam.cic, e->iam.opc);
1721 sig_ss7_unlock_private(p);
1732 ss7_apply_plan_to_number(p->
cid_num,
sizeof(p->
cid_num), linkset, e->iam.calling_party_num, e->iam.calling_nai);
1733 p->
callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind);
1736 if (e->iam.presentation_ind) {
1737 p->
callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind);
1747 ss7_apply_plan_to_number(p->
exten,
sizeof(p->
exten), linkset, e->iam.called_party_num, e->iam.called_nai);
1748 st = strchr(p->
exten,
'#');
1778 p->
orig_called_presentation = ss7_pres_scr2cid_pres(e->iam.orig_called_pres_ind, e->iam.orig_called_screening_ind);
1782 p->
redirecting_presentation = ss7_pres_scr2cid_pres(e->iam.redirecting_num_presentation_ind, e->iam.redirecting_num_screening_ind);
1799 if (e->iam.cot_check_required) {
1800 sig_ss7_loopback(p, 1);
1804 sig_ss7_set_caller_id(p);
1805 ss7_match_extension(linkset, p, e);
1806 sig_ss7_unlock_private(p);
1808 if (e->iam.cot_performed_on_previous_cic) {
1812 ast_verb(1,
"COT request on previous nonexistent CIC %d in IAM PC %d\n", (e->iam.cic - 1), e->iam.opc);
1815 ast_verb(1,
"COT request on previous CIC %d in IAM PC %d\n", (e->iam.cic - 1), e->iam.opc);
1816 p = linkset->
pvts[chanpos];
1817 sig_ss7_lock_private(p);
1818 if (sig_ss7_is_chan_available(p)) {
1819 sig_ss7_set_inservice(p, 0);
1820 sig_ss7_loopback(p, 1);
1822 sig_ss7_unlock_private(p);
1825 case ISUP_EVENT_DIGITTIMEOUT:
1826 chanpos = ss7_find_cic_gripe(linkset, e->digittimeout.cic, e->digittimeout.opc,
"DIGITTIMEOUT");
1828 isup_free_call(ss7, e->digittimeout.call);
1831 p = linkset->
pvts[chanpos];
1832 sig_ss7_lock_private(p);
1833 ast_debug(1,
"Digittimeout on CIC: %d PC: %d\n", e->digittimeout.cic, e->digittimeout.opc);
1837 sig_ss7_set_dnid(p, p->
exten);
1840 if (!(e->digittimeout.cot_check_required || e->digittimeout.cot_performed_on_previous_cic) || e->digittimeout.cot_check_passed) {
1841 ss7_start_call(p, linkset);
1844 ast_debug(1,
"Call on CIC for unconfigured extension %s\n", p->
exten);
1847 sig_ss7_unlock_private(p);
1849 case ISUP_EVENT_COT:
1850 if (e->cot.cot_performed_on_previous_cic) {
1854 p = linkset->
pvts[chanpos];
1855 sig_ss7_lock_private(p);
1856 sig_ss7_set_inservice(p, 1);
1857 sig_ss7_loopback(p, 0);
1858 sig_ss7_unlock_private(p);;
1859 ast_verb(1,
"Loop turned off on CIC: %d PC: %d\n", (e->cot.cic - 1), e->cot.opc);
1863 chanpos = ss7_find_cic_gripe(linkset, e->cot.cic, e->cot.opc,
"COT");
1865 isup_free_call(ss7, e->cot.call);
1868 p = linkset->
pvts[chanpos];
1870 sig_ss7_lock_private(p);
1874 sig_ss7_loopback(p, 0);
1875 ast_verb(1,
"Loop turned off on CIC: %d PC: %d\n", e->cot.cic, e->cot.opc);
1879 if ((e->cot.got_sent_msg & ISUP_GOT_IAM) && e->cot.passed && p->
called_complete) {
1880 ss7_start_call(p, linkset);
1884 sig_ss7_unlock_private(p);
1886 case ISUP_EVENT_CCR:
1887 ast_debug(1,
"Got CCR request on CIC %d\n", e->ccr.cic);
1888 chanpos = ss7_find_cic_gripe(linkset, e->ccr.cic, e->ccr.opc,
"CCR");
1890 isup_free_call(ss7, e->ccr.call);
1894 p = linkset->
pvts[chanpos];
1896 sig_ss7_lock_private(p);
1898 sig_ss7_loopback(p, 1);
1899 if (linkset->
type == SS7_ANSI) {
1900 isup_lpa(linkset->
ss7, e->ccr.cic, p->
dpc);
1902 sig_ss7_unlock_private(p);
1904 case ISUP_EVENT_CVT:
1905 ast_debug(1,
"Got CVT request on CIC %d\n", e->cvt.cic);
1906 chanpos = ss7_find_cic_gripe(linkset, e->cvt.cic, e->cvt.opc,
"CVT");
1908 isup_free_call(ss7, e->cvt.call);
1912 p = linkset->
pvts[chanpos];
1914 sig_ss7_lock_private(p);
1916 sig_ss7_loopback(p, 1);
1918 p->
ss7call = isup_free_call_if_clear(ss7, e->cvt.call);
1920 isup_cvr(linkset->
ss7, e->cvt.cic, p->
dpc);
1921 sig_ss7_unlock_private(p);
1923 case ISUP_EVENT_REL:
1924 chanpos = ss7_find_cic_gripe(linkset, e->rel.cic, e->rel.opc,
"REL");
1926 isup_free_call(ss7, e->rel.call);
1929 p = linkset->
pvts[chanpos];
1930 sig_ss7_lock_private(p);
1932 callid = func_ss7_linkset_callid(linkset, chanpos);
1933 sig_ss7_lock_owner(linkset, chanpos);
1935 snprintf(cause_str,
sizeof(cause_str),
"SS7 ISUP_EVENT_REL (%d)", e->rel.cause);
1936 ss7_queue_pvt_cause_data(p->
owner, cause_str, e->rel.cause);
1943 ast_verb(1,
"REL on CIC %d DPC %d without owner!\n", p->
cic, p->
dpc);
1949 sig_ss7_loopback(p, 0);
1952 sig_ss7_unlock_private(p);
1954 case ISUP_EVENT_ACM:
1955 chanpos = ss7_find_cic_gripe(linkset, e->acm.cic, e->acm.opc,
"ACM");
1957 isup_free_call(ss7, e->acm.call);
1961 p = linkset->
pvts[chanpos];
1963 ast_debug(1,
"Queueing frame from SS7_EVENT_ACM on CIC %d\n", p->
cic);
1965 if (e->acm.call_ref_ident > 0) {
1969 sig_ss7_lock_private(p);
1971 callid = func_ss7_linkset_callid(linkset, chanpos);
1976 sig_ss7_set_dialing(p, 0);
1978 if (e->acm.called_party_status_ind == 1) {
1982 sig_ss7_lock_owner(linkset, chanpos);
1990 sig_ss7_unlock_private(p);
1992 case ISUP_EVENT_CGB:
1993 chanpos = ss7_find_cic_gripe(linkset, e->cgb.startcic, e->cgb.opc,
"CGB");
1995 isup_free_call(ss7, e->cgb.call);
1998 p = linkset->
pvts[chanpos];
1999 ss7_check_range(linkset, e->cgb.startcic, e->cgb.endcic,
2000 e->cgb.opc, e->cgb.status);
2001 ss7_block_cics(linkset, e->cgb.startcic, e->cgb.endcic,
2002 e->cgb.opc, e->cgb.status, 1, 1,
2005 sig_ss7_lock_private(p);
2008 isup_cgba(linkset->
ss7, p->
ss7call, e->cgb.endcic, e->cgb.status);
2010 p->
ss7call = isup_free_call_if_clear(ss7, e->cgb.call);
2012 sig_ss7_unlock_private(p);
2014 case ISUP_EVENT_CGU:
2015 chanpos = ss7_find_cic_gripe(linkset, e->cgu.startcic, e->cgu.opc,
"CGU");
2017 isup_free_call(ss7, e->cgu.call);
2020 p = linkset->
pvts[chanpos];
2021 ss7_check_range(linkset, e->cgu.startcic, e->cgu.endcic,
2022 e->cgu.opc, e->cgu.status);
2023 ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic,
2024 e->cgu.opc, e->cgu.status, 0, 1,
2027 sig_ss7_lock_private(p);
2030 isup_cgua(linkset->
ss7, p->
ss7call, e->cgu.endcic, e->cgu.status);
2032 p->
ss7call = isup_free_call_if_clear(ss7, e->cgu.call);
2034 sig_ss7_unlock_private(p);
2036 case ISUP_EVENT_UCIC:
2037 chanpos = ss7_find_cic_gripe(linkset, e->ucic.cic, e->ucic.opc,
"UCIC");
2039 isup_free_call(ss7, e->ucic.call);
2042 p = linkset->
pvts[chanpos];
2043 ast_debug(1,
"Unequipped Circuit Id Code on CIC %d\n", e->ucic.cic);
2044 sig_ss7_lock_private(p);
2045 sig_ss7_lock_owner(linkset, chanpos);
2051 sig_ss7_set_inservice(p, 0);
2053 isup_free_call(ss7, e->ucic.call);
2054 sig_ss7_unlock_private(p);
2056 case ISUP_EVENT_BLO:
2057 chanpos = ss7_find_cic_gripe(linkset, e->blo.cic, e->blo.opc,
"BLO");
2059 isup_free_call(ss7, e->blo.call);
2062 p = linkset->
pvts[chanpos];
2063 ast_debug(1,
"Blocking CIC %d\n", e->blo.cic);
2064 sig_ss7_lock_private(p);
2067 isup_bla(linkset->
ss7, e->blo.call);
2068 sig_ss7_lock_owner(linkset, chanpos);
2070 p->
ss7call = isup_free_call_if_clear(ss7, e->blo.call);
2072 if (e->blo.got_sent_msg & ISUP_SENT_IAM) {
2078 sig_ss7_unlock_private(p);
2080 case ISUP_EVENT_BLA:
2081 chanpos = ss7_find_cic_gripe(linkset, e->bla.cic, e->bla.opc,
"BLA");
2083 isup_free_call(ss7, e->bla.call);
2086 ast_debug(1,
"Locally blocking CIC %d\n", e->bla.cic);
2087 p = linkset->
pvts[chanpos];
2088 sig_ss7_lock_private(p);
2094 sig_ss7_unlock_private(p);
2096 case ISUP_EVENT_UBL:
2097 chanpos = ss7_find_cic_gripe(linkset, e->ubl.cic, e->ubl.opc,
"UBL");
2099 isup_free_call(ss7, e->ubl.call);
2102 p = linkset->
pvts[chanpos];
2103 ast_debug(1,
"Remotely unblocking CIC %d PC %d\n", e->ubl.cic, e->ubl.opc);
2104 sig_ss7_lock_private(p);
2107 isup_uba(linkset->
ss7, e->ubl.call);
2111 sig_ss7_unlock_private(p);
2113 case ISUP_EVENT_UBA:
2114 chanpos = ss7_find_cic_gripe(linkset, e->uba.cic, e->uba.opc,
"UBA");
2116 isup_free_call(ss7, e->uba.call);
2119 p = linkset->
pvts[chanpos];
2120 ast_debug(1,
"Locally unblocking CIC %d PC %d\n", e->uba.cic, e->uba.opc);
2121 sig_ss7_lock_private(p);
2127 sig_ss7_unlock_private(p);
2129 case ISUP_EVENT_CON:
2130 case ISUP_EVENT_ANM:
2131 if (e->e == ISUP_EVENT_CON) {
2132 chanpos = ss7_find_cic_gripe(linkset, e->con.cic, e->con.opc,
"CON");
2134 isup_free_call(ss7, e->con.call);
2138 chanpos = ss7_find_cic_gripe(linkset, e->anm.cic, e->anm.opc,
"ANM");
2140 isup_free_call(ss7, e->anm.call);
2145 p = linkset->
pvts[chanpos];
2146 sig_ss7_lock_private(p);
2147 p->
ss7call = (e->e == ISUP_EVENT_ANM) ? e->anm.call : e->con.call;
2148 callid = func_ss7_linkset_callid(linkset, chanpos);
2154 ? e->anm.connected_num : e->con.connected_num)) {
2155 sig_ss7_lock_owner(linkset, chanpos);
2161 if (e->e == ISUP_EVENT_ANM) {
2162 ast_connected.id.number.presentation = ss7_pres_scr2cid_pres(
2163 e->anm.connected_presentation_ind,
2164 e->anm.connected_screening_ind);
2165 ss7_apply_plan_to_number(connected_num,
sizeof(connected_num),
2166 linkset, e->anm.connected_num, e->anm.connected_nai);
2167 ast_connected.id.number.str =
ast_strdup(connected_num);
2169 ast_connected.id.number.presentation = ss7_pres_scr2cid_pres(
2170 e->con.connected_presentation_ind,
2171 e->con.connected_screening_ind);
2172 ss7_apply_plan_to_number(connected_num,
sizeof(connected_num),
2173 linkset, e->con.connected_num, e->con.connected_nai);
2174 ast_connected.id.number.str =
ast_strdup(connected_num);
2176 ast_connected.id.number.valid = 1;
2185 sig_ss7_set_dialing(p, 0);
2186 sig_ss7_open_media(p);
2187 if (((e->e == ISUP_EVENT_ANM) ? !e->anm.echocontrol_ind :
2189 sig_ss7_set_echocanceller(p, 1);
2191 sig_ss7_unlock_private(p);
2193 case ISUP_EVENT_RLC:
2194 chanpos = ss7_find_cic_gripe(linkset, e->rlc.cic, e->rlc.opc,
"RLC");
2196 isup_free_call(ss7, e->rlc.call);
2200 p = linkset->
pvts[chanpos];
2201 sig_ss7_lock_private(p);
2203 callid = func_ss7_linkset_callid(linkset, chanpos);
2204 if (e->rlc.got_sent_msg & (ISUP_SENT_RSC | ISUP_SENT_REL)) {
2205 sig_ss7_loopback(p, 0);
2206 if (e->rlc.got_sent_msg & ISUP_SENT_RSC) {
2207 sig_ss7_set_inservice(p, 1);
2210 sig_ss7_lock_owner(linkset, chanpos);
2212 p->
ss7call = isup_free_call_if_clear(ss7, e->rlc.call);
2219 sig_ss7_unlock_private(p);
2221 case ISUP_EVENT_FAA:
2226 chanpos = ss7_find_cic_gripe(linkset, e->faa.cic, e->faa.opc,
"FAA");
2228 isup_free_call(ss7, e->faa.call);
2233 p = linkset->
pvts[chanpos];
2234 sig_ss7_lock_private(p);
2235 callid = func_ss7_linkset_callid(linkset, chanpos);
2236 ast_debug(1,
"FAA received on CIC %d\n", e->faa.cic);
2237 p->
ss7call = isup_free_call_if_clear(ss7, e->faa.call);
2238 sig_ss7_unlock_private(p);
2240 case ISUP_EVENT_CGBA:
2241 chanpos = ss7_find_cic_gripe(linkset, e->cgba.startcic, e->cgba.opc,
"CGBA");
2243 isup_free_call(ss7, e->cgba.call);
2247 ss7_block_cics(linkset, e->cgba.startcic, e->cgba.endcic,
2248 e->cgba.opc, e->cgba.status, 1, 0,
2251 p = linkset->
pvts[chanpos];
2252 sig_ss7_lock_private(p);
2258 sig_ss7_unlock_private(p);
2260 case ISUP_EVENT_CGUA:
2261 chanpos = ss7_find_cic_gripe(linkset, e->cgua.startcic, e->cgua.opc,
"CGUA");
2263 isup_free_call(ss7, e->cgua.call);
2267 ss7_block_cics(linkset, e->cgua.startcic, e->cgua.endcic,
2268 e->cgua.opc, e->cgua.status, 0, 0,
2271 p = linkset->
pvts[chanpos];
2272 sig_ss7_lock_private(p);
2278 sig_ss7_unlock_private(p);
2280 case ISUP_EVENT_SUS:
2281 chanpos = ss7_find_cic_gripe(linkset, e->sus.cic, e->sus.opc,
"SUS");
2283 isup_free_call(ss7, e->sus.call);
2287 p = linkset->
pvts[chanpos];
2288 sig_ss7_lock_private(p);
2293 sig_ss7_unlock_private(p);
2295 case ISUP_EVENT_RES:
2296 chanpos = ss7_find_cic_gripe(linkset, e->res.cic, e->res.opc,
"RES");
2298 isup_free_call(ss7, e->res.call);
2302 p = linkset->
pvts[chanpos];
2303 sig_ss7_lock_private(p);
2308 sig_ss7_unlock_private(p);
2311 ast_debug(1,
"Unknown event %s\n", ss7_event2str(e->e));
2333 pthread_kill(ss7->
master, SIGURG);
2342 sig_ss7_deadlock_avoidance_private(pvt);
2361 for (i = 0; i < linkset->
numchans; i++) {
2362 if (linkset->
pvts[i] && linkset->
pvts[i]->
cic == cic && linkset->
pvts[i]->
dpc == dpc) {
2365 sig_ss7_lock_private(linkset->
pvts[i]);
2367 res = ss7_start_rsc(linkset, i);
2368 sig_ss7_unlock_private(linkset->
pvts[i]);
2391 sig_ss7_lock_private(linkset->
pvts[which]);
2392 if (!ss7_find_alloc_call(linkset->
pvts[which])) {
2393 sig_ss7_unlock_private(linkset->
pvts[which]);
2404 sig_ss7_unlock_private(linkset->
pvts[which]);
2427 sig_ss7_lock_private(linkset->
pvts[chanpos]);
2428 if (!ss7_find_alloc_call(linkset->
pvts[chanpos])) {
2429 sig_ss7_unlock_private(linkset->
pvts[chanpos]);
2439 sig_ss7_unlock_private(linkset->
pvts[chanpos]);
2460 for (i = 0; i < linkset->
numchans; i++) {
2461 if (linkset->
pvts[i] && linkset->
pvts[i]->
cic == cic && linkset->
pvts[i]->
dpc == dpc) {
2462 ss7_clear_channels(linkset, cic, cic + range, dpc, SS7_HANGUP_FREE_CALL);
2463 ss7_block_cics(linkset, cic, cic + range, dpc,
NULL, 0, 1,
2465 ss7_block_cics(linkset, cic, cic + range, dpc,
NULL, 0, 0,
2468 sig_ss7_lock_private(linkset->
pvts[i]);
2469 if (!ss7_find_alloc_call(linkset->
pvts[i])) {
2470 sig_ss7_unlock_private(linkset->
pvts[i]);
2474 sig_ss7_unlock_private(linkset->
pvts[i]);
2483 sig_ss7_lock_private(linkset->
pvts[channel]);
2488 sig_ss7_unlock_private(linkset->
pvts[channel]);
2497 *nai = SS7_NAI_INTERNATIONAL;
2500 *nai = SS7_NAI_NATIONAL;
2503 *nai = SS7_NAI_NETWORKROUTED;
2506 *nai = SS7_NAI_UNKNOWN;
2509 *nai = SS7_NAI_SUBSCRIBER;
2511 *nai = SS7_NAI_SUBSCRIBER;
2527 linkset->
linkstate[which] &= ~LINKSTATE_UP;
2528 ss7_link_alarm(linkset->
ss7, linkset->
fds[which]);
2542 ss7_link_noalarm(linkset->
ss7, linkset->
fds[which]);
2562int 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)
2564 if (!linkset->
ss7) {
2565 linkset->
type = ss7type;
2566 linkset->
ss7 = ss7_new(ss7type);
2567 if (!linkset->
ss7) {
2573 ss7_set_network_ind(linkset->
ss7, networkindicator);
2574 ss7_set_pc(linkset->
ss7, pointcode);
2576 if (ss7_add_link(linkset->
ss7, transport, linkset->
fds[which], cur_slc, adjpointcode)) {
2582 ss7_link_alarm(linkset->
ss7, linkset->
fds[which]);
2585 ss7_link_noalarm(linkset->
ss7, linkset->
fds[which]);
2610 available = sig_ss7_is_chan_available(p);
2625static unsigned char cid_pres2ss7pres(
int cid_pres)
2627 return (cid_pres >> 5) & 0x03;
2630static unsigned char cid_pres2ss7screen(
int cid_pres)
2632 return cid_pres & 0x03;
2637 int connected_strip = 0;
2639 unsigned char connected_pres;
2640 unsigned char connected_screen;
2641 const char *connected_num;
2649 connected_strip = ss7_parse_prefix(p, connected_num, &connected_nai);
2654 connected_pres = cid_pres2ss7pres(
connected->id.number.presentation);
2655 connected_screen = cid_pres2ss7screen(
connected->id.number.presentation);
2657 isup_set_connected(p->
ss7call, connected_num + connected_strip, connected_nai, connected_pres, connected_screen);
2691static unsigned char ss7_redirect_info_ind(
struct ast_channel *ast)
2693 const char *redirect_info_ind;
2698 if (!strcasecmp(redirect_info_ind,
"CALL_REROUTED_PRES_ALLOWED")) {
2701 if (!strcasecmp(redirect_info_ind,
"CALL_REROUTED_INFO_RESTRICTED")) {
2704 if (!strcasecmp(redirect_info_ind,
"CALL_DIVERTED_PRES_ALLOWED")) {
2707 if (!strcasecmp(redirect_info_ind,
"CALL_DIVERTED_INFO_RESTRICTED")) {
2710 if (!strcasecmp(redirect_info_ind,
"CALL_REROUTED_PRES_RESTRICTED")) {
2713 if (!strcasecmp(redirect_info_ind,
"CALL_DIVERTED_PRES_RESTRICTED")) {
2716 if (!strcasecmp(redirect_info_ind,
"SPARE")) {
2743 int num_nai_strip = 0;
2746 if (!redirecting->
count) {
2750 isup_set_redirect_counter(p->
ss7call, redirecting->
count);
2757 num_nai_strip = ss7_parse_prefix(p, ss7_orig_called_num, &ss7_orig_called_nai);
2761 isup_set_orig_called_num(p->
ss7call, ss7_orig_called_num + num_nai_strip,
2762 ss7_orig_called_nai,
2772 num_nai_strip = ss7_parse_prefix(p, redirecting_number, &ss7_redirecting_num_nai);
2777 isup_set_redirecting_number(p->
ss7call, redirecting_number + num_nai_strip,
2778 ss7_redirecting_num_nai,
2783 isup_set_redirection_info(p->
ss7call, ss7_redirect_info_ind(ast),
2801 char ss7_called_nai;
2802 int called_nai_strip;
2803 char ss7_calling_nai;
2804 int calling_nai_strip;
2805 const char *col_req =
NULL;
2806 const char *ss7_cug_indicator_str;
2807 const char *ss7_cug_interlock_ni;
2808 const char *ss7_cug_interlock_code;
2809 const char *ss7_interworking_indicator;
2810 const char *ss7_forward_indicator_pmbits;
2811 unsigned char ss7_cug_indicator;
2812 const char *charge_str =
NULL;
2813 const char *gen_address =
NULL;
2814 const char *gen_digits =
NULL;
2815 const char *gen_dig_type =
NULL;
2816 const char *gen_dig_scheme =
NULL;
2817 const char *gen_name =
NULL;
2818 const char *jip_digits =
NULL;
2819 const char *lspi_ident =
NULL;
2820 const char *rlt_flag =
NULL;
2821 const char *call_ref_id =
NULL;
2822 const char *call_ref_pc =
NULL;
2823 const char *send_far =
NULL;
2824 const char *tmr =
NULL;
2831 c = strchr(dest,
'/');
2848 ss7_grab(p, p->
ss7);
2856 called_nai_strip = 0;
2859 called_nai_strip = ss7_parse_prefix(p,
c + p->
stripmsd, &ss7_called_nai);
2863 calling_nai_strip = 0;
2866 calling_nai_strip = ss7_parse_prefix(p, l, &ss7_calling_nai);
2869 isup_set_calling(p->
ss7call, l ? (l + calling_nai_strip) :
NULL, ss7_calling_nai,
2871 : (l ? SS7_PRESENTATION_ALLOWED
2873 ? SS7_PRESENTATION_ADDR_NOT_AVAILABLE : SS7_PRESENTATION_RESTRICTED)),
2881 isup_set_charge(p->
ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
2891 isup_set_gen_digits(p->
ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme));
2895 isup_set_generic_name(p->
ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
2899 isup_set_jip_digits(p->
ss7call, jip_digits);
2903 isup_set_lspi(p->
ss7call, lspi_ident, 0x18, 0x7, 0x00);
2906 if ((rlt_flag) && ((strncmp(
"NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
2907 isup_set_lspi(p->
ss7call, rlt_flag, 0x18, 0x7, 0x00);
2912 if (call_ref_id && call_ref_pc) {
2913 isup_set_callref(p->
ss7call, atoi(call_ref_id),
2914 call_ref_pc ? atoi(call_ref_pc) : 0);
2918 if (send_far && strncmp(
"NO", send_far, strlen(send_far)) != 0) {
2924 isup_set_tmr(p->
ss7call, atoi(tmr));
2926 if (!strcasecmp(tmr,
"SPEECH")) {
2927 isup_set_tmr(p->
ss7call, SS7_TMR_SPEECH);
2928 }
else if (!strcasecmp(tmr,
"SPARE")) {
2929 isup_set_tmr(p->
ss7call, SS7_TMR_SPARE);
2930 }
else if (!strcasecmp(tmr,
"3K1_AUDIO")) {
2931 isup_set_tmr(p->
ss7call, SS7_TMR_3K1_AUDIO);
2932 }
else if (!strcasecmp(tmr,
"64K_UNRESTRICTED")) {
2933 isup_set_tmr(p->
ss7call, SS7_TMR_64K_UNRESTRICTED);
2935 isup_set_tmr(p->
ss7call, SS7_TMR_N64K_OR_SPARE);
2946 if (!strcasecmp(ss7_cug_indicator_str,
"OUTGOING_ALLOWED")) {
2947 ss7_cug_indicator = ISUP_CUG_OUTGOING_ALLOWED;
2948 }
else if (!strcasecmp(ss7_cug_indicator_str,
"OUTGOING_NOT_ALLOWED")) {
2949 ss7_cug_indicator = ISUP_CUG_OUTGOING_NOT_ALLOWED;
2951 ss7_cug_indicator = ISUP_CUG_NON;
2954 if (ss7_cug_indicator != ISUP_CUG_NON) {
2957 if (ss7_cug_interlock_code && ss7_cug_interlock_ni && strlen(ss7_cug_interlock_ni) == 4) {
2958 isup_set_cug(p->
ss7call, ss7_cug_indicator, ss7_cug_interlock_ni, atoi(ss7_cug_interlock_code));
2963 ss7_redirecting_update(p, ast);
2967 if (ss7_interworking_indicator) {
2968 isup_set_interworking_indicator(p->
ss7call,
ast_true(ss7_interworking_indicator));
2972 if (ss7_forward_indicator_pmbits) {
2973 isup_set_forward_indicator_pmbits(p->
ss7call, atoi(ss7_forward_indicator_pmbits));
2979 sig_ss7_set_dialing(p, 1);
3003 sig_ss7_set_dialing(p, 0);
3004 sig_ss7_set_outgoing(p, 0);
3009 ss7_grab(p, p->
ss7);
3013 case SS7_HANGUP_SEND_REL:
3020 icause = atoi(cause);
3031 case SS7_HANGUP_SEND_RSC:
3035 case SS7_HANGUP_SEND_RLC:
3040 case SS7_HANGUP_FREE_CALL:
3045 case SS7_HANGUP_REEVENT_IAM:
3049 case SS7_HANGUP_DO_NOTHING:
3073 ss7_grab(p, p->
ss7);
3082 sig_ss7_open_media(p);
3097 if (pchan->
owner == oldchan) {
3098 pchan->
owner = newchan;
3119 switch (condition) {
3130 ss7_grab(p, p->
ss7);
3157 ss7_grab(p, p->
ss7);
3175 ss7_grab(p, p->
ss7);
3182 sig_ss7_set_echocanceller(p, 1);
3222 ss7_redirecting_update(p, chan);
3226 res = sig_ss7_play_tone(p, -1);
3251 if (p->
ss7->
type == SS7_ITU) {
3257 sig_ss7_set_outgoing(p, 1);
3259 p->
exten, assignedids, requestor);
3261 sig_ss7_set_outgoing(p, 0);
3283#define SIG_SS7_SC_HEADER "%-4s %4s %-4s %-3s %-3s %-10s %-4s %s\n"
3284#define SIG_SS7_SC_LINE "%4d %4d %-4s %-3s %-3s %-10s %-4s %s"
3287 ast_cli(fd, SIG_SS7_SC_HEADER,
"link",
"",
"Chan",
"Lcl",
"Rem",
"Call",
"SS7",
"Channel");
3288 ast_cli(fd, SIG_SS7_SC_HEADER,
"set",
"Chan",
"Idle",
"Blk",
"Blk",
"Level",
"Call",
"Name");
3298 for (idx = 0; idx < linkset->
numchans; ++idx) {
3299 if (!linkset->
pvts[idx]) {
3302 pvt = linkset->
pvts[idx];
3303 sig_ss7_lock_private(pvt);
3304 sig_ss7_lock_owner(linkset, idx);
3306 snprintf(line,
sizeof(line), SIG_SS7_SC_LINE,
3309 sig_ss7_is_chan_available(pvt) ?
"Yes" :
"No",
3319 sig_ss7_unlock_private(pvt);
3363 memset(
ss7, 0,
sizeof(*
ss7));
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_calloc(num, len)
A wrapper for calloc()
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define AST_PRES_UNAVAILABLE
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
@ AST_REDIRECTING_REASON_UNKNOWN
@ AST_REDIRECTING_REASON_NO_ANSWER
@ AST_REDIRECTING_REASON_DEFLECTION
@ AST_REDIRECTING_REASON_UNAVAILABLE
@ AST_REDIRECTING_REASON_UNCONDITIONAL
@ AST_REDIRECTING_REASON_USER_BUSY
#define AST_PRES_RESTRICTION
Internal Asterisk hangup causes.
#define AST_CAUSE_SWITCH_CONGESTION
#define AST_CAUSE_CONGESTION
#define AST_CAUSE_UNALLOCATED
#define AST_CAUSE_INTERWORKING
#define AST_CAUSE_INVALID_NUMBER_FORMAT
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
#define AST_CAUSE_NORMAL_CLEARING
#define AST_CAUSE_USER_BUSY
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
static int call(void *data)
const char * ast_channel_name(const struct ast_channel *chan)
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
#define ast_channel_lock(chan)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
ast_callid ast_channel_callid(const struct ast_channel *chan)
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_channel_trylock(chan)
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.
int ast_channel_hangupcause(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.
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.
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
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.
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
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.
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
ast_channel_state
ast_channel states
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Standard Command Line Interface.
void ast_cli(int fd, const char *fmt,...)
static struct ast_codec ulaw
void ast_verbose(const char *fmt,...)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_PVT_CAUSE_CODE
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...
#define ast_debug(level,...)
Log a DEBUG message.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
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...
#define ast_verb(level,...)
#define AST_PTHREADT_NULL
#define ast_mutex_init(pmutex)
#define DEADLOCK_AVOIDANCE(lock)
#define ast_mutex_unlock(a)
#define ast_mutex_trylock(a)
#define ast_mutex_lock(a)
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
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.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
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)
Interface header for SS7 signaling module.
void sig_ss7_cb_call_null(struct ss7 *ss7, struct isup_call *c, int lock)
void sig_ss7_link_noalarm(struct sig_ss7_linkset *linkset, int which)
#define LINKSTATE_INALARM
void sig_ss7_cli_show_channels_header(int fd)
#define SIG_SS7_DEBUG_DEFAULT
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 sig_ss7_init_linkset(struct sig_ss7_linkset *ss7)
void sig_ss7_link_alarm(struct sig_ss7_linkset *linkset, int which)
#define LINKSET_FLAG_EXPLICITACM
#define LINKSET_FLAG_AUTOACM
int sig_ss7_reset_group(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc, int range)
int sig_ss7_available(struct sig_ss7_chan *p)
void sig_ss7_cb_notinservice(struct ss7 *ss7, int cic, unsigned int dpc)
@ SS7_INDICATION_DIVERTED_PRES_ALLOWED
@ SS7_INDICATION_REROUTED_PRES_RESTRICTED
@ SS7_INDICATION_NO_REDIRECTION
@ SS7_INDICATION_DIVERTED_INFO_RESTRICTED
@ SS7_INDICATION_REROUTED_INFO_RESTRICTED
@ SS7_INDICATION_DIVERTED_PRES_RESTRICTED
@ SS7_INDICATION_REROUTED_PRES_ALLOWED
int sig_ss7_reset_cic(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc)
int sig_ss7_call(struct sig_ss7_chan *p, struct ast_channel *ast, const char *rdest)
void * ss7_linkset(void *data)
int sig_ss7_indicate(struct sig_ss7_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
#define SS7_BLOCKED_MAINTENANCE
int sig_ss7_group_blocking(struct sig_ss7_linkset *linkset, int do_block, int startcic, int endcic, unsigned char state[], int type)
int sig_ss7_find_cic(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc)
void sig_ss7_free_isup_call(struct sig_ss7_linkset *linkset, int channel)
struct sig_ss7_callback sig_ss7_callbacks
void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
@ SIG_SS7_TONE_CONGESTION
struct sig_ss7_chan * sig_ss7_chan_new(void *pvt_data, struct sig_ss7_linkset *ss7)
void sig_ss7_cli_show_channels(int fd, struct sig_ss7_linkset *linkset)
@ SIG_SS7_CALL_LEVEL_PROCEEDING
@ SIG_SS7_CALL_LEVEL_IDLE
@ SIG_SS7_CALL_LEVEL_SETUP
@ SIG_SS7_CALL_LEVEL_CONNECT
@ SIG_SS7_CALL_LEVEL_ALLOCATED
@ SIG_SS7_CALL_LEVEL_ALERTING
@ SIG_SS7_CALL_LEVEL_CONTINUITY
int sig_ss7_cic_blocking(struct sig_ss7_linkset *linkset, int do_block, int cic)
#define LINKSET_FLAG_DEFAULTECHOCONTROL
#define LINKSTATE_STARTING
#define LINKSET_FLAG_USEECHOCONTROL
void sig_ss7_chan_delete(struct sig_ss7_chan *doomed)
#define LINKSET_FLAG_INITIALHWBLO
int sig_ss7_cb_hangup(struct ss7 *ss7, int cic, unsigned int dpc, int cause, int do_hangup)
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 sig_ss7_hangup(struct sig_ss7_chan *p, struct ast_channel *ast)
void sig_ss7_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_ss7_chan *pchan)
#define SS7_BLOCKED_HARDWARE
#define SIG_SS7_NUM_DCHANS
int sig_ss7_answer(struct sig_ss7_chan *p, struct ast_channel *ast)
@ SS7_REDIRECTING_REASON_DEFLECTION_IMMEDIATE_RESPONSE
@ SS7_REDIRECTING_REASON_DEFLECTION_DURING_ALERTING
@ SS7_REDIRECTING_REASON_UNKNOWN
@ SS7_REDIRECTING_REASON_NO_ANSWER
@ SS7_REDIRECTING_REASON_USER_BUSY
@ SS7_REDIRECTING_REASON_UNAVAILABLE
@ SS7_REDIRECTING_REASON_UNCONDITIONAL
int sig_ss7_find_cic_range(struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Structure to pass both assignedid values to channel drivers.
Main Channel structure associated with a channel.
unsigned short transfercapability
char exten[AST_MAX_EXTENSION]
char chan_name[AST_CHANNEL_NAME]
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
Caller Party information.
Connected Line/Party information.
struct ast_party_id id
Connected party ID.
struct ast_party_number number
Subscriber phone number.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
unsigned char valid
TRUE if the number information is valid/present.
char * str
Subscriber phone number (Malloced)
int code
enum AST_REDIRECTING_REASON value for redirection
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
struct ast_party_redirecting_reason orig_reason
Reason for the redirection by the original party.
struct ast_party_redirecting_reason reason
Reason for the redirection.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
int count
Number of times the call was redirected.
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
struct ast_party_id orig
Who originally redirected the call (Sent to the party the call is redirected toward)
int(*const set_echocanceller)(void *pvt, int enable)
void(*const deadlock_avoidance_private)(void *pvt)
void(*const set_digital)(void *pvt, int is_digital)
struct sig_ss7_linkset *(*const find_linkset)(struct ss7 *ss7)
void(*const set_loopback)(void *pvt, int enable)
void(*const unlock_private)(void *pvt)
void(*const set_callerid)(void *pvt, const struct ast_party_caller *caller)
void(*const set_dnid)(void *pvt, const char *dnid)
void(*const set_outgoing)(void *pvt, int is_outgoing)
void(*const set_dialing)(void *pvt, int is_dialing)
void(*const set_alarm)(void *pvt, int in_alarm)
void(*const handle_link_exception)(struct sig_ss7_linkset *linkset, int which)
void(*const queue_control)(void *pvt, int subclass)
void(*const set_remotelyblocked)(void *pvt, int is_blocked)
void(*const lock_private)(void *pvt)
void(*const set_inservice)(void *pvt, int is_inservice)
void(*const open_media)(void *pvt)
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)
void(*const set_locallyblocked)(void *pvt, int is_blocked)
int(*const play_tone)(void *pvt, enum sig_ss7_tone tone)
char cid_subaddr[AST_MAX_EXTENSION]
char cid_num[AST_MAX_EXTENSION]
unsigned short cug_interlock_code
Binari Code to uniquely identify a CUG inside the network.
unsigned int echocontrol_ind
unsigned int outgoing
TRUE if this channel is being used for an outgoing call.
unsigned int loopedback
TRUE if this channel is in loopback.
unsigned int call_ref_ident
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
unsigned char redirect_info_reas
unsigned char redirect_info_orig_reas
unsigned char redirect_info
int redirecting_presentation
unsigned char redirect_info_ind
enum sig_ss7_call_level call_level
unsigned int use_callingpres
TRUE if we will use the calling presentation setting from the Asterisk channel for outgoing calls.
unsigned char calling_party_cat
char exten[AST_MAX_EXTENSION]
unsigned int rlt
XXX BOOLEAN Purpose???
struct isup_call * ss7call
Opaque libss7 call control structure.
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked.
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
unsigned int progress
TRUE if the call has seen inband-information progress through the network.
struct ast_channel * owner
unsigned char gen_dig_scheme
unsigned int called_complete
TRUE if the channel has completed collecting digits.
char cug_interlock_ni[5]
Network Identify Code as per Q.763 3.15.a.
unsigned char gen_add_type
unsigned char gen_add_pres_ind
unsigned char gen_add_num_plan
struct sig_ss7_linkset * ss7
unsigned char cug_indicator
Indication of the call being a CUG call and its permissions.
char context[AST_MAX_CONTEXT]
unsigned char redirect_counter
unsigned int inalarm
TRUE if channel is associated with a link that is down.
int orig_called_presentation
char cid_name[AST_MAX_EXTENSION]
unsigned int inservice
TRUE if channel is in service.
unsigned char redirect_info_counter
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
unsigned char gen_add_nai
unsigned int use_callerid
TRUE if caller ID is used on this channel.
char cid_ani[AST_MAX_EXTENSION]
char mohinterpret[MAX_MUSICCLASS]
unsigned char gen_dig_type
int fds[SIG_SS7_NUM_DCHANS]
char subscriberprefix[20]
enum sig_ss7_linkset::@143 state
int linkstate[SIG_SS7_NUM_DCHANS]
char networkroutedprefix[20]
char internationalprefix[10]
struct sig_ss7_chan * pvts[SIG_SS7_MAX_CHANNELS]
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
General Asterisk channel transcoding definitions.
#define AST_TRANS_CAP_DIGITAL