120#ifndef PRI_EVENT_FACILITY
121#error "Upgrade your libpri"
129#undef SUPPORT_USERUSER
137#if defined(HAVE_PRI_CCSS)
138struct sig_pri_cc_agent_prv {
144 unsigned char cc_request_response_pending;
147struct sig_pri_cc_monitor_instance {
159static const char *sig_pri_cc_type_name;
164static int pri_matchdigittimeout = 3000;
166static 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)
181static int pri_active_dchan_index(
struct sig_pri_span *pri);
209static 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",
218static void sig_pri_handle_dchan_exception(
struct sig_pri_span *pri,
int index)
225static void sig_pri_set_dialing(
struct sig_pri_chan *p,
int is_dialing)
232static void sig_pri_set_digital(
struct sig_pri_chan *p,
int is_digital)
240static void sig_pri_set_outgoing(
struct sig_pri_chan *p,
int is_outgoing)
268static const char *sig_pri_get_orig_dialstring(
struct sig_pri_chan *p)
277#if defined(HAVE_PRI_CCSS)
278static void sig_pri_make_cc_dialstring(
struct sig_pri_chan *p,
char *
buf,
size_t buf_size)
289static void sig_pri_dial_digits(
struct sig_pri_chan *p,
const char *dial_string)
305static void sig_pri_span_devstate_changed(
struct sig_pri_span *pri)
319static void sig_pri_set_caller_id(
struct sig_pri_chan *p)
328 caller.id.name.valid = 1;
330 caller.id.number.str = p->
cid_num;
331 caller.id.number.plan = p->
cid_ton;
333 caller.id.number.valid = 1;
336 caller.id.subaddress.valid = 1;
343 caller.ani.number.str = p->
cid_ani;
346 caller.ani.number.valid = 1;
361static void sig_pri_set_dnid(
struct sig_pri_chan *p,
const char *dnid)
376static void sig_pri_set_rdnis(
struct sig_pri_chan *p,
const char *rdnis)
383static void sig_pri_unlock_private(
struct sig_pri_chan *p)
397static void sig_pri_deadlock_avoidance_private(
struct sig_pri_chan *p)
403 sig_pri_unlock_private(p);
405 sig_pri_lock_private(p);
414 sig_pri_deadlock_avoidance_private(p);
418 pthread_kill(pri->
master, SIGURG);
435 switch (pri_reason) {
436 case PRI_REDIR_FORWARD_ON_BUSY:
439 case PRI_REDIR_FORWARD_ON_NO_REPLY:
442 case PRI_REDIR_DEFLECTION:
445 case PRI_REDIR_UNCONDITIONAL:
448 case PRI_REDIR_UNKNOWN:
470 switch (ast_reason) {
472 pri_reason = PRI_REDIR_FORWARD_ON_BUSY;
475 pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY;
478 pri_reason = PRI_REDIR_UNCONDITIONAL;
481 pri_reason = PRI_REDIR_DEFLECTION;
485 pri_reason = PRI_REDIR_UNKNOWN;
501static int pri_to_ast_presentation(
int pri_presentation)
503 int ast_presentation;
505 switch (pri_presentation) {
506 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED:
509 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
512 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
515 case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER:
519 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED:
522 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
525 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
528 case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER:
532 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED:
533 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
534 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
535 case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER:
544 return ast_presentation;
556static int ast_to_pri_presentation(
int ast_presentation)
558 int pri_presentation;
560 switch (ast_presentation) {
562 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
565 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
568 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
571 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER;
575 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
578 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
581 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
584 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER;
591 pri_presentation = PRES_NUMBER_NOT_AVAILABLE;
595 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
599 return pri_presentation;
615 switch (pri_char_set) {
617 case PRI_CHAR_SET_UNKNOWN:
620 case PRI_CHAR_SET_ISO8859_1:
623 case PRI_CHAR_SET_WITHDRAWN:
626 case PRI_CHAR_SET_ISO8859_2:
629 case PRI_CHAR_SET_ISO8859_3:
632 case PRI_CHAR_SET_ISO8859_4:
635 case PRI_CHAR_SET_ISO8859_5:
638 case PRI_CHAR_SET_ISO8859_7:
641 case PRI_CHAR_SET_ISO10646_BMPSTRING:
644 case PRI_CHAR_SET_ISO10646_UTF_8STRING:
665 switch (ast_char_set) {
668 pri_char_set = PRI_CHAR_SET_UNKNOWN;
671 pri_char_set = PRI_CHAR_SET_ISO8859_1;
674 pri_char_set = PRI_CHAR_SET_WITHDRAWN;
677 pri_char_set = PRI_CHAR_SET_ISO8859_2;
680 pri_char_set = PRI_CHAR_SET_ISO8859_3;
683 pri_char_set = PRI_CHAR_SET_ISO8859_4;
686 pri_char_set = PRI_CHAR_SET_ISO8859_5;
689 pri_char_set = PRI_CHAR_SET_ISO8859_7;
692 pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
695 pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
702#if defined(HAVE_PRI_SUBADDR)
711static void sig_pri_set_subaddress(
struct ast_party_subaddress *ast_subaddress,
const struct pri_party_subaddress *pri_subaddress)
714 if (pri_subaddress->length <= 0) {
719 if (!pri_subaddress->type) {
721 ast_subaddress->
str =
ast_strdup((
char *) pri_subaddress->data);
729 cnum =
ast_malloc(2 * pri_subaddress->length + 1);
736 len = pri_subaddress->length - 1;
737 for (x = 0; x <
len; ++x) {
738 ptr += sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[x]);
741 if (pri_subaddress->odd_even_indicator) {
743 sprintf(ptr,
"%01hhx", (
unsigned char)((pri_subaddress->data[
len]) >> 4));
746 sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[
len]);
748 ast_subaddress->
str = cnum;
750 ast_subaddress->
type = pri_subaddress->type;
752 ast_subaddress->
valid = 1;
756#if defined(HAVE_PRI_SUBADDR)
757static unsigned char ast_pri_pack_hex_char(
char c)
763 }
else if (
c < (
'9' + 1)) {
765 }
else if (
c <
'A') {
767 }
else if (
c < (
'F' + 1)) {
769 }
else if (
c <
'a') {
771 }
else if (
c < (
'f' + 1)) {
780#if defined(HAVE_PRI_SUBADDR)
796static int ast_pri_pack_hex_string(
unsigned char *dst,
char *src,
int maxlen)
799 int len = strlen(src);
801 if (
len > (2 * maxlen)) {
808 *dst = ast_pri_pack_hex_char(*src) << 4;
810 *dst |= ast_pri_pack_hex_char(*src);
815 *dst = ast_pri_pack_hex_char(*src) << 4;
821#if defined(HAVE_PRI_SUBADDR)
832static void sig_pri_party_subaddress_from_ast(
struct pri_party_subaddress *pri_subaddress,
const struct ast_party_subaddress *ast_subaddress)
835 pri_subaddress->type = ast_subaddress->
type;
836 if (!ast_subaddress->
type) {
839 sizeof(pri_subaddress->data));
840 pri_subaddress->length = strlen((
char *) pri_subaddress->data);
841 pri_subaddress->odd_even_indicator = 0;
842 pri_subaddress->valid = 1;
849 int length = ast_pri_pack_hex_string(pri_subaddress->data,
850 ast_subaddress->
str,
sizeof(pri_subaddress->data));
852 pri_subaddress->length = length;
854 length = strlen(ast_subaddress->
str);
855 if (length > 2 *
sizeof(pri_subaddress->data)) {
856 pri_subaddress->odd_even_indicator = 0;
858 pri_subaddress->odd_even_indicator = (length & 1);
860 pri_subaddress->valid = 1;
876static void sig_pri_party_name_from_ast(
struct pri_party_name *pri_name,
const struct ast_party_name *ast_name)
878 if (!ast_name->
valid) {
882 pri_name->presentation = ast_to_pri_presentation(ast_name->
presentation);
883 pri_name->char_set = ast_to_pri_char_set(ast_name->
char_set);
899static void sig_pri_party_number_from_ast(
struct pri_party_number *pri_number,
const struct ast_party_number *ast_number)
901 if (!ast_number->
valid) {
904 pri_number->valid = 1;
905 pri_number->presentation = ast_to_pri_presentation(ast_number->
presentation);
906 pri_number->plan = ast_number->
plan;
922static void sig_pri_party_id_from_ast(
struct pri_party_id *pri_id,
const struct ast_party_id *ast_id)
924 sig_pri_party_name_from_ast(&pri_id->name, &ast_id->
name);
925 sig_pri_party_number_from_ast(&pri_id->number, &ast_id->
number);
926#if defined(HAVE_PRI_SUBADDR)
927 sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->
subaddress);
943 struct pri_party_redirecting pri_redirecting;
949 memset(&pri_redirecting, 0,
sizeof(pri_redirecting));
951 sig_pri_party_id_from_ast(&pri_redirecting.from, &redirecting_from);
952 sig_pri_party_id_from_ast(&pri_redirecting.to, &redirecting_to);
953 sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &redirecting_orig);
954 pri_redirecting.count = ast_redirecting->
count;
955 pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->
orig_reason.
code);
956 pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->
reason.
code);
958 pri_redirecting_update(pvt->
pri->
pri, pvt->
call, &pri_redirecting);
968static void sig_pri_dsp_reset_and_flush_digits(
struct sig_pri_chan *p)
975static int sig_pri_set_echocanceller(
struct sig_pri_chan *p,
int enable)
1023 sig_pri_set_digital(p, 1);
1027 sig_pri_span_devstate_changed(p->
pri);
1061static void sig_pri_ami_channel_event(
struct sig_pri_chan *p)
1076 sig_pri_set_outgoing(p, 1);
1078 p->
exten, assignedids, requestor);
1080 sig_pri_set_outgoing(p, 0);
1095static const char *pri_order(
int level)
1105 return "Quaternary";
1112static int pri_active_dchan_index(
struct sig_pri_span *pri)
1138 if (pri->
dchans[idx] == old) {
1141 if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) {
1155 if (old && oldslot != newslot) {
1157 "Span %d: No D-channels up! Switching selected D-channel from %s to %s.\n",
1158 pri->
span, pri_order(oldslot), pri_order(newslot));
1166 if (old && oldslot != newslot) {
1168 "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n",
1169 pri_order(oldslot), pri->
fds[oldslot],
1170 pri_order(newslot), pri->
fds[newslot]);
1204static int sig_pri_is_chan_in_use(
struct sig_pri_chan *pvt)
1220 return !sig_pri_is_chan_in_use(pvt)
1221#if defined(HAVE_PRI_SERVICE_MESSAGES)
1223 && !pvt->service_status
1239static void sig_pri_lock_owner(
struct sig_pri_span *pri,
int chanpos)
1252 sig_pri_unlock_private(pri->
pvts[chanpos]);
1254 sig_pri_lock_private(pri->
pvts[chanpos]);
1272 sig_pri_lock_owner(pri, chanpos);
1290static void sig_pri_queue_hold(
struct sig_pri_span *pri,
int chanpos)
1292 sig_pri_lock_owner(pri, chanpos);
1310static void sig_pri_queue_unhold(
struct sig_pri_span *pri,
int chanpos)
1312 sig_pri_lock_owner(pri, chanpos);
1331static void pri_queue_control(
struct sig_pri_span *pri,
int chanpos,
int subclass)
1340 pri_queue_frame(pri, chanpos, &f);
1357static void sig_pri_queue_hangup(
struct sig_pri_span *pri,
int chanpos)
1365 sig_pri_lock_owner(pri, chanpos);
1372 sig_pri_unlock_private(pri->
pvts[chanpos]);
1377 sig_pri_lock_private(pri->
pvts[chanpos]);
1396static void pri_queue_pvt_cause_data(
struct sig_pri_span *pri,
int chanpos,
const char *cause,
int ast_cause)
1401 sig_pri_lock_owner(pri, chanpos);
1404 int datalen =
sizeof(*cause_code) + strlen(cause);
1406 memset(cause_code, 0, datalen);
1429static int pri_find_principle_by_call(
struct sig_pri_span *pri, q931_call *
call)
1437 for (idx = 0; idx < pri->
numchans; ++idx) {
1476static void sig_pri_kill_call(
struct sig_pri_span *pri, q931_call *
call,
int cause)
1480 chanpos = pri_find_principle_by_call(pri,
call);
1482 pri_hangup(pri->
pri,
call, cause);
1485 sig_pri_lock_private(pri->
pvts[chanpos]);
1487 pri_hangup(pri->
pri,
call, cause);
1489 sig_pri_unlock_private(pri->
pvts[chanpos]);
1490 sig_pri_span_devstate_changed(pri);
1495 sig_pri_unlock_private(pri->
pvts[chanpos]);
1511static int pri_find_principle(
struct sig_pri_span *pri,
int channel, q931_call *
call)
1523 prioffset = PRI_CHANNEL(channel);
1524 if (!prioffset || (channel & PRI_HELD_CALL)) {
1526 return pri_find_principle_by_call(pri,
call);
1529 span = PRI_SPAN(channel);
1530 if (!(channel & PRI_EXPLICIT)) {
1533 index = pri_active_dchan_index(pri);
1541 for (x = 0; x < pri->
numchans; x++) {
1567static int pri_fixup_principle(
struct sig_pri_span *pri,
int principle, q931_call *
call)
1571 if (principle < 0 || pri->numchans <= principle) {
1585 for (x = 0; x < pri->
numchans; x++) {
1594 new_chan =
pri->
pvts[principle];
1598 sig_pri_lock_private(old_chan);
1599 sig_pri_lock_owner(
pri, x);
1600 sig_pri_lock_private(new_chan);
1602 ast_verb(3,
"Moving call (%s) from channel %d to %d.\n",
1607 "Can't move call (%s) from channel %d to %d. It is already in use.\n",
1610 sig_pri_unlock_private(new_chan);
1611 if (old_chan->
owner) {
1614 sig_pri_unlock_private(old_chan);
1618 sig_pri_fixup_chans(old_chan, new_chan);
1628#if defined(HAVE_PRI_AOC_EVENTS)
1629 new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid;
1630 new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
1631 new_chan->holding_aoce = old_chan->holding_aoce;
1639#if defined(HAVE_PRI_CALL_WAITING)
1640 new_chan->is_call_waiting = old_chan->is_call_waiting;
1642#if defined(HAVE_PRI_SETUP_ACK_INBAND)
1643 new_chan->no_dialed_digits = old_chan->no_dialed_digits;
1646#if defined(HAVE_PRI_AOC_EVENTS)
1647 old_chan->aoc_s_request_invoke_id_valid = 0;
1648 old_chan->waiting_for_aoce = 0;
1649 old_chan->holding_aoce = 0;
1657#if defined(HAVE_PRI_CALL_WAITING)
1658 old_chan->is_call_waiting = 0;
1660#if defined(HAVE_PRI_SETUP_ACK_INBAND)
1661 old_chan->no_dialed_digits = 0;
1667#if defined(HAVE_PRI_REVERSE_CHARGE)
1668 new_chan->reverse_charging_indication = old_chan->reverse_charging_indication;
1670#if defined(HAVE_PRI_SETUP_KEYPAD)
1671 strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
1677#if defined(HAVE_PRI_TRANSFER)
1678 new_chan->xfer_data = old_chan->xfer_data;
1679 old_chan->xfer_data =
NULL;
1682#if defined(HAVE_PRI_AOC_EVENTS)
1683 new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
1684 new_chan->aoc_e = old_chan->aoc_e;
1711 sig_pri_open_media(new_chan);
1714 if (new_chan->
owner) {
1715 sig_pri_ami_channel_event(new_chan);
1718 sig_pri_unlock_private(old_chan);
1719 if (new_chan->
owner) {
1722 sig_pri_unlock_private(new_chan);
1726 ast_verb(3,
"Call specified, but not found.\n");
1756 sig_pri_kill_call(
pri,
call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
1759 chanpos = pri_fixup_principle(
pri, chanpos,
call);
1770 sig_pri_kill_call(
pri,
call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
1776static char * redirectingreason2str(
int redirectingreason)
1778 switch (redirectingreason) {
1786 return "UNCONDITIONAL";
1788 return "NOREDIRECT";
1792static char *dialplan2str(
int dialplan)
1794 if (dialplan == -1) {
1795 return(
"Dynamically set dialplan in ISDN");
1797 return (pri_plan2str(dialplan));
1810static void apply_plan_to_number(
char *
buf,
size_t size,
const struct sig_pri_span *
pri,
const char *
number,
int plan)
1813 case PRI_INTERNATIONAL_ISDN:
1816 case PRI_NATIONAL_ISDN:
1819 case PRI_LOCAL_ISDN:
1844static void apply_plan_to_existing_number(
char *
buf,
size_t size,
const struct sig_pri_span *
pri,
const char *
number,
int plan)
1866#if defined(HAVE_PRI_SERVICE_MESSAGES)
1876#if defined(HAVE_PRI_SERVICE_MESSAGES)
1880 "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n",
1882 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ?
"both ends" :
"far end" :
"near end");
1895 sig_pri_span_devstate_changed(
pri);
1899#if defined(HAVE_PRI_CALL_WAITING)
1941static int pri_find_empty_chan(
struct sig_pri_span *
pri,
int backwards)
1949 if (backwards && (x < 0))
1956 ast_debug(1,
"Found empty available channel %d/%d\n",
1968#if defined(HAVE_PRI_CALL_HOLD)
1989 ast_debug(1,
"Found empty available no B channel interface\n");
2004static void *do_idle_thread(
void *v_pvt)
2011 int timeout_ms = 30000;
2013 struct timeval start;
2064static void *pri_ss_thread(
void *data)
2095 sig_pri_dsp_reset_and_flush_digits(p);
2103 sig_pri_play_tone(p, -1);
2107 timeout = pri_matchdigittimeout;
2109 timeout = pri_gendigittimeout;
2112 ast_debug(1,
"waitfordigit returned < 0...\n");
2123 ast_verb(3,
"Going to extension s|1 because of empty extension received on overlap call\n");
2141 sig_pri_play_tone(p, -1);
2145 sig_pri_dsp_reset_and_flush_digits(p);
2146#if defined(JIRA_ASTERISK_15594)
2161 sig_pri_lock_private(p);
2163 pri_grab(p, p->
pri);
2167 pri_proceeding(p->
pri->
pri, p->
call, PVT_TO_CHANNEL(p), 0);
2170 sig_pri_unlock_private(p);
2174 sig_pri_set_echocanceller(p, 1);
2190 sig_pri_span_devstate_changed(p->
pri);
2199 if (!before_start_pri) {
2200 pri_find_dchan(pri);
2207 if (!before_start_pri)
2208 pri_restart(pri->
dchans[index]);
2222static void sig_pri_party_name_convert(
struct ast_party_name *ast_name,
const struct pri_party_name *pri_name)
2225 ast_name->
char_set = pri_to_ast_char_set(pri_name->char_set);
2226 ast_name->
presentation = pri_to_ast_presentation(pri_name->presentation);
2227 ast_name->
valid = 1;
2242static void sig_pri_party_number_convert(
struct ast_party_number *ast_number,
const struct pri_party_number *pri_number,
struct sig_pri_span *pri)
2246 apply_plan_to_existing_number(
number,
sizeof(
number), pri, pri_number->str,
2249 ast_number->
plan = pri_number->plan;
2250 ast_number->
presentation = pri_to_ast_presentation(pri_number->presentation);
2251 ast_number->
valid = 1;
2266static void sig_pri_party_id_convert(
struct ast_party_id *ast_id,
const struct pri_party_id *pri_id,
struct sig_pri_span *pri)
2268 if (pri_id->name.valid) {
2269 sig_pri_party_name_convert(&ast_id->
name, &pri_id->name);
2271 if (pri_id->number.valid) {
2272 sig_pri_party_number_convert(&ast_id->
number, &pri_id->number, pri);
2274#if defined(HAVE_PRI_SUBADDR)
2275 if (pri_id->subaddress.valid) {
2276 sig_pri_set_subaddress(&ast_id->
subaddress, &pri_id->subaddress);
2295 const struct pri_party_redirecting *pri_redirecting,
2301 sig_pri_party_id_convert(&ast_redirecting->
orig, &pri_redirecting->orig_called, pri);
2302 sig_pri_party_id_convert(&ast_redirecting->
from, &pri_redirecting->from, pri);
2303 sig_pri_party_id_convert(&ast_redirecting->
to, &pri_redirecting->to, pri);
2304 ast_redirecting->
count = pri_redirecting->count;
2305 ast_redirecting->
reason.
code = pri_to_ast_reason(pri_redirecting->reason);
2306 ast_redirecting->
orig_reason.
code = pri_to_ast_reason(pri_redirecting->orig_reason);
2320static int sig_pri_msn_match(
const char *msn_patterns,
const char *
exten)
2329 pattern = strtok_r(msn_list,
",", &list_tail);
2336 pattern = strtok_r(
NULL,
",", &list_tail);
2342#if defined(HAVE_PRI_MCID)
2345 const char *num_txt, *pres_txt;
2370 const char *name_txt, *pres_txt, *
charset;
2374 "%sNameValid: 0\r\n"
2391static void party_subaddress_json_to_ami(
struct ast_str **msg,
const char *
prefix,
struct ast_json *subaddress)
2393 const char *subaddress_txt, *type_txt;
2437 party_subaddress_json_to_ami(msg,
prefix, subaddress);
2448 if (!channel_string) {
2496static void sig_pri_mcid_event(
struct sig_pri_span *pri,
const struct pri_subcmd_mcid_req *mcid,
struct ast_channel *owner)
2503 sig_pri_party_id_convert(&connected_party, &mcid->answerer, pri);
2518 sig_pri_party_id_convert(&caller_party, &mcid->originator, pri);
2519 send_mcid(owner, &caller_party, &connected_party);
2526#if defined(HAVE_PRI_TRANSFER)
2527struct xfer_rsp_data {
2538#if defined(HAVE_PRI_TRANSFER)
2549static void sig_pri_transfer_rsp(
struct xfer_rsp_data *rsp,
int is_successful)
2551 if (rsp->responded) {
2556 pri_transfer_rsp(rsp->pri->pri, rsp->call, rsp->invoke_id, is_successful);
2560#if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
2578static 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)
2580 struct attempt_xfer_call {
2588 struct attempt_xfer_call *call_1;
2589 struct attempt_xfer_call *call_2;
2590 struct attempt_xfer_call c1;
2591 struct attempt_xfer_call c2;
2593 c1.pri = call_1_pri;
2594 c1.held = call_1_held;
2597 c2.pri = call_2_pri;
2598 c2.held = call_2_held;
2601 call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri);
2602 call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri);
2603 if (call_1->chanpos < 0 || call_2->chanpos < 0) {
2605#if defined(HAVE_PRI_TRANSFER)
2608 sig_pri_transfer_rsp(xfer_data, 0);
2615 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2616 sig_pri_lock_owner(pri, call_1->chanpos);
2617 call_1->ast = pri->
pvts[call_1->chanpos]->
owner;
2622 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2625 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2626 sig_pri_lock_owner(pri, call_2->chanpos);
2627 call_2->ast = pri->
pvts[call_2->chanpos]->
owner;
2632 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2634 if (!call_1->ast || !call_2->ast) {
2642#if defined(HAVE_PRI_TRANSFER)
2645 sig_pri_transfer_rsp(xfer_data, 0);
2651 ast_verb(3,
"TRANSFERRING %s to %s\n",
2654#if defined(HAVE_PRI_TRANSFER)
2661 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2662 pri->
pvts[call_1->chanpos]->xfer_data = xfer_data;
2663 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2664 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2665 pri->
pvts[call_2->chanpos]->xfer_data = xfer_data;
2666 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2675#if defined(HAVE_PRI_TRANSFER)
2684 rsp_chanpos = pri_find_principle_by_call(pri, call_1->pri);
2685 if (0 <= rsp_chanpos) {
2686 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2687 pri->
pvts[rsp_chanpos]->xfer_data =
NULL;
2688 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2690 rsp_chanpos = pri_find_principle_by_call(pri, call_2->pri);
2691 if (0 <= rsp_chanpos) {
2692 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2693 pri->
pvts[rsp_chanpos]->xfer_data =
NULL;
2694 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2698 sig_pri_transfer_rsp(xfer_data,
retval ? 0 : 1);
2707#if defined(HAVE_PRI_CCSS)
2719static int sig_pri_cc_agent_cmp_cc_id(
void *obj,
void *arg,
int flags)
2722 struct sig_pri_cc_agent_prv *agent_prv_1 = agent_1->
private_data;
2723 struct sig_pri_cc_agent_prv *agent_prv_2 = arg;
2725 return (agent_prv_1 && agent_prv_1->pri == agent_prv_2->pri
2730#if defined(HAVE_PRI_CCSS)
2749 struct sig_pri_cc_agent_prv finder = {
2755 sig_pri_cc_type_name);
2759#if defined(HAVE_PRI_CCSS)
2771static int sig_pri_cc_monitor_cmp_cc_id(
void *obj,
void *arg,
int flags)
2773 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
2774 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
2776 return (monitor_1->pri == monitor_2->pri
2781#if defined(HAVE_PRI_CCSS)
2798static struct sig_pri_cc_monitor_instance *sig_pri_find_cc_monitor_by_cc_id(
struct sig_pri_span *pri,
long cc_id)
2800 struct sig_pri_cc_monitor_instance finder = {
2805 return ao2_callback(sig_pri_cc_monitors, 0, sig_pri_cc_monitor_cmp_cc_id, &finder);
2809#if defined(HAVE_PRI_CCSS)
2817static void sig_pri_cc_monitor_instance_destroy(
void *data)
2819 struct sig_pri_cc_monitor_instance *monitor_instance = data;
2821 if (monitor_instance->cc_id != -1) {
2823 pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id);
2830#if defined(HAVE_PRI_CCSS)
2849static 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)
2851 struct sig_pri_cc_monitor_instance *monitor_instance;
2857 monitor_instance =
ao2_alloc(
sizeof(*monitor_instance) + strlen(device_name),
2858 sig_pri_cc_monitor_instance_destroy);
2859 if (!monitor_instance) {
2863 monitor_instance->cc_id = cc_id;
2864 monitor_instance->pri = pri;
2865 monitor_instance->core_id = core_id;
2866 strcpy(monitor_instance->name, device_name);
2870 ao2_link(sig_pri_cc_monitors, monitor_instance);
2871 return monitor_instance;
2875#if defined(HAVE_PRI_CCSS)
2897 struct sig_pri_cc_monitor_instance *monitor;
2904 pvt = pri->
pvts[chanpos];
2907 if (core_id == -1) {
2918 switch (monitor_policy) {
2929 sig_pri_make_cc_dialstring(pvt, dialstring,
sizeof(dialstring));
2930 monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
2937 monitor->cc_id = -1;
2968#if defined(HAVE_PRI_CCSS)
2980 sig_pri_lock_owner(pri, chanpos);
2997#if defined(HAVE_PRI_CCSS)
3008 switch (monitor_policy) {
3049#if defined(HAVE_PRI_CCSS)
3059static void sig_pri_cc_link_canceled(
struct sig_pri_span *pri,
long cc_id,
int is_agent)
3064 agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
3069 sig_pri_cc_type_name);
3072 struct sig_pri_cc_monitor_instance *monitor;
3074 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
3078 monitor->cc_id = -1;
3080 "%s monitor got canceled by link", sig_pri_cc_type_name);
3086#if defined(HAVE_PRI_AOC_EVENTS)
3096static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri(
enum PRI_AOC_CHARGED_ITEM
value)
3100 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3102 return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
3104 return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
3106 return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
3108 return PRI_AOC_CHARGED_ITEM_CALL_SETUP;
3110 return PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
3112 return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
3114 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3118#if defined(HAVE_PRI_AOC_EVENTS)
3131 case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE:
3133 case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
3135 case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
3137 case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
3139 case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
3141 case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
3143 case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
3150#if defined(HAVE_PRI_AOC_EVENTS)
3162 return PRI_AOC_MULTIPLIER_THOUSANDTH;
3164 return PRI_AOC_MULTIPLIER_HUNDREDTH;
3166 return PRI_AOC_MULTIPLIER_TENTH;
3168 return PRI_AOC_MULTIPLIER_ONE;
3170 return PRI_AOC_MULTIPLIER_TEN;
3172 return PRI_AOC_MULTIPLIER_HUNDRED;
3174 return PRI_AOC_MULTIPLIER_THOUSAND;
3176 return PRI_AOC_MULTIPLIER_ONE;
3181#if defined(HAVE_PRI_AOC_EVENTS)
3189static int sig_pri_aoc_multiplier_from_pri(
const int mult)
3192 case PRI_AOC_MULTIPLIER_THOUSANDTH:
3194 case PRI_AOC_MULTIPLIER_HUNDREDTH:
3196 case PRI_AOC_MULTIPLIER_TENTH:
3198 case PRI_AOC_MULTIPLIER_ONE:
3200 case PRI_AOC_MULTIPLIER_TEN:
3202 case PRI_AOC_MULTIPLIER_HUNDRED:
3204 case PRI_AOC_MULTIPLIER_THOUSAND:
3212#if defined(HAVE_PRI_AOC_EVENTS)
3227 return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
3229 return PRI_AOC_TIME_SCALE_TENTH_SECOND;
3231 return PRI_AOC_TIME_SCALE_SECOND;
3233 return PRI_AOC_TIME_SCALE_TEN_SECOND;
3235 return PRI_AOC_TIME_SCALE_MINUTE;
3237 return PRI_AOC_TIME_SCALE_HOUR;
3239 return PRI_AOC_TIME_SCALE_DAY;
3244#if defined(HAVE_PRI_AOC_EVENTS)
3258 case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND:
3260 case PRI_AOC_TIME_SCALE_TENTH_SECOND:
3262 case PRI_AOC_TIME_SCALE_SECOND:
3264 case PRI_AOC_TIME_SCALE_TEN_SECOND:
3266 case PRI_AOC_TIME_SCALE_MINUTE:
3268 case PRI_AOC_TIME_SCALE_HOUR:
3270 case PRI_AOC_TIME_SCALE_DAY:
3277#if defined(HAVE_PRI_AOC_EVENTS)
3291static void sig_pri_aoc_s_from_pri(
const struct pri_subcmd_aoc_s *aoc_s,
struct ast_channel *owner,
int passthrough)
3295 size_t encoded_size = 0;
3298 if (!owner || !aoc_s) {
3306 for (idx = 0; idx < aoc_s->num_items; ++idx) {
3309 charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable);
3314 switch (aoc_s->item[idx].rate_type) {
3315 case PRI_AOC_RATE_TYPE_DURATION:
3318 aoc_s->item[idx].rate.duration.amount.cost,
3319 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier),
3320 aoc_s->item[idx].rate.duration.currency,
3321 aoc_s->item[idx].rate.duration.time.length,
3322 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale),
3323 aoc_s->item[idx].rate.duration.granularity.length,
3324 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale),
3325 aoc_s->item[idx].rate.duration.charging_type);
3327 case PRI_AOC_RATE_TYPE_FLAT:
3330 aoc_s->item[idx].rate.flat.amount.cost,
3331 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier),
3332 aoc_s->item[idx].rate.flat.currency);
3334 case PRI_AOC_RATE_TYPE_VOLUME:
3337 aoc_s->item[idx].rate.volume.unit,
3338 aoc_s->item[idx].rate.volume.amount.cost,
3339 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier),
3340 aoc_s->item[idx].rate.volume.currency);
3342 case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
3345 aoc_s->item[idx].rate.special);
3347 case PRI_AOC_RATE_TYPE_FREE:
3350 case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
3359 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3370#if defined(HAVE_PRI_AOC_EVENTS)
3382static void sig_pri_aoc_request_from_pri(
const struct pri_subcmd_aoc_request *aoc_request,
struct sig_pri_chan *pvt, q931_call *
call)
3390 request = aoc_request->charging_request;
3392 if (
request & PRI_AOC_REQUEST_S) {
3396 pvt->aoc_s_request_invoke_id = aoc_request->invoke_id;
3397 pvt->aoc_s_request_invoke_id_valid = 1;
3400 pri_aoc_s_request_response_send(pvt->
pri->
pri,
3402 aoc_request->invoke_id,
3407 if (
request & PRI_AOC_REQUEST_D) {
3409 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3411 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3412 aoc_request->invoke_id);
3414 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3416 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3417 aoc_request->invoke_id);
3421 if (
request & PRI_AOC_REQUEST_E) {
3423 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3425 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3426 aoc_request->invoke_id);
3428 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3430 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3431 aoc_request->invoke_id);
3437#if defined(HAVE_PRI_AOC_EVENTS)
3451static void sig_pri_aoc_d_from_pri(
const struct pri_subcmd_aoc_d *aoc_d,
struct ast_channel *owner,
int passthrough)
3455 size_t encoded_size = 0;
3458 if (!owner || !aoc_d) {
3462 switch (aoc_d->charge) {
3463 case PRI_AOC_DE_CHARGE_CURRENCY:
3466 case PRI_AOC_DE_CHARGE_UNITS:
3469 case PRI_AOC_DE_CHARGE_FREE:
3481 switch (aoc_d->billing_accumulation) {
3483 ast_debug(1,
"AOC-D billing accumulation has unknown value: %d\n",
3484 aoc_d->billing_accumulation);
3494 switch (aoc_d->billing_id) {
3495 case PRI_AOC_D_BILLING_ID_NORMAL:
3498 case PRI_AOC_D_BILLING_ID_REVERSE:
3501 case PRI_AOC_D_BILLING_ID_CREDIT_CARD:
3504 case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE:
3510 switch (aoc_d->charge) {
3511 case PRI_AOC_DE_CHARGE_CURRENCY:
3513 aoc_d->recorded.money.amount.cost,
3514 sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier),
3515 aoc_d->recorded.money.currency);
3517 case PRI_AOC_DE_CHARGE_UNITS:
3520 for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) {
3523 (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0),
3524 aoc_d->recorded.unit.item[i].number,
3525 (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0),
3526 aoc_d->recorded.unit.item[i].type);
3532 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3543#if defined(HAVE_PRI_AOC_EVENTS)
3558static void sig_pri_aoc_e_from_pri(
const struct pri_subcmd_aoc_e *aoc_e,
struct ast_channel *owner,
int passthrough)
3562 size_t encoded_size = 0;
3569 switch (aoc_e->charge) {
3570 case PRI_AOC_DE_CHARGE_CURRENCY:
3573 case PRI_AOC_DE_CHARGE_UNITS:
3576 case PRI_AOC_DE_CHARGE_FREE:
3588 switch (aoc_e->associated.charging_type) {
3589 case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER:
3590 if (!aoc_e->associated.charge.number.valid) {
3595 case PRI_AOC_E_CHARGING_ASSOCIATION_ID:
3602 switch (aoc_e->billing_id) {
3603 case PRI_AOC_E_BILLING_ID_NORMAL:
3606 case PRI_AOC_E_BILLING_ID_REVERSE:
3609 case PRI_AOC_E_BILLING_ID_CREDIT_CARD:
3612 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL:
3615 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY:
3618 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY:
3621 case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION:
3624 case PRI_AOC_E_BILLING_ID_CALL_TRANSFER:
3627 case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE:
3633 switch (aoc_e->charge) {
3634 case PRI_AOC_DE_CHARGE_CURRENCY:
3636 aoc_e->recorded.money.amount.cost,
3637 sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier),
3638 aoc_e->recorded.money.currency);
3640 case PRI_AOC_DE_CHARGE_UNITS:
3643 for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) {
3646 (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0),
3647 aoc_e->recorded.unit.item[i].number,
3648 (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0),
3649 aoc_e->recorded.unit.item[i].type);
3654 if (passthrough && owner && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3665#if defined(HAVE_PRI_AOC_EVENTS)
3677 struct pri_subcmd_aoc_s aoc_s = { 0, };
3686 aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(
entry->charged_item);
3688 switch (
entry->rate_type) {
3690 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
3691 aoc_s.item[idx].rate.duration.amount.cost =
entry->rate.duration.amount;
3692 aoc_s.item[idx].rate.duration.amount.multiplier =
3693 sig_pri_aoc_multiplier_from_ast(
entry->rate.duration.multiplier);
3694 aoc_s.item[idx].rate.duration.time.length =
entry->rate.duration.time;
3695 aoc_s.item[idx].rate.duration.time.scale =
3696 sig_pri_aoc_scale_to_pri(
entry->rate.duration.time_scale);
3697 aoc_s.item[idx].rate.duration.granularity.length =
entry->rate.duration.granularity_time;
3698 aoc_s.item[idx].rate.duration.granularity.scale =
3699 sig_pri_aoc_scale_to_pri(
entry->rate.duration.granularity_time_scale);
3700 aoc_s.item[idx].rate.duration.charging_type =
entry->rate.duration.charging_type;
3704 entry->rate.duration.currency_name,
3705 sizeof(aoc_s.item[idx].rate.duration.currency));
3709 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
3710 aoc_s.item[idx].rate.flat.amount.cost =
entry->rate.flat.amount;
3711 aoc_s.item[idx].rate.flat.amount.multiplier =
3712 sig_pri_aoc_multiplier_from_ast(
entry->rate.flat.multiplier);
3716 entry->rate.flat.currency_name,
3717 sizeof(aoc_s.item[idx].rate.flat.currency));
3721 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
3722 aoc_s.item[idx].rate.volume.unit =
entry->rate.volume.volume_unit;
3723 aoc_s.item[idx].rate.volume.amount.cost =
entry->rate.volume.amount;
3724 aoc_s.item[idx].rate.volume.amount.multiplier =
3725 sig_pri_aoc_multiplier_from_ast(
entry->rate.volume.multiplier);
3729 entry->rate.volume.currency_name,
3730 sizeof(aoc_s.item[idx].rate.volume.currency));
3734 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
3735 aoc_s.item[idx].rate.special =
entry->rate.special_code;
3738 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
3741 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
3745 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
3749 aoc_s.num_items = idx;
3753 if (pvt->aoc_s_request_invoke_id_valid) {
3754 pri_aoc_s_request_response_send(pvt->
pri->
pri, pvt->
call, pvt->aoc_s_request_invoke_id, &aoc_s);
3755 pvt->aoc_s_request_invoke_id_valid = 0;
3757 pri_aoc_s_send(pvt->
pri->
pri, pvt->
call, &aoc_s);
3762#if defined(HAVE_PRI_AOC_EVENTS)
3774 struct pri_subcmd_aoc_d aoc_d = { 0, };
3780 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL;
3783 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE;
3786 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
3790 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
3796 aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
3801 aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
3805 ast_copy_string(aoc_d.recorded.money.currency, currency_name,
sizeof(aoc_d.recorded.money.currency));
3813 aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
3816 if (
entry->valid_amount) {
3817 aoc_d.recorded.unit.item[i].number =
entry->amount;
3819 aoc_d.recorded.unit.item[i].number = -1;
3821 if (
entry->valid_type) {
3822 aoc_d.recorded.unit.item[i].type =
entry->type;
3824 aoc_d.recorded.unit.item[i].type = -1;
3826 aoc_d.recorded.unit.num_items++;
3835 aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3839 pri_aoc_d_send(pvt->
pri->
pri, pvt->
call, &aoc_d);
3843#if defined(HAVE_PRI_AOC_EVENTS)
3855 struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
3858 memset(aoc_e, 0,
sizeof(*aoc_e));
3859 pvt->holding_aoce = 1;
3863 aoc_e->associated.charge.number.valid = 1;
3866 sizeof(aoc_e->associated.charge.number.str));
3868 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
3871 aoc_e->associated.charge.id = ca->
charge.
id;
3872 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
3881 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL;
3884 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE;
3887 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
3890 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
3893 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
3896 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
3899 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
3902 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
3906 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
3912 aoc_e->charge = PRI_AOC_DE_CHARGE_FREE;
3917 aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY;
3921 ast_copy_string(aoc_e->recorded.money.currency, currency_name,
sizeof(aoc_e->recorded.money.currency));
3929 aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS;
3932 if (
entry->valid_amount) {
3933 aoc_e->recorded.unit.item[i].number =
entry->amount;
3935 aoc_e->recorded.unit.item[i].number = -1;
3937 if (
entry->valid_type) {
3938 aoc_e->recorded.unit.item[i].type =
entry->type;
3940 aoc_e->recorded.unit.item[i].type = -1;
3942 aoc_e->recorded.unit.num_items++;
3949 aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3955#if defined(HAVE_PRI_AOC_EVENTS)
3968static void sig_pri_send_aoce_termination_request(
struct sig_pri_span *pri,
int chanpos,
unsigned int ms)
3973 size_t encoded_size;
3974 struct timeval whentohangup = { 0, };
3976 sig_pri_lock_owner(pri, chanpos);
3977 pvt = pri->
pvts[chanpos];
3984 goto cleanup_termination_request;
3991 goto cleanup_termination_request;
3995 whentohangup.tv_usec = (ms % 1000) * 1000;
3996 whentohangup.tv_sec = ms / 1000;
4000 goto cleanup_termination_request;
4003 pvt->waiting_for_aoce = 1;
4007cleanup_termination_request:
4023static int sig_pri_is_cis_call(
int channel)
4025 return channel != -1 && (channel & PRI_CIS_CALL);
4043static void sig_pri_handle_cis_subcmds(
struct sig_pri_span *pri,
int event_id,
4044 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4047#if defined(HAVE_PRI_CCSS)
4049 struct sig_pri_cc_agent_prv *agent_prv;
4050 struct sig_pri_cc_monitor_instance *monitor;
4056 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4057 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4059 switch (subcmd->cmd) {
4060#if defined(STATUS_REQUEST_PLACE_HOLDER)
4061 case PRI_SUBCMD_STATUS_REQ:
4062 case PRI_SUBCMD_STATUS_REQ_RSP:
4066#if defined(HAVE_PRI_CCSS)
4067 case PRI_SUBCMD_CC_REQ:
4068 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id);
4070 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4074 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4076 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4079 sig_pri_cc_type_name);
4084 agent_prv->cc_request_response_pending = 1;
4086 "%s caller accepted CC offer.", sig_pri_cc_type_name)) {
4087 agent_prv->cc_request_response_pending = 0;
4088 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4090 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4093 sig_pri_cc_type_name);
4098#if defined(HAVE_PRI_CCSS)
4099 case PRI_SUBCMD_CC_REQ_RSP:
4100 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4101 subcmd->u.cc_request_rsp.cc_id);
4103 pri_cc_cancel(pri->
pri, subcmd->u.cc_request_rsp.cc_id);
4106 switch (subcmd->u.cc_request_rsp.status) {
4109 "%s far end accepted CC request", sig_pri_cc_type_name);
4112 ast_verb(2,
"core_id:%d %s CC request timeout\n", monitor->core_id,
4113 sig_pri_cc_type_name);
4115 "%s CC request timeout", sig_pri_cc_type_name);
4118 ast_verb(2,
"core_id:%d %s CC request error: %s\n", monitor->core_id,
4119 sig_pri_cc_type_name,
4120 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
4122 "%s CC request error", sig_pri_cc_type_name);
4125 ast_verb(2,
"core_id:%d %s CC request reject: %s\n", monitor->core_id,
4126 sig_pri_cc_type_name,
4127 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
4129 "%s CC request reject", sig_pri_cc_type_name);
4132 ast_verb(2,
"core_id:%d %s CC request unknown status %d\n",
4133 monitor->core_id, sig_pri_cc_type_name,
4134 subcmd->u.cc_request_rsp.status);
4136 "%s CC request unknown status", sig_pri_cc_type_name);
4142#if defined(HAVE_PRI_CCSS)
4143 case PRI_SUBCMD_CC_REMOTE_USER_FREE:
4144 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4145 subcmd->u.cc_remote_user_free.cc_id);
4147 pri_cc_cancel(pri->
pri, subcmd->u.cc_remote_user_free.cc_id);
4151 "%s callee has become available", sig_pri_cc_type_name);
4155#if defined(HAVE_PRI_CCSS)
4156 case PRI_SUBCMD_CC_B_FREE:
4157 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4158 subcmd->u.cc_b_free.cc_id);
4160 pri_cc_cancel(pri->
pri, subcmd->u.cc_b_free.cc_id);
4167#if defined(HAVE_PRI_CCSS)
4168 case PRI_SUBCMD_CC_STATUS_REQ:
4169 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4170 subcmd->u.cc_status_req.cc_id);
4172 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req.cc_id);
4179#if defined(HAVE_PRI_CCSS)
4180 case PRI_SUBCMD_CC_STATUS_REQ_RSP:
4181 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
4183 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req_rsp.cc_id);
4192#if defined(HAVE_PRI_CCSS)
4193 case PRI_SUBCMD_CC_STATUS:
4194 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
4196 pri_cc_cancel(pri->
pri, subcmd->u.cc_status.cc_id);
4199 if (subcmd->u.cc_status.status) {
4201 sig_pri_cc_type_name);
4204 "%s agent caller is available", sig_pri_cc_type_name);
4209#if defined(HAVE_PRI_CCSS)
4210 case PRI_SUBCMD_CC_CANCEL:
4211 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4212 subcmd->u.cc_cancel.is_agent);
4215#if defined(HAVE_PRI_CCSS)
4216 case PRI_SUBCMD_CC_STOP_ALERTING:
4217 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4218 subcmd->u.cc_stop_alerting.cc_id);
4220 pri_cc_cancel(pri->
pri, subcmd->u.cc_stop_alerting.cc_id);
4227#if defined(HAVE_PRI_AOC_EVENTS)
4228 case PRI_SUBCMD_AOC_E:
4230 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e,
NULL, 0);
4234 ast_debug(2,
"Span %d: Unknown CIS subcommand(%d) in %s event.\n", pri->
span,
4235 subcmd->cmd, pri_event2str(event_id));
4258static void sig_pri_handle_subcmds(
struct sig_pri_span *pri,
int chanpos,
int event_id,
4259 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4264#if defined(HAVE_PRI_TRANSFER)
4265 struct xfer_rsp_data xfer_rsp;
4271 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4272 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4274 switch (subcmd->cmd) {
4275 case PRI_SUBCMD_CONNECTED_LINE:
4276 sig_pri_lock_owner(pri, chanpos);
4280 int caller_id_update;
4284 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id,
4288 caller_id_update = 0;
4289 if (ast_connected.id.name.str) {
4292 ast_connected.id.name.str,
sizeof(pri->
pvts[chanpos]->
cid_name));
4293 caller_id_update = 1;
4295 if (ast_connected.id.number.str) {
4298 ast_connected.id.number.str,
sizeof(pri->
pvts[chanpos]->
cid_num));
4299 pri->
pvts[chanpos]->
cid_ton = ast_connected.id.number.plan;
4300 caller_id_update = 1;
4305#if defined(HAVE_PRI_SUBADDR)
4306 if (ast_connected.id.subaddress.str) {
4308 ast_connected.id.subaddress.str,
4310 caller_id_update = 1;
4313 if (caller_id_update) {
4318 sig_pri_set_caller_id(pri->
pvts[chanpos]);
4321 ast_caller.id = ast_connected.id;
4322 ast_caller.ani = ast_connected.id;
4326 if (event_id != PRI_EVENT_RING) {
4337 case PRI_SUBCMD_REDIRECTING:
4338 sig_pri_lock_owner(pri, chanpos);
4341 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
4347 if (event_id != PRI_EVENT_RING) {
4362#if defined(HAVE_PRI_CALL_REROUTING)
4363 case PRI_SUBCMD_REROUTING:
4364 sig_pri_lock_owner(pri, chanpos);
4367 struct pri_party_redirecting pri_deflection;
4371 "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
4378 "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
4380 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4381 PRI_REROUTING_RSP_INVALID_NUMBER);
4386 ast_verb(3,
"Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
4395 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4396 PRI_REROUTING_RSP_OK_CLEAR);
4398 pri_deflection = subcmd->u.rerouting.deflection;
4401 switch (subcmd->u.rerouting.subscription_option) {
4405 pri_deflection.to.number.presentation =
4406 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
4407 pri_deflection.to.number.plan =
4408 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
4409 pri_deflection.to.number.str[0] =
'\0';
4417 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
4426 ast_channel_call_forward_set(owner, subcmd->u.rerouting.deflection.to.number.str);
4435#if defined(HAVE_PRI_CCSS)
4436 case PRI_SUBCMD_CC_AVAILABLE:
4437 sig_pri_lock_owner(pri, chanpos);
4443 case PRI_EVENT_RINGING:
4446 case PRI_EVENT_HANGUP_REQ:
4455 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id,
4457 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4462 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4466#if defined(HAVE_PRI_CCSS)
4467 case PRI_SUBCMD_CC_CALL:
4468 sig_pri_lock_owner(pri, chanpos);
4473 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
4478 "%s caller is attempting recall", sig_pri_cc_type_name);
4486#if defined(HAVE_PRI_CCSS)
4487 case PRI_SUBCMD_CC_CANCEL:
4488 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4489 subcmd->u.cc_cancel.is_agent);
4492#if defined(HAVE_PRI_TRANSFER)
4493 case PRI_SUBCMD_TRANSFER_CALL:
4497 "Call transfer subcommand without call to send response!\n");
4501 sig_pri_unlock_private(pri->
pvts[chanpos]);
4503 xfer_rsp.call = call_rsp;
4504 xfer_rsp.invoke_id = subcmd->u.
transfer.invoke_id;
4505 xfer_rsp.responded = 0;
4506 sig_pri_attempt_transfer(pri,
4507 subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held,
4508 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held,
4510 sig_pri_lock_private(pri->
pvts[chanpos]);
4513#if defined(HAVE_PRI_AOC_EVENTS)
4514 case PRI_SUBCMD_AOC_S:
4515 sig_pri_lock_owner(pri, chanpos);
4518 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
4524#if defined(HAVE_PRI_AOC_EVENTS)
4525 case PRI_SUBCMD_AOC_D:
4526 sig_pri_lock_owner(pri, chanpos);
4530 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
4536#if defined(HAVE_PRI_AOC_EVENTS)
4537 case PRI_SUBCMD_AOC_E:
4538 sig_pri_lock_owner(pri, chanpos);
4541 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
4548#if defined(HAVE_PRI_AOC_EVENTS)
4549 case PRI_SUBCMD_AOC_CHARGING_REQ:
4550 sig_pri_lock_owner(pri, chanpos);
4553 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->
pvts[chanpos],
4559#if defined(HAVE_PRI_AOC_EVENTS)
4560 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
4566 if (subcmd->u.aoc_request_response.valid_aoc_s) {
4567 sig_pri_lock_owner(pri, chanpos);
4570 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
4577#if defined(HAVE_PRI_MCID)
4578 case PRI_SUBCMD_MCID_REQ:
4579 sig_pri_lock_owner(pri, chanpos);
4581 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
4587#if defined(HAVE_PRI_MCID)
4588 case PRI_SUBCMD_MCID_RSP:
4592#if defined(HAVE_PRI_DISPLAY_TEXT)
4593 case PRI_SUBCMD_DISPLAY_TEXT:
4594 if (event_id != PRI_EVENT_RING) {
4599 sig_pri_lock_owner(pri, chanpos);
4605 memset(&f, 0,
sizeof(f));
4609 f.
data.
ptr = (
void *)&subcmd->u.display.text;
4610 f.
datalen = subcmd->u.display.length + 1;
4618 ast_debug(2,
"Span %d: Unknown call subcommand(%d) in %s event.\n",
4619 pri->
span, subcmd->cmd, pri_event2str(event_id));
4641 str =
"SIG_PRI_MOH_STATE_IDLE";
4644 str =
"SIG_PRI_MOH_STATE_NOTIFY";
4647 str =
"SIG_PRI_MOH_STATE_MOH";
4649#if defined(HAVE_PRI_CALL_HOLD)
4650 case SIG_PRI_MOH_STATE_HOLD_REQ:
4651 str =
"SIG_PRI_MOH_STATE_HOLD_REQ";
4653 case SIG_PRI_MOH_STATE_PEND_UNHOLD:
4654 str =
"SIG_PRI_MOH_STATE_PEND_UNHOLD";
4656 case SIG_PRI_MOH_STATE_HOLD:
4657 str =
"SIG_PRI_MOH_STATE_HOLD";
4659 case SIG_PRI_MOH_STATE_RETRIEVE_REQ:
4660 str =
"SIG_PRI_MOH_STATE_RETRIEVE_REQ";
4662 case SIG_PRI_MOH_STATE_PEND_HOLD:
4663 str =
"SIG_PRI_MOH_STATE_PEND_HOLD";
4665 case SIG_PRI_MOH_STATE_RETRIEVE_FAIL:
4666 str =
"SIG_PRI_MOH_STATE_RETRIEVE_FAIL";
4692 str =
"SIG_PRI_MOH_EVENT_RESET";
4695 str =
"SIG_PRI_MOH_EVENT_HOLD";
4698 str =
"SIG_PRI_MOH_EVENT_UNHOLD";
4700#if defined(HAVE_PRI_CALL_HOLD)
4701 case SIG_PRI_MOH_EVENT_HOLD_ACK:
4702 str =
"SIG_PRI_MOH_EVENT_HOLD_ACK";
4704 case SIG_PRI_MOH_EVENT_HOLD_REJ:
4705 str =
"SIG_PRI_MOH_EVENT_HOLD_REJ";
4707 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
4708 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_ACK";
4710 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
4711 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_REJ";
4713 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
4714 str =
"SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK";
4724#if defined(HAVE_PRI_CALL_HOLD)
4744 chanpos = pri_find_empty_chan(pvt->
pri, 1);
4747 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
4749 channel = PVT_TO_CHANNEL(pvt->
pri->
pvts[chanpos]);
4760 if (pri_retrieve(pvt->
pri->
pri, pvt->
call, channel)) {
4761 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
4763 return SIG_PRI_MOH_STATE_RETRIEVE_REQ;
4811#if defined(HAVE_PRI_CALL_HOLD)
4812 case SIG_PRI_MOH_SIGNALING_HOLD:
4818 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
4907#if defined(HAVE_PRI_CALL_HOLD)
4932 next_state = SIG_PRI_MOH_STATE_PEND_UNHOLD;
4934 case SIG_PRI_MOH_EVENT_HOLD_REJ:
4941 case SIG_PRI_MOH_EVENT_HOLD_ACK:
4942 next_state = SIG_PRI_MOH_STATE_HOLD;
4952#if defined(HAVE_PRI_CALL_HOLD)
4977 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
4979 case SIG_PRI_MOH_EVENT_HOLD_REJ:
4982 case SIG_PRI_MOH_EVENT_HOLD_ACK:
4983 next_state = sig_pri_moh_retrieve_call(pvt);
4993#if defined(HAVE_PRI_CALL_HOLD)
5018 next_state = sig_pri_moh_retrieve_call(pvt);
5020 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5035#if defined(HAVE_PRI_CALL_HOLD)
5060 next_state = SIG_PRI_MOH_STATE_PEND_HOLD;
5062 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
5063 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5066 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
5067 next_state = SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
5077#if defined(HAVE_PRI_CALL_HOLD)
5102 next_state = SIG_PRI_MOH_STATE_RETRIEVE_REQ;
5104 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
5105 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5127 case SIG_PRI_MOH_SIGNALING_HOLD:
5135 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
5140 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
5145 next_state = SIG_PRI_MOH_STATE_HOLD;
5155#if defined(HAVE_PRI_CALL_HOLD)
5180 next_state = SIG_PRI_MOH_STATE_HOLD;
5183 next_state = sig_pri_moh_retrieve_call(pvt);
5185 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5218#if defined(HAVE_PRI_CALL_HOLD)
5219 [SIG_PRI_MOH_STATE_HOLD_REQ] = sig_pri_moh_fsm_hold_req,
5220 [SIG_PRI_MOH_STATE_PEND_UNHOLD] = sig_pri_moh_fsm_pend_unhold,
5221 [SIG_PRI_MOH_STATE_HOLD] = sig_pri_moh_fsm_hold,
5222 [SIG_PRI_MOH_STATE_RETRIEVE_REQ] = sig_pri_moh_fsm_retrieve_req,
5223 [SIG_PRI_MOH_STATE_PEND_HOLD] = sig_pri_moh_fsm_pend_hold,
5224 [SIG_PRI_MOH_STATE_RETRIEVE_FAIL] = sig_pri_moh_fsm_retrieve_fail,
5245 const char *chan_name;
5250 chan_name =
"Unknown";
5253 ast_debug(2,
"Channel '%s' MOH-Event: %s in state %s\n", chan_name,
5254 sig_pri_moh_event_str(
event), sig_pri_moh_state_str(orig_state));
5256 || !sig_pri_moh_fsm[orig_state]) {
5259 sig_pri_moh_state_str(orig_state), orig_state);
5263 next_state = sig_pri_moh_fsm[orig_state](chan, pvt,
event);
5264 ast_debug(2,
"Channel '%s' MOH-Next-State: %s\n", chan_name,
5265 (orig_state == next_state) ?
"$" : sig_pri_moh_state_str(next_state));
5275static ast_callid func_pri_dchannel_new_callid(
void)
5305 sig_pri_lock_owner(
pri, chanpos);
5319#if defined(HAVE_PRI_CALL_HOLD)
5333static int sig_pri_handle_hold(
struct sig_pri_span *
pri, pri_event *ev)
5341 chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
5342 if (chanpos_old < 0) {
5353 sig_pri_lock_private(pri->
pvts[chanpos_old]);
5354 sig_pri_lock_owner(pri, chanpos_old);
5357 goto done_with_private;
5371 goto done_with_owner;
5373 chanpos_new = pri_find_empty_nobch(pri);
5374 if (chanpos_new < 0) {
5376 goto done_with_owner;
5378 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.subcmds, ev->hold.call);
5379 sig_pri_queue_hold(pri, chanpos_old);
5380 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
5381 if (chanpos_new < 0) {
5383 sig_pri_queue_unhold(pri, chanpos_old);
5389 sig_pri_unlock_private(pri->
pvts[chanpos_old]);
5391 if (chanpos_new < 0) {
5394 sig_pri_span_devstate_changed(pri);
5406#if defined(HAVE_PRI_CALL_HOLD)
5417static void sig_pri_handle_hold_ack(
struct sig_pri_span *pri, pri_event *ev)
5426 chanpos = pri_find_empty_nobch(pri);
5430 "Span %d: No hold channel available for held call that is on %d/%d\n",
5431 pri->
span, PRI_SPAN(ev->hold_ack.channel), PRI_CHANNEL(ev->hold_ack.channel));
5432 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5435 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_ack.call);
5438 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5442 sig_pri_lock_private(pri->
pvts[chanpos]);
5443 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5445 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_ack.subcmds, ev->hold_ack.call);
5446 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5447 SIG_PRI_MOH_EVENT_HOLD_ACK);
5448 sig_pri_unlock_private(pri->
pvts[chanpos]);
5449 sig_pri_span_devstate_changed(pri);
5457#if defined(HAVE_PRI_CALL_HOLD)
5468static void sig_pri_handle_hold_rej(
struct sig_pri_span *pri, pri_event *ev)
5473 chanpos = pri_find_principle(pri, ev->hold_rej.channel, ev->hold_rej.call);
5477 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5480 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_rej.call);
5483 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5487 ast_debug(1,
"Span %d: HOLD_REJECT cause: %d(%s)\n", pri->
span,
5488 ev->hold_rej.cause, pri_cause2str(ev->hold_rej.cause));
5490 sig_pri_lock_private(pri->
pvts[chanpos]);
5491 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5493 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_rej.subcmds, ev->hold_rej.call);
5494 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5495 SIG_PRI_MOH_EVENT_HOLD_REJ);
5496 sig_pri_unlock_private(pri->
pvts[chanpos]);
5504#if defined(HAVE_PRI_CALL_HOLD)
5515static void sig_pri_handle_retrieve(
struct sig_pri_span *pri, pri_event *ev)
5520 if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
5522 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5523 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5526 if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) {
5528 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5529 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5532 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) {
5533 chanpos = pri_find_empty_chan(pri, 1);
5535 chanpos = pri_find_principle(pri,
5536 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call);
5537 if (ev->retrieve.flexible
5543 chanpos = pri_find_empty_chan(pri, 1);
5547 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5548 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
5549 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5552 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call);
5555 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5556 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5559 sig_pri_lock_private(pri->
pvts[chanpos]);
5560 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5561 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.subcmds, ev->retrieve.call);
5562 sig_pri_queue_unhold(pri, chanpos);
5563 pri_retrieve_ack(pri->
pri, ev->retrieve.call,
5564 PVT_TO_CHANNEL(pri->
pvts[chanpos]));
5565 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5566 SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK);
5567 sig_pri_unlock_private(pri->
pvts[chanpos]);
5568 sig_pri_span_devstate_changed(pri);
5576#if defined(HAVE_PRI_CALL_HOLD)
5587static void sig_pri_handle_retrieve_ack(
struct sig_pri_span *pri, pri_event *ev)
5592 chanpos = pri_find_fixup_principle(pri, ev->retrieve_ack.channel,
5593 ev->retrieve_ack.call);
5598 sig_pri_lock_private(pri->
pvts[chanpos]);
5599 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5601 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_ack.subcmds,
5602 ev->retrieve_ack.call);
5603 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5604 SIG_PRI_MOH_EVENT_RETRIEVE_ACK);
5605 sig_pri_unlock_private(pri->
pvts[chanpos]);
5606 sig_pri_span_devstate_changed(pri);
5614#if defined(HAVE_PRI_CALL_HOLD)
5625static void sig_pri_handle_retrieve_rej(
struct sig_pri_span *pri, pri_event *ev)
5630 chanpos = pri_find_principle(pri, ev->retrieve_rej.channel, ev->retrieve_rej.call);
5634 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5637 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve_rej.call);
5640 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5644 ast_debug(1,
"Span %d: RETRIEVE_REJECT cause: %d(%s)\n", pri->
span,
5645 ev->retrieve_rej.cause, pri_cause2str(ev->retrieve_rej.cause));
5647 sig_pri_lock_private(pri->
pvts[chanpos]);
5648 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5650 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_rej.subcmds,
5651 ev->retrieve_rej.call);
5652 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5653 SIG_PRI_MOH_EVENT_RETRIEVE_REJ);
5654 sig_pri_unlock_private(pri->
pvts[chanpos]);
5673static void setup_incoming_channel(
struct sig_pri_span *pri,
int chanpos, pri_event *ev)
5677 char calledtonstr[10];
5679 sig_pri_lock_owner(pri, chanpos);
5687#if defined(HAVE_PRI_SUBADDR)
5688 if (ev->ring.calling.subaddress.valid) {
5691 &ev->ring.calling.subaddress);
5692 if (!ev->ring.calling.subaddress.type
5696 (
char *) ev->ring.calling.subaddress.data);
5699 if (ev->ring.called_subaddress.valid) {
5702 &ev->ring.called_subaddress);
5703 if (!ev->ring.called_subaddress.type
5707 (
char *) ev->ring.called_subaddress.data);
5715 if (ev->ring.ani2 >= 0) {
5717 snprintf(ani2str,
sizeof(ani2str),
"%d", ev->ring.ani2);
5721#ifdef SUPPORT_USERUSER
5727 snprintf(calledtonstr,
sizeof(calledtonstr),
"%d", ev->ring.calledplan);
5731 if (ev->ring.redirectingreason >= 0) {
5734 redirectingreason2str(ev->ring.redirectingreason));
5736#if defined(HAVE_PRI_REVERSE_CHARGE)
5737 pri->
pvts[chanpos]->reverse_charging_indication = ev->ring.reversecharge;
5739#if defined(HAVE_PRI_SETUP_KEYPAD)
5741 ev->ring.keypad_digits,
sizeof(pri->
pvts[chanpos]->keypad_digits));
5749 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->ring.subcmds,
5765static void sig_pri_handle_setup(
struct sig_pri_span *pri, pri_event *e)
5767 int exten_exists_or_can_exist;
5768 int could_match_more;
5779 && !sig_pri_msn_match(pri->
msn_list, e->ring.callednum)) {
5782 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n",
5784 pri_destroycall(pri->
pri, e->ring.call);
5787 if (sig_pri_is_cis_call(e->ring.channel)) {
5788 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, e->ring.call);
5791 chanpos = pri_find_principle_by_call(pri, e->ring.call);
5795 "Span %d: Got SETUP with duplicate call ptr (%p). Dropping call.\n",
5796 pri->
span, e->ring.call);
5797 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5800 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
5802 chanpos = pri_find_empty_chan(pri, 1);
5804 callid = func_pri_dchannel_new_callid();
5806 }
else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
5808#if defined(HAVE_PRI_CALL_WAITING)
5809 if (!pri->allow_call_waiting_calls)
5813 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5816#if defined(HAVE_PRI_CALL_WAITING)
5817 chanpos = pri_find_empty_nobch(pri);
5820 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5824 callid = func_pri_dchannel_new_callid();
5827 sig_pri_init_config(pri->
pvts[chanpos], pri);
5831 callid = func_pri_dchannel_new_callid();
5832 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
5835 "Span %d: SETUP on unconfigured channel %d/%d\n",
5836 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5851 "Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n",
5852 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5858 pri_check_restart(pri);
5865 "Span %d: SETUP requested unavailable channel %d/%d. Attempting to renegotiate.\n",
5866 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5870#if defined(ALWAYS_PICK_CHANNEL)
5871 if (e->ring.flexible) {
5875 if (chanpos < 0 && e->ring.flexible) {
5877 chanpos = pri_find_empty_chan(pri, 1);
5881 if (e->ring.flexible) {
5882 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5884 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5889 sig_pri_lock_private(pri->
pvts[chanpos]);
5892 pri->
pvts[chanpos]->
call = e->ring.call;
5895 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
5896 e->ring.redirectingnum, e->ring.callingplanrdnis);
5897 sig_pri_set_rdnis(pri->
pvts[chanpos], plancallingnum);
5900 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
5901 e->ring.callingnum, e->ring.callingplan);
5908 apply_plan_to_existing_number(plancallingani,
sizeof(plancallingani),
5909 pri, e->ring.callingani, e->ring.callingplanani);
5915#if defined(HAVE_PRI_SUBADDR)
5916 if (e->ring.calling.subaddress.valid) {
5920 sig_pri_set_subaddress(&calling_subaddress,
5921 &e->ring.calling.subaddress);
5922 if (calling_subaddress.str) {
5924 calling_subaddress.str,
5933 pri->
pvts[chanpos]->
cid_ton = e->ring.callingplan;
5935 if (e->ring.ani2 >= 0) {
5953 ? plancallingnum : e->ring.callednum);
5962 sig_pri_set_caller_id(pri->
pvts[chanpos]);
5965 sig_pri_set_dnid(pri->
pvts[chanpos], e->ring.callednum);
5969 ast_verb(3,
"Going to extension s|1 because of immediate=yes\n");
5985 ast_verb(3,
"Going to extension s|1 because of Complete received\n");
5996 if (!exten_exists_or_can_exist) {
5998 "Span %d: Extension %s@%s does not exist. Rejecting call from '%s'.\n",
6001 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
6004 sig_pri_unlock_private(pri->
pvts[chanpos]);
6005 sig_pri_span_devstate_changed(pri);
6010 switch (e->ring.layer1) {
6011 case PRI_LAYER_1_ALAW:
6014 case PRI_LAYER_1_ULAW:
6023 could_match_more = !e->ring.complete
6028 need_dialtone = could_match_more
6043 pri_proceeding(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 0);
6044 }
else if (pri->
switchtype == PRI_SWITCH_GR303_TMC) {
6046 pri_answer(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6049#if defined(HAVE_PRI_SETUP_ACK_INBAND)
6050 pri_setup_ack(pri->
pri, e->ring.call,
6051 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, need_dialtone);
6053 pri_need_more_info(pri->
pri, e->ring.call,
6054 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6064 sig_pri_unlock_private(pri->
pvts[chanpos]);
6066 c = sig_pri_new_ast_channel(pri->
pvts[chanpos],
6070 sig_pri_lock_private(pri->
pvts[chanpos]);
6073 setup_incoming_channel(pri, chanpos, e);
6076 if (could_match_more) {
6077#if !defined(HAVE_PRI_SETUP_ACK_INBAND)
6078 if (need_dialtone) {
6081#ifdef HAVE_PRI_PROG_W_CAUSE
6082 pri_progress_with_cause(pri->
pri, e->ring.call,
6083 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, -1);
6085 pri_progress(pri->
pri, e->ring.call,
6086 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6092 pri->
pvts[chanpos])) {
6093 ast_verb(3,
"Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
6094 plancallingnum,
S_OR(pri->
pvts[chanpos]->
exten,
"<unspecified>"),
6097 sig_pri_unlock_private(pri->
pvts[chanpos]);
6102 ast_verb(3,
"Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
6103 plancallingnum, pri->
pvts[chanpos]->
exten,
6106 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6107 sig_pri_unlock_private(pri->
pvts[chanpos]);
6116 sig_pri_unlock_private(pri->
pvts[chanpos]);
6121 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
6123 sig_pri_unlock_private(pri->
pvts[chanpos]);
6124 sig_pri_span_devstate_changed(pri);
6133static void *pri_dchannel(
void *vpri)
6140 struct timeval tv, lowest, *next;
6146 struct timeval lastidle = { 0, 0 };
6155 gettimeofday(&lastidle,
NULL);
6156 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
6160 cc = strchr(pri->
idleext,
'@');
6182 fds[i].events = POLLIN | POLLPRI;
6191 pri_check_restart(pri);
6193 sig_pri_span_devstate_changed(pri);
6211 if (haveidles < pri->minunused) {
6222 if (nextidle > -1) {
6237 sig_pri_lock_private(pri->
pvts[nextidle]);
6238 sig_pri_unlock_private(pri->
pvts[nextidle]);
6253 gettimeofday(&lastidle,
NULL);
6255 }
else if ((haveidles < pri->minunused) &&
6256 (activeidles > pri->
minidle)) {
6267 (activeidles <= pri->minidle))
6289 next = pri_schedule_next(pri->
dchans[i]);
6293 if (tv.tv_sec < 0) {
6308 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
6309 pthread_testcancel();
6311 res = poll(
fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
6312 pthread_testcancel();
6313 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
6321 e = pri_schedule_run(pri->
dchans[which]);
6325 }
else if (res > -1) {
6329 if (
fds[which].revents & POLLPRI) {
6330 sig_pri_handle_dchan_exception(pri, which);
6331 }
else if (
fds[which].revents & POLLIN) {
6332 e = pri_check_event(pri->
dchans[which]);
6341 if (
errno == ENODEV) {
6342 pri_destroy_later(pri);
6345 }
else if (
errno != EINTR)
6354 pri->
span, pri_event2str(e->e), e->e);
6357 if (e->e != PRI_EVENT_DCHAN_DOWN) {
6359 ast_verb(2,
"%s D-Channel on span %d up\n", pri_order(which), pri->
span);
6364 ast_verb(2,
"%s D-Channel on span %d down\n", pri_order(which), pri->
span);
6369 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->
pri != pri->
dchans[which]))
6374 case PRI_EVENT_DCHAN_UP:
6377 pri_find_dchan(pri);
6390 for (i = 0; i < pri->
numchans; i++) {
6395 sig_pri_span_devstate_changed(pri);
6397 case PRI_EVENT_DCHAN_DOWN:
6398 pri_find_dchan(pri);
6409 for (i = 0; i < pri->
numchans; i++) {
6413 if (pri_get_timer(p->
pri->
pri, PRI_TIMER_T309) < 0) {
6425 sig_pri_span_devstate_changed(
pri);
6428 case PRI_EVENT_RESTART:
6429 if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) {
6430 chanpos = pri_find_principle(
pri, e->restart.channel,
NULL);
6433 "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
6434 pri->
span, PRI_SPAN(e->restart.channel),
6435 PRI_CHANNEL(e->restart.channel));
6438#if defined(HAVE_PRI_SERVICE_MESSAGES)
6441 why =
pri->
pvts[chanpos]->service_status;
6444 "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n",
6445 pri->
span, PRI_SPAN(e->restart.channel),
6446 PRI_CHANNEL(e->restart.channel),
6447 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ?
"both ends" :
"far end" :
"near end");
6451 sig_pri_lock_private(
pri->
pvts[chanpos]);
6454 PRI_SPAN(e->restart.channel),
6455 PRI_CHANNEL(e->restart.channel));
6462 sig_pri_queue_hangup(
pri, chanpos);
6463 sig_pri_unlock_private(
pri->
pvts[chanpos]);
6469 sig_pri_lock_private(
pri->
pvts[x]);
6475 sig_pri_queue_hangup(
pri, x);
6476 sig_pri_unlock_private(
pri->
pvts[x]);
6479 sig_pri_span_devstate_changed(
pri);
6481 case PRI_EVENT_KEYPAD_DIGIT:
6482 if (sig_pri_is_cis_call(e->digit.channel)) {
6483 sig_pri_handle_cis_subcmds(
pri, e->e, e->digit.subcmds,
6487 chanpos = pri_find_principle_by_call(
pri, e->digit.call);
6490 "Span %d: Received keypad digits for unknown call.\n",
pri->
span);
6493 sig_pri_lock_private(
pri->
pvts[chanpos]);
6495 callid = func_pri_dchannel_chanpos_callid(
pri, chanpos);
6497 sig_pri_handle_subcmds(
pri, chanpos, e->e, e->digit.subcmds,
6503 int digitlen = strlen(e->digit.digits);
6506 for (i = 0; i < digitlen; i++) {
6509 pri_queue_frame(pri, chanpos, &f);
6512 sig_pri_unlock_private(pri->
pvts[chanpos]);
6515 case PRI_EVENT_INFO_RECEIVED:
6516 if (sig_pri_is_cis_call(e->ring.channel)) {
6517 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
6521 chanpos = pri_find_principle_by_call(pri, e->ring.call);
6524 "Span %d: Received INFORMATION for unknown call.\n", pri->
span);
6527 sig_pri_lock_private(pri->
pvts[chanpos]);
6529 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6531 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, e->ring.call);
6536 int digitlen = strlen(e->ring.callednum);
6539 for (i = 0; i < digitlen; i++) {
6542 pri_queue_frame(pri, chanpos, &f);
6545 sig_pri_unlock_private(pri->
pvts[chanpos]);
6547#if defined(HAVE_PRI_SERVICE_MESSAGES)
6548 case PRI_EVENT_SERVICE:
6549 chanpos = pri_find_principle(pri, e->service.channel,
NULL);
6551 ast_log(
LOG_WARNING,
"Received service change status %d on unconfigured channel %d/%d span %d\n",
6552 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6554 char db_chan_name[20];
6560 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, pri->
span, ch);
6561 why = &pri->
pvts[chanpos]->service_status;
6562 switch (e->service.changestatus) {
6566 *why &= ~SRVST_FAREND;
6568 snprintf(db_answer,
sizeof(db_answer),
"%s:%u",
6569 SRVST_TYPE_OOS, *why);
6570 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
6572 sig_pri_span_devstate_changed(pri);
6578 *why |= SRVST_FAREND;
6579 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS,
6581 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
6582 sig_pri_span_devstate_changed(pri);
6588 ast_log(
LOG_NOTICE,
"Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n",
6589 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->
span, ch, e->service.changestatus);
6592 case PRI_EVENT_SERVICE_ACK:
6593 chanpos = pri_find_principle(pri, e->service_ack.channel,
NULL);
6595 ast_log(
LOG_WARNING,
"Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
6596 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6598 ast_debug(2,
"Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n",
6599 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span, e->service_ack.changestatus);
6603 case PRI_EVENT_RING:
6604 sig_pri_handle_setup(pri, e);
6606 case PRI_EVENT_RINGING:
6607 if (sig_pri_is_cis_call(e->ringing.channel)) {
6608 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds,
6612 chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
6617 sig_pri_lock_private(pri->
pvts[chanpos]);
6619 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6621 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.subcmds,
6623 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCNR);
6624 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6625 sig_pri_lock_owner(pri, chanpos);
6637#ifdef PRI_PROGRESS_MASK
6638 && (e->ringing.progressmask
6639 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6641 && e->ringing.progress == 8
6647 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6648 sig_pri_open_media(pri->
pvts[chanpos]);
6651#ifdef SUPPORT_USERUSER
6655 sig_pri_lock_owner(pri, chanpos);
6659 e->ringing.useruserinfo);
6665 sig_pri_unlock_private(pri->
pvts[chanpos]);
6667 case PRI_EVENT_PROGRESS:
6668 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6669 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6670 e->proceeding.call);
6673 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6674 e->proceeding.call);
6678 sig_pri_lock_private(pri->
pvts[chanpos]);
6680 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6682 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6683 e->proceeding.call);
6685 if (e->proceeding.cause > -1) {
6687 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_PROGRESS (%d)", e->proceeding.cause);
6688 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->proceeding.cause);
6691 ast_verb(3,
"PROGRESS with cause code %d received\n", e->proceeding.cause);
6696 ast_verb(3,
"PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
6706#ifdef PRI_PROGRESS_MASK
6707 && (e->proceeding.progressmask
6708 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6710 && e->proceeding.progress == 8
6715 "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
6720 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6721 sig_pri_open_media(pri->
pvts[chanpos]);
6723 sig_pri_unlock_private(pri->
pvts[chanpos]);
6725 case PRI_EVENT_PROCEEDING:
6726 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6727 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6728 e->proceeding.call);
6731 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6732 e->proceeding.call);
6736 sig_pri_lock_private(pri->
pvts[chanpos]);
6738 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6740 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6741 e->proceeding.call);
6745 "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
6752#ifdef PRI_PROGRESS_MASK
6761 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
6763 && e->proceeding.progress == 8
6769 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6770 sig_pri_open_media(pri->
pvts[chanpos]);
6778 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6780 sig_pri_unlock_private(pri->
pvts[chanpos]);
6782 case PRI_EVENT_FACILITY:
6783 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) {
6785#if defined(HAVE_PRI_CALL_REROUTING)
6786 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6787 e->facility.subcall);
6789 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6794 chanpos = pri_find_principle_by_call(pri, e->facility.call);
6800 sig_pri_lock_private(pri->
pvts[chanpos]);
6802 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6804#if defined(HAVE_PRI_CALL_REROUTING)
6805 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6806 e->facility.subcall);
6808 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6811 sig_pri_unlock_private(pri->
pvts[chanpos]);
6813 case PRI_EVENT_ANSWER:
6814 if (sig_pri_is_cis_call(e->answer.channel)) {
6815#if defined(HAVE_PRI_CALL_WAITING)
6817 pri_connect_ack(pri->
pri, e->answer.call, 0);
6819 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds,
6823 chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
6827#if defined(HAVE_PRI_CALL_WAITING)
6828 if (pri->
pvts[chanpos]->is_call_waiting) {
6836 new_chanpos = pri_find_empty_chan(pri, 1);
6837 if (0 <= new_chanpos) {
6838 new_chanpos = pri_fixup_principle(pri, new_chanpos,
6841 if (new_chanpos < 0) {
6847 "Span %d: Channel not available for call waiting call.\n",
6849 sig_pri_lock_private(pri->
pvts[chanpos]);
6850 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
6852 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
6853 sig_pri_lock_owner(pri, chanpos);
6867 pri->
pvts[chanpos]->is_call_waiting = 0;
6869 pri_hangup(pri->
pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
6872 sig_pri_unlock_private(pri->
pvts[chanpos]);
6873 sig_pri_span_devstate_changed(pri);
6876 chanpos = new_chanpos;
6878 pri_connect_ack(pri->
pri, e->answer.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
6879 sig_pri_span_devstate_changed(pri);
6882 pri_connect_ack(pri->
pri, e->answer.call, 0);
6885 sig_pri_lock_private(pri->
pvts[chanpos]);
6887 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6889#if defined(HAVE_PRI_CALL_WAITING)
6890 if (pri->
pvts[chanpos]->is_call_waiting) {
6891 pri->
pvts[chanpos]->is_call_waiting = 0;
6895 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
6900 "Span %d: Channel %d/%d dialing deferred digit string: %s\n",
6907 sig_pri_dial_digits(pri->
pvts[chanpos],
6913 sig_pri_open_media(pri->
pvts[chanpos]);
6915 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6917 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6920#ifdef SUPPORT_USERUSER
6924 sig_pri_lock_owner(pri, chanpos);
6928 e->answer.useruserinfo);
6934 sig_pri_unlock_private(pri->
pvts[chanpos]);
6936#if defined(HAVE_PRI_CALL_WAITING)
6937 case PRI_EVENT_CONNECT_ACK:
6938 if (sig_pri_is_cis_call(e->connect_ack.channel)) {
6939 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds,
6940 e->connect_ack.call);
6943 chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel,
6944 e->connect_ack.call);
6949 sig_pri_lock_private(pri->
pvts[chanpos]);
6951 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6953 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.subcmds,
6954 e->connect_ack.call);
6955 sig_pri_open_media(pri->
pvts[chanpos]);
6956 sig_pri_unlock_private(pri->
pvts[chanpos]);
6957 sig_pri_span_devstate_changed(pri);
6960 case PRI_EVENT_HANGUP:
6961 if (sig_pri_is_cis_call(e->hangup.channel)) {
6962 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
6964 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6967 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
6973 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6976 sig_pri_lock_private(pri->
pvts[chanpos]);
6978 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6980 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
6982 switch (e->hangup.cause) {
6983 case PRI_CAUSE_INVALID_CALL_REFERENCE:
6988 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6997 switch (e->hangup.cause) {
6998 case PRI_CAUSE_USER_BUSY:
6999 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7000 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
7006 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP (%d)", e->hangup.cause);
7007 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7028 switch (e->hangup.cause) {
7029 case PRI_CAUSE_USER_BUSY:
7032 case PRI_CAUSE_CALL_REJECTED:
7033 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7034 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7035 case PRI_CAUSE_SWITCH_CONGESTION:
7036 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7037 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7048 sig_pri_queue_hangup(pri, chanpos);
7055 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7058 ast_verb(3,
"Span %d: Channel %d/%d got hangup, cause %d\n",
7063 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7066 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7071 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7075 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7077 if (e->hangup.aoc_units > -1)
7078 ast_verb(3,
"Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
7081#ifdef SUPPORT_USERUSER
7085 sig_pri_lock_owner(pri, chanpos);
7089 e->hangup.useruserinfo);
7095 sig_pri_unlock_private(pri->
pvts[chanpos]);
7096 sig_pri_span_devstate_changed(pri);
7098 case PRI_EVENT_HANGUP_REQ:
7099 if (sig_pri_is_cis_call(e->hangup.channel)) {
7100 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7102 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7105 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7111 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7114 sig_pri_lock_private(pri->
pvts[chanpos]);
7116 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7118 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
7120#if defined(HAVE_PRI_CALL_HOLD)
7121 if (e->hangup.call_active && e->hangup.call_held
7122 && pri->hold_disconnect_transfer) {
7124 sig_pri_unlock_private(pri->
pvts[chanpos]);
7125 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1,
7126 e->hangup.call_active, 0,
NULL)) {
7129 sig_pri_lock_private(pri->
pvts[chanpos]);
7132 switch (e->hangup.cause) {
7133 case PRI_CAUSE_USER_BUSY:
7134 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7135 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
7137 case PRI_CAUSE_INVALID_CALL_REFERENCE:
7144 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7151 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP_REQ (%d)", e->hangup.cause);
7152 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7172 switch (e->hangup.cause) {
7173 case PRI_CAUSE_USER_BUSY:
7176 case PRI_CAUSE_CALL_REJECTED:
7177 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7178 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7179 case PRI_CAUSE_SWITCH_CONGESTION:
7180 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7181 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7192#if defined(HAVE_PRI_AOC_EVENTS)
7193 if (!pri->
pvts[chanpos]->holding_aoce
7194 && pri->aoce_delayhangup
7196 sig_pri_send_aoce_termination_request(pri, chanpos,
7197 pri_get_timer(pri->
pri, PRI_TIMER_T305) / 2);
7201 sig_pri_queue_hangup(pri, chanpos);
7204 ast_verb(3,
"Span %d: Channel %d/%d got hangup request, cause %d\n",
7212 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7215 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7220 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7224 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7227#ifdef SUPPORT_USERUSER
7231 sig_pri_lock_owner(pri, chanpos);
7235 e->hangup.useruserinfo);
7241 sig_pri_unlock_private(pri->
pvts[chanpos]);
7242 sig_pri_span_devstate_changed(pri);
7244 case PRI_EVENT_HANGUP_ACK:
7245 if (sig_pri_is_cis_call(e->hangup.channel)) {
7246 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7250 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7254 sig_pri_lock_private(pri->
pvts[chanpos]);
7256 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7260 ast_verb(3,
"Span %d: Channel %d/%d got hangup ACK\n", pri->
span,
7263#ifdef SUPPORT_USERUSER
7267 sig_pri_lock_owner(pri, chanpos);
7271 e->hangup.useruserinfo);
7276 sig_pri_unlock_private(pri->
pvts[chanpos]);
7277 sig_pri_span_devstate_changed(pri);
7279 case PRI_EVENT_CONFIG_ERR:
7282 case PRI_EVENT_RESTART_ACK:
7283 chanpos = pri_find_principle(pri, e->restartack.channel,
NULL);
7292 sig_pri_lock_private(pri->
pvts[chanpos]);
7294 "Span %d: Assuming restart ack is for channel %d/%d\n",
7299 "Span %d: Got restart ack on channel %d/%d with owner\n",
7306 "Span %d: Channel %d/%d successfully restarted\n",
7309 sig_pri_unlock_private(pri->
pvts[chanpos]);
7311 pri_check_restart(pri);
7317 "Span %d: Restart ACK on strange channel %d/%d\n",
7318 pri->
span, PRI_SPAN(e->restartack.channel),
7319 PRI_CHANNEL(e->restartack.channel));
7322 sig_pri_lock_private(pri->
pvts[chanpos]);
7326 "Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n",
7329 sig_pri_unlock_private(pri->
pvts[chanpos]);
7334 "Span %d: Got restart ack on channel %d/%d with owner\n",
7341 "Span %d: Channel %d/%d successfully restarted\n",
7344 sig_pri_unlock_private(pri->
pvts[chanpos]);
7346 pri_check_restart(pri);
7349 case PRI_EVENT_SETUP_ACK:
7350 if (sig_pri_is_cis_call(e->setup_ack.channel)) {
7351 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds,
7355 chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
7360 sig_pri_lock_private(pri->
pvts[chanpos]);
7362 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7364 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.subcmds,
7372 for (
x = 0;
x <
len; ++
x) {
7374 pri_information(pri->
pri, pri->
pvts[chanpos]->
call,
7382#
if defined(HAVE_PRI_SETUP_ACK_INBAND)
7400 && ((e->setup_ack.progressmask & PRI_PROG_INBAND_AVAILABLE)
7402 || pri->
pvts[chanpos]->no_dialed_digits)
7411 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
7412 sig_pri_open_media(pri->
pvts[chanpos]);
7414 sig_pri_unlock_private(pri->
pvts[chanpos]);
7416 case PRI_EVENT_NOTIFY:
7417 if (sig_pri_is_cis_call(e->notify.channel)) {
7418#if defined(HAVE_PRI_CALL_HOLD)
7419 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
7422 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
NULL);
7426#if defined(HAVE_PRI_CALL_HOLD)
7427 chanpos = pri_find_principle_by_call(pri, e->notify.call);
7439 chanpos = pri_find_principle(pri, e->notify.channel,
NULL);
7442 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->
span);
7446 sig_pri_lock_private(pri->
pvts[chanpos]);
7448 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7450#if defined(HAVE_PRI_CALL_HOLD)
7451 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
7454 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
NULL);
7456 switch (e->notify.info) {
7457 case PRI_NOTIFY_REMOTE_HOLD:
7459 sig_pri_queue_hold(pri, chanpos);
7462 case PRI_NOTIFY_REMOTE_RETRIEVAL:
7464 sig_pri_queue_unhold(pri, chanpos);
7468 sig_pri_unlock_private(pri->
pvts[chanpos]);
7470#if defined(HAVE_PRI_CALL_HOLD)
7471 case PRI_EVENT_HOLD:
7473 if (sig_pri_handle_hold(pri, e)) {
7474 pri_hold_rej(pri->
pri, e->hold.call,
7475 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
7477 pri_hold_ack(pri->
pri, e->hold.call);
7481#if defined(HAVE_PRI_CALL_HOLD)
7482 case PRI_EVENT_HOLD_ACK:
7484 sig_pri_handle_hold_ack(pri, e);
7487#if defined(HAVE_PRI_CALL_HOLD)
7488 case PRI_EVENT_HOLD_REJ:
7490 sig_pri_handle_hold_rej(pri, e);
7493#if defined(HAVE_PRI_CALL_HOLD)
7494 case PRI_EVENT_RETRIEVE:
7496 sig_pri_handle_retrieve(pri, e);
7499#if defined(HAVE_PRI_CALL_HOLD)
7500 case PRI_EVENT_RETRIEVE_ACK:
7502 sig_pri_handle_retrieve_ack(pri, e);
7505#if defined(HAVE_PRI_CALL_HOLD)
7506 case PRI_EVENT_RETRIEVE_REJ:
7508 sig_pri_handle_retrieve_rej(pri, e);
7512 ast_debug(1,
"Span: %d Unhandled event: %s(%d)\n",
7513 pri->
span, pri_event2str(e->e), e->e);
7565 (pri->
dchanavail[
x] & DCHAN_NOTINALARM) ?
"No" :
"Yes",
7578 memset(pri, 0,
sizeof(*pri));
7595 sig_pri_set_outgoing(p, 0);
7596 sig_pri_set_digital(p, 0);
7597#if defined(HAVE_PRI_CALL_WAITING)
7598 if (p->is_call_waiting) {
7599 p->is_call_waiting = 0;
7610 sig_pri_set_dialing(p, 0);
7613 pri_grab(p, p->
pri);
7616#if defined(SUPPORT_USERUSER)
7620 pri_call_set_useruser(p->
call, useruser);
7624#if defined(HAVE_PRI_TRANSFER)
7634 sig_pri_transfer_rsp(p->xfer_data, 1);
7638#if defined(HAVE_PRI_AOC_EVENTS)
7639 if (p->holding_aoce) {
7640 pri_aoc_e_send(p->
pri->
pri, p->
call, &p->aoc_e);
7645 ast_debug(1,
"Already hungup... Calling hangup once, and clearing call\n");
7656 icause = atoi(cause);
7660 "Not yet hungup... Calling hangup with cause %d, and clearing call\n",
7666#if defined(HAVE_PRI_TRANSFER)
7667 p->xfer_data =
NULL;
7669#if defined(HAVE_PRI_AOC_EVENTS)
7670 p->aoc_s_request_invoke_id_valid = 0;
7671 p->holding_aoce = 0;
7672 p->waiting_for_aoce = 0;
7678 sig_pri_span_devstate_changed(p->
pri);
7716 subaddr = strchr(
number,
':');
7740 deferred = strchr(
number,
'w');
7745 while (isalpha(*
number)) {
7753 snprintf(called, called_buff_size,
"%s",
number);
7756 snprintf(called, called_buff_size,
"%s:%s",
number, subaddr);
7760enum SIG_PRI_CALL_OPT_FLAGS {
7761 OPT_KEYPAD = (1 << 0),
7762 OPT_REVERSE_CHARGE = (1 << 1),
7763 OPT_AOC_REQUEST = (1 << 2),
7765enum SIG_PRI_CALL_OPT_ARGS {
7767 OPT_ARG_AOC_REQUEST,
7785 char *
c, *l, *n, *s;
7786#ifdef SUPPORT_USERUSER
7787 const char *useruser;
7792 int prilocaldialplan;
7795#if defined(HAVE_PRI_SETUP_KEYPAD)
7808 ast_debug(1,
"CALLER NAME: %s NUM: %s\n",
7823 sig_pri_set_outgoing(p, 1);
7851 dialed_subaddress.type = 2;
7859 dialed_subaddress.str = s;
7860 dialed_subaddress.valid = 1;
7871 for (l = connected_id.
number.
str; l && *l; l++) {
7872 if (strchr(
"0123456789", *l)) {
7904 pri_grab(p, p->
pri);
7905 if (!(p->
call = pri_new_call(p->
pri->
pri))) {
7910 if (!(sr = pri_sr_new())) {
7921#if defined(HAVE_PRI_CALL_WAITING)
7922 if (p->is_call_waiting) {
7927 pri_sr_set_channel(sr, 0, 0, 1);
7937 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
7944 pri_facility_enable(p->
pri->
pri);
7949 if (pridialplan == -2 || pridialplan == -3) {
7951 if (pridialplan == -2) {
7954 pridialplan = PRI_INTERNATIONAL_ISDN;
7956 if (pridialplan == -2) {
7959 pridialplan = PRI_NATIONAL_ISDN;
7961 pridialplan = PRI_LOCAL_ISDN;
7967 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
7970 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
7973 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
7976 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
7979 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
7982 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
7985 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
7988 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
7991 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
7994 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
7997 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
8000 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
8003 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
8006 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
8017#if defined(HAVE_PRI_SETUP_KEYPAD)
8021 keypad = opt_args[OPT_ARG_KEYPAD];
8022 pri_sr_set_keypad_digits(sr, keypad);
8029 char *called =
c + p->
stripmsd + dp_strip;
8031 pri_sr_set_called(sr, called, pridialplan, s ? 1 : 0);
8032#if defined(HAVE_PRI_SETUP_ACK_INBAND)
8033 p->no_dialed_digits = !called[0];
8037#if defined(HAVE_PRI_SUBADDR)
8038 if (dialed_subaddress.valid) {
8039 struct pri_party_subaddress subaddress;
8041 memset(&subaddress, 0,
sizeof(subaddress));
8042 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
8043 pri_sr_set_called_subaddress(sr, &subaddress);
8046#if defined(HAVE_PRI_REVERSE_CHARGE)
8048 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
8051#if defined(HAVE_PRI_AOC_EVENTS)
8054 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
's')) {
8055 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
8057 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'd')) {
8058 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
8060 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'e')) {
8061 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
8086 if ((l !=
NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) {
8088 if (prilocaldialplan == -2) {
8091 prilocaldialplan = PRI_INTERNATIONAL_ISDN;
8093 if (prilocaldialplan == -2) {
8096 prilocaldialplan = PRI_NATIONAL_ISDN;
8098 prilocaldialplan = PRI_LOCAL_ISDN;
8100 }
else if (prilocaldialplan == -1) {
8105 while (*l >
'9' && *l !=
'*' && *l !=
'#') {
8108 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
8111 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
8114 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
8117 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
8120 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
8123 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
8126 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
8129 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
8132 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
8135 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
8138 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
8141 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
8144 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
8147 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
8152 "Unrecognized prilocaldialplan %s modifier: %c\n",
8153 *l >
'Z' ?
"NPI" :
"TON", *l);
8160 pri_sr_set_caller(sr, l ? (l + ldp_strip) :
NULL, n, prilocaldialplan,
8163#if defined(HAVE_PRI_SUBADDR)
8165 struct pri_party_subaddress subaddress;
8167 memset(&subaddress, 0,
sizeof(subaddress));
8168 sig_pri_party_subaddress_from_ast(&subaddress, &connected_id.
subaddress);
8169 pri_sr_set_caller_subaddress(sr, &subaddress);
8173 sig_pri_redirecting_update(p, ast);
8175#ifdef SUPPORT_USERUSER
8179 pri_sr_set_useruser(sr, useruser);
8182#if defined(HAVE_PRI_CCSS)
8191 struct sig_pri_cc_monitor_instance *instance;
8198 if (pri_cc_call(p->
pri->
pri, instance->cc_id, p->
call, sr)) {
8218 if (core_id == -1 && pri_setup(p->
pri->
pri, p->
call, sr)) {
8230 sig_pri_set_dialing(p, 1);
8239 switch (condition) {
8252 pri_grab(p, p->
pri);
8253#ifdef HAVE_PRI_PROG_W_CAUSE
8256 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8266 pri_grab(p, p->
pri);
8267 pri_acknowledge(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p),
8283 pri_grab(p, p->
pri);
8284 pri_proceeding(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 0);
8293 sig_pri_set_digital(p, 0);
8298 pri_grab(p, p->
pri);
8299#ifdef HAVE_PRI_PROG_W_CAUSE
8300 pri_progress_with_cause(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1, -1);
8302 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8351 pri_grab(p, p->
pri);
8352#ifdef HAVE_PRI_PROG_W_CAUSE
8355 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8364 pri_grab(p, p->
pri);
8374 pri_grab(p, p->
pri);
8386 res = sig_pri_play_tone(p, -1);
8391 struct pri_party_connected_line
connected;
8394 int colp_allowed = 0;
8397 pri_grab(p, p->
pri);
8416 if (!colp_allowed) {
8418 ast_debug(1,
"Blocked AST_CONTROL_CONNECTED_LINE on %s\n",
8424 sig_pri_party_id_from_ast(&
connected.id, &connected_id);
8435 dialplan = PRI_INTERNATIONAL_ISDN;
8439 dialplan = PRI_NATIONAL_ISDN;
8441 dialplan = PRI_LOCAL_ISDN;
8449 strlen(
connected.id.number.str + prefix_strip) + 1);
8467 pri_grab(p, p->
pri);
8468 sig_pri_redirecting_update(p, chan);
8473#if defined(HAVE_PRI_AOC_EVENTS)
8478 if (decoded && p->
pri) {
8479 pri_grab(p, p->
pri);
8483 sig_pri_aoc_s_from_ast(p, decoded);
8488 sig_pri_aoc_d_from_ast(p, decoded);
8493 sig_pri_aoc_e_from_ast(p, decoded);
8501 if (p->waiting_for_aoce) {
8502 p->waiting_for_aoce = 0;
8504 "Received final AOC-E msg, continue with hangup on %s\n",
8525#if defined(HAVE_PRI_MCID)
8528 pri_grab(p, p->
pri);
8544 pri_grab(p, p->
pri);
8545#if defined(HAVE_PRI_AOC_EVENTS)
8546 if (p->aoc_s_request_invoke_id_valid) {
8550 pri_aoc_s_request_response_send(p->
pri->
pri, p->
call,
8551 p->aoc_s_request_invoke_id,
NULL);
8552 p->aoc_s_request_invoke_id_valid = 0;
8558 sig_pri_set_dialing(p, 0);
8559 sig_pri_open_media(p);
8576static int sig_pri_available_check(
struct sig_pri_chan *pvt)
8588#if defined(HAVE_PRI_CALL_WAITING)
8607 if (
pri->num_call_waiting_calls <
pri->max_call_waiting_calls) {
8608 if (!
pri->num_call_waiting_calls) {
8621 idx = pri_find_empty_nobch(
pri);
8625 cw->is_call_waiting = 1;
8626 sig_pri_init_config(cw,
pri);
8647#
if defined(HAVE_PRI_CALL_WAITING)
8654 !
pri->num_call_waiting_calls &&
8656 sig_pri_available_check(p)) {
8662#if defined(HAVE_PRI_CALL_WAITING)
8663 if (!is_specific_channel) {
8666 cw = sig_pri_cw_available(
pri);
8690 ast_debug(1,
"Queueing digit '%c' since setup_ack not yet received\n",
8696 "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
8702 pri_grab(pvt, pvt->
pri);
8709 "Span %d: Digit '%c' may be ignored by peer. (Call level:%u(%s))\n",
8732 sig_pri_open_media(pvt);
8743 sig_pri_set_dialing(pvt, 0);
8745 sig_pri_set_echocanceller(pvt, 1);
8749#if defined(HAVE_PRI_MWI)
8761static 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)
8763 struct pri_party_id voicemail;
8766 ast_debug(1,
"Send MWI indication for %s(%s) vm_number:%s num_messages:%d\n",
8767 vm_box, mbox_id,
S_OR(vm_number,
"<not-present>"), num_messages);
8771 mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8772 mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8775 memset(&voicemail, 0,
sizeof(voicemail));
8776 voicemail.number.valid = 1;
8777 voicemail.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8778 voicemail.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8780 ast_copy_string(voicemail.number.str, vm_number,
sizeof(voicemail.number.str));
8784#if defined(HAVE_PRI_MWI_V2)
8785 pri_mwi_indicate_v2(pri->
pri, &
mailbox, &voicemail, 1 , num_messages,
8794#if defined(HAVE_PRI_MWI)
8816 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8817 if (!pri->mbox[idx].sub) {
8822 if (!strcmp(pri->mbox[idx].uniqueid, mwi_state->
uniqueid)) {
8824 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number,
8825 pri->mbox[idx].vm_box, pri->mbox[idx].uniqueid, mwi_state->
new_msgs);
8832#if defined(HAVE_PRI_MWI)
8840static void sig_pri_mwi_cache_update(
struct sig_pri_span *pri)
8845 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8847 if (!pri->mbox[idx].sub) {
8853 pri->mbox[idx].uniqueid);
8860 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number, pri->mbox[idx].vm_box,
8861 pri->mbox[idx].uniqueid, mwi_state->
new_msgs);
8874#if defined(HAVE_PRI_MWI)
8878#if defined(HAVE_PRI_MWI)
8879 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8880 if (pri->mbox[idx].sub) {
8899static int sig_pri_cmp_pri_chans(
const void *left,
const void *right)
8939#if defined(HAVE_PRI_MWI)
8941 char *prev_vm_number;
8944#if defined(HAVE_PRI_MWI)
8947 if (
pri->mbox[i].sub) {
8954 sig_pri_sort_pri_chans(
pri);
8956#if defined(HAVE_PRI_MWI)
8961 prev_vm_number =
NULL;
8962 saveptr =
pri->mwi_vm_numbers;
8966 vm_number =
strsep(&saveptr,
",");
8972 vm_number = prev_vm_number;
8975 prev_vm_number = vm_number;
8977 pri->mbox[i].vm_number = vm_number;
8984 saveptr =
pri->mwi_vm_boxes;
9002 saveptr =
pri->mwi_mailboxes;
9006 mbox_id =
strsep(&saveptr,
",");
9013 pri->mbox[i].uniqueid = mbox_id;
9014 if (!
pri->mbox[i].vm_box || !mbox_id) {
9016 ast_debug(1,
"%s span %d MWI position %d disabled. vm_box:%s mbox_id:%s.\n",
9017 sig_pri_cc_type_name,
pri->
span, i,
9018 pri->mbox[i].vm_box ?:
"<missing>",
9019 mbox_id ?:
"<missing>");
9024 if (!
pri->mbox[i].sub) {
9025 ast_log(
LOG_ERROR,
"%s span %d could not subscribe to MWI events for %s(%s).\n",
9026 sig_pri_cc_type_name,
pri->
span,
pri->mbox[i].vm_box, mbox_id);
9028#if defined(HAVE_PRI_MWI_V2)
9031 sig_pri_cc_type_name,
pri->
span,
pri->mbox[i].vm_box, mbox_id);
9051#if defined(HAVE_PRI_SERVICE_MESSAGES)
9052 if (
pri->enable_service_message_support) {
9053 pri_set_service_message_support(
pri->
dchans[i], 1);
9060#ifdef HAVE_PRI_PROG_W_CAUSE
9063#ifdef HAVE_PRI_INBANDDISCONNECT
9064 pri_set_inbanddisconnect(
pri->
dchans[i],
pri->inbanddisconnect);
9078#ifdef PRI_GETSET_TIMERS
9079 for (x = 0; x < PRI_MAX_TIMERS; x++) {
9089#if defined(HAVE_PRI_CALL_HOLD)
9090 pri_hold_enable(
pri->
pri, 1);
9092#if defined(HAVE_PRI_CALL_REROUTING)
9093 pri_reroute_enable(
pri->
pri, 1);
9095#if defined(HAVE_PRI_HANGUP_FIX)
9096 pri_hangup_fix_enable(
pri->
pri, 1);
9098#if defined(HAVE_PRI_CCSS)
9099 pri_cc_enable(
pri->
pri, 1);
9100 pri_cc_recall_mode(
pri->
pri,
pri->cc_ptmp_recall_mode);
9101 pri_cc_retain_signaling_req(
pri->
pri,
pri->cc_qsig_signaling_link_req);
9102 pri_cc_retain_signaling_rsp(
pri->
pri,
pri->cc_qsig_signaling_link_rsp);
9104#if defined(HAVE_PRI_TRANSFER)
9105 pri_transfer_enable(
pri->
pri, 1);
9107#if defined(HAVE_PRI_AOC_EVENTS)
9108 pri_aoc_events_enable(
pri->
pri, 1);
9110#if defined(HAVE_PRI_CALL_WAITING)
9111 pri_connect_ack_enable(
pri->
pri, 1);
9113#if defined(HAVE_PRI_MCID)
9114 pri_mcid_enable(
pri->
pri, 1);
9116#if defined(HAVE_PRI_DISPLAY_TEXT)
9117 pri_display_options_send(
pri->
pri,
pri->display_flags_send);
9118 pri_display_options_receive(
pri->
pri,
pri->display_flags_receive);
9120#if defined(HAVE_PRI_DATETIME_SEND)
9121 pri_date_time_send_option(
pri->
pri,
pri->datetime_send);
9123#if defined(HAVE_PRI_L2_PERSISTENCE)
9124 pri_persistent_layer2_option(
pri->
pri,
pri->l2_persistence);
9140#if defined(HAVE_PRI_MWI)
9149 sig_pri_mwi_cache_update(
pri);
9165 pri_grab(p, p->
pri);
9168 if (pri_get_timer(p->
pri->
pri, PRI_TIMER_T309) < 0) {
9178 sig_pri_span_devstate_changed(p->
pri);
9224#define SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n"
9225#define SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s"
9228 ast_cli(fd, SIG_PRI_SC_HEADER,
"PRI",
"",
"B",
"Chan",
"Call",
"PRI",
"Channel");
9229 ast_cli(fd, SIG_PRI_SC_HEADER,
"Span",
"Chan",
"Chan",
"Idle",
"Level",
"Call",
"Name");
9244 sig_pri_lock_private(pvt);
9245 sig_pri_lock_owner(
pri, idx);
9248 sig_pri_unlock_private(pvt);
9252 snprintf(line,
sizeof(line), SIG_PRI_SC_LINE,
9258 pvt->
call ?
"Yes" :
"No",
9264 sig_pri_unlock_private(pvt);
9273static void build_status(
char *s,
size_t len,
int status,
int active)
9275 if (!s ||
len < 1) {
9278 snprintf(s,
len,
"%s%s, %s",
9279 (
status & DCHAN_NOTINALARM) ?
"" :
"In Alarm, ",
9280 (
status & DCHAN_UP) ?
"Up" :
"Down",
9281 (active) ?
"Active" :
"Standby");
9303#ifdef PRI_DUMP_INFO_STR
9304 char *info_str =
NULL;
9306 ast_cli(fd,
"%s D-channel: %d\n", pri_order(x), dchannels[x]);
9310#ifdef PRI_DUMP_INFO_STR
9311 info_str = pri_dump_info_str(
pri->
pri);
9328 sig_pri_lock_private(p);
9331 ast_debug(1,
"Unable to find pri or call on channel!\n");
9332 sig_pri_unlock_private(p);
9336 pri_grab(p, p->
pri);
9337 pri_keypad_facility(p->
pri->
pri, p->
call, digits);
9340 sig_pri_unlock_private(p);
9349 sig_pri_lock_private(p);
9352 ast_debug(1,
"Unable to find pri or call on channel!\n");
9353 sig_pri_unlock_private(p);
9357 pri_grab(p, p->
pri);
9358 res = pri_callrerouting_facility(p->
pri->
pri, p->
call, destination, original, reason);
9361 sig_pri_unlock_private(p);
9366#if defined(HAVE_PRI_SERVICE_MESSAGES)
9367int pri_maintenance_bservice(
struct pri *
pri,
struct sig_pri_chan *p,
int changestatus)
9369 int channel = PVT_TO_CHANNEL(p);
9372 return pri_maintenance_service(
pri, span,
channel, changestatus);
9378 if (pchan->
owner == oldchan) {
9379 pchan->
owner = newchan;
9383#if defined(HAVE_PRI_DISPLAY_TEXT)
9393 struct pri_subcmd_display_txt display;
9397 display.length = strlen(display.text);
9398 display.char_set = 0;
9399 pri_grab(p, p->
pri);
9400 pri_display_text(p->
pri->
pri, p->
call, &display);
9406#if defined(HAVE_PRI_CCSS)
9425 struct sig_pri_cc_agent_prv *cc_pvt;
9433 cc_pvt->pri = pvt_chan->
pri;
9434 cc_pvt->cc_id = pri_cc_available(pvt_chan->
pri->
pri, pvt_chan->
call);
9436 if (cc_pvt->cc_id == -1) {
9445#if defined(HAVE_PRI_CCSS)
9474#if defined(HAVE_PRI_CCSS)
9495#if defined(HAVE_PRI_CCSS)
9516 struct sig_pri_cc_agent_prv *cc_pvt;
9519 const char *failed_msg;
9520 static const char *failed_to_send =
"Failed to send the CC request response.";
9521 static const char *not_accepted =
"The core declined the CC request.";
9525 if (cc_pvt->cc_request_response_pending) {
9526 cc_pvt->cc_request_response_pending = 0;
9542 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id,
status);
9546 failed_msg = failed_to_send;
9553 failed_msg = failed_to_send;
9555 failed_msg = not_accepted;
9568#if defined(HAVE_PRI_CCSS)
9586 struct sig_pri_cc_agent_prv *cc_pvt;
9590 pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
9596#if defined(HAVE_PRI_CCSS)
9621 struct sig_pri_cc_agent_prv *cc_pvt;
9625 pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
9631#if defined(HAVE_PRI_CCSS)
9655 struct sig_pri_cc_agent_prv *cc_pvt;
9659 pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
9665#if defined(HAVE_PRI_CCSS)
9689#if defined(HAVE_PRI_CCSS)
9711 struct sig_pri_cc_agent_prv *cc_pvt;
9715 pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
9721#if defined(HAVE_PRI_CCSS)
9738 struct sig_pri_cc_agent_prv *cc_pvt;
9748 if (cc_pvt->cc_request_response_pending) {
9749 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2);
9752 pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
9759#if defined(HAVE_PRI_CCSS)
9770static int sig_pri_cc_monitor_instance_hash_fn(
const void *obj,
const int flags)
9772 const struct sig_pri_cc_monitor_instance *monitor_instance = obj;
9774 return monitor_instance->core_id;
9778#if defined(HAVE_PRI_CCSS)
9790static int sig_pri_cc_monitor_instance_cmp_fn(
void *obj,
void *arg,
int flags)
9792 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
9793 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
9799#if defined(HAVE_PRI_CCSS)
9820 struct sig_pri_cc_monitor_instance *instance;
9840 res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
9847#if defined(HAVE_PRI_CCSS)
9863 struct sig_pri_cc_monitor_instance *instance;
9867 pri_cc_status(instance->pri->pri, instance->cc_id, 1);
9874#if defined(HAVE_PRI_CCSS)
9889 struct sig_pri_cc_monitor_instance *instance;
9893 pri_cc_status(instance->pri->pri, instance->cc_id, 0);
9900#if defined(HAVE_PRI_CCSS)
9919 struct sig_pri_cc_monitor_instance *instance;
9937 pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
9944#if defined(HAVE_PRI_CCSS)
9973#if defined(HAVE_PRI_CCSS)
9987 struct sig_pri_cc_monitor_instance *instance;
9989 instance = monitor_pvt;
10009#if defined(HAVE_PRI_MCID)
10015#if defined(HAVE_PRI_CCSS)
10016 sig_pri_cc_type_name = cc_type_name;
10018 sig_pri_cc_monitor_instance_hash_fn,
NULL, sig_pri_cc_monitor_instance_cmp_fn);
10019 if (!sig_pri_cc_monitors) {
10032#if defined(HAVE_PRI_CCSS)
10033 if (sig_pri_cc_monitors) {
10034 ao2_ref(sig_pri_cc_monitors, -1);
10035 sig_pri_cc_monitors =
NULL;
10039#if defined(HAVE_PRI_MCID)
Generic Advice of Charge encode and decode routines.
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
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
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.
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
const char * ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded)
get the currency name for AOC-D and AOC-E messages
@ AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION
@ AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT
@ AST_AOC_CHARGED_ITEM_NA
@ AST_AOC_CHARGED_ITEM_USER_USER_INFO
@ AST_AOC_CHARGED_ITEM_CALL_SETUP
@ AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE
@ AST_AOC_CHARGED_ITEM_CALL_ATTEMPT
@ AST_AOC_CHARGE_CURRENCY
@ AST_AOC_TIME_SCALE_TEN_SECOND
@ AST_AOC_TIME_SCALE_TENTH_SECOND
@ AST_AOC_TIME_SCALE_MINUTE
@ AST_AOC_TIME_SCALE_SECOND
@ AST_AOC_TIME_SCALE_HOUR
@ AST_AOC_TIME_SCALE_HUNDREDTH_SECOND
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
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.
int ast_aoc_get_termination_request(struct ast_aoc_decoded *decoded)
get whether or not the AST_AOC_REQUEST message as a termination request.
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
@ AST_AOC_MULT_ONEHUNDREDTH
@ AST_AOC_MULT_ONETHOUSANDTH
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
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
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
@ AST_AOC_CHARGING_ASSOCIATION_NA
@ AST_AOC_CHARGING_ASSOCIATION_ID
@ AST_AOC_CHARGING_ASSOCIATION_NUMBER
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging association number for an AOC-E message
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.
@ AST_AOC_BILLING_CALL_FWD_BUSY
@ AST_AOC_BILLING_CALL_FWD_NO_REPLY
@ AST_AOC_BILLING_CALL_DEFLECTION
@ AST_AOC_BILLING_CREDIT_CARD
@ AST_AOC_BILLING_CALL_TRANSFER
@ AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL
@ AST_AOC_BILLING_REVERSE_CHARGE
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.
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.
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 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.
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
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.
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
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.
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.
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
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
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
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
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.
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_aoc_set_termination_request(struct ast_aoc_decoded *decoded)
Mark the AST_AOC_REQUEST message as a termination request.
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 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.
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded)
get the currency amount for AOC-D and AOC-E messages
@ AST_AOC_RATE_TYPE_VOLUME
@ AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING
@ AST_AOC_RATE_TYPE_SPECIAL_CODE
@ AST_AOC_RATE_TYPE_DURATION
Persistent data storage (akin to *doze registry)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Asterisk main include file. File version handling, generic pbx functions.
void ast_std_free(void *ptr)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
#define ao2_unlink(container, obj)
Remove an object from a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
@ AST_BRIDGE_TRANSFER_SUCCESS
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define AST_PRES_USER_NUMBER_UNSCREENED
#define AST_PRES_UNAVAILABLE
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
#define AST_PRES_RESTRICTED
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
#define AST_PRES_NETWORK_NUMBER
#define AST_PRES_NUMBER_NOT_AVAILABLE
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
AST_REDIRECTING_REASON
redirecting reason codes.
@ AST_REDIRECTING_REASON_UNKNOWN
@ AST_REDIRECTING_REASON_NO_ANSWER
@ AST_REDIRECTING_REASON_DEFLECTION
@ AST_REDIRECTING_REASON_UNCONDITIONAL
@ AST_REDIRECTING_REASON_USER_BUSY
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Internal Asterisk hangup causes.
#define AST_CAUSE_SWITCH_CONGESTION
#define AST_CAUSE_UNALLOCATED
#define AST_CAUSE_INVALID_NUMBER_FORMAT
#define AST_CAUSE_NORMAL_CLEARING
#define AST_CAUSE_USER_BUSY
enum ast_cc_service_type service
int ast_cc_agent_accept_request(int core_id, const char *const debug,...)
Accept inbound CC request.
int ast_cc_agent_caller_busy(int core_id, const char *const debug,...)
Indicate that the caller is busy.
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...
#define AST_CC_GENERIC_MONITOR_TYPE
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.
int ast_cc_monitor_stop_ringing(int core_id)
Alert a caller to stop ringing.
int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
Set up a CC recall datastore on a channel.
ast_cc_agent_response_reason
@ AST_CC_AGENT_RESPONSE_FAILURE_INVALID
@ AST_CC_AGENT_RESPONSE_SUCCESS
@ AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY
int ast_cc_monitor_request_acked(int core_id, const char *const debug,...)
Indicate that an outbound entity has accepted our CC request.
int ast_cc_agent_recalling(int core_id, const char *const debug,...)
Tell the CC core that a caller is currently recalling.
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.
int ast_cc_monitor_status_request(int core_id)
Request the status of a caller or callers.
ast_cc_monitor_policies
The various possibilities for cc_monitor_policy values.
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.
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
int ast_cc_agent_caller_available(int core_id, const char *const debug,...)
Indicate that a previously unavailable caller has become available.
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.
int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
Set the first level CC_INTERFACES channel variable for a channel.
int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
Response with a caller's current status.
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_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
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...
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.
int ast_cc_get_current_core_id(struct ast_channel *chan)
Get the core id for the current call.
static int request(void *obj)
static int call(void *data)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
const char * ast_channel_name(const struct ast_channel *chan)
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.
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
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.
struct ast_party_id ast_channel_redirecting_effective_to(struct ast_channel *chan)
struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan)
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
void ast_party_subaddress_init(struct ast_party_subaddress *init)
Initialize the given subaddress structure.
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
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...
#define ast_channel_lock(chan)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
#define ast_channel_ref(c)
Increase channel reference count.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
ast_callid ast_channel_callid(const struct ast_channel *chan)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
const char * ast_channel_context(const struct ast_channel *chan)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
#define ast_channel_trylock(chan)
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
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.
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.
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 ast_channel_hangupcause(const struct ast_channel *chan)
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
@ AST_PARTY_CHAR_SET_UNKNOWN
@ AST_PARTY_CHAR_SET_ISO8859_4
@ AST_PARTY_CHAR_SET_WITHDRAWN
@ AST_PARTY_CHAR_SET_ISO8859_5
@ AST_PARTY_CHAR_SET_ISO8859_7
@ AST_PARTY_CHAR_SET_ISO8859_2
@ AST_PARTY_CHAR_SET_ISO8859_1
@ AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING
@ AST_PARTY_CHAR_SET_ISO10646_BMPSTRING
@ AST_PARTY_CHAR_SET_ISO8859_3
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.
struct ast_party_id ast_channel_redirecting_effective_orig(struct ast_channel *chan)
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel.
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
void ast_party_id_invalidate(struct ast_party_id *id)
Invalidate all components of the given party id.
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
#define ast_channel_unref(c)
Decrease channel reference count.
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
void ast_channel_context_set(struct ast_channel *chan, const char *value)
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
Destroy the party subaddress contents.
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
const char * ast_channel_exten(const struct ast_channel *chan)
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
ast_channel_state
ast_channel states
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Standard Command Line Interface.
void ast_cli(int fd, const char *fmt,...)
ast_device_state
Device States.
void ast_verbose(const char *fmt,...)
Call Parking and Pickup API Includes code and algorithms from the Zapata library.
Generic File Format Support. Should be included by clients of the file handling routines....
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_append(struct mansession *s, const char *fmt,...)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
static char prefix[MAX_PREFIX]
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
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.
char * strsep(char **str, const char *delims)
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_PVT_CAUSE_CODE
struct ast_frame ast_null_frame
#define ast_debug(level,...)
Log a DEBUG message.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
#define ast_verb(level,...)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
struct ast_json * ast_json_party_id(struct ast_party_id *party)
Construct an ast_party_id as JSON.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
int ast_json_is_true(const struct ast_json *value)
Check if value is JSON true.
#define AST_PTHREADT_NULL
#define ast_mutex_init(pmutex)
#define DEADLOCK_AVOIDANCE(lock)
#define ast_mutex_unlock(a)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
#define ast_mutex_trylock(a)
#define ast_mutex_lock(a)
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
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.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
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...
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.
Options provided by main asterisk program.
Core PBX routines and definitions.
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current 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.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
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.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
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)
struct stasis_forward * sub
static void to_ami(struct ast_sip_subscription *sub, struct ast_str **buf)
Say numbers and dates (maybe words one day too)
Interface header for PRI signaling module.
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
void sig_pri_unload(void)
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)
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)
int pri_is_up(struct sig_pri_span *pri)
int sig_pri_cc_agent_status_req(struct ast_cc_agent *agent)
@ SIG_PRI_MOH_STATE_NOTIFY
struct sig_pri_callback sig_pri_callbacks
@ SIG_PRI_MOH_EVENT_RESET
@ SIG_PRI_MOH_EVENT_UNHOLD
int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
#define SIG_PRI_NUM_DCHANS
int sig_pri_cc_agent_start_offer_timer(struct ast_cc_agent *agent)
int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast)
int sig_pri_cc_monitor_unsuspend(struct ast_cc_monitor *monitor)
int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel)
int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rdest, int timeout, int layer1)
#define DAHDI_OVERLAPDIAL_OUTGOING
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)
int sig_pri_cc_monitor_req_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
int sig_pri_start_pri(struct sig_pri_span *pri)
int sig_pri_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
void sig_pri_cli_show_channels(int fd, struct sig_pri_span *pri)
void sig_pri_cc_agent_req_rsp(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
int sig_pri_cc_monitor_suspend(struct ast_cc_monitor *monitor)
@ SIG_PRI_RESET_NO_ACK
Peer may not be sending the expected RESTART ACKNOWLEDGE.
@ SIG_PRI_RESET_ACTIVE
The channel is being RESTARTed.
@ SIG_PRI_RESET_IDLE
The channel is not being RESTARTed.
#define SIG_PRI_DEBUG_DEFAULT
void sig_pri_stop_pri(struct sig_pri_span *pri)
void sig_pri_cc_agent_destructor(struct ast_cc_agent *agent)
void sig_pri_cli_show_spans(int fd, int span, struct sig_pri_span *pri)
void sig_pri_init_pri(struct sig_pri_span *pri)
#define SIG_PRI_AOC_GRANT_D
int sig_pri_cc_agent_start_monitoring(struct ast_cc_agent *agent)
#define DAHDI_CHAN_MAPPING_LOGICAL
int sig_pri_cc_agent_init(struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
int sig_pri_load(const char *cc_type_name)
@ SIG_PRI_CALL_LEVEL_IDLE
@ SIG_PRI_CALL_LEVEL_CONNECT
@ SIG_PRI_CALL_LEVEL_OVERLAP
@ SIG_PRI_CALL_LEVEL_PROCEEDING
@ SIG_PRI_CALL_LEVEL_DEFER_DIAL
@ SIG_PRI_CALL_LEVEL_ALERTING
@ SIG_PRI_CALL_LEVEL_SETUP
@ SIG_PRI_MOH_SIGNALING_MOH
@ SIG_PRI_MOH_SIGNALING_NOTIFY
int sig_pri_cc_agent_callee_available(struct ast_cc_agent *agent)
#define DAHDI_OVERLAPDIAL_INCOMING
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)
#define SIG_PRI_AOC_GRANT_E
void sig_pri_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
void sig_pri_cc_monitor_destructor(void *monitor_pvt)
void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
struct sig_pri_chan * sig_pri_chan_new(void *pvt_data, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
void pri_event_noalarm(struct sig_pri_span *pri, int index, int before_start_pri)
void sig_pri_cli_show_span(int fd, int *dchannels, struct sig_pri_span *pri)
void sig_pri_chan_delete(struct sig_pri_chan *doomed)
int sig_pri_answer(struct sig_pri_chan *p, struct ast_channel *ast)
#define SIG_PRI_AOC_GRANT_S
@ SIG_PRI_TONE_CONGESTION
void pri_event_alarm(struct sig_pri_span *pri, int index, int before_start_pri)
int sig_pri_cc_agent_stop_offer_timer(struct ast_cc_agent *agent)
void sig_pri_cli_show_channels_header(int fd)
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
int sig_pri_cc_agent_party_b_free(struct ast_cc_agent *agent)
int sig_pri_cc_monitor_status_rsp(struct ast_cc_monitor *monitor, enum ast_device_state devstate)
int sig_pri_cc_agent_stop_ringing(struct ast_cc_agent *agent)
int sig_pri_digit_begin(struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
int pri_send_keypad_facility_exec(struct sig_pri_chan *p, const char *digits)
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
#define STASIS_MESSAGE_TYPE_DEFN_LOCAL(name,...)
Boiler-plate messaging macro for defining local message types.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
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.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
union ast_aoc_charging_association::@183 charge
struct ast_aoc_charging_association_number number
Structure to pass both assignedid values to channel drivers.
void * private_data
Data that is private to a monitor technology.
enum ast_cc_service_type service_offered
Blob of data associated with a channel.
struct ast_channel_snapshot * snapshot
Main Channel structure associated with a channel.
unsigned short transfercapability
struct ast_channel::@331 fds
char exten[AST_MAX_EXTENSION]
char chan_name[AST_CHANNEL_NAME]
Structure used to handle boolean flags.
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
Abstract JSON element (object, array, string, int, ...).
Struct containing info for an AMI event to send out.
The structure that contains MWI state.
const ast_string_field uniqueid
Caller Party information.
struct ast_party_id id
Caller party ID.
int ani2
Automatic Number Identification 2 (Info Digits)
Connected Line/Party information.
struct ast_party_dialed::@208 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Information needed to identify an endpoint in a call.
struct ast_party_subaddress subaddress
Subscriber subaddress.
char * tag
User-set "tag".
struct ast_party_name name
Subscriber name.
struct ast_party_number number
Subscriber phone number.
Information needed to specify a name in a call.
int char_set
Character set the name is using.
int presentation
Q.931 encoded presentation-indicator encoded field.
unsigned char valid
TRUE if the name information is valid/present.
char * str
Subscriber name (Malloced)
Information needed to specify a number in a call.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
unsigned char valid
TRUE if the number information is valid/present.
char * str
Subscriber phone number (Malloced)
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
int code
enum AST_REDIRECTING_REASON value for redirection
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
struct ast_party_id priv_to
Call is redirecting to a new party (Sent to the caller) - private representation.
struct ast_party_redirecting_reason orig_reason
Reason for the redirection by the original party.
struct ast_party_redirecting_reason reason
Reason for the redirection.
struct ast_party_id priv_from
Who is redirecting the call (Sent to the party the call is redirected toward) - private representatio...
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
int count
Number of times the call was redirected.
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
struct ast_party_id orig
Who originally redirected the call (Sent to the party the call is redirected toward)
struct ast_party_id priv_orig
Who originally redirected the call (Sent to the party the call is redirected toward) - private repres...
Information needed to specify a subaddress in a call.
unsigned char odd_even_indicator
TRUE if odd number of address signals.
unsigned char valid
TRUE if the subaddress information is valid/present.
char * str
Malloced subaddress string.
int type
Q.931 subaddress type.
Support for dynamic strings.
In case you didn't read that giant block of text above the mansession_session struct,...
int(*const set_echocanceller)(void *pvt, int enable)
void(*const set_rdnis)(void *pvt, const char *rdnis)
void(*const deadlock_avoidance_private)(void *pvt)
void(*const set_digital)(void *pvt, int is_digital)
void(*const dial_digits)(void *pvt, const char *dial_string)
void(*const unlock_private)(void *pvt)
void(*const init_config)(void *pvt, struct sig_pri_span *pri)
int(*const play_tone)(void *pvt, enum sig_pri_tone tone)
const char *(*const get_orig_dialstring)(void *pvt)
void(*const make_cc_dialstring)(void *pvt, char *buf, size_t buf_size)
void(* destroy_later)(struct sig_pri_span *pri)
int(*const new_nobch_intf)(struct sig_pri_span *pri)
void(*const set_callerid)(void *pvt, const struct ast_party_caller *caller)
void(*const set_dnid)(void *pvt, const char *dnid)
void(*const set_outgoing)(void *pvt, int is_outgoing)
void(*const set_dialing)(void *pvt, int is_dialing)
void(*const set_alarm)(void *pvt, int in_alarm)
void(*const ami_channel_event)(void *pvt, struct ast_channel *chan)
Post an AMI B channel association event.
void(*const handle_dchan_exception)(struct sig_pri_span *pri, int index)
void(*const queue_control)(void *pvt, int subclass)
void(*const update_span_devstate)(struct sig_pri_span *pri)
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)
int(*const dsp_reset_and_flush_digits)(void *pvt)
void(*const lock_private)(void *pvt)
void(* module_unref)(void)
void(*const open_media)(void *pvt)
void(*const fixup_chans)(void *old_chan, void *new_chan)
char user_tag[AST_MAX_EXTENSION *2]
User tag for party id's sent from this device driver.
char cid_subaddr[AST_MAX_EXTENSION]
struct sig_pri_span * pri
char cid_num[AST_MAX_EXTENSION]
enum sig_pri_reset_state resetting
Channel reset/restart state.
unsigned int allocated
TRUE when this channel is allocated.
char moh_suggested[MAX_MUSICCLASS]
unsigned int use_callingpres
unsigned int priexclusive
char exten[AST_MAX_EXTENSION]
unsigned int hidecallerid
struct ast_channel * owner
enum sig_pri_call_level call_level
char deferred_digits[AST_MAX_EXTENSION]
unsigned int priindication_oob
unsigned int hidecalleridname
char context[AST_MAX_CONTEXT]
enum sig_pri_moh_state moh_state
char cid_name[AST_MAX_EXTENSION]
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
unsigned int use_callerid
char cid_ani[AST_MAX_EXTENSION]
unsigned int alreadyhungup
char mohinterpret[MAX_MUSICCLASS]
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
char idleext[AST_MAX_EXTENSION]
enum sig_pri_moh_signaling moh_signaling
unsigned int inband_on_setup_ack
char msn_list[AST_MAX_EXTENSION]
int discardremoteholdretrieval
unsigned int inband_on_proceeding
int fds[SIG_PRI_NUM_DCHANS]
unsigned int append_msn_to_user_tag
int pritimers[PRI_MAX_TIMERS]
unsigned int layer1_ignored
struct pri * dchans[SIG_PRI_NUM_DCHANS]
unsigned int no_d_channels
char idlecontext[AST_MAX_CONTEXT]
enum sig_pri_colp_signaling colp_send
int dchanavail[SIG_PRI_NUM_DCHANS]
unsigned int force_restart_unavailable_chans
TRUE if forcing RESTART when receive cause 44 on this span.
unsigned int transfer
TRUE if call transfer is enabled for the span.
char internationalprefix[10]
int dchan_logical_span[SIG_PRI_NUM_DCHANS]
char idledial[AST_MAX_EXTENSION]
char initial_user_tag[AST_MAX_EXTENSION]
Initial user tag for party id's sent from this device driver.
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller,...
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
General Asterisk channel transcoding definitions.
#define AST_TRANS_CAP_DIGITAL
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_pthread_create_background(a, b, c, d)
#define ast_pthread_create_detached(a, b, c, d)