120 #ifndef PRI_EVENT_FACILITY 121 #error "Upgrade your libpri" 129 #undef SUPPORT_USERUSER 137 #if defined(HAVE_PRI_CCSS) 138 struct sig_pri_cc_agent_prv {
144 unsigned char cc_request_response_pending;
147 struct sig_pri_cc_monitor_instance {
159 static const char *sig_pri_cc_type_name;
164 static int pri_matchdigittimeout = 3000;
166 static int pri_gendigittimeout = 8000;
168 #define DCHAN_NOTINALARM (1 << 0) 169 #define DCHAN_UP (1 << 1) 172 #define PRI_CHANNEL(p) ((p) & 0xff) 173 #define PRI_SPAN(p) (((p) >> 8) & 0xff) 174 #define PRI_EXPLICIT (1 << 16) 175 #define PRI_CIS_CALL (1 << 17) 176 #define PRI_HELD_CALL (1 << 18) 179 #define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP) 181 static int pri_active_dchan_index(
struct sig_pri_span *pri);
209 static unsigned int PVT_TO_CHANNEL(
struct sig_pri_chan *p)
211 int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->
mastertrunkgroup ? PRI_EXPLICIT : 0));
212 ast_debug(5,
"prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n",
218 static void sig_pri_handle_dchan_exception(
struct sig_pri_span *pri,
int index)
225 static void sig_pri_set_dialing(
struct sig_pri_chan *p,
int is_dialing)
232 static void sig_pri_set_digital(
struct sig_pri_chan *p,
int is_digital)
240 static void sig_pri_set_outgoing(
struct sig_pri_chan *p,
int is_outgoing)
268 static const char *sig_pri_get_orig_dialstring(
struct sig_pri_chan *p)
277 #if defined(HAVE_PRI_CCSS) 278 static void sig_pri_make_cc_dialstring(
struct sig_pri_chan *p,
char *
buf,
size_t buf_size)
289 static void sig_pri_dial_digits(
struct sig_pri_chan *p,
const char *dial_string)
307 static void sig_pri_span_devstate_changed(
struct sig_pri_span *pri)
323 static void sig_pri_set_caller_id(
struct sig_pri_chan *p)
332 caller.id.name.valid = 1;
334 caller.id.number.str = p->
cid_num;
335 caller.id.number.plan = p->
cid_ton;
337 caller.id.number.valid = 1;
340 caller.id.subaddress.valid = 1;
347 caller.ani.number.str = p->
cid_ani;
350 caller.ani.number.valid = 1;
367 static void sig_pri_set_dnid(
struct sig_pri_chan *p,
const char *dnid)
384 static void sig_pri_set_rdnis(
struct sig_pri_chan *p,
const char *rdnis)
391 static void sig_pri_unlock_private(
struct sig_pri_chan *p)
398 static void sig_pri_lock_private(
struct sig_pri_chan *p)
405 static void sig_pri_deadlock_avoidance_private(
struct sig_pri_chan *p)
411 sig_pri_unlock_private(p);
413 sig_pri_lock_private(p);
422 sig_pri_deadlock_avoidance_private(p);
426 pthread_kill(pri->
master, SIGURG);
443 switch (pri_reason) {
444 case PRI_REDIR_FORWARD_ON_BUSY:
447 case PRI_REDIR_FORWARD_ON_NO_REPLY:
450 case PRI_REDIR_DEFLECTION:
453 case PRI_REDIR_UNCONDITIONAL:
456 case PRI_REDIR_UNKNOWN:
478 switch (ast_reason) {
480 pri_reason = PRI_REDIR_FORWARD_ON_BUSY;
483 pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY;
486 pri_reason = PRI_REDIR_UNCONDITIONAL;
489 pri_reason = PRI_REDIR_DEFLECTION;
493 pri_reason = PRI_REDIR_UNKNOWN;
509 static int pri_to_ast_presentation(
int pri_presentation)
511 int ast_presentation;
513 switch (pri_presentation) {
514 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED:
517 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
520 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
523 case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER:
527 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED:
530 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
533 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
536 case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER:
540 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED:
541 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
542 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
543 case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER:
552 return ast_presentation;
564 static int ast_to_pri_presentation(
int ast_presentation)
566 int pri_presentation;
568 switch (ast_presentation) {
570 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
573 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
576 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
579 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER;
583 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
586 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
589 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
592 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER;
599 pri_presentation = PRES_NUMBER_NOT_AVAILABLE;
603 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
607 return pri_presentation;
623 switch (pri_char_set) {
625 case PRI_CHAR_SET_UNKNOWN:
628 case PRI_CHAR_SET_ISO8859_1:
631 case PRI_CHAR_SET_WITHDRAWN:
634 case PRI_CHAR_SET_ISO8859_2:
637 case PRI_CHAR_SET_ISO8859_3:
640 case PRI_CHAR_SET_ISO8859_4:
643 case PRI_CHAR_SET_ISO8859_5:
646 case PRI_CHAR_SET_ISO8859_7:
649 case PRI_CHAR_SET_ISO10646_BMPSTRING:
652 case PRI_CHAR_SET_ISO10646_UTF_8STRING:
673 switch (ast_char_set) {
676 pri_char_set = PRI_CHAR_SET_UNKNOWN;
679 pri_char_set = PRI_CHAR_SET_ISO8859_1;
682 pri_char_set = PRI_CHAR_SET_WITHDRAWN;
685 pri_char_set = PRI_CHAR_SET_ISO8859_2;
688 pri_char_set = PRI_CHAR_SET_ISO8859_3;
691 pri_char_set = PRI_CHAR_SET_ISO8859_4;
694 pri_char_set = PRI_CHAR_SET_ISO8859_5;
697 pri_char_set = PRI_CHAR_SET_ISO8859_7;
700 pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
703 pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
710 #if defined(HAVE_PRI_SUBADDR) 722 static void sig_pri_set_subaddress(
struct ast_party_subaddress *ast_subaddress,
const struct pri_party_subaddress *pri_subaddress)
725 if (pri_subaddress->length <= 0) {
730 if (!pri_subaddress->type) {
732 ast_subaddress->
str =
ast_strdup((
char *) pri_subaddress->data);
740 cnum =
ast_malloc(2 * pri_subaddress->length + 1);
747 len = pri_subaddress->length - 1;
748 for (x = 0; x <
len; ++x) {
749 ptr += sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[x]);
752 if (pri_subaddress->odd_even_indicator) {
754 sprintf(ptr,
"%01hhx", (
unsigned char)((pri_subaddress->data[len]) >> 4));
757 sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[len]);
759 ast_subaddress->
str = cnum;
761 ast_subaddress->
type = pri_subaddress->type;
763 ast_subaddress->
valid = 1;
767 #if defined(HAVE_PRI_SUBADDR) 768 static unsigned char ast_pri_pack_hex_char(
char c)
774 }
else if (c < (
'9' + 1)) {
776 }
else if (c <
'A') {
778 }
else if (c < (
'F' + 1)) {
780 }
else if (c <
'a') {
782 }
else if (c < (
'f' + 1)) {
791 #if defined(HAVE_PRI_SUBADDR) 807 static int ast_pri_pack_hex_string(
unsigned char *dst,
char *src,
int maxlen)
810 int len = strlen(src);
812 if (len > (2 * maxlen)) {
816 res = len / 2 + len % 2;
819 *dst = ast_pri_pack_hex_char(*src) << 4;
821 *dst |= ast_pri_pack_hex_char(*src);
826 *dst = ast_pri_pack_hex_char(*src) << 4;
832 #if defined(HAVE_PRI_SUBADDR) 845 static void sig_pri_party_subaddress_from_ast(
struct pri_party_subaddress *pri_subaddress,
const struct ast_party_subaddress *ast_subaddress)
848 pri_subaddress->type = ast_subaddress->
type;
849 if (!ast_subaddress->
type) {
852 sizeof(pri_subaddress->data));
853 pri_subaddress->length = strlen((
char *) pri_subaddress->data);
854 pri_subaddress->odd_even_indicator = 0;
855 pri_subaddress->valid = 1;
862 int length = ast_pri_pack_hex_string(pri_subaddress->data,
863 ast_subaddress->
str,
sizeof(pri_subaddress->data));
865 pri_subaddress->length = length;
867 length = strlen(ast_subaddress->
str);
868 if (length > 2 *
sizeof(pri_subaddress->data)) {
869 pri_subaddress->odd_even_indicator = 0;
871 pri_subaddress->odd_even_indicator = (length & 1);
873 pri_subaddress->valid = 1;
891 static void sig_pri_party_name_from_ast(
struct pri_party_name *pri_name,
const struct ast_party_name *ast_name)
893 if (!ast_name->
valid) {
897 pri_name->presentation = ast_to_pri_presentation(ast_name->
presentation);
898 pri_name->char_set = ast_to_pri_char_set(ast_name->
char_set);
916 static void sig_pri_party_number_from_ast(
struct pri_party_number *pri_number,
const struct ast_party_number *ast_number)
918 if (!ast_number->
valid) {
921 pri_number->valid = 1;
922 pri_number->presentation = ast_to_pri_presentation(ast_number->
presentation);
923 pri_number->plan = ast_number->
plan;
941 static void sig_pri_party_id_from_ast(
struct pri_party_id *pri_id,
const struct ast_party_id *ast_id)
943 sig_pri_party_name_from_ast(&pri_id->name, &ast_id->
name);
944 sig_pri_party_number_from_ast(&pri_id->number, &ast_id->
number);
945 #if defined(HAVE_PRI_SUBADDR) 946 sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->
subaddress);
964 struct pri_party_redirecting pri_redirecting;
970 memset(&pri_redirecting, 0,
sizeof(pri_redirecting));
972 sig_pri_party_id_from_ast(&pri_redirecting.from, &redirecting_from);
973 sig_pri_party_id_from_ast(&pri_redirecting.to, &redirecting_to);
974 sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &redirecting_orig);
975 pri_redirecting.count = ast_redirecting->
count;
976 pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->
orig_reason.
code);
977 pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->
reason.
code);
979 pri_redirecting_update(pvt->
pri->
pri, pvt->
call, &pri_redirecting);
991 static void sig_pri_dsp_reset_and_flush_digits(
struct sig_pri_chan *p)
998 static int sig_pri_set_echocanceller(
struct sig_pri_chan *p,
int enable)
1046 sig_pri_set_digital(p, 1);
1050 sig_pri_span_devstate_changed(p->
pri);
1088 static void sig_pri_ami_channel_event(
struct sig_pri_chan *p)
1097 int transfercapability)
1103 sig_pri_set_outgoing(p, 1);
1105 p->
exten, assignedids, requestor);
1107 sig_pri_set_outgoing(p, 0);
1122 static const char *pri_order(
int level)
1132 return "Quaternary";
1139 static int pri_active_dchan_index(
struct sig_pri_span *pri)
1165 if (pri->
dchans[idx] == old) {
1168 if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) {
1182 if (old && oldslot != newslot) {
1184 "Span %d: No D-channels up! Switching selected D-channel from %s to %s.\n",
1185 pri->
span, pri_order(oldslot), pri_order(newslot));
1193 if (old && oldslot != newslot) {
1195 "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n",
1196 pri_order(oldslot), pri->
fds[oldslot],
1197 pri_order(newslot), pri->
fds[newslot]);
1231 static int sig_pri_is_chan_in_use(
struct sig_pri_chan *pvt)
1247 return !sig_pri_is_chan_in_use(pvt)
1248 #if defined(HAVE_PRI_SERVICE_MESSAGES) 1250 && !pvt->service_status
1268 static void sig_pri_lock_owner(
struct sig_pri_span *pri,
int chanpos)
1281 sig_pri_unlock_private(pri->
pvts[chanpos]);
1283 sig_pri_lock_private(pri->
pvts[chanpos]);
1303 sig_pri_lock_owner(pri, chanpos);
1323 static void sig_pri_queue_hold(
struct sig_pri_span *pri,
int chanpos)
1325 sig_pri_lock_owner(pri, chanpos);
1345 static void sig_pri_queue_unhold(
struct sig_pri_span *pri,
int chanpos)
1347 sig_pri_lock_owner(pri, chanpos);
1368 static void pri_queue_control(
struct sig_pri_span *pri,
int chanpos,
int subclass)
1377 pri_queue_frame(pri, chanpos, &f);
1396 static void sig_pri_queue_hangup(
struct sig_pri_span *pri,
int chanpos)
1404 sig_pri_lock_owner(pri, chanpos);
1411 sig_pri_unlock_private(pri->
pvts[chanpos]);
1416 sig_pri_lock_private(pri->
pvts[chanpos]);
1436 static void pri_queue_pvt_cause_data(
struct sig_pri_span *pri,
int chanpos,
const char *cause,
int ast_cause)
1441 sig_pri_lock_owner(pri, chanpos);
1444 int datalen =
sizeof(*cause_code) + strlen(cause);
1446 memset(cause_code, 0, datalen);
1469 static int pri_find_principle_by_call(
struct sig_pri_span *pri, q931_call *
call)
1477 for (idx = 0; idx < pri->
numchans; ++idx) {
1499 static void pri_destroy_later(
struct sig_pri_span *pri)
1520 static void sig_pri_kill_call(
struct sig_pri_span *pri, q931_call *call,
int cause)
1524 chanpos = pri_find_principle_by_call(pri, call);
1526 pri_hangup(pri->
pri, call, cause);
1529 sig_pri_lock_private(pri->
pvts[chanpos]);
1531 pri_hangup(pri->
pri, call, cause);
1533 sig_pri_unlock_private(pri->
pvts[chanpos]);
1534 sig_pri_span_devstate_changed(pri);
1539 sig_pri_unlock_private(pri->
pvts[chanpos]);
1567 prioffset = PRI_CHANNEL(channel);
1568 if (!prioffset || (channel & PRI_HELD_CALL)) {
1570 return pri_find_principle_by_call(pri, call);
1573 span = PRI_SPAN(channel);
1574 if (!(channel & PRI_EXPLICIT)) {
1577 index = pri_active_dchan_index(pri);
1585 for (x = 0; x < pri->
numchans; x++) {
1611 static int pri_fixup_principle(
struct sig_pri_span *pri,
int principle, q931_call *call)
1615 if (principle < 0 || pri->numchans <= principle) {
1623 if (pri->
pvts[principle] && pri->
pvts[principle]->
call == call) {
1629 for (x = 0; x < pri->
numchans; x++) {
1638 new_chan = pri->
pvts[principle];
1639 old_chan = pri->
pvts[x];
1642 sig_pri_lock_private(old_chan);
1643 sig_pri_lock_owner(pri, x);
1644 sig_pri_lock_private(new_chan);
1646 ast_verb(3,
"Moving call (%s) from channel %d to %d.\n",
1651 "Can't move call (%s) from channel %d to %d. It is already in use.\n",
1654 sig_pri_unlock_private(new_chan);
1655 if (old_chan->
owner) {
1658 sig_pri_unlock_private(old_chan);
1662 sig_pri_fixup_chans(old_chan, new_chan);
1672 #if defined(HAVE_PRI_AOC_EVENTS) 1673 new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid;
1674 new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
1675 new_chan->holding_aoce = old_chan->holding_aoce;
1683 #if defined(HAVE_PRI_CALL_WAITING) 1684 new_chan->is_call_waiting = old_chan->is_call_waiting;
1686 #if defined(HAVE_PRI_SETUP_ACK_INBAND) 1687 new_chan->no_dialed_digits = old_chan->no_dialed_digits;
1690 #if defined(HAVE_PRI_AOC_EVENTS) 1691 old_chan->aoc_s_request_invoke_id_valid = 0;
1692 old_chan->waiting_for_aoce = 0;
1693 old_chan->holding_aoce = 0;
1701 #if defined(HAVE_PRI_CALL_WAITING) 1702 old_chan->is_call_waiting = 0;
1704 #if defined(HAVE_PRI_SETUP_ACK_INBAND) 1705 old_chan->no_dialed_digits = 0;
1711 #if defined(HAVE_PRI_REVERSE_CHARGE) 1712 new_chan->reverse_charging_indication = old_chan->reverse_charging_indication;
1714 #if defined(HAVE_PRI_SETUP_KEYPAD) 1715 strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
1721 #if defined(HAVE_PRI_TRANSFER) 1722 new_chan->xfer_data = old_chan->xfer_data;
1723 old_chan->xfer_data =
NULL;
1726 #if defined(HAVE_PRI_AOC_EVENTS) 1727 new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
1728 new_chan->aoc_e = old_chan->aoc_e;
1755 sig_pri_open_media(new_chan);
1758 if (new_chan->
owner) {
1759 sig_pri_ami_channel_event(new_chan);
1762 sig_pri_unlock_private(old_chan);
1763 if (new_chan->
owner) {
1766 sig_pri_unlock_private(new_chan);
1770 ast_verb(3,
"Call specified, but not found.\n");
1792 static int pri_find_fixup_principle(
struct sig_pri_span *pri,
int channel, q931_call *call)
1796 chanpos = pri_find_principle(pri, channel, call);
1799 pri->
span, PRI_SPAN(channel), PRI_CHANNEL(channel));
1800 sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
1803 chanpos = pri_fixup_principle(pri, chanpos, call);
1806 pri->
span, PRI_SPAN(channel), PRI_CHANNEL(channel));
1814 sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
1820 static char * redirectingreason2str(
int redirectingreason)
1822 switch (redirectingreason) {
1830 return "UNCONDITIONAL";
1832 return "NOREDIRECT";
1836 static char *dialplan2str(
int dialplan)
1838 if (dialplan == -1) {
1839 return(
"Dynamically set dialplan in ISDN");
1841 return (pri_plan2str(dialplan));
1856 static void apply_plan_to_number(
char *buf,
size_t size,
const struct sig_pri_span *pri,
const char *
number,
int plan)
1859 case PRI_INTERNATIONAL_ISDN:
1862 case PRI_NATIONAL_ISDN:
1865 case PRI_LOCAL_ISDN:
1866 snprintf(buf, size,
"%s%s", pri->
localprefix, number);
1875 snprintf(buf, size,
"%s", number);
1892 static void apply_plan_to_existing_number(
char *buf,
size_t size,
const struct sig_pri_span *pri,
const char *number,
int plan)
1901 apply_plan_to_number(buf, size, pri, number, plan);
1914 static void pri_check_restart(
struct sig_pri_span *pri)
1916 #if defined(HAVE_PRI_SERVICE_MESSAGES) 1926 #if defined(HAVE_PRI_SERVICE_MESSAGES) 1930 "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n",
1932 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ?
"both ends" :
"far end" :
"near end");
1945 sig_pri_span_devstate_changed(pri);
1949 #if defined(HAVE_PRI_CALL_WAITING) 1964 pvt->
stripmsd = pri->ch_cfg.stripmsd;
1993 static int pri_find_empty_chan(
struct sig_pri_span *pri,
int backwards)
2001 if (backwards && (x < 0))
2003 if (!backwards && (x >= pri->
numchans))
2008 ast_debug(1,
"Found empty available channel %d/%d\n",
2020 #if defined(HAVE_PRI_CALL_HOLD) 2033 static int pri_find_empty_nobch(
struct sig_pri_span *pri)
2037 for (idx = 0; idx < pri->
numchans; ++idx) {
2041 ast_debug(1,
"Found empty available no B channel interface\n");
2056 static void *do_idle_thread(
void *v_pvt)
2063 int timeout_ms = 30000;
2065 struct timeval start;
2116 static void *pri_ss_thread(
void *data)
2147 sig_pri_dsp_reset_and_flush_digits(p);
2151 len = strlen(exten);
2155 sig_pri_play_tone(p, -1);
2159 timeout = pri_matchdigittimeout;
2161 timeout = pri_gendigittimeout;
2164 ast_debug(1,
"waitfordigit returned < 0...\n");
2175 ast_verb(3,
"Going to extension s|1 because of empty extension received on overlap call\n");
2193 sig_pri_play_tone(p, -1);
2197 sig_pri_dsp_reset_and_flush_digits(p);
2198 #if defined(JIRA_ASTERISK_15594) 2213 sig_pri_lock_private(p);
2215 pri_grab(p, p->
pri);
2219 pri_proceeding(p->
pri->
pri, p->
call, PVT_TO_CHANNEL(p), 0);
2222 sig_pri_unlock_private(p);
2226 sig_pri_set_echocanceller(p, 1);
2242 sig_pri_span_devstate_changed(p->
pri);
2251 if (!before_start_pri) {
2252 pri_find_dchan(pri);
2259 if (!before_start_pri)
2260 pri_restart(pri->
dchans[index]);
2276 static void sig_pri_party_name_convert(
struct ast_party_name *ast_name,
const struct pri_party_name *pri_name)
2279 ast_name->
char_set = pri_to_ast_char_set(pri_name->char_set);
2280 ast_name->
presentation = pri_to_ast_presentation(pri_name->presentation);
2281 ast_name->
valid = 1;
2298 static void sig_pri_party_number_convert(
struct ast_party_number *ast_number,
const struct pri_party_number *pri_number,
struct sig_pri_span *pri)
2302 apply_plan_to_existing_number(number,
sizeof(number), pri, pri_number->str,
2305 ast_number->
plan = pri_number->plan;
2306 ast_number->
presentation = pri_to_ast_presentation(pri_number->presentation);
2307 ast_number->
valid = 1;
2324 static void sig_pri_party_id_convert(
struct ast_party_id *ast_id,
const struct pri_party_id *pri_id,
struct sig_pri_span *pri)
2326 if (pri_id->name.valid) {
2327 sig_pri_party_name_convert(&ast_id->
name, &pri_id->name);
2329 if (pri_id->number.valid) {
2330 sig_pri_party_number_convert(&ast_id->
number, &pri_id->number, pri);
2332 #if defined(HAVE_PRI_SUBADDR) 2333 if (pri_id->subaddress.valid) {
2334 sig_pri_set_subaddress(&ast_id->
subaddress, &pri_id->subaddress);
2355 const struct pri_party_redirecting *pri_redirecting,
2361 sig_pri_party_id_convert(&ast_redirecting->
orig, &pri_redirecting->orig_called, pri);
2362 sig_pri_party_id_convert(&ast_redirecting->
from, &pri_redirecting->from, pri);
2363 sig_pri_party_id_convert(&ast_redirecting->
to, &pri_redirecting->to, pri);
2364 ast_redirecting->
count = pri_redirecting->count;
2365 ast_redirecting->
reason.
code = pri_to_ast_reason(pri_redirecting->reason);
2366 ast_redirecting->
orig_reason.
code = pri_to_ast_reason(pri_redirecting->orig_reason);
2380 static int sig_pri_msn_match(
const char *msn_patterns,
const char *exten)
2389 pattern = strtok_r(msn_list,
",", &list_tail);
2396 pattern = strtok_r(
NULL,
",", &list_tail);
2402 #if defined(HAVE_PRI_MCID) 2403 static void party_number_json_to_ami(
struct ast_str **msg,
const char *
prefix,
struct ast_json *number)
2405 const char *num_txt, *pres_txt;
2412 prefix, prefix, prefix);
2425 ast_str_append(msg, 0,
"%sNumPres: %d (%s)\r\n", prefix, pres, pres_txt);
2428 static void party_name_json_to_ami(
struct ast_str **msg,
const char *prefix,
struct ast_json *
name)
2430 const char *name_txt, *pres_txt, *
charset;
2434 "%sNameValid: 0\r\n" 2447 ast_str_append(msg, 0,
"%sNameCharSet: %s\r\n", prefix, charset);
2448 ast_str_append(msg, 0,
"%sNamePres: %d (%s)\r\n", prefix, pres, pres_txt);
2451 static void party_subaddress_json_to_ami(
struct ast_str **msg,
const char *prefix,
struct ast_json *subaddress)
2453 const char *subaddress_txt, *type_txt;
2463 ast_str_append(msg, 0,
"%sSubaddr: %s\r\n", prefix, subaddress_txt);
2464 ast_str_append(msg, 0,
"%sSubaddrType: %s\r\n", prefix, type_txt);
2479 static void party_json_to_ami(
struct ast_str **msg,
const char *prefix,
struct ast_json *party)
2493 party_number_json_to_ami(msg, prefix, number);
2496 party_name_json_to_ami(msg, prefix, name);
2499 party_subaddress_json_to_ami(msg, prefix, subaddress);
2510 if (!channel_string) {
2560 static void sig_pri_mcid_event(
struct sig_pri_span *pri,
const struct pri_subcmd_mcid_req *mcid,
struct ast_channel *owner)
2567 sig_pri_party_id_convert(&connected_party, &mcid->answerer, pri);
2582 sig_pri_party_id_convert(&caller_party, &mcid->originator, pri);
2583 send_mcid(owner, &caller_party, &connected_party);
2590 #if defined(HAVE_PRI_TRANSFER) 2591 struct xfer_rsp_data {
2602 #if defined(HAVE_PRI_TRANSFER) 2615 static void sig_pri_transfer_rsp(
struct xfer_rsp_data *rsp,
int is_successful)
2617 if (rsp->responded) {
2622 pri_transfer_rsp(rsp->pri->pri, rsp->call, rsp->invoke_id, is_successful);
2626 #if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER) 2644 static int sig_pri_attempt_transfer(
struct sig_pri_span *pri, q931_call *call_1_pri,
int call_1_held, q931_call *call_2_pri,
int call_2_held,
struct xfer_rsp_data *xfer_data)
2646 struct attempt_xfer_call {
2654 struct attempt_xfer_call *call_1;
2655 struct attempt_xfer_call *call_2;
2656 struct attempt_xfer_call c1;
2657 struct attempt_xfer_call c2;
2659 c1.pri = call_1_pri;
2660 c1.held = call_1_held;
2663 c2.pri = call_2_pri;
2664 c2.held = call_2_held;
2667 call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri);
2668 call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri);
2669 if (call_1->chanpos < 0 || call_2->chanpos < 0) {
2671 #if defined(HAVE_PRI_TRANSFER) 2674 sig_pri_transfer_rsp(xfer_data, 0);
2681 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2682 sig_pri_lock_owner(pri, call_1->chanpos);
2683 call_1->ast = pri->
pvts[call_1->chanpos]->
owner;
2688 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2691 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2692 sig_pri_lock_owner(pri, call_2->chanpos);
2693 call_2->ast = pri->
pvts[call_2->chanpos]->
owner;
2698 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2700 if (!call_1->ast || !call_2->ast) {
2708 #if defined(HAVE_PRI_TRANSFER) 2711 sig_pri_transfer_rsp(xfer_data, 0);
2717 ast_verb(3,
"TRANSFERRING %s to %s\n",
2720 #if defined(HAVE_PRI_TRANSFER) 2727 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2728 pri->
pvts[call_1->chanpos]->xfer_data = xfer_data;
2729 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2730 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2731 pri->
pvts[call_2->chanpos]->xfer_data = xfer_data;
2732 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2741 #if defined(HAVE_PRI_TRANSFER) 2750 rsp_chanpos = pri_find_principle_by_call(pri, call_1->pri);
2751 if (0 <= rsp_chanpos) {
2752 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2753 pri->
pvts[rsp_chanpos]->xfer_data =
NULL;
2754 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2756 rsp_chanpos = pri_find_principle_by_call(pri, call_2->pri);
2757 if (0 <= rsp_chanpos) {
2758 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2759 pri->
pvts[rsp_chanpos]->xfer_data =
NULL;
2760 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2764 sig_pri_transfer_rsp(xfer_data, retval ? 0 : 1);
2773 #if defined(HAVE_PRI_CCSS) 2785 static int sig_pri_cc_agent_cmp_cc_id(
void *obj,
void *arg,
int flags)
2788 struct sig_pri_cc_agent_prv *agent_prv_1 = agent_1->
private_data;
2789 struct sig_pri_cc_agent_prv *agent_prv_2 = arg;
2791 return (agent_prv_1 && agent_prv_1->pri == agent_prv_2->pri
2796 #if defined(HAVE_PRI_CCSS) 2815 struct sig_pri_cc_agent_prv finder = {
2821 sig_pri_cc_type_name);
2825 #if defined(HAVE_PRI_CCSS) 2837 static int sig_pri_cc_monitor_cmp_cc_id(
void *obj,
void *arg,
int flags)
2839 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
2840 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
2842 return (monitor_1->pri == monitor_2->pri
2847 #if defined(HAVE_PRI_CCSS) 2864 static struct sig_pri_cc_monitor_instance *sig_pri_find_cc_monitor_by_cc_id(
struct sig_pri_span *pri,
long cc_id)
2866 struct sig_pri_cc_monitor_instance finder = {
2871 return ao2_callback(sig_pri_cc_monitors, 0, sig_pri_cc_monitor_cmp_cc_id, &finder);
2875 #if defined(HAVE_PRI_CCSS) 2885 static void sig_pri_cc_monitor_instance_destroy(
void *data)
2887 struct sig_pri_cc_monitor_instance *monitor_instance = data;
2889 if (monitor_instance->cc_id != -1) {
2891 pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id);
2898 #if defined(HAVE_PRI_CCSS) 2917 static struct sig_pri_cc_monitor_instance *sig_pri_cc_monitor_instance_init(
int core_id,
struct sig_pri_span *pri,
long cc_id,
const char *device_name)
2919 struct sig_pri_cc_monitor_instance *monitor_instance;
2925 monitor_instance =
ao2_alloc(
sizeof(*monitor_instance) + strlen(device_name),
2926 sig_pri_cc_monitor_instance_destroy);
2927 if (!monitor_instance) {
2931 monitor_instance->cc_id = cc_id;
2932 monitor_instance->pri = pri;
2933 monitor_instance->core_id = core_id;
2934 strcpy(monitor_instance->name, device_name);
2938 ao2_link(sig_pri_cc_monitors, monitor_instance);
2939 return monitor_instance;
2943 #if defined(HAVE_PRI_CCSS) 2965 struct sig_pri_cc_monitor_instance *
monitor;
2972 pvt = pri->
pvts[chanpos];
2975 if (core_id == -1) {
2986 switch (monitor_policy) {
2997 sig_pri_make_cc_dialstring(pvt, dialstring,
sizeof(dialstring));
2998 monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
3005 monitor->cc_id = -1;
3012 sig_pri_get_orig_dialstring(pvt), service,
NULL);
3038 #if defined(HAVE_PRI_CCSS) 3050 sig_pri_lock_owner(pri, chanpos);
3056 if (core_id == -1) {
3067 #if defined(HAVE_PRI_CCSS) 3078 switch (monitor_policy) {
3086 sig_pri_get_orig_dialstring(pri->
pvts[chanpos]), service,
NULL);
3104 sig_pri_get_orig_dialstring(pri->
pvts[chanpos]), service,
NULL);
3110 sig_pri_get_orig_dialstring(pri->
pvts[chanpos]), service,
NULL);
3119 #if defined(HAVE_PRI_CCSS) 3131 static void sig_pri_cc_link_canceled(
struct sig_pri_span *pri,
long cc_id,
int is_agent)
3136 agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
3141 sig_pri_cc_type_name);
3144 struct sig_pri_cc_monitor_instance *
monitor;
3146 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
3150 monitor->cc_id = -1;
3152 "%s monitor got canceled by link", sig_pri_cc_type_name);
3158 #if defined(HAVE_PRI_AOC_EVENTS) 3168 static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri(
enum PRI_AOC_CHARGED_ITEM
value)
3172 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3174 return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
3176 return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
3178 return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
3180 return PRI_AOC_CHARGED_ITEM_CALL_SETUP;
3182 return PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
3184 return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
3186 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3190 #if defined(HAVE_PRI_AOC_EVENTS) 3203 case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE:
3205 case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
3207 case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
3209 case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
3211 case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
3213 case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
3215 case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
3222 #if defined(HAVE_PRI_AOC_EVENTS) 3234 return PRI_AOC_MULTIPLIER_THOUSANDTH;
3236 return PRI_AOC_MULTIPLIER_HUNDREDTH;
3238 return PRI_AOC_MULTIPLIER_TENTH;
3240 return PRI_AOC_MULTIPLIER_ONE;
3242 return PRI_AOC_MULTIPLIER_TEN;
3244 return PRI_AOC_MULTIPLIER_HUNDRED;
3246 return PRI_AOC_MULTIPLIER_THOUSAND;
3248 return PRI_AOC_MULTIPLIER_ONE;
3253 #if defined(HAVE_PRI_AOC_EVENTS) 3261 static int sig_pri_aoc_multiplier_from_pri(
const int mult)
3264 case PRI_AOC_MULTIPLIER_THOUSANDTH:
3266 case PRI_AOC_MULTIPLIER_HUNDREDTH:
3268 case PRI_AOC_MULTIPLIER_TENTH:
3270 case PRI_AOC_MULTIPLIER_ONE:
3272 case PRI_AOC_MULTIPLIER_TEN:
3274 case PRI_AOC_MULTIPLIER_HUNDRED:
3276 case PRI_AOC_MULTIPLIER_THOUSAND:
3284 #if defined(HAVE_PRI_AOC_EVENTS) 3294 static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri(
enum ast_aoc_time_scale value)
3299 return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
3301 return PRI_AOC_TIME_SCALE_TENTH_SECOND;
3303 return PRI_AOC_TIME_SCALE_SECOND;
3305 return PRI_AOC_TIME_SCALE_TEN_SECOND;
3307 return PRI_AOC_TIME_SCALE_MINUTE;
3309 return PRI_AOC_TIME_SCALE_HOUR;
3311 return PRI_AOC_TIME_SCALE_DAY;
3316 #if defined(HAVE_PRI_AOC_EVENTS) 3326 static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast(
enum PRI_AOC_TIME_SCALE value)
3330 case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND:
3332 case PRI_AOC_TIME_SCALE_TENTH_SECOND:
3334 case PRI_AOC_TIME_SCALE_SECOND:
3336 case PRI_AOC_TIME_SCALE_TEN_SECOND:
3338 case PRI_AOC_TIME_SCALE_MINUTE:
3340 case PRI_AOC_TIME_SCALE_HOUR:
3342 case PRI_AOC_TIME_SCALE_DAY:
3349 #if defined(HAVE_PRI_AOC_EVENTS) 3365 static void sig_pri_aoc_s_from_pri(
const struct pri_subcmd_aoc_s *aoc_s,
struct ast_channel *owner,
int passthrough)
3369 size_t encoded_size = 0;
3372 if (!owner || !aoc_s) {
3380 for (idx = 0; idx < aoc_s->num_items; ++idx) {
3383 charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable);
3388 switch (aoc_s->item[idx].rate_type) {
3389 case PRI_AOC_RATE_TYPE_DURATION:
3392 aoc_s->item[idx].rate.duration.amount.cost,
3393 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier),
3394 aoc_s->item[idx].rate.duration.currency,
3395 aoc_s->item[idx].rate.duration.time.length,
3396 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale),
3397 aoc_s->item[idx].rate.duration.granularity.length,
3398 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale),
3399 aoc_s->item[idx].rate.duration.charging_type);
3401 case PRI_AOC_RATE_TYPE_FLAT:
3404 aoc_s->item[idx].rate.flat.amount.cost,
3405 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier),
3406 aoc_s->item[idx].rate.flat.currency);
3408 case PRI_AOC_RATE_TYPE_VOLUME:
3411 aoc_s->item[idx].rate.volume.unit,
3412 aoc_s->item[idx].rate.volume.amount.cost,
3413 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier),
3414 aoc_s->item[idx].rate.volume.currency);
3416 case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
3419 aoc_s->item[idx].rate.special);
3421 case PRI_AOC_RATE_TYPE_FREE:
3424 case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
3433 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3444 #if defined(HAVE_PRI_AOC_EVENTS) 3458 static void sig_pri_aoc_request_from_pri(
const struct pri_subcmd_aoc_request *aoc_request,
struct sig_pri_chan *pvt, q931_call *call)
3466 request = aoc_request->charging_request;
3468 if (request & PRI_AOC_REQUEST_S) {
3472 pvt->aoc_s_request_invoke_id = aoc_request->invoke_id;
3473 pvt->aoc_s_request_invoke_id_valid = 1;
3476 pri_aoc_s_request_response_send(pvt->
pri->
pri,
3478 aoc_request->invoke_id,
3483 if (request & PRI_AOC_REQUEST_D) {
3485 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3487 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3488 aoc_request->invoke_id);
3490 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3492 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3493 aoc_request->invoke_id);
3497 if (request & PRI_AOC_REQUEST_E) {
3499 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3501 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3502 aoc_request->invoke_id);
3504 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3506 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3507 aoc_request->invoke_id);
3513 #if defined(HAVE_PRI_AOC_EVENTS) 3529 static void sig_pri_aoc_d_from_pri(
const struct pri_subcmd_aoc_d *aoc_d,
struct ast_channel *owner,
int passthrough)
3533 size_t encoded_size = 0;
3536 if (!owner || !aoc_d) {
3540 switch (aoc_d->charge) {
3541 case PRI_AOC_DE_CHARGE_CURRENCY:
3544 case PRI_AOC_DE_CHARGE_UNITS:
3547 case PRI_AOC_DE_CHARGE_FREE:
3559 switch (aoc_d->billing_accumulation) {
3561 ast_debug(1,
"AOC-D billing accumulation has unknown value: %d\n",
3562 aoc_d->billing_accumulation);
3572 switch (aoc_d->billing_id) {
3573 case PRI_AOC_D_BILLING_ID_NORMAL:
3576 case PRI_AOC_D_BILLING_ID_REVERSE:
3579 case PRI_AOC_D_BILLING_ID_CREDIT_CARD:
3582 case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE:
3588 switch (aoc_d->charge) {
3589 case PRI_AOC_DE_CHARGE_CURRENCY:
3591 aoc_d->recorded.money.amount.cost,
3592 sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier),
3593 aoc_d->recorded.money.currency);
3595 case PRI_AOC_DE_CHARGE_UNITS:
3598 for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) {
3601 (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0),
3602 aoc_d->recorded.unit.item[i].number,
3603 (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0),
3604 aoc_d->recorded.unit.item[i].type);
3610 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3621 #if defined(HAVE_PRI_AOC_EVENTS) 3638 static void sig_pri_aoc_e_from_pri(
const struct pri_subcmd_aoc_e *aoc_e,
struct ast_channel *owner,
int passthrough)
3642 size_t encoded_size = 0;
3649 switch (aoc_e->charge) {
3650 case PRI_AOC_DE_CHARGE_CURRENCY:
3653 case PRI_AOC_DE_CHARGE_UNITS:
3656 case PRI_AOC_DE_CHARGE_FREE:
3668 switch (aoc_e->associated.charging_type) {
3669 case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER:
3670 if (!aoc_e->associated.charge.number.valid) {
3675 case PRI_AOC_E_CHARGING_ASSOCIATION_ID:
3682 switch (aoc_e->billing_id) {
3683 case PRI_AOC_E_BILLING_ID_NORMAL:
3686 case PRI_AOC_E_BILLING_ID_REVERSE:
3689 case PRI_AOC_E_BILLING_ID_CREDIT_CARD:
3692 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL:
3695 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY:
3698 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY:
3701 case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION:
3704 case PRI_AOC_E_BILLING_ID_CALL_TRANSFER:
3707 case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE:
3713 switch (aoc_e->charge) {
3714 case PRI_AOC_DE_CHARGE_CURRENCY:
3716 aoc_e->recorded.money.amount.cost,
3717 sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier),
3718 aoc_e->recorded.money.currency);
3720 case PRI_AOC_DE_CHARGE_UNITS:
3723 for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) {
3726 (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0),
3727 aoc_e->recorded.unit.item[i].number,
3728 (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0),
3729 aoc_e->recorded.unit.item[i].type);
3734 if (passthrough && owner && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3745 #if defined(HAVE_PRI_AOC_EVENTS) 3759 struct pri_subcmd_aoc_s aoc_s = { 0, };
3768 aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(entry->
charged_item);
3772 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
3774 aoc_s.item[idx].rate.duration.amount.multiplier =
3777 aoc_s.item[idx].rate.duration.time.scale =
3780 aoc_s.item[idx].rate.duration.granularity.scale =
3787 sizeof(aoc_s.item[idx].rate.duration.currency));
3791 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
3793 aoc_s.item[idx].rate.flat.amount.multiplier =
3799 sizeof(aoc_s.item[idx].rate.flat.currency));
3803 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
3806 aoc_s.item[idx].rate.volume.amount.multiplier =
3812 sizeof(aoc_s.item[idx].rate.volume.currency));
3816 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
3820 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
3823 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
3827 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
3831 aoc_s.num_items = idx;
3835 if (pvt->aoc_s_request_invoke_id_valid) {
3836 pri_aoc_s_request_response_send(pvt->
pri->
pri, pvt->
call, pvt->aoc_s_request_invoke_id, &aoc_s);
3837 pvt->aoc_s_request_invoke_id_valid = 0;
3839 pri_aoc_s_send(pvt->
pri->
pri, pvt->
call, &aoc_s);
3844 #if defined(HAVE_PRI_AOC_EVENTS) 3858 struct pri_subcmd_aoc_d aoc_d = { 0, };
3864 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL;
3867 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE;
3870 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
3874 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
3880 aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
3885 aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
3889 ast_copy_string(aoc_d.recorded.money.currency, currency_name,
sizeof(aoc_d.recorded.money.currency));
3897 aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
3901 aoc_d.recorded.unit.item[i].number = entry->
amount;
3903 aoc_d.recorded.unit.item[i].number = -1;
3906 aoc_d.recorded.unit.item[i].type = entry->
type;
3908 aoc_d.recorded.unit.item[i].type = -1;
3910 aoc_d.recorded.unit.num_items++;
3919 aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3923 pri_aoc_d_send(pvt->
pri->
pri, pvt->
call, &aoc_d);
3927 #if defined(HAVE_PRI_AOC_EVENTS) 3941 struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
3944 memset(aoc_e, 0,
sizeof(*aoc_e));
3945 pvt->holding_aoce = 1;
3949 aoc_e->associated.charge.number.valid = 1;
3952 sizeof(aoc_e->associated.charge.number.str));
3954 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
3957 aoc_e->associated.charge.id = ca->
charge.
id;
3958 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
3967 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL;
3970 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE;
3973 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
3976 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
3979 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
3982 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
3985 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
3988 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
3992 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
3998 aoc_e->charge = PRI_AOC_DE_CHARGE_FREE;
4003 aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY;
4007 ast_copy_string(aoc_e->recorded.money.currency, currency_name,
sizeof(aoc_e->recorded.money.currency));
4015 aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS;
4019 aoc_e->recorded.unit.item[i].number = entry->
amount;
4021 aoc_e->recorded.unit.item[i].number = -1;
4024 aoc_e->recorded.unit.item[i].type = entry->
type;
4026 aoc_e->recorded.unit.item[i].type = -1;
4028 aoc_e->recorded.unit.num_items++;
4035 aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
4041 #if defined(HAVE_PRI_AOC_EVENTS) 4056 static void sig_pri_send_aoce_termination_request(
struct sig_pri_span *pri,
int chanpos,
unsigned int ms)
4061 size_t encoded_size;
4062 struct timeval whentohangup = { 0, };
4064 sig_pri_lock_owner(pri, chanpos);
4065 pvt = pri->
pvts[chanpos];
4072 goto cleanup_termination_request;
4079 goto cleanup_termination_request;
4083 whentohangup.tv_usec = (ms % 1000) * 1000;
4084 whentohangup.tv_sec = ms / 1000;
4088 goto cleanup_termination_request;
4091 pvt->waiting_for_aoce = 1;
4095 cleanup_termination_request:
4111 static int sig_pri_is_cis_call(
int channel)
4113 return channel != -1 && (channel & PRI_CIS_CALL);
4133 static void sig_pri_handle_cis_subcmds(
struct sig_pri_span *pri,
int event_id,
4134 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4137 #if defined(HAVE_PRI_CCSS) 4139 struct sig_pri_cc_agent_prv *agent_prv;
4140 struct sig_pri_cc_monitor_instance *
monitor;
4146 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4147 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4149 switch (subcmd->cmd) {
4150 #if defined(STATUS_REQUEST_PLACE_HOLDER) 4151 case PRI_SUBCMD_STATUS_REQ:
4152 case PRI_SUBCMD_STATUS_REQ_RSP:
4156 #if defined(HAVE_PRI_CCSS) 4157 case PRI_SUBCMD_CC_REQ:
4158 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id);
4160 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4164 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4166 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4169 sig_pri_cc_type_name);
4174 agent_prv->cc_request_response_pending = 1;
4176 "%s caller accepted CC offer.", sig_pri_cc_type_name)) {
4177 agent_prv->cc_request_response_pending = 0;
4178 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4180 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4183 sig_pri_cc_type_name);
4188 #if defined(HAVE_PRI_CCSS) 4189 case PRI_SUBCMD_CC_REQ_RSP:
4190 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4191 subcmd->u.cc_request_rsp.cc_id);
4193 pri_cc_cancel(pri->
pri, subcmd->u.cc_request_rsp.cc_id);
4196 switch (subcmd->u.cc_request_rsp.status) {
4199 "%s far end accepted CC request", sig_pri_cc_type_name);
4202 ast_verb(2,
"core_id:%d %s CC request timeout\n", monitor->core_id,
4203 sig_pri_cc_type_name);
4205 "%s CC request timeout", sig_pri_cc_type_name);
4208 ast_verb(2,
"core_id:%d %s CC request error: %s\n", monitor->core_id,
4209 sig_pri_cc_type_name,
4210 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
4212 "%s CC request error", sig_pri_cc_type_name);
4215 ast_verb(2,
"core_id:%d %s CC request reject: %s\n", monitor->core_id,
4216 sig_pri_cc_type_name,
4217 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
4219 "%s CC request reject", sig_pri_cc_type_name);
4222 ast_verb(2,
"core_id:%d %s CC request unknown status %d\n",
4223 monitor->core_id, sig_pri_cc_type_name,
4224 subcmd->u.cc_request_rsp.status);
4226 "%s CC request unknown status", sig_pri_cc_type_name);
4232 #if defined(HAVE_PRI_CCSS) 4233 case PRI_SUBCMD_CC_REMOTE_USER_FREE:
4234 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4235 subcmd->u.cc_remote_user_free.cc_id);
4237 pri_cc_cancel(pri->
pri, subcmd->u.cc_remote_user_free.cc_id);
4241 "%s callee has become available", sig_pri_cc_type_name);
4245 #if defined(HAVE_PRI_CCSS) 4246 case PRI_SUBCMD_CC_B_FREE:
4247 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4248 subcmd->u.cc_b_free.cc_id);
4250 pri_cc_cancel(pri->
pri, subcmd->u.cc_b_free.cc_id);
4257 #if defined(HAVE_PRI_CCSS) 4258 case PRI_SUBCMD_CC_STATUS_REQ:
4259 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4260 subcmd->u.cc_status_req.cc_id);
4262 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req.cc_id);
4269 #if defined(HAVE_PRI_CCSS) 4270 case PRI_SUBCMD_CC_STATUS_REQ_RSP:
4271 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
4273 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req_rsp.cc_id);
4282 #if defined(HAVE_PRI_CCSS) 4283 case PRI_SUBCMD_CC_STATUS:
4284 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
4286 pri_cc_cancel(pri->
pri, subcmd->u.cc_status.cc_id);
4289 if (subcmd->u.cc_status.status) {
4291 sig_pri_cc_type_name);
4294 "%s agent caller is available", sig_pri_cc_type_name);
4299 #if defined(HAVE_PRI_CCSS) 4300 case PRI_SUBCMD_CC_CANCEL:
4301 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4302 subcmd->u.cc_cancel.is_agent);
4305 #if defined(HAVE_PRI_CCSS) 4306 case PRI_SUBCMD_CC_STOP_ALERTING:
4307 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4308 subcmd->u.cc_stop_alerting.cc_id);
4310 pri_cc_cancel(pri->
pri, subcmd->u.cc_stop_alerting.cc_id);
4317 #if defined(HAVE_PRI_AOC_EVENTS) 4318 case PRI_SUBCMD_AOC_E:
4320 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e,
NULL, 0);
4324 ast_debug(2,
"Span %d: Unknown CIS subcommand(%d) in %s event.\n", pri->
span,
4325 subcmd->cmd, pri_event2str(event_id));
4350 static void sig_pri_handle_subcmds(
struct sig_pri_span *pri,
int chanpos,
int event_id,
4351 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4356 #if defined(HAVE_PRI_TRANSFER) 4357 struct xfer_rsp_data xfer_rsp;
4363 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4364 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4366 switch (subcmd->cmd) {
4367 case PRI_SUBCMD_CONNECTED_LINE:
4368 sig_pri_lock_owner(pri, chanpos);
4372 int caller_id_update;
4376 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id,
4380 caller_id_update = 0;
4381 if (ast_connected.id.name.str) {
4384 ast_connected.id.name.str,
sizeof(pri->
pvts[chanpos]->
cid_name));
4385 caller_id_update = 1;
4387 if (ast_connected.id.number.str) {
4390 ast_connected.id.number.str,
sizeof(pri->
pvts[chanpos]->
cid_num));
4391 pri->
pvts[chanpos]->
cid_ton = ast_connected.id.number.plan;
4392 caller_id_update = 1;
4397 #if defined(HAVE_PRI_SUBADDR) 4398 if (ast_connected.id.subaddress.str) {
4400 ast_connected.id.subaddress.str,
4402 caller_id_update = 1;
4405 if (caller_id_update) {
4410 sig_pri_set_caller_id(pri->
pvts[chanpos]);
4413 ast_caller.id = ast_connected.id;
4414 ast_caller.ani = ast_connected.id;
4418 if (event_id != PRI_EVENT_RING) {
4429 case PRI_SUBCMD_REDIRECTING:
4430 sig_pri_lock_owner(pri, chanpos);
4433 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
4439 if (event_id != PRI_EVENT_RING) {
4454 #if defined(HAVE_PRI_CALL_REROUTING) 4455 case PRI_SUBCMD_REROUTING:
4456 sig_pri_lock_owner(pri, chanpos);
4459 struct pri_party_redirecting pri_deflection;
4463 "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
4470 "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
4472 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4473 PRI_REROUTING_RSP_INVALID_NUMBER);
4478 ast_verb(3,
"Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
4487 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4488 PRI_REROUTING_RSP_OK_CLEAR);
4490 pri_deflection = subcmd->u.rerouting.deflection;
4493 switch (subcmd->u.rerouting.subscription_option) {
4497 pri_deflection.to.number.presentation =
4498 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
4499 pri_deflection.to.number.plan =
4500 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
4501 pri_deflection.to.number.str[0] =
'\0';
4509 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
4518 ast_channel_call_forward_set(owner, subcmd->u.rerouting.deflection.to.number.str);
4527 #if defined(HAVE_PRI_CCSS) 4528 case PRI_SUBCMD_CC_AVAILABLE:
4529 sig_pri_lock_owner(pri, chanpos);
4535 case PRI_EVENT_RINGING:
4538 case PRI_EVENT_HANGUP_REQ:
4547 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id,
4549 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4554 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4558 #if defined(HAVE_PRI_CCSS) 4559 case PRI_SUBCMD_CC_CALL:
4560 sig_pri_lock_owner(pri, chanpos);
4565 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
4570 "%s caller is attempting recall", sig_pri_cc_type_name);
4578 #if defined(HAVE_PRI_CCSS) 4579 case PRI_SUBCMD_CC_CANCEL:
4580 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4581 subcmd->u.cc_cancel.is_agent);
4584 #if defined(HAVE_PRI_TRANSFER) 4585 case PRI_SUBCMD_TRANSFER_CALL:
4589 "Call transfer subcommand without call to send response!\n");
4593 sig_pri_unlock_private(pri->
pvts[chanpos]);
4595 xfer_rsp.call = call_rsp;
4596 xfer_rsp.invoke_id = subcmd->u.
transfer.invoke_id;
4597 xfer_rsp.responded = 0;
4598 sig_pri_attempt_transfer(pri,
4599 subcmd->u.
transfer.call_1, subcmd->u.transfer.is_call_1_held,
4600 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held,
4602 sig_pri_lock_private(pri->
pvts[chanpos]);
4605 #if defined(HAVE_PRI_AOC_EVENTS) 4606 case PRI_SUBCMD_AOC_S:
4607 sig_pri_lock_owner(pri, chanpos);
4610 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
4616 #if defined(HAVE_PRI_AOC_EVENTS) 4617 case PRI_SUBCMD_AOC_D:
4618 sig_pri_lock_owner(pri, chanpos);
4622 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
4628 #if defined(HAVE_PRI_AOC_EVENTS) 4629 case PRI_SUBCMD_AOC_E:
4630 sig_pri_lock_owner(pri, chanpos);
4633 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
4640 #if defined(HAVE_PRI_AOC_EVENTS) 4641 case PRI_SUBCMD_AOC_CHARGING_REQ:
4642 sig_pri_lock_owner(pri, chanpos);
4645 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->
pvts[chanpos],
4651 #if defined(HAVE_PRI_AOC_EVENTS) 4652 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
4658 if (subcmd->u.aoc_request_response.valid_aoc_s) {
4659 sig_pri_lock_owner(pri, chanpos);
4662 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
4669 #if defined(HAVE_PRI_MCID) 4670 case PRI_SUBCMD_MCID_REQ:
4671 sig_pri_lock_owner(pri, chanpos);
4673 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
4679 #if defined(HAVE_PRI_MCID) 4680 case PRI_SUBCMD_MCID_RSP:
4684 #if defined(HAVE_PRI_DISPLAY_TEXT) 4685 case PRI_SUBCMD_DISPLAY_TEXT:
4686 if (event_id != PRI_EVENT_RING) {
4691 sig_pri_lock_owner(pri, chanpos);
4697 memset(&f, 0,
sizeof(f));
4701 f.
data.
ptr = (
void *)&subcmd->u.display.text;
4702 f.
datalen = subcmd->u.display.length + 1;
4710 ast_debug(2,
"Span %d: Unknown call subcommand(%d) in %s event.\n",
4711 pri->
span, subcmd->cmd, pri_event2str(event_id));
4733 str =
"SIG_PRI_MOH_STATE_IDLE";
4736 str =
"SIG_PRI_MOH_STATE_NOTIFY";
4739 str =
"SIG_PRI_MOH_STATE_MOH";
4741 #if defined(HAVE_PRI_CALL_HOLD) 4742 case SIG_PRI_MOH_STATE_HOLD_REQ:
4743 str =
"SIG_PRI_MOH_STATE_HOLD_REQ";
4745 case SIG_PRI_MOH_STATE_PEND_UNHOLD:
4746 str =
"SIG_PRI_MOH_STATE_PEND_UNHOLD";
4748 case SIG_PRI_MOH_STATE_HOLD:
4749 str =
"SIG_PRI_MOH_STATE_HOLD";
4751 case SIG_PRI_MOH_STATE_RETRIEVE_REQ:
4752 str =
"SIG_PRI_MOH_STATE_RETRIEVE_REQ";
4754 case SIG_PRI_MOH_STATE_PEND_HOLD:
4755 str =
"SIG_PRI_MOH_STATE_PEND_HOLD";
4757 case SIG_PRI_MOH_STATE_RETRIEVE_FAIL:
4758 str =
"SIG_PRI_MOH_STATE_RETRIEVE_FAIL";
4784 str =
"SIG_PRI_MOH_EVENT_RESET";
4787 str =
"SIG_PRI_MOH_EVENT_HOLD";
4790 str =
"SIG_PRI_MOH_EVENT_UNHOLD";
4792 #if defined(HAVE_PRI_CALL_HOLD) 4793 case SIG_PRI_MOH_EVENT_HOLD_ACK:
4794 str =
"SIG_PRI_MOH_EVENT_HOLD_ACK";
4796 case SIG_PRI_MOH_EVENT_HOLD_REJ:
4797 str =
"SIG_PRI_MOH_EVENT_HOLD_REJ";
4799 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
4800 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_ACK";
4802 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
4803 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_REJ";
4805 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
4806 str =
"SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK";
4816 #if defined(HAVE_PRI_CALL_HOLD) 4836 chanpos = pri_find_empty_chan(pvt->
pri, 1);
4839 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
4841 channel = PVT_TO_CHANNEL(pvt->
pri->
pvts[chanpos]);
4852 if (pri_retrieve(pvt->
pri->
pri, pvt->
call, channel)) {
4853 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
4855 return SIG_PRI_MOH_STATE_RETRIEVE_REQ;
4903 #if defined(HAVE_PRI_CALL_HOLD) 4904 case SIG_PRI_MOH_SIGNALING_HOLD:
4910 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
4999 #if defined(HAVE_PRI_CALL_HOLD) 5024 next_state = SIG_PRI_MOH_STATE_PEND_UNHOLD;
5026 case SIG_PRI_MOH_EVENT_HOLD_REJ:
5033 case SIG_PRI_MOH_EVENT_HOLD_ACK:
5034 next_state = SIG_PRI_MOH_STATE_HOLD;
5044 #if defined(HAVE_PRI_CALL_HOLD) 5069 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
5071 case SIG_PRI_MOH_EVENT_HOLD_REJ:
5074 case SIG_PRI_MOH_EVENT_HOLD_ACK:
5075 next_state = sig_pri_moh_retrieve_call(pvt);
5085 #if defined(HAVE_PRI_CALL_HOLD) 5110 next_state = sig_pri_moh_retrieve_call(pvt);
5112 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5127 #if defined(HAVE_PRI_CALL_HOLD) 5152 next_state = SIG_PRI_MOH_STATE_PEND_HOLD;
5154 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
5155 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5158 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
5159 next_state = SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
5169 #if defined(HAVE_PRI_CALL_HOLD) 5194 next_state = SIG_PRI_MOH_STATE_RETRIEVE_REQ;
5196 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
5197 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5219 case SIG_PRI_MOH_SIGNALING_HOLD:
5227 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
5232 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
5237 next_state = SIG_PRI_MOH_STATE_HOLD;
5247 #if defined(HAVE_PRI_CALL_HOLD) 5272 next_state = SIG_PRI_MOH_STATE_HOLD;
5275 next_state = sig_pri_moh_retrieve_call(pvt);
5277 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5310 #if defined(HAVE_PRI_CALL_HOLD) 5311 [SIG_PRI_MOH_STATE_HOLD_REQ] = sig_pri_moh_fsm_hold_req,
5312 [SIG_PRI_MOH_STATE_PEND_UNHOLD] = sig_pri_moh_fsm_pend_unhold,
5313 [SIG_PRI_MOH_STATE_HOLD] = sig_pri_moh_fsm_hold,
5314 [SIG_PRI_MOH_STATE_RETRIEVE_REQ] = sig_pri_moh_fsm_retrieve_req,
5315 [SIG_PRI_MOH_STATE_PEND_HOLD] = sig_pri_moh_fsm_pend_hold,
5316 [SIG_PRI_MOH_STATE_RETRIEVE_FAIL] = sig_pri_moh_fsm_retrieve_fail,
5339 const char *chan_name;
5344 chan_name =
"Unknown";
5347 ast_debug(2,
"Channel '%s' MOH-Event: %s in state %s\n", chan_name,
5348 sig_pri_moh_event_str(event), sig_pri_moh_state_str(orig_state));
5350 || !sig_pri_moh_fsm[orig_state]) {
5353 sig_pri_moh_state_str(orig_state), orig_state);
5357 next_state = sig_pri_moh_fsm[orig_state](chan, pvt, event);
5358 ast_debug(2,
"Channel '%s' MOH-Next-State: %s\n", chan_name,
5359 (orig_state == next_state) ?
"$" : sig_pri_moh_state_str(next_state));
5369 static ast_callid func_pri_dchannel_new_callid(
void)
5399 sig_pri_lock_owner(pri, chanpos);
5413 #if defined(HAVE_PRI_CALL_HOLD) 5427 static int sig_pri_handle_hold(
struct sig_pri_span *pri, pri_event *ev)
5435 chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
5436 if (chanpos_old < 0) {
5447 sig_pri_lock_private(pri->
pvts[chanpos_old]);
5448 sig_pri_lock_owner(pri, chanpos_old);
5451 goto done_with_private;
5465 goto done_with_owner;
5467 chanpos_new = pri_find_empty_nobch(pri);
5468 if (chanpos_new < 0) {
5470 goto done_with_owner;
5472 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.subcmds, ev->hold.call);
5473 sig_pri_queue_hold(pri, chanpos_old);
5474 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
5475 if (chanpos_new < 0) {
5477 sig_pri_queue_unhold(pri, chanpos_old);
5483 sig_pri_unlock_private(pri->
pvts[chanpos_old]);
5485 if (chanpos_new < 0) {
5488 sig_pri_span_devstate_changed(pri);
5500 #if defined(HAVE_PRI_CALL_HOLD) 5513 static void sig_pri_handle_hold_ack(
struct sig_pri_span *pri, pri_event *ev)
5522 chanpos = pri_find_empty_nobch(pri);
5526 "Span %d: No hold channel available for held call that is on %d/%d\n",
5527 pri->
span, PRI_SPAN(ev->hold_ack.channel), PRI_CHANNEL(ev->hold_ack.channel));
5528 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5531 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_ack.call);
5534 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5538 sig_pri_lock_private(pri->
pvts[chanpos]);
5539 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5541 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_ack.subcmds, ev->hold_ack.call);
5542 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5543 SIG_PRI_MOH_EVENT_HOLD_ACK);
5544 sig_pri_unlock_private(pri->
pvts[chanpos]);
5545 sig_pri_span_devstate_changed(pri);
5553 #if defined(HAVE_PRI_CALL_HOLD) 5566 static void sig_pri_handle_hold_rej(
struct sig_pri_span *pri, pri_event *ev)
5571 chanpos = pri_find_principle(pri, ev->hold_rej.channel, ev->hold_rej.call);
5575 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5578 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_rej.call);
5581 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5585 ast_debug(1,
"Span %d: HOLD_REJECT cause: %d(%s)\n", pri->
span,
5586 ev->hold_rej.cause, pri_cause2str(ev->hold_rej.cause));
5588 sig_pri_lock_private(pri->
pvts[chanpos]);
5589 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5591 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_rej.subcmds, ev->hold_rej.call);
5592 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5593 SIG_PRI_MOH_EVENT_HOLD_REJ);
5594 sig_pri_unlock_private(pri->
pvts[chanpos]);
5602 #if defined(HAVE_PRI_CALL_HOLD) 5615 static void sig_pri_handle_retrieve(
struct sig_pri_span *pri, pri_event *ev)
5620 if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
5622 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5623 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5626 if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) {
5628 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5629 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5632 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) {
5633 chanpos = pri_find_empty_chan(pri, 1);
5635 chanpos = pri_find_principle(pri,
5636 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call);
5637 if (ev->retrieve.flexible
5643 chanpos = pri_find_empty_chan(pri, 1);
5647 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5648 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
5649 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5652 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call);
5655 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5656 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5659 sig_pri_lock_private(pri->
pvts[chanpos]);
5660 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5661 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.subcmds, ev->retrieve.call);
5662 sig_pri_queue_unhold(pri, chanpos);
5663 pri_retrieve_ack(pri->
pri, ev->retrieve.call,
5664 PVT_TO_CHANNEL(pri->
pvts[chanpos]));
5665 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5666 SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK);
5667 sig_pri_unlock_private(pri->
pvts[chanpos]);
5668 sig_pri_span_devstate_changed(pri);
5676 #if defined(HAVE_PRI_CALL_HOLD) 5689 static void sig_pri_handle_retrieve_ack(
struct sig_pri_span *pri, pri_event *ev)
5694 chanpos = pri_find_fixup_principle(pri, ev->retrieve_ack.channel,
5695 ev->retrieve_ack.call);
5700 sig_pri_lock_private(pri->
pvts[chanpos]);
5701 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5703 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_ack.subcmds,
5704 ev->retrieve_ack.call);
5705 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5706 SIG_PRI_MOH_EVENT_RETRIEVE_ACK);
5707 sig_pri_unlock_private(pri->
pvts[chanpos]);
5708 sig_pri_span_devstate_changed(pri);
5716 #if defined(HAVE_PRI_CALL_HOLD) 5729 static void sig_pri_handle_retrieve_rej(
struct sig_pri_span *pri, pri_event *ev)
5734 chanpos = pri_find_principle(pri, ev->retrieve_rej.channel, ev->retrieve_rej.call);
5738 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5741 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve_rej.call);
5744 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5748 ast_debug(1,
"Span %d: RETRIEVE_REJECT cause: %d(%s)\n", pri->
span,
5749 ev->retrieve_rej.cause, pri_cause2str(ev->retrieve_rej.cause));
5751 sig_pri_lock_private(pri->
pvts[chanpos]);
5752 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5754 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_rej.subcmds,
5755 ev->retrieve_rej.call);
5756 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5757 SIG_PRI_MOH_EVENT_RETRIEVE_REJ);
5758 sig_pri_unlock_private(pri->
pvts[chanpos]);
5779 static void setup_incoming_channel(
struct sig_pri_span *pri,
int chanpos, pri_event *ev)
5783 char calledtonstr[10];
5785 sig_pri_lock_owner(pri, chanpos);
5793 #if defined(HAVE_PRI_SUBADDR) 5794 if (ev->ring.calling.subaddress.valid) {
5797 &ev->ring.calling.subaddress);
5798 if (!ev->ring.calling.subaddress.type
5802 (
char *) ev->ring.calling.subaddress.
data);
5805 if (ev->ring.called_subaddress.valid) {
5808 &ev->ring.called_subaddress);
5809 if (!ev->ring.called_subaddress.type
5813 (
char *) ev->ring.called_subaddress.
data);
5821 if (ev->ring.ani2 >= 0) {
5823 snprintf(ani2str,
sizeof(ani2str),
"%d", ev->ring.ani2);
5827 #ifdef SUPPORT_USERUSER 5833 snprintf(calledtonstr,
sizeof(calledtonstr),
"%d", ev->ring.calledplan);
5837 if (ev->ring.redirectingreason >= 0) {
5840 redirectingreason2str(ev->ring.redirectingreason));
5842 #if defined(HAVE_PRI_REVERSE_CHARGE) 5843 pri->
pvts[chanpos]->reverse_charging_indication = ev->ring.reversecharge;
5845 #if defined(HAVE_PRI_SETUP_KEYPAD) 5847 ev->ring.keypad_digits,
sizeof(pri->
pvts[chanpos]->keypad_digits));
5855 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->ring.subcmds,
5873 static void sig_pri_handle_setup(
struct sig_pri_span *pri, pri_event *e)
5875 int exten_exists_or_can_exist;
5876 int could_match_more;
5887 && !sig_pri_msn_match(pri->
msn_list, e->ring.callednum)) {
5890 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n",
5892 pri_destroycall(pri->
pri, e->ring.call);
5895 if (sig_pri_is_cis_call(e->ring.channel)) {
5896 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, e->ring.call);
5899 chanpos = pri_find_principle_by_call(pri, e->ring.call);
5903 "Span %d: Got SETUP with duplicate call ptr (%p). Dropping call.\n",
5904 pri->
span, e->ring.call);
5905 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5908 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
5910 chanpos = pri_find_empty_chan(pri, 1);
5912 callid = func_pri_dchannel_new_callid();
5914 }
else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
5916 #if defined(HAVE_PRI_CALL_WAITING) 5917 if (!pri->allow_call_waiting_calls)
5921 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5924 #if defined(HAVE_PRI_CALL_WAITING) 5925 chanpos = pri_find_empty_nobch(pri);
5928 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5932 callid = func_pri_dchannel_new_callid();
5935 sig_pri_init_config(pri->
pvts[chanpos], pri);
5939 callid = func_pri_dchannel_new_callid();
5940 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
5943 "Span %d: SETUP on unconfigured channel %d/%d\n",
5944 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5959 "Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n",
5960 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5966 pri_check_restart(pri);
5973 "Span %d: SETUP requested unavailable channel %d/%d. Attempting to renegotiate.\n",
5974 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5978 #if defined(ALWAYS_PICK_CHANNEL) 5979 if (e->ring.flexible) {
5983 if (chanpos < 0 && e->ring.flexible) {
5985 chanpos = pri_find_empty_chan(pri, 1);
5989 if (e->ring.flexible) {
5990 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5992 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5997 sig_pri_lock_private(pri->
pvts[chanpos]);
6000 pri->
pvts[chanpos]->
call = e->ring.call;
6003 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
6004 e->ring.redirectingnum, e->ring.callingplanrdnis);
6005 sig_pri_set_rdnis(pri->
pvts[chanpos], plancallingnum);
6008 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
6009 e->ring.callingnum, e->ring.callingplan);
6016 apply_plan_to_existing_number(plancallingani,
sizeof(plancallingani),
6017 pri, e->ring.callingani, e->ring.callingplanani);
6023 #if defined(HAVE_PRI_SUBADDR) 6024 if (e->ring.calling.subaddress.valid) {
6028 sig_pri_set_subaddress(&calling_subaddress,
6029 &e->ring.calling.subaddress);
6030 if (calling_subaddress.str) {
6032 calling_subaddress.str,
6041 pri->
pvts[chanpos]->
cid_ton = e->ring.callingplan;
6043 if (e->ring.ani2 >= 0) {
6061 ? plancallingnum : e->ring.callednum);
6070 sig_pri_set_caller_id(pri->
pvts[chanpos]);
6073 sig_pri_set_dnid(pri->
pvts[chanpos], e->ring.callednum);
6077 ast_verb(3,
"Going to extension s|1 because of immediate=yes\n");
6093 ast_verb(3,
"Going to extension s|1 because of Complete received\n");
6104 if (!exten_exists_or_can_exist) {
6106 "Span %d: Extension %s@%s does not exist. Rejecting call from '%s'.\n",
6109 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
6112 sig_pri_unlock_private(pri->
pvts[chanpos]);
6113 sig_pri_span_devstate_changed(pri);
6118 switch (e->ring.layer1) {
6119 case PRI_LAYER_1_ALAW:
6122 case PRI_LAYER_1_ULAW:
6131 could_match_more = !e->ring.complete
6136 need_dialtone = could_match_more
6151 pri_proceeding(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 0);
6152 }
else if (pri->
switchtype == PRI_SWITCH_GR303_TMC) {
6154 pri_answer(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6157 #if defined(HAVE_PRI_SETUP_ACK_INBAND) 6158 pri_setup_ack(pri->
pri, e->ring.call,
6159 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, need_dialtone);
6161 pri_need_more_info(pri->
pri, e->ring.call,
6162 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6172 sig_pri_unlock_private(pri->
pvts[chanpos]);
6174 c = sig_pri_new_ast_channel(pri->
pvts[chanpos],
6178 sig_pri_lock_private(pri->
pvts[chanpos]);
6181 setup_incoming_channel(pri, chanpos, e);
6184 if (could_match_more) {
6185 #if !defined(HAVE_PRI_SETUP_ACK_INBAND) 6186 if (need_dialtone) {
6189 #ifdef HAVE_PRI_PROG_W_CAUSE 6190 pri_progress_with_cause(pri->
pri, e->ring.call,
6191 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, -1);
6193 pri_progress(pri->
pri, e->ring.call,
6194 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6200 pri->
pvts[chanpos])) {
6201 ast_verb(3,
"Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
6202 plancallingnum,
S_OR(pri->
pvts[chanpos]->
exten,
"<unspecified>"),
6205 sig_pri_unlock_private(pri->
pvts[chanpos]);
6210 ast_verb(3,
"Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
6211 plancallingnum, pri->
pvts[chanpos]->
exten,
6214 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6215 sig_pri_unlock_private(pri->
pvts[chanpos]);
6224 sig_pri_unlock_private(pri->
pvts[chanpos]);
6229 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
6231 sig_pri_unlock_private(pri->
pvts[chanpos]);
6232 sig_pri_span_devstate_changed(pri);
6241 static void *pri_dchannel(
void *vpri)
6245 struct pollfd fds[SIG_PRI_NUM_DCHANS];
6248 struct timeval tv, lowest, *next;
6254 struct timeval lastidle = { 0, 0 };
6263 gettimeofday(&lastidle,
NULL);
6264 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
6268 cc = strchr(pri->
idleext,
'@');
6289 fds[i].fd = pri->
fds[i];
6290 fds[i].events = POLLIN | POLLPRI;
6299 pri_check_restart(pri);
6301 sig_pri_span_devstate_changed(pri);
6316 for (x = pri->
numchans; x >= 0; x--) {
6319 if (haveidles < pri->minunused) {
6330 if (nextidle > -1) {
6345 sig_pri_lock_private(pri->
pvts[nextidle]);
6346 sig_pri_unlock_private(pri->
pvts[nextidle]);
6361 gettimeofday(&lastidle,
NULL);
6363 }
else if ((haveidles < pri->minunused) &&
6364 (activeidles > pri->
minidle)) {
6367 for (x = pri->
numchans; x >= 0; x--) {
6375 (activeidles <= pri->minidle))
6397 next = pri_schedule_next(pri->
dchans[i]);
6401 if (tv.tv_sec < 0) {
6416 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
6417 pthread_testcancel();
6419 res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
6420 pthread_testcancel();
6421 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
6429 e = pri_schedule_run(pri->
dchans[which]);
6433 }
else if (res > -1) {
6437 if (fds[which].revents & POLLPRI) {
6438 sig_pri_handle_dchan_exception(pri, which);
6439 }
else if (fds[which].revents & POLLIN) {
6440 e = pri_check_event(pri->
dchans[which]);
6449 if (
errno == ENODEV) {
6450 pri_destroy_later(pri);
6453 }
else if (
errno != EINTR)
6462 pri->
span, pri_event2str(e->e), e->e);
6465 if (e->e != PRI_EVENT_DCHAN_DOWN) {
6467 ast_verb(2,
"%s D-Channel on span %d up\n", pri_order(which), pri->
span);
6472 ast_verb(2,
"%s D-Channel on span %d down\n", pri_order(which), pri->
span);
6477 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->
pri != pri->
dchans[which]))
6482 case PRI_EVENT_DCHAN_UP:
6485 pri_find_dchan(pri);
6498 for (i = 0; i < pri->
numchans; i++) {
6503 sig_pri_span_devstate_changed(pri);
6505 case PRI_EVENT_DCHAN_DOWN:
6506 pri_find_dchan(pri);
6517 for (i = 0; i < pri->
numchans; i++) {
6521 if (pri_get_timer(p->
pri->
pri, PRI_TIMER_T309) < 0) {
6533 sig_pri_span_devstate_changed(pri);
6536 case PRI_EVENT_RESTART:
6537 if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) {
6538 chanpos = pri_find_principle(pri, e->restart.channel,
NULL);
6541 "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
6542 pri->
span, PRI_SPAN(e->restart.channel),
6543 PRI_CHANNEL(e->restart.channel));
6546 #if defined(HAVE_PRI_SERVICE_MESSAGES) 6549 why = pri->
pvts[chanpos]->service_status;
6552 "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n",
6553 pri->
span, PRI_SPAN(e->restart.channel),
6554 PRI_CHANNEL(e->restart.channel),
6555 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ?
"both ends" :
"far end" :
"near end");
6559 sig_pri_lock_private(pri->
pvts[chanpos]);
6561 ast_verb(3,
"Span %d: Channel %d/%d restarted\n", pri->
span,
6562 PRI_SPAN(e->restart.channel),
6563 PRI_CHANNEL(e->restart.channel));
6565 pri_destroycall(pri->
pri, pri->
pvts[chanpos]->
call);
6570 sig_pri_queue_hangup(pri, chanpos);
6571 sig_pri_unlock_private(pri->
pvts[chanpos]);
6574 ast_verb(3,
"Restart requested on entire span %d\n", pri->
span);
6575 for (x = 0; x < pri->
numchans; x++)
6577 sig_pri_lock_private(pri->
pvts[x]);
6583 sig_pri_queue_hangup(pri, x);
6584 sig_pri_unlock_private(pri->
pvts[x]);
6587 sig_pri_span_devstate_changed(pri);
6589 case PRI_EVENT_KEYPAD_DIGIT:
6590 if (sig_pri_is_cis_call(e->digit.channel)) {
6591 sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds,
6595 chanpos = pri_find_principle_by_call(pri, e->digit.call);
6598 "Span %d: Received keypad digits for unknown call.\n", pri->
span);
6601 sig_pri_lock_private(pri->
pvts[chanpos]);
6603 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6605 sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.subcmds,
6611 int digitlen = strlen(e->digit.digits);
6614 for (i = 0; i < digitlen; i++) {
6617 pri_queue_frame(pri, chanpos, &f);
6620 sig_pri_unlock_private(pri->
pvts[chanpos]);
6623 case PRI_EVENT_INFO_RECEIVED:
6624 if (sig_pri_is_cis_call(e->ring.channel)) {
6625 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
6629 chanpos = pri_find_principle_by_call(pri, e->ring.call);
6632 "Span %d: Received INFORMATION for unknown call.\n", pri->
span);
6635 sig_pri_lock_private(pri->
pvts[chanpos]);
6637 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6639 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, e->ring.call);
6644 int digitlen = strlen(e->ring.callednum);
6647 for (i = 0; i < digitlen; i++) {
6650 pri_queue_frame(pri, chanpos, &f);
6653 sig_pri_unlock_private(pri->
pvts[chanpos]);
6655 #if defined(HAVE_PRI_SERVICE_MESSAGES) 6656 case PRI_EVENT_SERVICE:
6657 chanpos = pri_find_principle(pri, e->service.channel,
NULL);
6659 ast_log(
LOG_WARNING,
"Received service change status %d on unconfigured channel %d/%d span %d\n",
6660 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6662 char db_chan_name[20];
6668 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, pri->
span, ch);
6669 why = &pri->
pvts[chanpos]->service_status;
6670 switch (e->service.changestatus) {
6674 *why &= ~SRVST_FAREND;
6676 snprintf(db_answer,
sizeof(db_answer),
"%s:%u",
6677 SRVST_TYPE_OOS, *why);
6678 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
6680 sig_pri_span_devstate_changed(pri);
6686 *why |= SRVST_FAREND;
6687 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS,
6689 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
6690 sig_pri_span_devstate_changed(pri);
6696 ast_log(
LOG_NOTICE,
"Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n",
6697 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->
span, ch, e->service.changestatus);
6700 case PRI_EVENT_SERVICE_ACK:
6701 chanpos = pri_find_principle(pri, e->service_ack.channel,
NULL);
6703 ast_log(
LOG_WARNING,
"Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
6704 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6706 ast_debug(2,
"Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n",
6707 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span, e->service_ack.changestatus);
6711 case PRI_EVENT_RING:
6712 sig_pri_handle_setup(pri, e);
6714 case PRI_EVENT_RINGING:
6715 if (sig_pri_is_cis_call(e->ringing.channel)) {
6716 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds,
6720 chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
6725 sig_pri_lock_private(pri->
pvts[chanpos]);
6727 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6729 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.subcmds,
6731 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCNR);
6732 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6733 sig_pri_lock_owner(pri, chanpos);
6745 #ifdef PRI_PROGRESS_MASK
6746 && (e->ringing.progressmask
6747 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6749 && e->ringing.progress == 8
6755 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6756 sig_pri_open_media(pri->
pvts[chanpos]);
6759 #ifdef SUPPORT_USERUSER 6763 sig_pri_lock_owner(pri, chanpos);
6767 e->ringing.useruserinfo);
6773 sig_pri_unlock_private(pri->
pvts[chanpos]);
6775 case PRI_EVENT_PROGRESS:
6776 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6777 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6778 e->proceeding.call);
6781 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6782 e->proceeding.call);
6786 sig_pri_lock_private(pri->
pvts[chanpos]);
6788 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6790 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6791 e->proceeding.call);
6793 if (e->proceeding.cause > -1) {
6795 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_PROGRESS (%d)", e->proceeding.cause);
6796 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->proceeding.cause);
6799 ast_verb(3,
"PROGRESS with cause code %d received\n", e->proceeding.cause);
6804 ast_verb(3,
"PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
6814 #ifdef PRI_PROGRESS_MASK
6815 && (e->proceeding.progressmask
6816 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6818 && e->proceeding.progress == 8
6823 "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
6828 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6829 sig_pri_open_media(pri->
pvts[chanpos]);
6831 sig_pri_unlock_private(pri->
pvts[chanpos]);
6833 case PRI_EVENT_PROCEEDING:
6834 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6835 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6836 e->proceeding.call);
6839 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6840 e->proceeding.call);
6844 sig_pri_lock_private(pri->
pvts[chanpos]);
6846 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6848 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6849 e->proceeding.call);
6853 "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
6860 #ifdef PRI_PROGRESS_MASK
6869 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
6871 && e->proceeding.progress == 8
6877 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6878 sig_pri_open_media(pri->
pvts[chanpos]);
6886 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6888 sig_pri_unlock_private(pri->
pvts[chanpos]);
6890 case PRI_EVENT_FACILITY:
6891 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) {
6893 #if defined(HAVE_PRI_CALL_REROUTING) 6894 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6895 e->facility.subcall);
6897 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6902 chanpos = pri_find_principle_by_call(pri, e->facility.call);
6908 sig_pri_lock_private(pri->
pvts[chanpos]);
6910 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6912 #if defined(HAVE_PRI_CALL_REROUTING) 6913 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6914 e->facility.subcall);
6916 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6919 sig_pri_unlock_private(pri->
pvts[chanpos]);
6921 case PRI_EVENT_ANSWER:
6922 if (sig_pri_is_cis_call(e->answer.channel)) {
6923 #if defined(HAVE_PRI_CALL_WAITING) 6925 pri_connect_ack(pri->
pri, e->answer.call, 0);
6927 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds,
6931 chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
6935 #if defined(HAVE_PRI_CALL_WAITING) 6936 if (pri->
pvts[chanpos]->is_call_waiting) {
6944 new_chanpos = pri_find_empty_chan(pri, 1);
6945 if (0 <= new_chanpos) {
6946 new_chanpos = pri_fixup_principle(pri, new_chanpos,
6949 if (new_chanpos < 0) {
6955 "Span %d: Channel not available for call waiting call.\n",
6957 sig_pri_lock_private(pri->
pvts[chanpos]);
6958 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
6960 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
6961 sig_pri_lock_owner(pri, chanpos);
6975 pri->
pvts[chanpos]->is_call_waiting = 0;
6977 pri_hangup(pri->
pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
6980 sig_pri_unlock_private(pri->
pvts[chanpos]);
6981 sig_pri_span_devstate_changed(pri);
6984 chanpos = new_chanpos;
6986 pri_connect_ack(pri->
pri, e->answer.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
6987 sig_pri_span_devstate_changed(pri);
6990 pri_connect_ack(pri->
pri, e->answer.call, 0);
6993 sig_pri_lock_private(pri->
pvts[chanpos]);
6995 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6997 #if defined(HAVE_PRI_CALL_WAITING) 6998 if (pri->
pvts[chanpos]->is_call_waiting) {
6999 pri->
pvts[chanpos]->is_call_waiting = 0;
7003 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
7008 "Span %d: Channel %d/%d dialing deferred digit string: %s\n",
7015 sig_pri_dial_digits(pri->
pvts[chanpos],
7021 sig_pri_open_media(pri->
pvts[chanpos]);
7023 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
7025 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
7028 #ifdef SUPPORT_USERUSER 7032 sig_pri_lock_owner(pri, chanpos);
7036 e->answer.useruserinfo);
7042 sig_pri_unlock_private(pri->
pvts[chanpos]);
7044 #if defined(HAVE_PRI_CALL_WAITING) 7045 case PRI_EVENT_CONNECT_ACK:
7046 if (sig_pri_is_cis_call(e->connect_ack.channel)) {
7047 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds,
7048 e->connect_ack.call);
7051 chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel,
7052 e->connect_ack.call);
7057 sig_pri_lock_private(pri->
pvts[chanpos]);
7059 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7061 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.subcmds,
7062 e->connect_ack.call);
7063 sig_pri_open_media(pri->
pvts[chanpos]);
7064 sig_pri_unlock_private(pri->
pvts[chanpos]);
7065 sig_pri_span_devstate_changed(pri);
7068 case PRI_EVENT_HANGUP:
7069 if (sig_pri_is_cis_call(e->hangup.channel)) {
7070 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7072 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7075 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7081 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7084 sig_pri_lock_private(pri->
pvts[chanpos]);
7086 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7088 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
7090 switch (e->hangup.cause) {
7091 case PRI_CAUSE_INVALID_CALL_REFERENCE:
7096 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7105 switch (e->hangup.cause) {
7106 case PRI_CAUSE_USER_BUSY:
7107 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7108 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
7114 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP (%d)", e->hangup.cause);
7115 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7136 switch (e->hangup.cause) {
7137 case PRI_CAUSE_USER_BUSY:
7140 case PRI_CAUSE_CALL_REJECTED:
7141 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7142 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7143 case PRI_CAUSE_SWITCH_CONGESTION:
7144 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7145 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7156 sig_pri_queue_hangup(pri, chanpos);
7163 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7166 ast_verb(3,
"Span %d: Channel %d/%d got hangup, cause %d\n",
7171 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7174 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7179 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7183 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7185 if (e->hangup.aoc_units > -1)
7186 ast_verb(3,
"Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
7189 #ifdef SUPPORT_USERUSER 7193 sig_pri_lock_owner(pri, chanpos);
7197 e->hangup.useruserinfo);
7203 sig_pri_unlock_private(pri->
pvts[chanpos]);
7204 sig_pri_span_devstate_changed(pri);
7206 case PRI_EVENT_HANGUP_REQ:
7207 if (sig_pri_is_cis_call(e->hangup.channel)) {
7208 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7210 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7213 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7219 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7222 sig_pri_lock_private(pri->
pvts[chanpos]);
7224 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7226 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
7228 #if defined(HAVE_PRI_CALL_HOLD) 7229 if (e->hangup.call_active && e->hangup.call_held
7230 && pri->hold_disconnect_transfer) {
7232 sig_pri_unlock_private(pri->
pvts[chanpos]);
7233 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1,
7234 e->hangup.call_active, 0,
NULL)) {
7237 sig_pri_lock_private(pri->
pvts[chanpos]);
7240 switch (e->hangup.cause) {
7241 case PRI_CAUSE_USER_BUSY:
7242 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7243 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
7245 case PRI_CAUSE_INVALID_CALL_REFERENCE:
7252 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7259 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP_REQ (%d)", e->hangup.cause);
7260 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7280 switch (e->hangup.cause) {
7281 case PRI_CAUSE_USER_BUSY:
7284 case PRI_CAUSE_CALL_REJECTED:
7285 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7286 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7287 case PRI_CAUSE_SWITCH_CONGESTION:
7288 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7289 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7300 #if defined(HAVE_PRI_AOC_EVENTS) 7301 if (!pri->
pvts[chanpos]->holding_aoce
7302 && pri->aoce_delayhangup
7304 sig_pri_send_aoce_termination_request(pri, chanpos,
7305 pri_get_timer(pri->
pri, PRI_TIMER_T305) / 2);
7309 sig_pri_queue_hangup(pri, chanpos);
7312 ast_verb(3,
"Span %d: Channel %d/%d got hangup request, cause %d\n",
7320 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7323 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7328 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7332 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7335 #ifdef SUPPORT_USERUSER 7339 sig_pri_lock_owner(pri, chanpos);
7343 e->hangup.useruserinfo);
7349 sig_pri_unlock_private(pri->
pvts[chanpos]);
7350 sig_pri_span_devstate_changed(pri);
7352 case PRI_EVENT_HANGUP_ACK:
7353 if (sig_pri_is_cis_call(e->hangup.channel)) {
7354 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7358 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7362 sig_pri_lock_private(pri->
pvts[chanpos]);
7364 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7368 ast_verb(3,
"Span %d: Channel %d/%d got hangup ACK\n", pri->
span,
7371 #ifdef SUPPORT_USERUSER 7375 sig_pri_lock_owner(pri, chanpos);
7379 e->hangup.useruserinfo);
7384 sig_pri_unlock_private(pri->
pvts[chanpos]);
7385 sig_pri_span_devstate_changed(pri);
7387 case PRI_EVENT_CONFIG_ERR:
7390 case PRI_EVENT_RESTART_ACK:
7391 chanpos = pri_find_principle(pri, e->restartack.channel,
NULL);
7396 for (x = 0; x < pri->
numchans; x++) {
7400 sig_pri_lock_private(pri->
pvts[chanpos]);
7402 "Span %d: Assuming restart ack is for channel %d/%d\n",
7407 "Span %d: Got restart ack on channel %d/%d with owner\n",
7414 "Span %d: Channel %d/%d successfully restarted\n",
7417 sig_pri_unlock_private(pri->
pvts[chanpos]);
7419 pri_check_restart(pri);
7425 "Span %d: Restart ACK on strange channel %d/%d\n",
7426 pri->
span, PRI_SPAN(e->restartack.channel),
7427 PRI_CHANNEL(e->restartack.channel));
7430 sig_pri_lock_private(pri->
pvts[chanpos]);
7434 "Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n",
7437 sig_pri_unlock_private(pri->
pvts[chanpos]);
7442 "Span %d: Got restart ack on channel %d/%d with owner\n",
7449 "Span %d: Channel %d/%d successfully restarted\n",
7452 sig_pri_unlock_private(pri->
pvts[chanpos]);
7454 pri_check_restart(pri);
7457 case PRI_EVENT_SETUP_ACK:
7458 if (sig_pri_is_cis_call(e->setup_ack.channel)) {
7459 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds,
7463 chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
7468 sig_pri_lock_private(pri->
pvts[chanpos]);
7470 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7472 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.subcmds,
7480 for (x = 0; x <
len; ++
x) {
7482 pri_information(pri->
pri, pri->
pvts[chanpos]->
call,
7490 #
if defined(HAVE_PRI_SETUP_ACK_INBAND)
7508 && ((e->setup_ack.progressmask & PRI_PROG_INBAND_AVAILABLE)
7510 || pri->
pvts[chanpos]->no_dialed_digits)
7519 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
7520 sig_pri_open_media(pri->
pvts[chanpos]);
7522 sig_pri_unlock_private(pri->
pvts[chanpos]);
7524 case PRI_EVENT_NOTIFY:
7525 if (sig_pri_is_cis_call(e->notify.channel)) {
7526 #if defined(HAVE_PRI_CALL_HOLD) 7527 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
7530 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
NULL);
7534 #if defined(HAVE_PRI_CALL_HOLD) 7535 chanpos = pri_find_principle_by_call(pri, e->notify.call);
7547 chanpos = pri_find_principle(pri, e->notify.channel,
NULL);
7550 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->
span);
7554 sig_pri_lock_private(pri->
pvts[chanpos]);
7556 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7558 #if defined(HAVE_PRI_CALL_HOLD) 7559 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
7562 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
NULL);
7564 switch (e->notify.info) {
7565 case PRI_NOTIFY_REMOTE_HOLD:
7567 sig_pri_queue_hold(pri, chanpos);
7570 case PRI_NOTIFY_REMOTE_RETRIEVAL:
7572 sig_pri_queue_unhold(pri, chanpos);
7576 sig_pri_unlock_private(pri->
pvts[chanpos]);
7578 #if defined(HAVE_PRI_CALL_HOLD) 7579 case PRI_EVENT_HOLD:
7581 if (sig_pri_handle_hold(pri, e)) {
7582 pri_hold_rej(pri->
pri, e->hold.call,
7583 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
7585 pri_hold_ack(pri->
pri, e->hold.call);
7589 #if defined(HAVE_PRI_CALL_HOLD) 7590 case PRI_EVENT_HOLD_ACK:
7592 sig_pri_handle_hold_ack(pri, e);
7595 #if defined(HAVE_PRI_CALL_HOLD) 7596 case PRI_EVENT_HOLD_REJ:
7598 sig_pri_handle_hold_rej(pri, e);
7601 #if defined(HAVE_PRI_CALL_HOLD) 7602 case PRI_EVENT_RETRIEVE:
7604 sig_pri_handle_retrieve(pri, e);
7607 #if defined(HAVE_PRI_CALL_HOLD) 7608 case PRI_EVENT_RETRIEVE_ACK:
7610 sig_pri_handle_retrieve_ack(pri, e);
7613 #if defined(HAVE_PRI_CALL_HOLD) 7614 case PRI_EVENT_RETRIEVE_REJ:
7616 sig_pri_handle_retrieve_rej(pri, e);
7620 ast_debug(1,
"Span: %d Unhandled event: %s(%d)\n",
7621 pri->
span, pri_event2str(e->e), e->e);
7672 (pri->
dchans[x] == pri->
pri) ?
"Yes" :
"No",
7673 (pri->
dchanavail[x] & DCHAN_NOTINALARM) ?
"No" :
"Yes",
7674 (pri->
dchanavail[x] & DCHAN_UP) ?
"Yes" :
"No",
7686 memset(pri, 0,
sizeof(*pri));
7703 sig_pri_set_outgoing(p, 0);
7704 sig_pri_set_digital(p, 0);
7705 #if defined(HAVE_PRI_CALL_WAITING) 7706 if (p->is_call_waiting) {
7707 p->is_call_waiting = 0;
7718 sig_pri_set_dialing(p, 0);
7721 pri_grab(p, p->
pri);
7724 #if defined(SUPPORT_USERUSER) 7728 pri_call_set_useruser(p->
call, useruser);
7732 #if defined(HAVE_PRI_TRANSFER) 7742 sig_pri_transfer_rsp(p->xfer_data, 1);
7746 #if defined(HAVE_PRI_AOC_EVENTS) 7747 if (p->holding_aoce) {
7748 pri_aoc_e_send(p->
pri->
pri, p->
call, &p->aoc_e);
7753 ast_debug(1,
"Already hungup... Calling hangup once, and clearing call\n");
7764 icause = atoi(cause);
7768 "Not yet hungup... Calling hangup with cause %d, and clearing call\n",
7774 #if defined(HAVE_PRI_TRANSFER) 7775 p->xfer_data =
NULL;
7777 #if defined(HAVE_PRI_AOC_EVENTS) 7778 p->aoc_s_request_invoke_id_valid = 0;
7779 p->holding_aoce = 0;
7780 p->waiting_for_aoce = 0;
7786 sig_pri_span_devstate_changed(p->
pri);
7826 subaddr = strchr(number,
':');
7844 if (strlen(number) < p->
stripmsd) {
7850 deferred = strchr(number,
'w');
7855 while (isalpha(*number)) {
7863 snprintf(called, called_buff_size,
"%s", number);
7866 snprintf(called, called_buff_size,
"%s:%s", number, subaddr);
7870 enum SIG_PRI_CALL_OPT_FLAGS {
7871 OPT_KEYPAD = (1 << 0),
7872 OPT_REVERSE_CHARGE = (1 << 1),
7873 OPT_AOC_REQUEST = (1 << 2),
7875 enum SIG_PRI_CALL_OPT_ARGS {
7877 OPT_ARG_AOC_REQUEST,
7895 char *
c, *l, *n, *s;
7896 #ifdef SUPPORT_USERUSER 7897 const char *useruser;
7902 int prilocaldialplan;
7905 #if defined(HAVE_PRI_SETUP_KEYPAD) 7918 ast_debug(1,
"CALLER NAME: %s NUM: %s\n",
7933 sig_pri_set_outgoing(p, 1);
7961 dialed_subaddress.type = 2;
7969 dialed_subaddress.str = s;
7970 dialed_subaddress.valid = 1;
7981 for (l = connected_id.
number.
str; l && *l; l++) {
7982 if (strchr(
"0123456789", *l)) {
8014 pri_grab(p, p->
pri);
8015 if (!(p->
call = pri_new_call(p->
pri->
pri))) {
8020 if (!(sr = pri_sr_new())) {
8031 #if defined(HAVE_PRI_CALL_WAITING) 8032 if (p->is_call_waiting) {
8037 pri_sr_set_channel(sr, 0, 0, 1);
8047 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
8054 pri_facility_enable(p->
pri->
pri);
8059 if (pridialplan == -2 || pridialplan == -3) {
8061 if (pridialplan == -2) {
8064 pridialplan = PRI_INTERNATIONAL_ISDN;
8066 if (pridialplan == -2) {
8069 pridialplan = PRI_NATIONAL_ISDN;
8071 pridialplan = PRI_LOCAL_ISDN;
8077 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
8080 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
8083 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
8086 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
8089 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
8092 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
8095 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
8098 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
8101 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
8104 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
8107 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
8110 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
8113 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
8116 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
8127 #if defined(HAVE_PRI_SETUP_KEYPAD) 8131 keypad = opt_args[OPT_ARG_KEYPAD];
8132 pri_sr_set_keypad_digits(sr, keypad);
8139 char *called = c + p->
stripmsd + dp_strip;
8141 pri_sr_set_called(sr, called, pridialplan, s ? 1 : 0);
8142 #if defined(HAVE_PRI_SETUP_ACK_INBAND) 8143 p->no_dialed_digits = !called[0];
8147 #if defined(HAVE_PRI_SUBADDR) 8148 if (dialed_subaddress.valid) {
8149 struct pri_party_subaddress subaddress;
8151 memset(&subaddress, 0,
sizeof(subaddress));
8152 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
8153 pri_sr_set_called_subaddress(sr, &subaddress);
8156 #if defined(HAVE_PRI_REVERSE_CHARGE) 8158 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
8161 #if defined(HAVE_PRI_AOC_EVENTS) 8164 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
's')) {
8165 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
8167 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'd')) {
8168 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
8170 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'e')) {
8171 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
8196 if ((l !=
NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) {
8198 if (prilocaldialplan == -2) {
8201 prilocaldialplan = PRI_INTERNATIONAL_ISDN;
8203 if (prilocaldialplan == -2) {
8206 prilocaldialplan = PRI_NATIONAL_ISDN;
8208 prilocaldialplan = PRI_LOCAL_ISDN;
8210 }
else if (prilocaldialplan == -1) {
8215 while (*l >
'9' && *l !=
'*' && *l !=
'#') {
8218 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
8221 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
8224 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
8227 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
8230 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
8233 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
8236 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
8239 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
8242 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
8245 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
8248 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
8251 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
8254 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
8257 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
8262 "Unrecognized prilocaldialplan %s modifier: %c\n",
8263 *l >
'Z' ?
"NPI" :
"TON", *l);
8270 pri_sr_set_caller(sr, l ? (l + ldp_strip) :
NULL, n, prilocaldialplan,
8273 #if defined(HAVE_PRI_SUBADDR) 8275 struct pri_party_subaddress subaddress;
8277 memset(&subaddress, 0,
sizeof(subaddress));
8278 sig_pri_party_subaddress_from_ast(&subaddress, &connected_id.
subaddress);
8279 pri_sr_set_caller_subaddress(sr, &subaddress);
8283 sig_pri_redirecting_update(p, ast);
8285 #ifdef SUPPORT_USERUSER 8289 pri_sr_set_useruser(sr, useruser);
8292 #if defined(HAVE_PRI_CCSS) 8301 struct sig_pri_cc_monitor_instance *instance;
8308 if (pri_cc_call(p->
pri->
pri, instance->cc_id, p->
call, sr)) {
8328 if (core_id == -1 && pri_setup(p->
pri->
pri, p->
call, sr)) {
8340 sig_pri_set_dialing(p, 1);
8349 switch (condition) {
8362 pri_grab(p, p->
pri);
8363 #ifdef HAVE_PRI_PROG_W_CAUSE 8366 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8376 pri_grab(p, p->
pri);
8377 pri_acknowledge(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p),
8393 pri_grab(p, p->
pri);
8394 pri_proceeding(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 0);
8403 sig_pri_set_digital(p, 0);
8408 pri_grab(p, p->
pri);
8409 #ifdef HAVE_PRI_PROG_W_CAUSE 8410 pri_progress_with_cause(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1, -1);
8412 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8461 pri_grab(p, p->
pri);
8462 #ifdef HAVE_PRI_PROG_W_CAUSE 8465 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8474 pri_grab(p, p->
pri);
8484 pri_grab(p, p->
pri);
8496 res = sig_pri_play_tone(p, -1);
8501 struct pri_party_connected_line connected;
8504 int colp_allowed = 0;
8507 pri_grab(p, p->
pri);
8526 if (!colp_allowed) {
8528 ast_debug(1,
"Blocked AST_CONTROL_CONNECTED_LINE on %s\n",
8533 memset(&connected, 0,
sizeof(connected));
8534 sig_pri_party_id_from_ast(&connected.id, &connected_id);
8545 dialplan = PRI_INTERNATIONAL_ISDN;
8549 dialplan = PRI_NATIONAL_ISDN;
8551 dialplan = PRI_LOCAL_ISDN;
8559 strlen(connected.id.
number.
str + prefix_strip) + 1);
8570 pri_connected_line_update(p->
pri->
pri, p->
call, &connected);
8577 pri_grab(p, p->
pri);
8578 sig_pri_redirecting_update(p, chan);
8583 #if defined(HAVE_PRI_AOC_EVENTS) 8588 if (decoded && p->
pri) {
8589 pri_grab(p, p->
pri);
8593 sig_pri_aoc_s_from_ast(p, decoded);
8598 sig_pri_aoc_d_from_ast(p, decoded);
8603 sig_pri_aoc_e_from_ast(p, decoded);
8611 if (p->waiting_for_aoce) {
8612 p->waiting_for_aoce = 0;
8614 "Received final AOC-E msg, continue with hangup on %s\n",
8635 #if defined(HAVE_PRI_MCID) 8638 pri_grab(p, p->
pri);
8654 pri_grab(p, p->
pri);
8655 #if defined(HAVE_PRI_AOC_EVENTS) 8656 if (p->aoc_s_request_invoke_id_valid) {
8660 pri_aoc_s_request_response_send(p->
pri->
pri, p->
call,
8661 p->aoc_s_request_invoke_id,
NULL);
8662 p->aoc_s_request_invoke_id_valid = 0;
8668 sig_pri_set_dialing(p, 0);
8669 sig_pri_open_media(p);
8686 static int sig_pri_available_check(
struct sig_pri_chan *pvt)
8698 #if defined(HAVE_PRI_CALL_WAITING) 8717 if (pri->num_call_waiting_calls < pri->max_call_waiting_calls) {
8718 if (!pri->num_call_waiting_calls) {
8724 for (idx = 0; idx < pri->
numchans; ++idx) {
8725 if (pri->
pvts[idx] && sig_pri_available_check(pri->
pvts[idx])) {
8731 idx = pri_find_empty_nobch(pri);
8734 cw = pri->
pvts[idx];
8735 cw->is_call_waiting = 1;
8736 sig_pri_init_config(cw, pri);
8757 #
if defined(HAVE_PRI_CALL_WAITING)
8764 !pri->num_call_waiting_calls &&
8766 sig_pri_available_check(p)) {
8772 #if defined(HAVE_PRI_CALL_WAITING) 8773 if (!is_specific_channel) {
8776 cw = sig_pri_cw_available(pri);
8799 if (len <
sizeof(pvt->
dialdest) - 1) {
8800 ast_debug(1,
"Queueing digit '%c' since setup_ack not yet received\n",
8806 "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
8812 pri_grab(pvt, pvt->
pri);
8813 pri_information(pvt->
pri->
pri, pvt->
call, digit);
8819 "Span %d: Digit '%c' may be ignored by peer. (Call level:%u(%s))\n",
8844 sig_pri_open_media(pvt);
8855 sig_pri_set_dialing(pvt, 0);
8857 sig_pri_set_echocanceller(pvt, 1);
8861 #if defined(HAVE_PRI_MWI) 8875 static void sig_pri_send_mwi_indication(
struct sig_pri_span *pri,
const char *vm_number,
const char *
vm_box,
const char *mbox_id,
int num_messages)
8877 struct pri_party_id voicemail;
8880 ast_debug(1,
"Send MWI indication for %s(%s) vm_number:%s num_messages:%d\n",
8881 vm_box, mbox_id,
S_OR(vm_number,
"<not-present>"), num_messages);
8885 mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8886 mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8889 memset(&voicemail, 0,
sizeof(voicemail));
8890 voicemail.number.valid = 1;
8891 voicemail.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8892 voicemail.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8894 ast_copy_string(voicemail.number.str, vm_number,
sizeof(voicemail.number.str));
8898 #if defined(HAVE_PRI_MWI_V2) 8899 pri_mwi_indicate_v2(pri->
pri, &
mailbox, &voicemail, 1 , num_messages,
8908 #if defined(HAVE_PRI_MWI) 8933 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8934 if (!pri->mbox[idx].sub) {
8939 if (!strcmp(pri->mbox[idx].uniqueid, mwi_state->
uniqueid)) {
8941 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number,
8942 pri->mbox[idx].vm_box, pri->mbox[idx].uniqueid, mwi_state->
new_msgs);
8949 #if defined(HAVE_PRI_MWI) 8959 static void sig_pri_mwi_cache_update(
struct sig_pri_span *pri)
8964 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8966 if (!pri->mbox[idx].sub) {
8972 pri->mbox[idx].uniqueid);
8979 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number, pri->mbox[idx].vm_box,
8980 pri->mbox[idx].uniqueid, mwi_state->
new_msgs);
8995 #if defined(HAVE_PRI_MWI) 8999 #if defined(HAVE_PRI_MWI) 9000 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
9001 if (pri->mbox[idx].sub) {
9020 static int sig_pri_cmp_pri_chans(
const void *left,
const void *right)
9053 static void sig_pri_sort_pri_chans(
struct sig_pri_span *pri)
9055 qsort(&pri->
pvts, pri->
numchans,
sizeof(pri->
pvts[0]), sig_pri_cmp_pri_chans);
9062 #if defined(HAVE_PRI_MWI) 9064 char *prev_vm_number;
9067 #if defined(HAVE_PRI_MWI) 9069 for (i = 0; i <
ARRAY_LEN(pri->mbox); ++i) {
9070 if (pri->mbox[i].sub) {
9077 sig_pri_sort_pri_chans(pri);
9079 #if defined(HAVE_PRI_MWI) 9084 prev_vm_number =
NULL;
9085 saveptr = pri->mwi_vm_numbers;
9086 for (i = 0; i <
ARRAY_LEN(pri->mbox); ++i) {
9089 vm_number =
strsep(&saveptr,
",");
9095 vm_number = prev_vm_number;
9098 prev_vm_number = vm_number;
9100 pri->mbox[i].vm_number = vm_number;
9107 saveptr = pri->mwi_vm_boxes;
9108 for (i = 0; i <
ARRAY_LEN(pri->mbox); ++i) {
9111 vm_box =
strsep(&saveptr,
",");
9118 pri->mbox[i].vm_box =
vm_box;
9125 saveptr = pri->mwi_mailboxes;
9126 for (i = 0; i <
ARRAY_LEN(pri->mbox); ++i) {
9129 mbox_id =
strsep(&saveptr,
",");
9136 pri->mbox[i].uniqueid = mbox_id;
9137 if (!pri->mbox[i].vm_box || !mbox_id) {
9139 ast_debug(1,
"%s span %d MWI position %d disabled. vm_box:%s mbox_id:%s.\n",
9140 sig_pri_cc_type_name, pri->
span, i,
9141 pri->mbox[i].vm_box ?:
"<missing>",
9142 mbox_id ?:
"<missing>");
9147 if (!pri->mbox[i].sub) {
9148 ast_log(
LOG_ERROR,
"%s span %d could not subscribe to MWI events for %s(%s).\n",
9149 sig_pri_cc_type_name, pri->
span, pri->mbox[i].vm_box, mbox_id);
9151 #if defined(HAVE_PRI_MWI_V2) 9154 sig_pri_cc_type_name, pri->
span, pri->mbox[i].vm_box, mbox_id);
9161 if (pri->
fds[i] == -1) {
9174 #if defined(HAVE_PRI_SERVICE_MESSAGES) 9175 if (pri->enable_service_message_support) {
9176 pri_set_service_message_support(pri->
dchans[i], 1);
9183 #ifdef HAVE_PRI_PROG_W_CAUSE 9186 #ifdef HAVE_PRI_INBANDDISCONNECT 9187 pri_set_inbanddisconnect(pri->
dchans[i], pri->inbanddisconnect);
9193 if (pri->
fds[i] > 0)
9201 #ifdef PRI_GETSET_TIMERS 9202 for (x = 0; x < PRI_MAX_TIMERS; x++) {
9212 #if defined(HAVE_PRI_CALL_HOLD) 9213 pri_hold_enable(pri->
pri, 1);
9215 #if defined(HAVE_PRI_CALL_REROUTING) 9216 pri_reroute_enable(pri->
pri, 1);
9218 #if defined(HAVE_PRI_HANGUP_FIX) 9219 pri_hangup_fix_enable(pri->
pri, 1);
9221 #if defined(HAVE_PRI_CCSS) 9222 pri_cc_enable(pri->
pri, 1);
9223 pri_cc_recall_mode(pri->
pri, pri->cc_ptmp_recall_mode);
9224 pri_cc_retain_signaling_req(pri->
pri, pri->cc_qsig_signaling_link_req);
9225 pri_cc_retain_signaling_rsp(pri->
pri, pri->cc_qsig_signaling_link_rsp);
9227 #if defined(HAVE_PRI_TRANSFER) 9228 pri_transfer_enable(pri->
pri, 1);
9230 #if defined(HAVE_PRI_AOC_EVENTS) 9231 pri_aoc_events_enable(pri->
pri, 1);
9233 #if defined(HAVE_PRI_CALL_WAITING) 9234 pri_connect_ack_enable(pri->
pri, 1);
9236 #if defined(HAVE_PRI_MCID) 9237 pri_mcid_enable(pri->
pri, 1);
9239 #if defined(HAVE_PRI_DISPLAY_TEXT) 9240 pri_display_options_send(pri->
pri, pri->display_flags_send);
9241 pri_display_options_receive(pri->
pri, pri->display_flags_receive);
9243 #if defined(HAVE_PRI_DATETIME_SEND) 9244 pri_date_time_send_option(pri->
pri, pri->datetime_send);
9246 #if defined(HAVE_PRI_L2_PERSISTENCE) 9247 pri_persistent_layer2_option(pri->
pri, pri->l2_persistence);
9255 if (pri->
fds[i] > 0)
9263 #if defined(HAVE_PRI_MWI) 9272 sig_pri_mwi_cache_update(pri);
9290 pri_grab(p, p->
pri);
9293 if (pri_get_timer(p->
pri->
pri, PRI_TIMER_T309) < 0) {
9303 sig_pri_span_devstate_changed(p->
pri);
9351 #define SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n" 9352 #define SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s" 9355 ast_cli(fd, SIG_PRI_SC_HEADER,
"PRI",
"",
"B",
"Chan",
"Call",
"PRI",
"Channel");
9356 ast_cli(fd, SIG_PRI_SC_HEADER,
"Span",
"Chan",
"Chan",
"Idle",
"Level",
"Call",
"Name");
9366 for (idx = 0; idx < pri->
numchans; ++idx) {
9367 if (!pri->
pvts[idx]) {
9370 pvt = pri->
pvts[idx];
9371 sig_pri_lock_private(pvt);
9372 sig_pri_lock_owner(pri, idx);
9375 sig_pri_unlock_private(pvt);
9379 snprintf(line,
sizeof(line), SIG_PRI_SC_LINE,
9385 pvt->
call ?
"Yes" :
"No",
9391 sig_pri_unlock_private(pvt);
9402 if (!s || len < 1) {
9405 snprintf(s, len,
"%s%s, %s",
9406 (status & DCHAN_NOTINALARM) ?
"" :
"In Alarm, ",
9407 (status & DCHAN_UP) ?
"Up" :
"Down",
9408 (active) ?
"Active" :
"Standby");
9418 ast_cli(fd,
"PRI span %d/%d: %s\n", span, x, status);
9430 #ifdef PRI_DUMP_INFO_STR 9431 char *info_str =
NULL;
9433 ast_cli(fd,
"%s D-channel: %d\n", pri_order(x), dchannels[x]);
9435 ast_cli(fd,
"Status: %s\n", status);
9437 #ifdef PRI_DUMP_INFO_STR 9438 info_str = pri_dump_info_str(pri->
pri);
9444 pri_dump_info(pri->
pri);
9455 sig_pri_lock_private(p);
9458 ast_debug(1,
"Unable to find pri or call on channel!\n");
9459 sig_pri_unlock_private(p);
9463 pri_grab(p, p->
pri);
9464 pri_keypad_facility(p->
pri->
pri, p->
call, digits);
9467 sig_pri_unlock_private(p);
9476 sig_pri_lock_private(p);
9479 ast_debug(1,
"Unable to find pri or call on channel!\n");
9480 sig_pri_unlock_private(p);
9484 pri_grab(p, p->
pri);
9485 res = pri_callrerouting_facility(p->
pri->
pri, p->
call, destination, original, reason);
9488 sig_pri_unlock_private(p);
9493 #if defined(HAVE_PRI_SERVICE_MESSAGES) 9494 int pri_maintenance_bservice(
struct pri *pri,
struct sig_pri_chan *p,
int changestatus)
9496 int channel = PVT_TO_CHANNEL(p);
9497 int span = PRI_SPAN(channel);
9499 return pri_maintenance_service(pri, span, channel, changestatus);
9505 if (pchan->
owner == oldchan) {
9506 pchan->
owner = newchan;
9510 #if defined(HAVE_PRI_DISPLAY_TEXT) 9522 struct pri_subcmd_display_txt display;
9526 display.length = strlen(display.text);
9527 display.char_set = 0;
9528 pri_grab(p, p->
pri);
9529 pri_display_text(p->
pri->
pri, p->
call, &display);
9535 #if defined(HAVE_PRI_CCSS) 9554 struct sig_pri_cc_agent_prv *cc_pvt;
9562 cc_pvt->pri = pvt_chan->
pri;
9563 cc_pvt->cc_id = pri_cc_available(pvt_chan->
pri->
pri, pvt_chan->
call);
9565 if (cc_pvt->cc_id == -1) {
9574 #if defined(HAVE_PRI_CCSS) 9603 #if defined(HAVE_PRI_CCSS) 9624 #if defined(HAVE_PRI_CCSS) 9647 struct sig_pri_cc_agent_prv *cc_pvt;
9650 const char *failed_msg;
9651 static const char *failed_to_send =
"Failed to send the CC request response.";
9652 static const char *not_accepted =
"The core declined the CC request.";
9656 if (cc_pvt->cc_request_response_pending) {
9657 cc_pvt->cc_request_response_pending = 0;
9673 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status);
9677 failed_msg = failed_to_send;
9684 failed_msg = failed_to_send;
9686 failed_msg = not_accepted;
9699 #if defined(HAVE_PRI_CCSS) 9717 struct sig_pri_cc_agent_prv *cc_pvt;
9721 pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
9727 #if defined(HAVE_PRI_CCSS) 9752 struct sig_pri_cc_agent_prv *cc_pvt;
9756 pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
9762 #if defined(HAVE_PRI_CCSS) 9786 struct sig_pri_cc_agent_prv *cc_pvt;
9790 pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
9796 #if defined(HAVE_PRI_CCSS) 9820 #if defined(HAVE_PRI_CCSS) 9842 struct sig_pri_cc_agent_prv *cc_pvt;
9846 pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
9852 #if defined(HAVE_PRI_CCSS) 9871 struct sig_pri_cc_agent_prv *cc_pvt;
9881 if (cc_pvt->cc_request_response_pending) {
9882 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2);
9885 pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
9892 #if defined(HAVE_PRI_CCSS) 9903 static int sig_pri_cc_monitor_instance_hash_fn(
const void *obj,
const int flags)
9905 const struct sig_pri_cc_monitor_instance *monitor_instance = obj;
9907 return monitor_instance->core_id;
9911 #if defined(HAVE_PRI_CCSS) 9923 static int sig_pri_cc_monitor_instance_cmp_fn(
void *obj,
void *arg,
int flags)
9925 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
9926 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
9932 #if defined(HAVE_PRI_CCSS) 9953 struct sig_pri_cc_monitor_instance *instance;
9973 res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
9980 #if defined(HAVE_PRI_CCSS) 9996 struct sig_pri_cc_monitor_instance *instance;
10000 pri_cc_status(instance->pri->pri, instance->cc_id, 1);
10007 #if defined(HAVE_PRI_CCSS) 10022 struct sig_pri_cc_monitor_instance *instance;
10026 pri_cc_status(instance->pri->pri, instance->cc_id, 0);
10033 #if defined(HAVE_PRI_CCSS) 10052 struct sig_pri_cc_monitor_instance *instance;
10055 switch (devstate) {
10070 pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
10077 #if defined(HAVE_PRI_CCSS) 10106 #if defined(HAVE_PRI_CCSS) 10120 struct sig_pri_cc_monitor_instance *instance;
10122 instance = monitor_pvt;
10142 #if defined(HAVE_PRI_MCID) 10148 #if defined(HAVE_PRI_CCSS) 10149 sig_pri_cc_type_name = cc_type_name;
10151 sig_pri_cc_monitor_instance_hash_fn,
NULL, sig_pri_cc_monitor_instance_cmp_fn);
10152 if (!sig_pri_cc_monitors) {
10167 #if defined(HAVE_PRI_CCSS) 10168 if (sig_pri_cc_monitors) {
10169 ao2_ref(sig_pri_cc_monitors, -1);
10170 sig_pri_cc_monitors =
NULL;
10174 #if defined(HAVE_PRI_MCID) void(*const lock_private)(void *pvt)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char *const debug,...)
Indicate that a failure has occurred on a specific monitor.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
void sig_pri_unload(void)
Struct containing info for an AMI event to send out.
Information needed to identify an endpoint in a call.
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
int presentation
Q.931 encoded presentation-indicator encoded field.
int sig_pri_cc_monitor_unsuspend(struct ast_cc_monitor *monitor)
void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
void ast_std_free(void *ptr)
int dchan_logical_span[SIG_PRI_NUM_DCHANS]
#define ast_channel_lock(chan)
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 DAHDI_OVERLAPDIAL_INCOMING
char user_tag[AST_MAX_EXTENSION *2]
User tag for party id's sent from this device driver.
static char exten[AST_MAX_EXTENSION]
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name, unsigned long time, enum ast_aoc_time_scale time_scale, unsigned long granularity_time, enum ast_aoc_time_scale granularity_time_scale, int step_function)
Add AOC-S duration rate entry.
Main Channel structure associated with a channel.
struct ast_party_dialed::@246 number
Dialed/Called number.
int sig_pri_cc_agent_party_b_free(struct ast_cc_agent *agent)
ast_device_state
Device States.
unsigned int alreadyhungup
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel)
char * str
Subscriber phone number (Malloced)
General Asterisk channel transcoding definitions.
unsigned int priexclusive
void astman_append(struct mansession *s, const char *fmt,...)
Asterisk main include file. File version handling, generic pbx functions.
int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
struct ast_party_id priv_to
Call is redirecting to a new party (Sent to the caller) - private representation. ...
char * str
Subscriber phone number (Malloced)
char chan_name[AST_CHANNEL_NAME]
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan)
int ast_aoc_set_termination_request(struct ast_aoc_decoded *decoded)
Mark the AST_AOC_REQUEST message as a termination request.
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
unsigned int use_callingpres
struct ast_json * ast_json_party_id(struct ast_party_id *party)
Construct an ast_party_id as JSON.
void sig_pri_cli_show_span(int fd, int *dchannels, struct sig_pri_span *pri)
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void sig_pri_cli_show_spans(int fd, int span, struct sig_pri_span *pri)
#define ast_pthread_create_detached(a, b, c, d)
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded, const unsigned int amount_is_present, const unsigned int amount, const unsigned int type_is_present, const unsigned int type)
Adds a unit entry into the list of units.
void(*const init_config)(void *pvt, struct sig_pri_span *pri)
int ast_cc_get_current_core_id(struct ast_channel *chan)
Get the core id for the current call.
void sig_pri_cli_show_channels(int fd, struct sig_pri_span *pri)
void sig_pri_cli_show_channels_header(int fd)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
#define ast_test_flag(p, flag)
#define AST_CAUSE_SWITCH_CONGESTION
struct ast_party_id priv_orig
Who originally redirected the call (Sent to the party the call is redirected toward) - private repres...
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
unsigned int priindication_oob
unsigned int use_callerid
char idleext[AST_MAX_EXTENSION]
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_party_name name
Subscriber name.
union ast_aoc_charging_association::@221 charge
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 pri_event_alarm(struct sig_pri_span *pri, int index, int before_start_pri)
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
struct ast_channel_snapshot * snapshot
int sig_pri_cc_agent_stop_offer_timer(struct ast_cc_agent *agent)
unsigned int transfer
TRUE if call transfer is enabled for the span.
struct sig_pri_callback sig_pri_callbacks
struct ast_aoc_duration_rate duration
#define DEADLOCK_AVOIDANCE(lock)
Interface header for PRI signaling module.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S flat rate entry.
int sig_pri_cc_monitor_req_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
#define ao2_callback(c, flags, cb_fn, arg)
struct ast_party_id priv_from
Who is redirecting the call (Sent to the party the call is redirected toward) - private representatio...
int sig_pri_cc_monitor_suspend(struct ast_cc_monitor *monitor)
int ast_cc_agent_caller_busy(int core_id, const char *const debug,...)
Indicate that the caller is busy.
char idlecontext[AST_MAX_CONTEXT]
struct ast_channel * owner
int ast_json_is_true(const struct ast_json *value)
Check if value is JSON true.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
Response with a caller's current status.
enum ast_aoc_total_type ast_aoc_get_total_type(struct ast_aoc_decoded *decoded)
get the type of total for a AOC-D message
int ast_cc_monitor_request_acked(int core_id, const char *const debug,...)
Indicate that an outbound entity has accepted our CC request.
char cid_ani[AST_MAX_EXTENSION]
void(*const set_rdnis)(void *pvt, const char *rdnis)
struct ast_aoc_charging_association_number number
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
int ast_cc_monitor_party_b_free(int core_id)
Alert a caller that though the callee has become free, the caller himself is not and may not call bac...
enum ast_cc_service_type service
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
int char_set
Character set the name is using.
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
Structure to pass both assignedid values to channel drivers.
void(*const deadlock_avoidance_private)(void *pvt)
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
void(*const set_dialing)(void *pvt, int is_dialing)
ast_channel_state
ast_channel states
char * str
Subscriber name (Malloced)
enum sig_pri_reset_state resetting
Channel reset/restart state.
int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int code)
Add AOC-S special rate entry.
#define DAHDI_OVERLAPDIAL_OUTGOING
enum sig_pri_moh_state moh_state
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
struct ast_party_id ast_channel_redirecting_effective_to(struct ast_channel *chan)
unsigned char valid
TRUE if the subaddress information is valid/present.
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
struct ast_party_id ast_channel_redirecting_effective_orig(struct ast_channel *chan)
void(*const set_callerid)(void *pvt, const struct ast_party_caller *caller)
The channel is not being RESTARTed.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int sig_pri_ami_show_spans(struct mansession *s, const char *show_cmd, struct sig_pri_span *pri, const int *dchannels, const char *action_id)
void(*const fixup_chans)(void *old_chan, void *new_chan)
uint8_t charging_type
Charging interval type.
#define ast_mutex_lock(a)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
void ast_verbose(const char *fmt,...)
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
#define ast_strdup(str)
A wrapper for strdup()
static int call(void *data)
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, enum ast_aoc_volume_unit volume_unit, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S volume rate entry.
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
ast_cc_agent_response_reason
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define SIG_PRI_AOC_GRANT_S
int dchanavail[SIG_PRI_NUM_DCHANS]
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
generate AOC manager event for an AOC-S, AOC-D, or AOC-E msg
int ast_queue_cc_frame(struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
Queue an AST_CONTROL_CC frame.
char * str
Malloced subaddress string.
int ast_cc_agent_accept_request(int core_id, const char *const debug,...)
Accept inbound CC request.
int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, int from_beginning)
Add AOC-S indicating charge item is free.
void(*const dial_digits)(void *pvt, const char *dial_string)
enum sig_pri_colp_signaling colp_send
void ast_cli(int fd, const char *fmt,...)
#define AST_CAUSE_INVALID_NUMBER_FORMAT
int ast_cc_agent_recalling(int core_id, const char *const debug,...)
Tell the CC core that a caller is currently recalling.
unsigned int inband_on_setup_ack
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define AST_PRES_NETWORK_NUMBER
int code
enum AST_REDIRECTING_REASON value for redirection
unsigned char odd_even_indicator
TRUE if odd number of address signals.
#define ast_verb(level,...)
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char *const monitor_type)
Decide if a call to a particular channel is a CC recall.
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
void(*const unlock_private)(void *pvt)
ast_cc_monitor_policies
The various possibilities for cc_monitor_policy values.
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching 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.
const struct ast_aoc_s_entry * ast_aoc_s_get_rate_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific AOC-S rate entry.
struct ast_frame_subclass subclass
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Blob of data associated with a channel.
#define AST_PRES_RESTRICTED
unsigned int no_d_channels
int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast)
#define ast_strlen_zero(foo)
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
int pri_send_keypad_facility_exec(struct sig_pri_chan *p, const char *digits)
void(* destroy_later)(struct sig_pri_span *pri)
struct ast_party_id orig
Who originally redirected the call (Sent to the party the call is redirected toward) ...
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define ast_pthread_create_background(a, b, c, d)
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging accociation number for an AOC-E message
void(*const open_media)(void *pvt)
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
struct ast_party_id id
Caller party ID.
void sig_pri_init_pri(struct sig_pri_span *pri)
int(*const play_tone)(void *pvt, enum sig_pri_tone tone)
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
#define ast_debug(level,...)
Log a DEBUG message.
int sig_pri_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
Generic Advice of Charge encode and decode routines.
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
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 ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
Set the first level CC_INTERFACES channel variable for a channel.
#define AST_PRES_USER_NUMBER_UNSCREENED
unsigned int inband_on_proceeding
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
#define ast_mutex_trylock(a)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
struct ast_party_redirecting_reason orig_reason
Reason for the redirection by the original party.
int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
Set up a CC recall datastore on a channel.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
Destroy the party subaddress contents.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int sig_pri_cc_agent_stop_ringing(struct ast_cc_agent *agent)
int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item)
Add AOC-S entry indicating charge item is not available.
#define AST_PTHREADT_NULL
enum sig_pri_call_level call_level
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
void(*const handle_dchan_exception)(struct sig_pri_span *pri, int index)
#define AST_MAX_EXTENSION
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#define AST_CAUSE_NORMAL_CLEARING
Caller Party information.
#define ao2_ref(o, delta)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
In case you didn't read that giant block of text above the mansession_session struct, the struct mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
int ast_cc_agent_caller_available(int core_id, const char *const debug,...)
Indicate that a previously unavailable caller has become available.
#define ast_strdupa(s)
duplicate a string in memory from the stack
struct ast_aoc_flat_rate flat
char internationalprefix[10]
char currency_name[AOC_CURRENCY_NAME_SIZE]
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
The channel is being RESTARTed.
#define ast_malloc(len)
A wrapper for malloc()
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
void(*const ami_channel_event)(void *pvt, struct ast_channel *chan)
Post an AMI B channel association event.
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
AST_REDIRECTING_REASON
redirecting reason codes.
const char * ast_channel_exten(const struct ast_channel *chan)
Core PBX routines and definitions.
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded)
get the currency amount for AOC-D and AOC-E messages
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_CC_GENERIC_MONITOR_TYPE
void sig_pri_chan_delete(struct sig_pri_chan *doomed)
int(*const set_echocanceller)(void *pvt, int enable)
int(*const dsp_reset_and_flush_digits)(void *pvt)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
char moh_suggested[MAX_MUSICCLASS]
int sig_pri_cc_agent_init(struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
int(*const new_nobch_intf)(struct sig_pri_span *pri)
struct ast_party_subaddress subaddress
Subscriber subaddress.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id)
set the billing id for a AOC-D or AST_AOC_E message
int sig_pri_cc_monitor_status_rsp(struct ast_cc_monitor *monitor, enum ast_device_state devstate)
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
struct ast_aoc_volume_rate volume
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
unsigned int force_restart_unavailable_chans
TRUE if forcing RESTART when receive cause 44 on this span.
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define ao2_unlink(container, obj)
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
static unsigned int monitor
const struct ast_aoc_unit_entry * ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific unit entry.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ani2
Automatic Number Identification 2 (Info Digits)
#define PRI_TRANS_CAP_DIGITAL
struct ast_cc_agent * ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char *const type)
Call a callback on all agents of a specific type.
#define SIG_PRI_NUM_DCHANS
Connected Line/Party information.
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
int ast_aoc_get_termination_request(struct ast_aoc_decoded *decoded)
get whether or not the AST_AOC_REQUEST message as a termination request.
void(*const set_digital)(void *pvt, int is_digital)
char idledial[AST_MAX_EXTENSION]
#define ao2_alloc(data_size, destructor_fn)
#define AST_PRES_NUMBER_NOT_AVAILABLE
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
uint32_t granularity_time
char exten[AST_MAX_EXTENSION]
#define ast_channel_unlock(chan)
void sig_pri_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
enum ast_aoc_billing_id ast_aoc_get_billing_id(struct ast_aoc_decoded *decoded)
get the billing id for AOC-D and AOC-E messages
int ast_cc_monitor_status_request(int core_id)
Request the status of a caller or callers.
unsigned int hidecalleridname
#define ast_calloc(num, len)
A wrapper for calloc()
struct ast_channel *(*const new_ast_channel)(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
unsigned int append_msn_to_user_tag
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
char initial_user_tag[AST_MAX_EXTENSION]
Initial user tag for party id's sent from this device driver.
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type)
Sets the type of total for a AOC-D message.
void * ast_mwi_unsubscribe_and_join(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic, block until the final message is received, and then unsubscribe fr...
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
static void to_ami(struct ast_sip_subscription *sub, struct ast_str **buf)
char cid_subaddr[AST_MAX_EXTENSION]
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
int pri_send_callrerouting_facility_exec(struct sig_pri_chan *p, enum ast_channel_state chanstate, const char *destination, const char *original, const char *reason)
char currency_name[AOC_CURRENCY_NAME_SIZE]
const char * ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded)
get the currency name for AOC-D and AOC-E messages
int ast_cc_request_is_within_limits(void)
Check if the incoming CC request is within the bounds set by the cc_max_requests configuration option...
static int request(void *obj)
void sig_pri_cc_monitor_destructor(void *monitor_pvt)
char cid_num[AST_MAX_EXTENSION]
int sig_pri_start_pri(struct sig_pri_span *pri)
char msn_list[AST_MAX_EXTENSION]
struct ast_party_redirecting_reason reason
Reason for the redirection.
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
char deferred_digits[AST_MAX_EXTENSION]
int sig_pri_cc_agent_start_monitoring(struct ast_cc_agent *agent)
Structure used to handle boolean flags.
void(*const set_alarm)(void *pvt, int in_alarm)
union ast_aoc_s_entry::@220 rate
Charge rate being applied.
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
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...
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
struct ast_frame ast_null_frame
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded)
get the charging type for an AOC-D or AOC-E message
int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rdest, int timeout, int layer1)
char * tag
User-set "tag".
void(*const set_dnid)(void *pvt, const char *dnid)
int type
Q.931 subaddress type.
unsigned int hidecallerid
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
int sig_pri_answer(struct sig_pri_chan *p, struct ast_channel *ast)
char * strsep(char **str, const char *delims)
#define ast_channel_ref(c)
Increase channel reference count.
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
int count
Number of times the call was redirected.
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
struct ast_channel * sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int transfercapability)
void sig_pri_stop_pri(struct sig_pri_span *pri)
int ast_channel_hangupcause(const struct ast_channel *chan)
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
void ast_party_id_invalidate(struct ast_party_id *id)
Invalidate all components of the given party id.
void ast_channel_context_set(struct ast_channel *chan, const char *value)
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.
Peer may not be sending the expected RESTART ACKNOWLEDGE.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
void ast_party_subaddress_init(struct ast_party_subaddress *init)
Initialize the given subaddress structure.
void(*const update_span_devstate)(struct sig_pri_span *pri)
const char * ast_channel_name(const struct ast_channel *chan)
int sig_pri_digit_begin(struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
#define AST_CAUSE_USER_BUSY
void sig_pri_cc_agent_destructor(struct ast_cc_agent *agent)
const ast_string_field uniqueid
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.
Information needed to specify a number in a call.
int discardremoteholdretrieval
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
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.
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
struct stasis_forward * sub
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
int pritimers[PRI_MAX_TIMERS]
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
struct stasis_message * stasis_cache_get(struct stasis_cache *cache, struct stasis_message_type *type, const char *id)
Retrieve an item from the cache for the ast_eid_default entity.
void(*const make_cc_dialstring)(void *pvt, char *buf, size_t buf_size)
struct sig_pri_span * pri
Abstract JSON element (object, array, string, int, ...).
Options provided by main asterisk program.
unsigned int layer1_ignored
const char * ast_channel_context(const struct ast_channel *chan)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id)
set the charging association id for an AST_AOC_E message
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
union ast_frame::@263 data
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
enum ast_frame_type frametype
void(*const set_outgoing)(void *pvt, int is_outgoing)
void * private_data
Data that is private to a monitor technology.
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
#define DAHDI_CHAN_MAPPING_LOGICAL
#define AST_PRES_UNAVAILABLE
#define ast_mutex_init(pmutex)
#define SIG_PRI_AOC_GRANT_E
enum ast_aoc_currency_multiplier ast_aoc_get_currency_multiplier(struct ast_aoc_decoded *decoded)
get the currency multiplier for AOC-D and AOC-E messages
#define ast_channel_trylock(chan)
unsigned char valid
TRUE if the name information is valid/present.
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
Information needed to specify a subaddress in a call.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
int sig_pri_cc_agent_start_offer_timer(struct ast_cc_agent *agent)
int sig_pri_load(const char *cc_type_name)
struct sig_pri_chan * sig_pri_chan_new(void *pvt_data, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
The structure that contains MWI state.
char cid_name[AST_MAX_EXTENSION]
enum sig_pri_moh_signaling moh_signaling
const char *(*const get_orig_dialstring)(void *pvt)
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
enum ast_cc_service_type service_offered
Say numbers and dates (maybe words one day too)
unsigned int ast_aoc_get_unit_count(struct ast_aoc_decoded *decoded)
get the number of unit entries for AOC-D and AOC-E messages
unsigned int allocated
TRUE when this channel is allocated.
void ast_channel_priority_set(struct ast_channel *chan, int value)
struct ast_cc_monitor * ast_cc_get_monitor_by_recall_core_id(const int core_id, const char *const device_name)
Get the associated monitor given the device name and core_id.
struct pri * dchans[SIG_PRI_NUM_DCHANS]
char context[AST_MAX_CONTEXT]
#define SIG_PRI_DEBUG_DEFAULT
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
int ast_cc_monitor_stop_ringing(int core_id)
Alert a caller to stop ringing.
Persistant data storage (akin to *doze registry)
Information needed to specify a name in a call.
void(* module_unref)(void)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
void sig_pri_cc_agent_req_rsp(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define SIG_PRI_AOC_GRANT_D
unsigned char valid
TRUE if the number information is valid/present.
uint16_t granularity_time_scale
ast_callid ast_channel_callid(const struct ast_channel *chan)
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)
int sig_pri_cc_agent_callee_available(struct ast_cc_agent *agent)
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. ...
char mohinterpret[MAX_MUSICCLASS]
int pri_is_up(struct sig_pri_span *pri)
#define AST_TRANS_CAP_DIGITAL
int ast_cc_monitor_callee_available(const int core_id, const char *const debug,...)
Alert the core that a device being monitored has become available.
void(*const queue_control)(void *pvt, int subclass)
int fds[SIG_PRI_NUM_DCHANS]
#define STASIS_MESSAGE_TYPE_DEFN_LOCAL(name,...)
Boiler-plate messaging macro for defining local message types.
void pri_event_noalarm(struct sig_pri_span *pri, int index, int before_start_pri)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define ast_mutex_unlock(a)
static char prefix[MAX_PREFIX]
#define AST_APP_ARG(name)
Define an application argument.
char currency_name[AOC_CURRENCY_NAME_SIZE]
static msg_t * build_status(struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
int sig_pri_cc_agent_status_req(struct ast_cc_agent *agent)
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded, const unsigned int amount, const enum ast_aoc_currency_multiplier multiplier, const char *name)
Sets the currency values for a AOC-D or AOC-E message.
const struct ast_aoc_charging_association * ast_aoc_get_association_info(struct ast_aoc_decoded *decoded)
get the charging association info for AOC-E messages
struct ast_party_number number
Subscriber phone number.
#define ao2_link(container, obj)