123#ifndef PRI_EVENT_FACILITY
124#error "Upgrade your libpri"
132#undef SUPPORT_USERUSER
140#if defined(HAVE_PRI_CCSS)
141struct sig_pri_cc_agent_prv {
147 unsigned char cc_request_response_pending;
150struct sig_pri_cc_monitor_instance {
162static const char *sig_pri_cc_type_name;
167static int pri_matchdigittimeout = 3000;
169static int pri_gendigittimeout = 8000;
171#define DCHAN_NOTINALARM (1 << 0)
172#define DCHAN_UP (1 << 1)
175#define PRI_CHANNEL(p) ((p) & 0xff)
176#define PRI_SPAN(p) (((p) >> 8) & 0xff)
177#define PRI_EXPLICIT (1 << 16)
178#define PRI_CIS_CALL (1 << 17)
179#define PRI_HELD_CALL (1 << 18)
182#define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP)
184static int pri_active_dchan_index(
struct sig_pri_span *pri);
212static unsigned int PVT_TO_CHANNEL(
struct sig_pri_chan *p)
214 int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->
mastertrunkgroup ? PRI_EXPLICIT : 0));
215 ast_debug(5,
"prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n",
221static void sig_pri_handle_dchan_exception(
struct sig_pri_span *pri,
int index)
228static void sig_pri_set_dialing(
struct sig_pri_chan *p,
int is_dialing)
235static void sig_pri_set_digital(
struct sig_pri_chan *p,
int is_digital)
243static void sig_pri_set_outgoing(
struct sig_pri_chan *p,
int is_outgoing)
271static const char *sig_pri_get_orig_dialstring(
struct sig_pri_chan *p)
280#if defined(HAVE_PRI_CCSS)
281static void sig_pri_make_cc_dialstring(
struct sig_pri_chan *p,
char *
buf,
size_t buf_size)
292static void sig_pri_dial_digits(
struct sig_pri_chan *p,
const char *dial_string)
308static void sig_pri_span_devstate_changed(
struct sig_pri_span *pri)
322static void sig_pri_set_caller_id(
struct sig_pri_chan *p)
331 caller.id.name.valid = 1;
333 caller.id.number.str = p->
cid_num;
334 caller.id.number.plan = p->
cid_ton;
336 caller.id.number.valid = 1;
339 caller.id.subaddress.valid = 1;
346 caller.ani.number.str = p->
cid_ani;
349 caller.ani.number.valid = 1;
364static void sig_pri_set_dnid(
struct sig_pri_chan *p,
const char *dnid)
379static void sig_pri_set_rdnis(
struct sig_pri_chan *p,
const char *rdnis)
386static void sig_pri_unlock_private(
struct sig_pri_chan *p)
400static void sig_pri_deadlock_avoidance_private(
struct sig_pri_chan *p)
406 sig_pri_unlock_private(p);
408 sig_pri_lock_private(p);
417 sig_pri_deadlock_avoidance_private(p);
421 pthread_kill(pri->
master, SIGURG);
438 switch (pri_reason) {
439 case PRI_REDIR_FORWARD_ON_BUSY:
442 case PRI_REDIR_FORWARD_ON_NO_REPLY:
445 case PRI_REDIR_DEFLECTION:
448 case PRI_REDIR_UNCONDITIONAL:
451 case PRI_REDIR_UNKNOWN:
473 switch (ast_reason) {
475 pri_reason = PRI_REDIR_FORWARD_ON_BUSY;
478 pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY;
481 pri_reason = PRI_REDIR_UNCONDITIONAL;
484 pri_reason = PRI_REDIR_DEFLECTION;
488 pri_reason = PRI_REDIR_UNKNOWN;
504static int pri_to_ast_presentation(
int pri_presentation)
506 int ast_presentation;
508 switch (pri_presentation) {
509 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED:
512 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
515 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
518 case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER:
522 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED:
525 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
528 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
531 case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER:
535 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED:
536 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
537 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
538 case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER:
547 return ast_presentation;
559static int ast_to_pri_presentation(
int ast_presentation)
561 int pri_presentation;
563 switch (ast_presentation) {
565 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
568 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
571 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
574 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER;
578 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
581 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
584 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
587 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER;
594 pri_presentation = PRES_NUMBER_NOT_AVAILABLE;
598 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
602 return pri_presentation;
618 switch (pri_char_set) {
620 case PRI_CHAR_SET_UNKNOWN:
623 case PRI_CHAR_SET_ISO8859_1:
626 case PRI_CHAR_SET_WITHDRAWN:
629 case PRI_CHAR_SET_ISO8859_2:
632 case PRI_CHAR_SET_ISO8859_3:
635 case PRI_CHAR_SET_ISO8859_4:
638 case PRI_CHAR_SET_ISO8859_5:
641 case PRI_CHAR_SET_ISO8859_7:
644 case PRI_CHAR_SET_ISO10646_BMPSTRING:
647 case PRI_CHAR_SET_ISO10646_UTF_8STRING:
668 switch (ast_char_set) {
671 pri_char_set = PRI_CHAR_SET_UNKNOWN;
674 pri_char_set = PRI_CHAR_SET_ISO8859_1;
677 pri_char_set = PRI_CHAR_SET_WITHDRAWN;
680 pri_char_set = PRI_CHAR_SET_ISO8859_2;
683 pri_char_set = PRI_CHAR_SET_ISO8859_3;
686 pri_char_set = PRI_CHAR_SET_ISO8859_4;
689 pri_char_set = PRI_CHAR_SET_ISO8859_5;
692 pri_char_set = PRI_CHAR_SET_ISO8859_7;
695 pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
698 pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
705#if defined(HAVE_PRI_SUBADDR)
714static void sig_pri_set_subaddress(
struct ast_party_subaddress *ast_subaddress,
const struct pri_party_subaddress *pri_subaddress)
717 if (pri_subaddress->length <= 0) {
722 if (!pri_subaddress->type) {
724 ast_subaddress->
str =
ast_strdup((
char *) pri_subaddress->data);
732 cnum =
ast_malloc(2 * pri_subaddress->length + 1);
739 len = pri_subaddress->length - 1;
740 for (x = 0; x <
len; ++x) {
741 ptr += sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[x]);
744 if (pri_subaddress->odd_even_indicator) {
746 sprintf(ptr,
"%01hhx", (
unsigned char)((pri_subaddress->data[
len]) >> 4));
749 sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[
len]);
751 ast_subaddress->
str = cnum;
753 ast_subaddress->
type = pri_subaddress->type;
755 ast_subaddress->
valid = 1;
759#if defined(HAVE_PRI_SUBADDR)
760static unsigned char ast_pri_pack_hex_char(
char c)
766 }
else if (
c < (
'9' + 1)) {
768 }
else if (
c <
'A') {
770 }
else if (
c < (
'F' + 1)) {
772 }
else if (
c <
'a') {
774 }
else if (
c < (
'f' + 1)) {
783#if defined(HAVE_PRI_SUBADDR)
799static int ast_pri_pack_hex_string(
unsigned char *dst,
char *src,
int maxlen)
802 int len = strlen(src);
804 if (
len > (2 * maxlen)) {
811 *dst = ast_pri_pack_hex_char(*src) << 4;
813 *dst |= ast_pri_pack_hex_char(*src);
818 *dst = ast_pri_pack_hex_char(*src) << 4;
824#if defined(HAVE_PRI_SUBADDR)
835static void sig_pri_party_subaddress_from_ast(
struct pri_party_subaddress *pri_subaddress,
const struct ast_party_subaddress *ast_subaddress)
838 pri_subaddress->type = ast_subaddress->
type;
839 if (!ast_subaddress->
type) {
842 sizeof(pri_subaddress->data));
843 pri_subaddress->length = strlen((
char *) pri_subaddress->data);
844 pri_subaddress->odd_even_indicator = 0;
845 pri_subaddress->valid = 1;
852 int length = ast_pri_pack_hex_string(pri_subaddress->data,
853 ast_subaddress->
str,
sizeof(pri_subaddress->data));
855 pri_subaddress->length = length;
857 length = strlen(ast_subaddress->
str);
858 if (length > 2 *
sizeof(pri_subaddress->data)) {
859 pri_subaddress->odd_even_indicator = 0;
861 pri_subaddress->odd_even_indicator = (length & 1);
863 pri_subaddress->valid = 1;
879static void sig_pri_party_name_from_ast(
struct pri_party_name *pri_name,
const struct ast_party_name *ast_name)
881 if (!ast_name->
valid) {
885 pri_name->presentation = ast_to_pri_presentation(ast_name->
presentation);
886 pri_name->char_set = ast_to_pri_char_set(ast_name->
char_set);
902static void sig_pri_party_number_from_ast(
struct pri_party_number *pri_number,
const struct ast_party_number *ast_number)
904 if (!ast_number->
valid) {
907 pri_number->valid = 1;
908 pri_number->presentation = ast_to_pri_presentation(ast_number->
presentation);
909 pri_number->plan = ast_number->
plan;
925static void sig_pri_party_id_from_ast(
struct pri_party_id *pri_id,
const struct ast_party_id *ast_id)
927 sig_pri_party_name_from_ast(&pri_id->name, &ast_id->
name);
928 sig_pri_party_number_from_ast(&pri_id->number, &ast_id->
number);
929#if defined(HAVE_PRI_SUBADDR)
930 sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->
subaddress);
946 struct pri_party_redirecting pri_redirecting;
952 memset(&pri_redirecting, 0,
sizeof(pri_redirecting));
954 sig_pri_party_id_from_ast(&pri_redirecting.from, &redirecting_from);
955 sig_pri_party_id_from_ast(&pri_redirecting.to, &redirecting_to);
956 sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &redirecting_orig);
957 pri_redirecting.count = ast_redirecting->
count;
958 pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->
orig_reason.
code);
959 pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->
reason.
code);
961 pri_redirecting_update(pvt->
pri->
pri, pvt->
call, &pri_redirecting);
971static void sig_pri_dsp_reset_and_flush_digits(
struct sig_pri_chan *p)
978static int sig_pri_set_echocanceller(
struct sig_pri_chan *p,
int enable)
1026 sig_pri_set_digital(p, 1);
1030 sig_pri_span_devstate_changed(p->
pri);
1064static void sig_pri_ami_channel_event(
struct sig_pri_chan *p)
1079 sig_pri_set_outgoing(p, 1);
1081 p->
exten, assignedids, requestor);
1083 sig_pri_set_outgoing(p, 0);
1098static const char *pri_order(
int level)
1108 return "Quaternary";
1115static int pri_active_dchan_index(
struct sig_pri_span *pri)
1141 if (pri->
dchans[idx] == old) {
1144 if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) {
1158 if (old && oldslot != newslot) {
1160 "Span %d: No D-channels up! Switching selected D-channel from %s to %s.\n",
1161 pri->
span, pri_order(oldslot), pri_order(newslot));
1169 if (old && oldslot != newslot) {
1171 "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n",
1172 pri_order(oldslot), pri->
fds[oldslot],
1173 pri_order(newslot), pri->
fds[newslot]);
1207static int sig_pri_is_chan_in_use(
struct sig_pri_chan *pvt)
1223 return !sig_pri_is_chan_in_use(pvt)
1224#if defined(HAVE_PRI_SERVICE_MESSAGES)
1226 && !pvt->service_status
1242static void sig_pri_lock_owner(
struct sig_pri_span *pri,
int chanpos)
1255 sig_pri_unlock_private(pri->
pvts[chanpos]);
1257 sig_pri_lock_private(pri->
pvts[chanpos]);
1275 sig_pri_lock_owner(pri, chanpos);
1293static void sig_pri_queue_hold(
struct sig_pri_span *pri,
int chanpos)
1295 sig_pri_lock_owner(pri, chanpos);
1313static void sig_pri_queue_unhold(
struct sig_pri_span *pri,
int chanpos)
1315 sig_pri_lock_owner(pri, chanpos);
1334static void pri_queue_control(
struct sig_pri_span *pri,
int chanpos,
int subclass)
1343 pri_queue_frame(pri, chanpos, &f);
1360static void sig_pri_queue_hangup(
struct sig_pri_span *pri,
int chanpos)
1368 sig_pri_lock_owner(pri, chanpos);
1375 sig_pri_unlock_private(pri->
pvts[chanpos]);
1380 sig_pri_lock_private(pri->
pvts[chanpos]);
1399static void pri_queue_pvt_cause_data(
struct sig_pri_span *pri,
int chanpos,
const char *cause,
int ast_cause)
1404 sig_pri_lock_owner(pri, chanpos);
1407 int datalen =
sizeof(*cause_code) + strlen(cause);
1409 memset(cause_code, 0, datalen);
1432static int pri_find_principle_by_call(
struct sig_pri_span *pri, q931_call *
call)
1440 for (idx = 0; idx < pri->
numchans; ++idx) {
1479static void sig_pri_kill_call(
struct sig_pri_span *pri, q931_call *
call,
int cause)
1483 chanpos = pri_find_principle_by_call(pri,
call);
1485 pri_hangup(pri->
pri,
call, cause);
1488 sig_pri_lock_private(pri->
pvts[chanpos]);
1490 pri_hangup(pri->
pri,
call, cause);
1492 sig_pri_unlock_private(pri->
pvts[chanpos]);
1493 sig_pri_span_devstate_changed(pri);
1498 sig_pri_unlock_private(pri->
pvts[chanpos]);
1514static int pri_find_principle(
struct sig_pri_span *pri,
int channel, q931_call *
call)
1526 prioffset = PRI_CHANNEL(channel);
1527 if (!prioffset || (channel & PRI_HELD_CALL)) {
1529 return pri_find_principle_by_call(pri,
call);
1532 span = PRI_SPAN(channel);
1533 if (!(channel & PRI_EXPLICIT)) {
1536 index = pri_active_dchan_index(pri);
1544 for (x = 0; x < pri->
numchans; x++) {
1570static int pri_fixup_principle(
struct sig_pri_span *pri,
int principle, q931_call *
call)
1574 if (principle < 0 || pri->numchans <= principle) {
1588 for (x = 0; x < pri->
numchans; x++) {
1597 new_chan =
pri->
pvts[principle];
1601 sig_pri_lock_private(old_chan);
1602 sig_pri_lock_owner(
pri, x);
1603 sig_pri_lock_private(new_chan);
1605 ast_verb(3,
"Moving call (%s) from channel %d to %d.\n",
1610 "Can't move call (%s) from channel %d to %d. It is already in use.\n",
1613 sig_pri_unlock_private(new_chan);
1614 if (old_chan->
owner) {
1617 sig_pri_unlock_private(old_chan);
1621 sig_pri_fixup_chans(old_chan, new_chan);
1631#if defined(HAVE_PRI_AOC_EVENTS)
1632 new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid;
1633 new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
1634 new_chan->holding_aoce = old_chan->holding_aoce;
1642#if defined(HAVE_PRI_CALL_WAITING)
1643 new_chan->is_call_waiting = old_chan->is_call_waiting;
1645#if defined(HAVE_PRI_SETUP_ACK_INBAND)
1646 new_chan->no_dialed_digits = old_chan->no_dialed_digits;
1649#if defined(HAVE_PRI_AOC_EVENTS)
1650 old_chan->aoc_s_request_invoke_id_valid = 0;
1651 old_chan->waiting_for_aoce = 0;
1652 old_chan->holding_aoce = 0;
1660#if defined(HAVE_PRI_CALL_WAITING)
1661 old_chan->is_call_waiting = 0;
1663#if defined(HAVE_PRI_SETUP_ACK_INBAND)
1664 old_chan->no_dialed_digits = 0;
1670#if defined(HAVE_PRI_REVERSE_CHARGE)
1671 new_chan->reverse_charging_indication = old_chan->reverse_charging_indication;
1673#if defined(HAVE_PRI_SETUP_KEYPAD)
1674 strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
1680#if defined(HAVE_PRI_TRANSFER)
1681 new_chan->xfer_data = old_chan->xfer_data;
1682 old_chan->xfer_data =
NULL;
1685#if defined(HAVE_PRI_AOC_EVENTS)
1686 new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
1687 new_chan->aoc_e = old_chan->aoc_e;
1714 sig_pri_open_media(new_chan);
1717 if (new_chan->
owner) {
1718 sig_pri_ami_channel_event(new_chan);
1721 sig_pri_unlock_private(old_chan);
1722 if (new_chan->
owner) {
1725 sig_pri_unlock_private(new_chan);
1729 ast_verb(3,
"Call specified, but not found.\n");
1759 sig_pri_kill_call(
pri,
call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
1762 chanpos = pri_fixup_principle(
pri, chanpos,
call);
1773 sig_pri_kill_call(
pri,
call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
1779static char * redirectingreason2str(
int redirectingreason)
1781 switch (redirectingreason) {
1789 return "UNCONDITIONAL";
1791 return "NOREDIRECT";
1795static char *dialplan2str(
int dialplan)
1797 if (dialplan == -1) {
1798 return(
"Dynamically set dialplan in ISDN");
1800 return (pri_plan2str(dialplan));
1813static void apply_plan_to_number(
char *
buf,
size_t size,
const struct sig_pri_span *
pri,
const char *
number,
int plan)
1816 case PRI_INTERNATIONAL_ISDN:
1819 case PRI_NATIONAL_ISDN:
1822 case PRI_LOCAL_ISDN:
1847static void apply_plan_to_existing_number(
char *
buf,
size_t size,
const struct sig_pri_span *
pri,
const char *
number,
int plan)
1869#if defined(HAVE_PRI_SERVICE_MESSAGES)
1879#if defined(HAVE_PRI_SERVICE_MESSAGES)
1883 "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n",
1885 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ?
"both ends" :
"far end" :
"near end");
1898 sig_pri_span_devstate_changed(
pri);
1902#if defined(HAVE_PRI_CALL_WAITING)
1944static int pri_find_empty_chan(
struct sig_pri_span *
pri,
int backwards)
1952 if (backwards && (x < 0))
1959 ast_debug(1,
"Found empty available channel %d/%d\n",
1971#if defined(HAVE_PRI_CALL_HOLD)
1992 ast_debug(1,
"Found empty available no B channel interface\n");
2007static void *do_idle_thread(
void *v_pvt)
2014 int timeout_ms = 30000;
2016 struct timeval start;
2067static void *pri_ss_thread(
void *data)
2098 sig_pri_dsp_reset_and_flush_digits(p);
2106 sig_pri_play_tone(p, -1);
2110 timeout = pri_matchdigittimeout;
2112 timeout = pri_gendigittimeout;
2115 ast_debug(1,
"waitfordigit returned < 0...\n");
2126 ast_verb(3,
"Going to extension s|1 because of empty extension received on overlap call\n");
2144 sig_pri_play_tone(p, -1);
2148 sig_pri_dsp_reset_and_flush_digits(p);
2149#if defined(JIRA_ASTERISK_15594)
2164 sig_pri_lock_private(p);
2166 pri_grab(p, p->
pri);
2170 pri_proceeding(p->
pri->
pri, p->
call, PVT_TO_CHANNEL(p), 0);
2173 sig_pri_unlock_private(p);
2177 sig_pri_set_echocanceller(p, 1);
2193 sig_pri_span_devstate_changed(p->
pri);
2202 if (!before_start_pri) {
2203 pri_find_dchan(pri);
2210 if (!before_start_pri)
2211 pri_restart(pri->
dchans[index]);
2225static void sig_pri_party_name_convert(
struct ast_party_name *ast_name,
const struct pri_party_name *pri_name)
2228 ast_name->
char_set = pri_to_ast_char_set(pri_name->char_set);
2229 ast_name->
presentation = pri_to_ast_presentation(pri_name->presentation);
2230 ast_name->
valid = 1;
2245static void sig_pri_party_number_convert(
struct ast_party_number *ast_number,
const struct pri_party_number *pri_number,
struct sig_pri_span *pri)
2249 apply_plan_to_existing_number(
number,
sizeof(
number), pri, pri_number->str,
2252 ast_number->
plan = pri_number->plan;
2253 ast_number->
presentation = pri_to_ast_presentation(pri_number->presentation);
2254 ast_number->
valid = 1;
2269static void sig_pri_party_id_convert(
struct ast_party_id *ast_id,
const struct pri_party_id *pri_id,
struct sig_pri_span *pri)
2271 if (pri_id->name.valid) {
2272 sig_pri_party_name_convert(&ast_id->
name, &pri_id->name);
2274 if (pri_id->number.valid) {
2275 sig_pri_party_number_convert(&ast_id->
number, &pri_id->number, pri);
2277#if defined(HAVE_PRI_SUBADDR)
2278 if (pri_id->subaddress.valid) {
2279 sig_pri_set_subaddress(&ast_id->
subaddress, &pri_id->subaddress);
2298 const struct pri_party_redirecting *pri_redirecting,
2304 sig_pri_party_id_convert(&ast_redirecting->
orig, &pri_redirecting->orig_called, pri);
2305 sig_pri_party_id_convert(&ast_redirecting->
from, &pri_redirecting->from, pri);
2306 sig_pri_party_id_convert(&ast_redirecting->
to, &pri_redirecting->to, pri);
2307 ast_redirecting->
count = pri_redirecting->count;
2308 ast_redirecting->
reason.
code = pri_to_ast_reason(pri_redirecting->reason);
2309 ast_redirecting->
orig_reason.
code = pri_to_ast_reason(pri_redirecting->orig_reason);
2323static int sig_pri_msn_match(
const char *msn_patterns,
const char *
exten)
2332 pattern = strtok_r(msn_list,
",", &list_tail);
2339 pattern = strtok_r(
NULL,
",", &list_tail);
2345#if defined(HAVE_PRI_MCID)
2348 const char *num_txt, *pres_txt;
2373 const char *name_txt, *pres_txt, *
charset;
2377 "%sNameValid: 0\r\n"
2394static void party_subaddress_json_to_ami(
struct ast_str **msg,
const char *
prefix,
struct ast_json *subaddress)
2396 const char *subaddress_txt, *type_txt;
2440 party_subaddress_json_to_ami(msg,
prefix, subaddress);
2451 if (!channel_string) {
2499static void sig_pri_mcid_event(
struct sig_pri_span *pri,
const struct pri_subcmd_mcid_req *mcid,
struct ast_channel *owner)
2506 sig_pri_party_id_convert(&connected_party, &mcid->answerer, pri);
2521 sig_pri_party_id_convert(&caller_party, &mcid->originator, pri);
2522 send_mcid(owner, &caller_party, &connected_party);
2529#if defined(HAVE_PRI_TRANSFER)
2530struct xfer_rsp_data {
2541#if defined(HAVE_PRI_TRANSFER)
2552static void sig_pri_transfer_rsp(
struct xfer_rsp_data *rsp,
int is_successful)
2554 if (rsp->responded) {
2559 pri_transfer_rsp(rsp->pri->pri, rsp->call, rsp->invoke_id, is_successful);
2563#if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
2581static 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)
2583 struct attempt_xfer_call {
2591 struct attempt_xfer_call *call_1;
2592 struct attempt_xfer_call *call_2;
2593 struct attempt_xfer_call c1;
2594 struct attempt_xfer_call c2;
2596 c1.pri = call_1_pri;
2597 c1.held = call_1_held;
2600 c2.pri = call_2_pri;
2601 c2.held = call_2_held;
2604 call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri);
2605 call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri);
2606 if (call_1->chanpos < 0 || call_2->chanpos < 0) {
2608#if defined(HAVE_PRI_TRANSFER)
2611 sig_pri_transfer_rsp(xfer_data, 0);
2618 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2619 sig_pri_lock_owner(pri, call_1->chanpos);
2620 call_1->ast = pri->
pvts[call_1->chanpos]->
owner;
2625 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2628 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2629 sig_pri_lock_owner(pri, call_2->chanpos);
2630 call_2->ast = pri->
pvts[call_2->chanpos]->
owner;
2635 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2637 if (!call_1->ast || !call_2->ast) {
2645#if defined(HAVE_PRI_TRANSFER)
2648 sig_pri_transfer_rsp(xfer_data, 0);
2654 ast_verb(3,
"TRANSFERRING %s to %s\n",
2657#if defined(HAVE_PRI_TRANSFER)
2664 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2665 pri->
pvts[call_1->chanpos]->xfer_data = xfer_data;
2666 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2667 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2668 pri->
pvts[call_2->chanpos]->xfer_data = xfer_data;
2669 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2678#if defined(HAVE_PRI_TRANSFER)
2687 rsp_chanpos = pri_find_principle_by_call(pri, call_1->pri);
2688 if (0 <= rsp_chanpos) {
2689 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2690 pri->
pvts[rsp_chanpos]->xfer_data =
NULL;
2691 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2693 rsp_chanpos = pri_find_principle_by_call(pri, call_2->pri);
2694 if (0 <= rsp_chanpos) {
2695 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2696 pri->
pvts[rsp_chanpos]->xfer_data =
NULL;
2697 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2701 sig_pri_transfer_rsp(xfer_data, retval ? 0 : 1);
2710#if defined(HAVE_PRI_CCSS)
2722static int sig_pri_cc_agent_cmp_cc_id(
void *obj,
void *arg,
int flags)
2725 struct sig_pri_cc_agent_prv *agent_prv_1 = agent_1->
private_data;
2726 struct sig_pri_cc_agent_prv *agent_prv_2 = arg;
2728 return (agent_prv_1 && agent_prv_1->pri == agent_prv_2->pri
2733#if defined(HAVE_PRI_CCSS)
2752 struct sig_pri_cc_agent_prv finder = {
2758 sig_pri_cc_type_name);
2762#if defined(HAVE_PRI_CCSS)
2774static int sig_pri_cc_monitor_cmp_cc_id(
void *obj,
void *arg,
int flags)
2776 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
2777 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
2779 return (monitor_1->pri == monitor_2->pri
2784#if defined(HAVE_PRI_CCSS)
2801static struct sig_pri_cc_monitor_instance *sig_pri_find_cc_monitor_by_cc_id(
struct sig_pri_span *pri,
long cc_id)
2803 struct sig_pri_cc_monitor_instance finder = {
2808 return ao2_callback(sig_pri_cc_monitors, 0, sig_pri_cc_monitor_cmp_cc_id, &finder);
2812#if defined(HAVE_PRI_CCSS)
2820static void sig_pri_cc_monitor_instance_destroy(
void *data)
2822 struct sig_pri_cc_monitor_instance *monitor_instance = data;
2824 if (monitor_instance->cc_id != -1) {
2826 pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id);
2833#if defined(HAVE_PRI_CCSS)
2852static 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)
2854 struct sig_pri_cc_monitor_instance *monitor_instance;
2860 monitor_instance =
ao2_alloc(
sizeof(*monitor_instance) + strlen(device_name),
2861 sig_pri_cc_monitor_instance_destroy);
2862 if (!monitor_instance) {
2866 monitor_instance->cc_id = cc_id;
2867 monitor_instance->pri = pri;
2868 monitor_instance->core_id = core_id;
2869 strcpy(monitor_instance->name, device_name);
2873 ao2_link(sig_pri_cc_monitors, monitor_instance);
2874 return monitor_instance;
2878#if defined(HAVE_PRI_CCSS)
2900 struct sig_pri_cc_monitor_instance *monitor;
2907 pvt = pri->
pvts[chanpos];
2910 if (core_id == -1) {
2921 switch (monitor_policy) {
2932 sig_pri_make_cc_dialstring(pvt, dialstring,
sizeof(dialstring));
2933 monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
2940 monitor->cc_id = -1;
2971#if defined(HAVE_PRI_CCSS)
2983 sig_pri_lock_owner(pri, chanpos);
3000#if defined(HAVE_PRI_CCSS)
3011 switch (monitor_policy) {
3052#if defined(HAVE_PRI_CCSS)
3062static void sig_pri_cc_link_canceled(
struct sig_pri_span *pri,
long cc_id,
int is_agent)
3067 agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
3072 sig_pri_cc_type_name);
3075 struct sig_pri_cc_monitor_instance *monitor;
3077 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
3081 monitor->cc_id = -1;
3083 "%s monitor got canceled by link", sig_pri_cc_type_name);
3089#if defined(HAVE_PRI_AOC_EVENTS)
3099static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri(
enum PRI_AOC_CHARGED_ITEM
value)
3103 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3105 return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
3107 return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
3109 return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
3111 return PRI_AOC_CHARGED_ITEM_CALL_SETUP;
3113 return PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
3115 return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
3117 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3121#if defined(HAVE_PRI_AOC_EVENTS)
3134 case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE:
3136 case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
3138 case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
3140 case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
3142 case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
3144 case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
3146 case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
3153#if defined(HAVE_PRI_AOC_EVENTS)
3165 return PRI_AOC_MULTIPLIER_THOUSANDTH;
3167 return PRI_AOC_MULTIPLIER_HUNDREDTH;
3169 return PRI_AOC_MULTIPLIER_TENTH;
3171 return PRI_AOC_MULTIPLIER_ONE;
3173 return PRI_AOC_MULTIPLIER_TEN;
3175 return PRI_AOC_MULTIPLIER_HUNDRED;
3177 return PRI_AOC_MULTIPLIER_THOUSAND;
3179 return PRI_AOC_MULTIPLIER_ONE;
3184#if defined(HAVE_PRI_AOC_EVENTS)
3192static int sig_pri_aoc_multiplier_from_pri(
const int mult)
3195 case PRI_AOC_MULTIPLIER_THOUSANDTH:
3197 case PRI_AOC_MULTIPLIER_HUNDREDTH:
3199 case PRI_AOC_MULTIPLIER_TENTH:
3201 case PRI_AOC_MULTIPLIER_ONE:
3203 case PRI_AOC_MULTIPLIER_TEN:
3205 case PRI_AOC_MULTIPLIER_HUNDRED:
3207 case PRI_AOC_MULTIPLIER_THOUSAND:
3215#if defined(HAVE_PRI_AOC_EVENTS)
3230 return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
3232 return PRI_AOC_TIME_SCALE_TENTH_SECOND;
3234 return PRI_AOC_TIME_SCALE_SECOND;
3236 return PRI_AOC_TIME_SCALE_TEN_SECOND;
3238 return PRI_AOC_TIME_SCALE_MINUTE;
3240 return PRI_AOC_TIME_SCALE_HOUR;
3242 return PRI_AOC_TIME_SCALE_DAY;
3247#if defined(HAVE_PRI_AOC_EVENTS)
3261 case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND:
3263 case PRI_AOC_TIME_SCALE_TENTH_SECOND:
3265 case PRI_AOC_TIME_SCALE_SECOND:
3267 case PRI_AOC_TIME_SCALE_TEN_SECOND:
3269 case PRI_AOC_TIME_SCALE_MINUTE:
3271 case PRI_AOC_TIME_SCALE_HOUR:
3273 case PRI_AOC_TIME_SCALE_DAY:
3280#if defined(HAVE_PRI_AOC_EVENTS)
3294static void sig_pri_aoc_s_from_pri(
const struct pri_subcmd_aoc_s *aoc_s,
struct ast_channel *owner,
int passthrough)
3298 size_t encoded_size = 0;
3301 if (!owner || !aoc_s) {
3309 for (idx = 0; idx < aoc_s->num_items; ++idx) {
3312 charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable);
3317 switch (aoc_s->item[idx].rate_type) {
3318 case PRI_AOC_RATE_TYPE_DURATION:
3321 aoc_s->item[idx].rate.duration.amount.cost,
3322 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier),
3323 aoc_s->item[idx].rate.duration.currency,
3324 aoc_s->item[idx].rate.duration.time.length,
3325 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale),
3326 aoc_s->item[idx].rate.duration.granularity.length,
3327 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale),
3328 aoc_s->item[idx].rate.duration.charging_type);
3330 case PRI_AOC_RATE_TYPE_FLAT:
3333 aoc_s->item[idx].rate.flat.amount.cost,
3334 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier),
3335 aoc_s->item[idx].rate.flat.currency);
3337 case PRI_AOC_RATE_TYPE_VOLUME:
3340 aoc_s->item[idx].rate.volume.unit,
3341 aoc_s->item[idx].rate.volume.amount.cost,
3342 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier),
3343 aoc_s->item[idx].rate.volume.currency);
3345 case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
3348 aoc_s->item[idx].rate.special);
3350 case PRI_AOC_RATE_TYPE_FREE:
3353 case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
3362 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3373#if defined(HAVE_PRI_AOC_EVENTS)
3385static void sig_pri_aoc_request_from_pri(
const struct pri_subcmd_aoc_request *aoc_request,
struct sig_pri_chan *pvt, q931_call *
call)
3393 request = aoc_request->charging_request;
3395 if (
request & PRI_AOC_REQUEST_S) {
3399 pvt->aoc_s_request_invoke_id = aoc_request->invoke_id;
3400 pvt->aoc_s_request_invoke_id_valid = 1;
3403 pri_aoc_s_request_response_send(pvt->
pri->
pri,
3405 aoc_request->invoke_id,
3410 if (
request & PRI_AOC_REQUEST_D) {
3412 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3414 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3415 aoc_request->invoke_id);
3417 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3419 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3420 aoc_request->invoke_id);
3424 if (
request & PRI_AOC_REQUEST_E) {
3426 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3428 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3429 aoc_request->invoke_id);
3431 pri_aoc_de_request_response_send(pvt->
pri->
pri,
3433 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3434 aoc_request->invoke_id);
3440#if defined(HAVE_PRI_AOC_EVENTS)
3454static void sig_pri_aoc_d_from_pri(
const struct pri_subcmd_aoc_d *aoc_d,
struct ast_channel *owner,
int passthrough)
3458 size_t encoded_size = 0;
3461 if (!owner || !aoc_d) {
3465 switch (aoc_d->charge) {
3466 case PRI_AOC_DE_CHARGE_CURRENCY:
3469 case PRI_AOC_DE_CHARGE_UNITS:
3472 case PRI_AOC_DE_CHARGE_FREE:
3484 switch (aoc_d->billing_accumulation) {
3486 ast_debug(1,
"AOC-D billing accumulation has unknown value: %d\n",
3487 aoc_d->billing_accumulation);
3497 switch (aoc_d->billing_id) {
3498 case PRI_AOC_D_BILLING_ID_NORMAL:
3501 case PRI_AOC_D_BILLING_ID_REVERSE:
3504 case PRI_AOC_D_BILLING_ID_CREDIT_CARD:
3507 case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE:
3513 switch (aoc_d->charge) {
3514 case PRI_AOC_DE_CHARGE_CURRENCY:
3516 aoc_d->recorded.money.amount.cost,
3517 sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier),
3518 aoc_d->recorded.money.currency);
3520 case PRI_AOC_DE_CHARGE_UNITS:
3523 for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) {
3526 (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0),
3527 aoc_d->recorded.unit.item[i].number,
3528 (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0),
3529 aoc_d->recorded.unit.item[i].type);
3535 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3546#if defined(HAVE_PRI_AOC_EVENTS)
3561static void sig_pri_aoc_e_from_pri(
const struct pri_subcmd_aoc_e *aoc_e,
struct ast_channel *owner,
int passthrough)
3565 size_t encoded_size = 0;
3572 switch (aoc_e->charge) {
3573 case PRI_AOC_DE_CHARGE_CURRENCY:
3576 case PRI_AOC_DE_CHARGE_UNITS:
3579 case PRI_AOC_DE_CHARGE_FREE:
3591 switch (aoc_e->associated.charging_type) {
3592 case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER:
3593 if (!aoc_e->associated.charge.number.valid) {
3598 case PRI_AOC_E_CHARGING_ASSOCIATION_ID:
3605 switch (aoc_e->billing_id) {
3606 case PRI_AOC_E_BILLING_ID_NORMAL:
3609 case PRI_AOC_E_BILLING_ID_REVERSE:
3612 case PRI_AOC_E_BILLING_ID_CREDIT_CARD:
3615 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL:
3618 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY:
3621 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY:
3624 case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION:
3627 case PRI_AOC_E_BILLING_ID_CALL_TRANSFER:
3630 case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE:
3636 switch (aoc_e->charge) {
3637 case PRI_AOC_DE_CHARGE_CURRENCY:
3639 aoc_e->recorded.money.amount.cost,
3640 sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier),
3641 aoc_e->recorded.money.currency);
3643 case PRI_AOC_DE_CHARGE_UNITS:
3646 for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) {
3649 (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0),
3650 aoc_e->recorded.unit.item[i].number,
3651 (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0),
3652 aoc_e->recorded.unit.item[i].type);
3657 if (passthrough && owner && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3668#if defined(HAVE_PRI_AOC_EVENTS)
3680 struct pri_subcmd_aoc_s aoc_s = { 0, };
3689 aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(entry->
charged_item);
3693 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
3695 aoc_s.item[idx].rate.duration.amount.multiplier =
3698 aoc_s.item[idx].rate.duration.time.scale =
3701 aoc_s.item[idx].rate.duration.granularity.scale =
3708 sizeof(aoc_s.item[idx].rate.duration.currency));
3712 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
3714 aoc_s.item[idx].rate.flat.amount.multiplier =
3720 sizeof(aoc_s.item[idx].rate.flat.currency));
3724 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
3727 aoc_s.item[idx].rate.volume.amount.multiplier =
3733 sizeof(aoc_s.item[idx].rate.volume.currency));
3737 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
3741 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
3744 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
3748 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
3752 aoc_s.num_items = idx;
3756 if (pvt->aoc_s_request_invoke_id_valid) {
3757 pri_aoc_s_request_response_send(pvt->
pri->
pri, pvt->
call, pvt->aoc_s_request_invoke_id, &aoc_s);
3758 pvt->aoc_s_request_invoke_id_valid = 0;
3760 pri_aoc_s_send(pvt->
pri->
pri, pvt->
call, &aoc_s);
3765#if defined(HAVE_PRI_AOC_EVENTS)
3777 struct pri_subcmd_aoc_d aoc_d = { 0, };
3783 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL;
3786 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE;
3789 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
3793 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
3799 aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
3804 aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
3808 ast_copy_string(aoc_d.recorded.money.currency, currency_name,
sizeof(aoc_d.recorded.money.currency));
3816 aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
3820 aoc_d.recorded.unit.item[i].number = entry->
amount;
3822 aoc_d.recorded.unit.item[i].number = -1;
3825 aoc_d.recorded.unit.item[i].type = entry->
type;
3827 aoc_d.recorded.unit.item[i].type = -1;
3829 aoc_d.recorded.unit.num_items++;
3838 aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3842 pri_aoc_d_send(pvt->
pri->
pri, pvt->
call, &aoc_d);
3846#if defined(HAVE_PRI_AOC_EVENTS)
3858 struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
3861 memset(aoc_e, 0,
sizeof(*aoc_e));
3862 pvt->holding_aoce = 1;
3866 aoc_e->associated.charge.number.valid = 1;
3869 sizeof(aoc_e->associated.charge.number.str));
3871 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
3874 aoc_e->associated.charge.id = ca->
charge.
id;
3875 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
3884 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL;
3887 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE;
3890 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
3893 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
3896 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
3899 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
3902 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
3905 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
3909 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
3915 aoc_e->charge = PRI_AOC_DE_CHARGE_FREE;
3920 aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY;
3924 ast_copy_string(aoc_e->recorded.money.currency, currency_name,
sizeof(aoc_e->recorded.money.currency));
3932 aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS;
3936 aoc_e->recorded.unit.item[i].number = entry->
amount;
3938 aoc_e->recorded.unit.item[i].number = -1;
3941 aoc_e->recorded.unit.item[i].type = entry->
type;
3943 aoc_e->recorded.unit.item[i].type = -1;
3945 aoc_e->recorded.unit.num_items++;
3952 aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3958#if defined(HAVE_PRI_AOC_EVENTS)
3971static void sig_pri_send_aoce_termination_request(
struct sig_pri_span *pri,
int chanpos,
unsigned int ms)
3976 size_t encoded_size;
3977 struct timeval whentohangup = { 0, };
3979 sig_pri_lock_owner(pri, chanpos);
3980 pvt = pri->
pvts[chanpos];
3987 goto cleanup_termination_request;
3994 goto cleanup_termination_request;
3998 whentohangup.tv_usec = (ms % 1000) * 1000;
3999 whentohangup.tv_sec = ms / 1000;
4003 goto cleanup_termination_request;
4006 pvt->waiting_for_aoce = 1;
4010cleanup_termination_request:
4026static int sig_pri_is_cis_call(
int channel)
4028 return channel != -1 && (channel & PRI_CIS_CALL);
4046static void sig_pri_handle_cis_subcmds(
struct sig_pri_span *pri,
int event_id,
4047 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4050#if defined(HAVE_PRI_CCSS)
4052 struct sig_pri_cc_agent_prv *agent_prv;
4053 struct sig_pri_cc_monitor_instance *monitor;
4059 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4060 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4062 switch (subcmd->cmd) {
4063#if defined(STATUS_REQUEST_PLACE_HOLDER)
4064 case PRI_SUBCMD_STATUS_REQ:
4065 case PRI_SUBCMD_STATUS_REQ_RSP:
4069#if defined(HAVE_PRI_CCSS)
4070 case PRI_SUBCMD_CC_REQ:
4071 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id);
4073 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4077 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4079 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4082 sig_pri_cc_type_name);
4087 agent_prv->cc_request_response_pending = 1;
4089 "%s caller accepted CC offer.", sig_pri_cc_type_name)) {
4090 agent_prv->cc_request_response_pending = 0;
4091 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4093 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4096 sig_pri_cc_type_name);
4101#if defined(HAVE_PRI_CCSS)
4102 case PRI_SUBCMD_CC_REQ_RSP:
4103 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4104 subcmd->u.cc_request_rsp.cc_id);
4106 pri_cc_cancel(pri->
pri, subcmd->u.cc_request_rsp.cc_id);
4109 switch (subcmd->u.cc_request_rsp.status) {
4112 "%s far end accepted CC request", sig_pri_cc_type_name);
4115 ast_verb(2,
"core_id:%d %s CC request timeout\n", monitor->core_id,
4116 sig_pri_cc_type_name);
4118 "%s CC request timeout", sig_pri_cc_type_name);
4121 ast_verb(2,
"core_id:%d %s CC request error: %s\n", monitor->core_id,
4122 sig_pri_cc_type_name,
4123 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
4125 "%s CC request error", sig_pri_cc_type_name);
4128 ast_verb(2,
"core_id:%d %s CC request reject: %s\n", monitor->core_id,
4129 sig_pri_cc_type_name,
4130 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
4132 "%s CC request reject", sig_pri_cc_type_name);
4135 ast_verb(2,
"core_id:%d %s CC request unknown status %d\n",
4136 monitor->core_id, sig_pri_cc_type_name,
4137 subcmd->u.cc_request_rsp.status);
4139 "%s CC request unknown status", sig_pri_cc_type_name);
4145#if defined(HAVE_PRI_CCSS)
4146 case PRI_SUBCMD_CC_REMOTE_USER_FREE:
4147 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4148 subcmd->u.cc_remote_user_free.cc_id);
4150 pri_cc_cancel(pri->
pri, subcmd->u.cc_remote_user_free.cc_id);
4154 "%s callee has become available", sig_pri_cc_type_name);
4158#if defined(HAVE_PRI_CCSS)
4159 case PRI_SUBCMD_CC_B_FREE:
4160 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4161 subcmd->u.cc_b_free.cc_id);
4163 pri_cc_cancel(pri->
pri, subcmd->u.cc_b_free.cc_id);
4170#if defined(HAVE_PRI_CCSS)
4171 case PRI_SUBCMD_CC_STATUS_REQ:
4172 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4173 subcmd->u.cc_status_req.cc_id);
4175 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req.cc_id);
4182#if defined(HAVE_PRI_CCSS)
4183 case PRI_SUBCMD_CC_STATUS_REQ_RSP:
4184 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
4186 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req_rsp.cc_id);
4195#if defined(HAVE_PRI_CCSS)
4196 case PRI_SUBCMD_CC_STATUS:
4197 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
4199 pri_cc_cancel(pri->
pri, subcmd->u.cc_status.cc_id);
4202 if (subcmd->u.cc_status.status) {
4204 sig_pri_cc_type_name);
4207 "%s agent caller is available", sig_pri_cc_type_name);
4212#if defined(HAVE_PRI_CCSS)
4213 case PRI_SUBCMD_CC_CANCEL:
4214 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4215 subcmd->u.cc_cancel.is_agent);
4218#if defined(HAVE_PRI_CCSS)
4219 case PRI_SUBCMD_CC_STOP_ALERTING:
4220 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4221 subcmd->u.cc_stop_alerting.cc_id);
4223 pri_cc_cancel(pri->
pri, subcmd->u.cc_stop_alerting.cc_id);
4230#if defined(HAVE_PRI_AOC_EVENTS)
4231 case PRI_SUBCMD_AOC_E:
4233 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e,
NULL, 0);
4237 ast_debug(2,
"Span %d: Unknown CIS subcommand(%d) in %s event.\n", pri->
span,
4238 subcmd->cmd, pri_event2str(event_id));
4261static void sig_pri_handle_subcmds(
struct sig_pri_span *pri,
int chanpos,
int event_id,
4262 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4267#if defined(HAVE_PRI_TRANSFER)
4268 struct xfer_rsp_data xfer_rsp;
4274 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4275 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4277 switch (subcmd->cmd) {
4278 case PRI_SUBCMD_CONNECTED_LINE:
4279 sig_pri_lock_owner(pri, chanpos);
4283 int caller_id_update;
4287 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id,
4291 caller_id_update = 0;
4292 if (ast_connected.id.name.str) {
4295 ast_connected.id.name.str,
sizeof(pri->
pvts[chanpos]->
cid_name));
4296 caller_id_update = 1;
4298 if (ast_connected.id.number.str) {
4301 ast_connected.id.number.str,
sizeof(pri->
pvts[chanpos]->
cid_num));
4302 pri->
pvts[chanpos]->
cid_ton = ast_connected.id.number.plan;
4303 caller_id_update = 1;
4308#if defined(HAVE_PRI_SUBADDR)
4309 if (ast_connected.id.subaddress.str) {
4311 ast_connected.id.subaddress.str,
4313 caller_id_update = 1;
4316 if (caller_id_update) {
4321 sig_pri_set_caller_id(pri->
pvts[chanpos]);
4324 ast_caller.id = ast_connected.id;
4325 ast_caller.ani = ast_connected.id;
4329 if (event_id != PRI_EVENT_RING) {
4340 case PRI_SUBCMD_REDIRECTING:
4341 sig_pri_lock_owner(pri, chanpos);
4344 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
4350 if (event_id != PRI_EVENT_RING) {
4365#if defined(HAVE_PRI_CALL_REROUTING)
4366 case PRI_SUBCMD_REROUTING:
4367 sig_pri_lock_owner(pri, chanpos);
4370 struct pri_party_redirecting pri_deflection;
4374 "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
4381 "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
4383 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4384 PRI_REROUTING_RSP_INVALID_NUMBER);
4389 ast_verb(3,
"Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
4398 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4399 PRI_REROUTING_RSP_OK_CLEAR);
4401 pri_deflection = subcmd->u.rerouting.deflection;
4404 switch (subcmd->u.rerouting.subscription_option) {
4408 pri_deflection.to.number.presentation =
4409 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
4410 pri_deflection.to.number.plan =
4411 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
4412 pri_deflection.to.number.str[0] =
'\0';
4420 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
4429 ast_channel_call_forward_set(owner, subcmd->u.rerouting.deflection.to.number.str);
4438#if defined(HAVE_PRI_CCSS)
4439 case PRI_SUBCMD_CC_AVAILABLE:
4440 sig_pri_lock_owner(pri, chanpos);
4446 case PRI_EVENT_RINGING:
4449 case PRI_EVENT_HANGUP_REQ:
4458 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id,
4460 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4465 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4469#if defined(HAVE_PRI_CCSS)
4470 case PRI_SUBCMD_CC_CALL:
4471 sig_pri_lock_owner(pri, chanpos);
4476 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
4481 "%s caller is attempting recall", sig_pri_cc_type_name);
4489#if defined(HAVE_PRI_CCSS)
4490 case PRI_SUBCMD_CC_CANCEL:
4491 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4492 subcmd->u.cc_cancel.is_agent);
4495#if defined(HAVE_PRI_TRANSFER)
4496 case PRI_SUBCMD_TRANSFER_CALL:
4500 "Call transfer subcommand without call to send response!\n");
4504 sig_pri_unlock_private(pri->
pvts[chanpos]);
4506 xfer_rsp.call = call_rsp;
4507 xfer_rsp.invoke_id = subcmd->u.
transfer.invoke_id;
4508 xfer_rsp.responded = 0;
4509 sig_pri_attempt_transfer(pri,
4510 subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held,
4511 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held,
4513 sig_pri_lock_private(pri->
pvts[chanpos]);
4516#if defined(HAVE_PRI_AOC_EVENTS)
4517 case PRI_SUBCMD_AOC_S:
4518 sig_pri_lock_owner(pri, chanpos);
4521 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
4527#if defined(HAVE_PRI_AOC_EVENTS)
4528 case PRI_SUBCMD_AOC_D:
4529 sig_pri_lock_owner(pri, chanpos);
4533 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
4539#if defined(HAVE_PRI_AOC_EVENTS)
4540 case PRI_SUBCMD_AOC_E:
4541 sig_pri_lock_owner(pri, chanpos);
4544 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
4551#if defined(HAVE_PRI_AOC_EVENTS)
4552 case PRI_SUBCMD_AOC_CHARGING_REQ:
4553 sig_pri_lock_owner(pri, chanpos);
4556 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->
pvts[chanpos],
4562#if defined(HAVE_PRI_AOC_EVENTS)
4563 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
4569 if (subcmd->u.aoc_request_response.valid_aoc_s) {
4570 sig_pri_lock_owner(pri, chanpos);
4573 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
4580#if defined(HAVE_PRI_MCID)
4581 case PRI_SUBCMD_MCID_REQ:
4582 sig_pri_lock_owner(pri, chanpos);
4584 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
4590#if defined(HAVE_PRI_MCID)
4591 case PRI_SUBCMD_MCID_RSP:
4595#if defined(HAVE_PRI_DISPLAY_TEXT)
4596 case PRI_SUBCMD_DISPLAY_TEXT:
4597 if (event_id != PRI_EVENT_RING) {
4602 sig_pri_lock_owner(pri, chanpos);
4608 memset(&f, 0,
sizeof(f));
4612 f.
data.
ptr = (
void *)&subcmd->u.display.text;
4613 f.
datalen = subcmd->u.display.length + 1;
4621 ast_debug(2,
"Span %d: Unknown call subcommand(%d) in %s event.\n",
4622 pri->
span, subcmd->cmd, pri_event2str(event_id));
4644 str =
"SIG_PRI_MOH_STATE_IDLE";
4647 str =
"SIG_PRI_MOH_STATE_NOTIFY";
4650 str =
"SIG_PRI_MOH_STATE_MOH";
4652#if defined(HAVE_PRI_CALL_HOLD)
4653 case SIG_PRI_MOH_STATE_HOLD_REQ:
4654 str =
"SIG_PRI_MOH_STATE_HOLD_REQ";
4656 case SIG_PRI_MOH_STATE_PEND_UNHOLD:
4657 str =
"SIG_PRI_MOH_STATE_PEND_UNHOLD";
4659 case SIG_PRI_MOH_STATE_HOLD:
4660 str =
"SIG_PRI_MOH_STATE_HOLD";
4662 case SIG_PRI_MOH_STATE_RETRIEVE_REQ:
4663 str =
"SIG_PRI_MOH_STATE_RETRIEVE_REQ";
4665 case SIG_PRI_MOH_STATE_PEND_HOLD:
4666 str =
"SIG_PRI_MOH_STATE_PEND_HOLD";
4668 case SIG_PRI_MOH_STATE_RETRIEVE_FAIL:
4669 str =
"SIG_PRI_MOH_STATE_RETRIEVE_FAIL";
4695 str =
"SIG_PRI_MOH_EVENT_RESET";
4698 str =
"SIG_PRI_MOH_EVENT_HOLD";
4701 str =
"SIG_PRI_MOH_EVENT_UNHOLD";
4703#if defined(HAVE_PRI_CALL_HOLD)
4704 case SIG_PRI_MOH_EVENT_HOLD_ACK:
4705 str =
"SIG_PRI_MOH_EVENT_HOLD_ACK";
4707 case SIG_PRI_MOH_EVENT_HOLD_REJ:
4708 str =
"SIG_PRI_MOH_EVENT_HOLD_REJ";
4710 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
4711 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_ACK";
4713 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
4714 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_REJ";
4716 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
4717 str =
"SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK";
4727#if defined(HAVE_PRI_CALL_HOLD)
4747 chanpos = pri_find_empty_chan(pvt->
pri, 1);
4750 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
4752 channel = PVT_TO_CHANNEL(pvt->
pri->
pvts[chanpos]);
4763 if (pri_retrieve(pvt->
pri->
pri, pvt->
call, channel)) {
4764 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
4766 return SIG_PRI_MOH_STATE_RETRIEVE_REQ;
4814#if defined(HAVE_PRI_CALL_HOLD)
4815 case SIG_PRI_MOH_SIGNALING_HOLD:
4821 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
4910#if defined(HAVE_PRI_CALL_HOLD)
4935 next_state = SIG_PRI_MOH_STATE_PEND_UNHOLD;
4937 case SIG_PRI_MOH_EVENT_HOLD_REJ:
4944 case SIG_PRI_MOH_EVENT_HOLD_ACK:
4945 next_state = SIG_PRI_MOH_STATE_HOLD;
4955#if defined(HAVE_PRI_CALL_HOLD)
4980 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
4982 case SIG_PRI_MOH_EVENT_HOLD_REJ:
4985 case SIG_PRI_MOH_EVENT_HOLD_ACK:
4986 next_state = sig_pri_moh_retrieve_call(pvt);
4996#if defined(HAVE_PRI_CALL_HOLD)
5021 next_state = sig_pri_moh_retrieve_call(pvt);
5023 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5038#if defined(HAVE_PRI_CALL_HOLD)
5063 next_state = SIG_PRI_MOH_STATE_PEND_HOLD;
5065 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
5066 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5069 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
5070 next_state = SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
5080#if defined(HAVE_PRI_CALL_HOLD)
5105 next_state = SIG_PRI_MOH_STATE_RETRIEVE_REQ;
5107 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
5108 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5130 case SIG_PRI_MOH_SIGNALING_HOLD:
5138 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
5143 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
5148 next_state = SIG_PRI_MOH_STATE_HOLD;
5158#if defined(HAVE_PRI_CALL_HOLD)
5183 next_state = SIG_PRI_MOH_STATE_HOLD;
5186 next_state = sig_pri_moh_retrieve_call(pvt);
5188 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
5221#if defined(HAVE_PRI_CALL_HOLD)
5222 [SIG_PRI_MOH_STATE_HOLD_REQ] = sig_pri_moh_fsm_hold_req,
5223 [SIG_PRI_MOH_STATE_PEND_UNHOLD] = sig_pri_moh_fsm_pend_unhold,
5224 [SIG_PRI_MOH_STATE_HOLD] = sig_pri_moh_fsm_hold,
5225 [SIG_PRI_MOH_STATE_RETRIEVE_REQ] = sig_pri_moh_fsm_retrieve_req,
5226 [SIG_PRI_MOH_STATE_PEND_HOLD] = sig_pri_moh_fsm_pend_hold,
5227 [SIG_PRI_MOH_STATE_RETRIEVE_FAIL] = sig_pri_moh_fsm_retrieve_fail,
5248 const char *chan_name;
5253 chan_name =
"Unknown";
5256 ast_debug(2,
"Channel '%s' MOH-Event: %s in state %s\n", chan_name,
5257 sig_pri_moh_event_str(
event), sig_pri_moh_state_str(orig_state));
5259 || !sig_pri_moh_fsm[orig_state]) {
5262 sig_pri_moh_state_str(orig_state), orig_state);
5266 next_state = sig_pri_moh_fsm[orig_state](chan, pvt,
event);
5267 ast_debug(2,
"Channel '%s' MOH-Next-State: %s\n", chan_name,
5268 (orig_state == next_state) ?
"$" : sig_pri_moh_state_str(next_state));
5278static ast_callid func_pri_dchannel_new_callid(
void)
5308 sig_pri_lock_owner(
pri, chanpos);
5322#if defined(HAVE_PRI_CALL_HOLD)
5336static int sig_pri_handle_hold(
struct sig_pri_span *
pri, pri_event *ev)
5344 chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
5345 if (chanpos_old < 0) {
5356 sig_pri_lock_private(pri->
pvts[chanpos_old]);
5357 sig_pri_lock_owner(pri, chanpos_old);
5360 goto done_with_private;
5374 goto done_with_owner;
5376 chanpos_new = pri_find_empty_nobch(pri);
5377 if (chanpos_new < 0) {
5379 goto done_with_owner;
5381 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.subcmds, ev->hold.call);
5382 sig_pri_queue_hold(pri, chanpos_old);
5383 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
5384 if (chanpos_new < 0) {
5386 sig_pri_queue_unhold(pri, chanpos_old);
5392 sig_pri_unlock_private(pri->
pvts[chanpos_old]);
5394 if (chanpos_new < 0) {
5397 sig_pri_span_devstate_changed(pri);
5409#if defined(HAVE_PRI_CALL_HOLD)
5420static void sig_pri_handle_hold_ack(
struct sig_pri_span *pri, pri_event *ev)
5429 chanpos = pri_find_empty_nobch(pri);
5433 "Span %d: No hold channel available for held call that is on %d/%d\n",
5434 pri->
span, PRI_SPAN(ev->hold_ack.channel), PRI_CHANNEL(ev->hold_ack.channel));
5435 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5438 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_ack.call);
5441 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5445 sig_pri_lock_private(pri->
pvts[chanpos]);
5446 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5448 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_ack.subcmds, ev->hold_ack.call);
5449 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5450 SIG_PRI_MOH_EVENT_HOLD_ACK);
5451 sig_pri_unlock_private(pri->
pvts[chanpos]);
5452 sig_pri_span_devstate_changed(pri);
5460#if defined(HAVE_PRI_CALL_HOLD)
5471static void sig_pri_handle_hold_rej(
struct sig_pri_span *pri, pri_event *ev)
5476 chanpos = pri_find_principle(pri, ev->hold_rej.channel, ev->hold_rej.call);
5480 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5483 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_rej.call);
5486 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5490 ast_debug(1,
"Span %d: HOLD_REJECT cause: %d(%s)\n", pri->
span,
5491 ev->hold_rej.cause, pri_cause2str(ev->hold_rej.cause));
5493 sig_pri_lock_private(pri->
pvts[chanpos]);
5494 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5496 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_rej.subcmds, ev->hold_rej.call);
5497 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5498 SIG_PRI_MOH_EVENT_HOLD_REJ);
5499 sig_pri_unlock_private(pri->
pvts[chanpos]);
5507#if defined(HAVE_PRI_CALL_HOLD)
5518static void sig_pri_handle_retrieve(
struct sig_pri_span *pri, pri_event *ev)
5523 if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
5525 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5526 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5529 if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) {
5531 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5532 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5535 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) {
5536 chanpos = pri_find_empty_chan(pri, 1);
5538 chanpos = pri_find_principle(pri,
5539 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call);
5540 if (ev->retrieve.flexible
5546 chanpos = pri_find_empty_chan(pri, 1);
5550 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5551 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
5552 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5555 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call);
5558 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5559 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5562 sig_pri_lock_private(pri->
pvts[chanpos]);
5563 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5564 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.subcmds, ev->retrieve.call);
5565 sig_pri_queue_unhold(pri, chanpos);
5566 pri_retrieve_ack(pri->
pri, ev->retrieve.call,
5567 PVT_TO_CHANNEL(pri->
pvts[chanpos]));
5568 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5569 SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK);
5570 sig_pri_unlock_private(pri->
pvts[chanpos]);
5571 sig_pri_span_devstate_changed(pri);
5579#if defined(HAVE_PRI_CALL_HOLD)
5590static void sig_pri_handle_retrieve_ack(
struct sig_pri_span *pri, pri_event *ev)
5595 chanpos = pri_find_fixup_principle(pri, ev->retrieve_ack.channel,
5596 ev->retrieve_ack.call);
5601 sig_pri_lock_private(pri->
pvts[chanpos]);
5602 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5604 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_ack.subcmds,
5605 ev->retrieve_ack.call);
5606 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5607 SIG_PRI_MOH_EVENT_RETRIEVE_ACK);
5608 sig_pri_unlock_private(pri->
pvts[chanpos]);
5609 sig_pri_span_devstate_changed(pri);
5617#if defined(HAVE_PRI_CALL_HOLD)
5628static void sig_pri_handle_retrieve_rej(
struct sig_pri_span *pri, pri_event *ev)
5633 chanpos = pri_find_principle(pri, ev->retrieve_rej.channel, ev->retrieve_rej.call);
5637 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5640 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve_rej.call);
5643 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5647 ast_debug(1,
"Span %d: RETRIEVE_REJECT cause: %d(%s)\n", pri->
span,
5648 ev->retrieve_rej.cause, pri_cause2str(ev->retrieve_rej.cause));
5650 sig_pri_lock_private(pri->
pvts[chanpos]);
5651 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5653 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_rej.subcmds,
5654 ev->retrieve_rej.call);
5655 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->
owner, pri->
pvts[chanpos],
5656 SIG_PRI_MOH_EVENT_RETRIEVE_REJ);
5657 sig_pri_unlock_private(pri->
pvts[chanpos]);
5676static void setup_incoming_channel(
struct sig_pri_span *pri,
int chanpos, pri_event *ev)
5680 char calledtonstr[10];
5682 sig_pri_lock_owner(pri, chanpos);
5690#if defined(HAVE_PRI_SUBADDR)
5691 if (ev->ring.calling.subaddress.valid) {
5694 &ev->ring.calling.subaddress);
5695 if (!ev->ring.calling.subaddress.type
5699 (
char *) ev->ring.calling.subaddress.data);
5702 if (ev->ring.called_subaddress.valid) {
5705 &ev->ring.called_subaddress);
5706 if (!ev->ring.called_subaddress.type
5710 (
char *) ev->ring.called_subaddress.data);
5718 if (ev->ring.ani2 >= 0) {
5720 snprintf(ani2str,
sizeof(ani2str),
"%d", ev->ring.ani2);
5724#ifdef SUPPORT_USERUSER
5730 snprintf(calledtonstr,
sizeof(calledtonstr),
"%d", ev->ring.calledplan);
5734 if (ev->ring.redirectingreason >= 0) {
5737 redirectingreason2str(ev->ring.redirectingreason));
5739#if defined(HAVE_PRI_REVERSE_CHARGE)
5740 pri->
pvts[chanpos]->reverse_charging_indication = ev->ring.reversecharge;
5742#if defined(HAVE_PRI_SETUP_KEYPAD)
5744 ev->ring.keypad_digits,
sizeof(pri->
pvts[chanpos]->keypad_digits));
5752 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->ring.subcmds,
5768static void sig_pri_handle_setup(
struct sig_pri_span *pri, pri_event *e)
5770 int exten_exists_or_can_exist;
5771 int could_match_more;
5782 && !sig_pri_msn_match(pri->
msn_list, e->ring.callednum)) {
5785 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n",
5787 pri_destroycall(pri->
pri, e->ring.call);
5790 if (sig_pri_is_cis_call(e->ring.channel)) {
5791 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, e->ring.call);
5794 chanpos = pri_find_principle_by_call(pri, e->ring.call);
5798 "Span %d: Got SETUP with duplicate call ptr (%p). Dropping call.\n",
5799 pri->
span, e->ring.call);
5800 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5803 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
5805 chanpos = pri_find_empty_chan(pri, 1);
5807 callid = func_pri_dchannel_new_callid();
5809 }
else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
5811#if defined(HAVE_PRI_CALL_WAITING)
5812 if (!pri->allow_call_waiting_calls)
5816 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5819#if defined(HAVE_PRI_CALL_WAITING)
5820 chanpos = pri_find_empty_nobch(pri);
5823 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5827 callid = func_pri_dchannel_new_callid();
5830 sig_pri_init_config(pri->
pvts[chanpos], pri);
5834 callid = func_pri_dchannel_new_callid();
5835 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
5838 "Span %d: SETUP on unconfigured channel %d/%d\n",
5839 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5854 "Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n",
5855 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5861 pri_check_restart(pri);
5868 "Span %d: SETUP requested unavailable channel %d/%d. Attempting to renegotiate.\n",
5869 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5873#if defined(ALWAYS_PICK_CHANNEL)
5874 if (e->ring.flexible) {
5878 if (chanpos < 0 && e->ring.flexible) {
5880 chanpos = pri_find_empty_chan(pri, 1);
5884 if (e->ring.flexible) {
5885 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5887 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5892 sig_pri_lock_private(pri->
pvts[chanpos]);
5895 pri->
pvts[chanpos]->
call = e->ring.call;
5898 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
5899 e->ring.redirectingnum, e->ring.callingplanrdnis);
5900 sig_pri_set_rdnis(pri->
pvts[chanpos], plancallingnum);
5903 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
5904 e->ring.callingnum, e->ring.callingplan);
5911 apply_plan_to_existing_number(plancallingani,
sizeof(plancallingani),
5912 pri, e->ring.callingani, e->ring.callingplanani);
5918#if defined(HAVE_PRI_SUBADDR)
5919 if (e->ring.calling.subaddress.valid) {
5923 sig_pri_set_subaddress(&calling_subaddress,
5924 &e->ring.calling.subaddress);
5925 if (calling_subaddress.str) {
5927 calling_subaddress.str,
5936 pri->
pvts[chanpos]->
cid_ton = e->ring.callingplan;
5938 if (e->ring.ani2 >= 0) {
5956 ? plancallingnum : e->ring.callednum);
5965 sig_pri_set_caller_id(pri->
pvts[chanpos]);
5968 sig_pri_set_dnid(pri->
pvts[chanpos], e->ring.callednum);
5972 ast_verb(3,
"Going to extension s|1 because of immediate=yes\n");
5988 ast_verb(3,
"Going to extension s|1 because of Complete received\n");
5999 if (!exten_exists_or_can_exist) {
6001 "Span %d: Extension %s@%s does not exist. Rejecting call from '%s'.\n",
6004 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
6007 sig_pri_unlock_private(pri->
pvts[chanpos]);
6008 sig_pri_span_devstate_changed(pri);
6013 switch (e->ring.layer1) {
6014 case PRI_LAYER_1_ALAW:
6017 case PRI_LAYER_1_ULAW:
6026 could_match_more = !e->ring.complete
6031 need_dialtone = could_match_more
6046 pri_proceeding(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 0);
6047 }
else if (pri->
switchtype == PRI_SWITCH_GR303_TMC) {
6049 pri_answer(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6052#if defined(HAVE_PRI_SETUP_ACK_INBAND)
6053 pri_setup_ack(pri->
pri, e->ring.call,
6054 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, need_dialtone);
6056 pri_need_more_info(pri->
pri, e->ring.call,
6057 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6067 sig_pri_unlock_private(pri->
pvts[chanpos]);
6069 c = sig_pri_new_ast_channel(pri->
pvts[chanpos],
6073 sig_pri_lock_private(pri->
pvts[chanpos]);
6076 setup_incoming_channel(pri, chanpos, e);
6079 if (could_match_more) {
6080#if !defined(HAVE_PRI_SETUP_ACK_INBAND)
6081 if (need_dialtone) {
6084#ifdef HAVE_PRI_PROG_W_CAUSE
6085 pri_progress_with_cause(pri->
pri, e->ring.call,
6086 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, -1);
6088 pri_progress(pri->
pri, e->ring.call,
6089 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6095 pri->
pvts[chanpos])) {
6096 ast_verb(3,
"Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
6097 plancallingnum,
S_OR(pri->
pvts[chanpos]->
exten,
"<unspecified>"),
6100 sig_pri_unlock_private(pri->
pvts[chanpos]);
6105 ast_verb(3,
"Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
6106 plancallingnum, pri->
pvts[chanpos]->
exten,
6109 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6110 sig_pri_unlock_private(pri->
pvts[chanpos]);
6119 sig_pri_unlock_private(pri->
pvts[chanpos]);
6124 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
6126 sig_pri_unlock_private(pri->
pvts[chanpos]);
6127 sig_pri_span_devstate_changed(pri);
6136static void *pri_dchannel(
void *vpri)
6143 struct timeval tv, lowest, *next;
6149 struct timeval lastidle = { 0, 0 };
6158 gettimeofday(&lastidle,
NULL);
6159 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
6163 cc = strchr(pri->
idleext,
'@');
6185 fds[i].events = POLLIN | POLLPRI;
6194 pri_check_restart(pri);
6196 sig_pri_span_devstate_changed(pri);
6214 if (haveidles < pri->minunused) {
6225 if (nextidle > -1) {
6240 sig_pri_lock_private(pri->
pvts[nextidle]);
6241 sig_pri_unlock_private(pri->
pvts[nextidle]);
6256 gettimeofday(&lastidle,
NULL);
6258 }
else if ((haveidles < pri->minunused) &&
6259 (activeidles > pri->
minidle)) {
6270 (activeidles <= pri->minidle))
6292 next = pri_schedule_next(pri->
dchans[i]);
6296 if (tv.tv_sec < 0) {
6311 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
6312 pthread_testcancel();
6314 res = poll(
fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
6315 pthread_testcancel();
6316 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
6324 e = pri_schedule_run(pri->
dchans[which]);
6328 }
else if (res > -1) {
6332 if (
fds[which].revents & POLLPRI) {
6333 sig_pri_handle_dchan_exception(pri, which);
6334 }
else if (
fds[which].revents & POLLIN) {
6335 e = pri_check_event(pri->
dchans[which]);
6344 if (
errno == ENODEV) {
6345 pri_destroy_later(pri);
6348 }
else if (
errno != EINTR)
6357 pri->
span, pri_event2str(e->e), e->e);
6360 if (e->e != PRI_EVENT_DCHAN_DOWN) {
6362 ast_verb(2,
"%s D-Channel on span %d up\n", pri_order(which), pri->
span);
6367 ast_verb(2,
"%s D-Channel on span %d down\n", pri_order(which), pri->
span);
6372 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->
pri != pri->
dchans[which]))
6377 case PRI_EVENT_DCHAN_UP:
6380 pri_find_dchan(pri);
6393 for (i = 0; i < pri->
numchans; i++) {
6398 sig_pri_span_devstate_changed(pri);
6400 case PRI_EVENT_DCHAN_DOWN:
6401 pri_find_dchan(pri);
6412 for (i = 0; i < pri->
numchans; i++) {
6416 if (pri_get_timer(p->
pri->
pri, PRI_TIMER_T309) < 0) {
6428 sig_pri_span_devstate_changed(
pri);
6431 case PRI_EVENT_RESTART:
6432 if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) {
6433 chanpos = pri_find_principle(
pri, e->restart.channel,
NULL);
6436 "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
6437 pri->
span, PRI_SPAN(e->restart.channel),
6438 PRI_CHANNEL(e->restart.channel));
6441#if defined(HAVE_PRI_SERVICE_MESSAGES)
6444 why =
pri->
pvts[chanpos]->service_status;
6447 "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n",
6448 pri->
span, PRI_SPAN(e->restart.channel),
6449 PRI_CHANNEL(e->restart.channel),
6450 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ?
"both ends" :
"far end" :
"near end");
6454 sig_pri_lock_private(
pri->
pvts[chanpos]);
6457 PRI_SPAN(e->restart.channel),
6458 PRI_CHANNEL(e->restart.channel));
6465 sig_pri_queue_hangup(
pri, chanpos);
6466 sig_pri_unlock_private(
pri->
pvts[chanpos]);
6472 sig_pri_lock_private(
pri->
pvts[x]);
6478 sig_pri_queue_hangup(
pri, x);
6479 sig_pri_unlock_private(
pri->
pvts[x]);
6482 sig_pri_span_devstate_changed(
pri);
6484 case PRI_EVENT_KEYPAD_DIGIT:
6485 if (sig_pri_is_cis_call(e->digit.channel)) {
6486 sig_pri_handle_cis_subcmds(
pri, e->e, e->digit.subcmds,
6490 chanpos = pri_find_principle_by_call(
pri, e->digit.call);
6493 "Span %d: Received keypad digits for unknown call.\n",
pri->
span);
6496 sig_pri_lock_private(
pri->
pvts[chanpos]);
6498 callid = func_pri_dchannel_chanpos_callid(
pri, chanpos);
6500 sig_pri_handle_subcmds(
pri, chanpos, e->e, e->digit.subcmds,
6506 int digitlen = strlen(e->digit.digits);
6509 for (i = 0; i < digitlen; i++) {
6512 pri_queue_frame(pri, chanpos, &f);
6515 sig_pri_unlock_private(pri->
pvts[chanpos]);
6518 case PRI_EVENT_INFO_RECEIVED:
6519 if (sig_pri_is_cis_call(e->ring.channel)) {
6520 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
6524 chanpos = pri_find_principle_by_call(pri, e->ring.call);
6527 "Span %d: Received INFORMATION for unknown call.\n", pri->
span);
6530 sig_pri_lock_private(pri->
pvts[chanpos]);
6532 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6534 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, e->ring.call);
6539 int digitlen = strlen(e->ring.callednum);
6542 for (i = 0; i < digitlen; i++) {
6545 pri_queue_frame(pri, chanpos, &f);
6548 sig_pri_unlock_private(pri->
pvts[chanpos]);
6550#if defined(HAVE_PRI_SERVICE_MESSAGES)
6551 case PRI_EVENT_SERVICE:
6552 chanpos = pri_find_principle(pri, e->service.channel,
NULL);
6554 ast_log(
LOG_WARNING,
"Received service change status %d on unconfigured channel %d/%d span %d\n",
6555 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6557 char db_chan_name[20];
6563 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, pri->
span, ch);
6564 why = &pri->
pvts[chanpos]->service_status;
6565 switch (e->service.changestatus) {
6569 *why &= ~SRVST_FAREND;
6571 snprintf(db_answer,
sizeof(db_answer),
"%s:%u",
6572 SRVST_TYPE_OOS, *why);
6573 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
6575 sig_pri_span_devstate_changed(pri);
6581 *why |= SRVST_FAREND;
6582 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS,
6584 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
6585 sig_pri_span_devstate_changed(pri);
6591 ast_log(
LOG_NOTICE,
"Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n",
6592 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->
span, ch, e->service.changestatus);
6595 case PRI_EVENT_SERVICE_ACK:
6596 chanpos = pri_find_principle(pri, e->service_ack.channel,
NULL);
6598 ast_log(
LOG_WARNING,
"Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
6599 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6601 ast_debug(2,
"Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n",
6602 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span, e->service_ack.changestatus);
6606 case PRI_EVENT_RING:
6607 sig_pri_handle_setup(pri, e);
6609 case PRI_EVENT_RINGING:
6610 if (sig_pri_is_cis_call(e->ringing.channel)) {
6611 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds,
6615 chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
6620 sig_pri_lock_private(pri->
pvts[chanpos]);
6622 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6624 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.subcmds,
6626 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCNR);
6627 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6628 sig_pri_lock_owner(pri, chanpos);
6640#ifdef PRI_PROGRESS_MASK
6641 && (e->ringing.progressmask
6642 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6644 && e->ringing.progress == 8
6650 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6651 sig_pri_open_media(pri->
pvts[chanpos]);
6654#ifdef SUPPORT_USERUSER
6658 sig_pri_lock_owner(pri, chanpos);
6662 e->ringing.useruserinfo);
6668 sig_pri_unlock_private(pri->
pvts[chanpos]);
6670 case PRI_EVENT_PROGRESS:
6671 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6672 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6673 e->proceeding.call);
6676 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6677 e->proceeding.call);
6681 sig_pri_lock_private(pri->
pvts[chanpos]);
6683 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6685 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6686 e->proceeding.call);
6688 if (e->proceeding.cause > -1) {
6690 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_PROGRESS (%d)", e->proceeding.cause);
6691 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->proceeding.cause);
6694 ast_verb(3,
"PROGRESS with cause code %d received\n", e->proceeding.cause);
6699 ast_verb(3,
"PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
6709#ifdef PRI_PROGRESS_MASK
6710 && (e->proceeding.progressmask
6711 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6713 && e->proceeding.progress == 8
6718 "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
6723 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6724 sig_pri_open_media(pri->
pvts[chanpos]);
6726 sig_pri_unlock_private(pri->
pvts[chanpos]);
6728 case PRI_EVENT_PROCEEDING:
6729 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6730 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6731 e->proceeding.call);
6734 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6735 e->proceeding.call);
6739 sig_pri_lock_private(pri->
pvts[chanpos]);
6741 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6743 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6744 e->proceeding.call);
6748 "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
6755#ifdef PRI_PROGRESS_MASK
6764 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
6766 && e->proceeding.progress == 8
6772 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6773 sig_pri_open_media(pri->
pvts[chanpos]);
6781 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6783 sig_pri_unlock_private(pri->
pvts[chanpos]);
6785 case PRI_EVENT_FACILITY:
6786 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) {
6788#if defined(HAVE_PRI_CALL_REROUTING)
6789 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6790 e->facility.subcall);
6792 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6797 chanpos = pri_find_principle_by_call(pri, e->facility.call);
6803 sig_pri_lock_private(pri->
pvts[chanpos]);
6805 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6807#if defined(HAVE_PRI_CALL_REROUTING)
6808 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6809 e->facility.subcall);
6811 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6814 sig_pri_unlock_private(pri->
pvts[chanpos]);
6816 case PRI_EVENT_ANSWER:
6817 if (sig_pri_is_cis_call(e->answer.channel)) {
6818#if defined(HAVE_PRI_CALL_WAITING)
6820 pri_connect_ack(pri->
pri, e->answer.call, 0);
6822 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds,
6826 chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
6830#if defined(HAVE_PRI_CALL_WAITING)
6831 if (pri->
pvts[chanpos]->is_call_waiting) {
6839 new_chanpos = pri_find_empty_chan(pri, 1);
6840 if (0 <= new_chanpos) {
6841 new_chanpos = pri_fixup_principle(pri, new_chanpos,
6844 if (new_chanpos < 0) {
6850 "Span %d: Channel not available for call waiting call.\n",
6852 sig_pri_lock_private(pri->
pvts[chanpos]);
6853 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
6855 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
6856 sig_pri_lock_owner(pri, chanpos);
6870 pri->
pvts[chanpos]->is_call_waiting = 0;
6872 pri_hangup(pri->
pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
6875 sig_pri_unlock_private(pri->
pvts[chanpos]);
6876 sig_pri_span_devstate_changed(pri);
6879 chanpos = new_chanpos;
6881 pri_connect_ack(pri->
pri, e->answer.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
6882 sig_pri_span_devstate_changed(pri);
6885 pri_connect_ack(pri->
pri, e->answer.call, 0);
6888 sig_pri_lock_private(pri->
pvts[chanpos]);
6890 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6892#if defined(HAVE_PRI_CALL_WAITING)
6893 if (pri->
pvts[chanpos]->is_call_waiting) {
6894 pri->
pvts[chanpos]->is_call_waiting = 0;
6898 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
6903 "Span %d: Channel %d/%d dialing deferred digit string: %s\n",
6910 sig_pri_dial_digits(pri->
pvts[chanpos],
6916 sig_pri_open_media(pri->
pvts[chanpos]);
6918 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6920 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6923#ifdef SUPPORT_USERUSER
6927 sig_pri_lock_owner(pri, chanpos);
6931 e->answer.useruserinfo);
6937 sig_pri_unlock_private(pri->
pvts[chanpos]);
6939#if defined(HAVE_PRI_CALL_WAITING)
6940 case PRI_EVENT_CONNECT_ACK:
6941 if (sig_pri_is_cis_call(e->connect_ack.channel)) {
6942 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds,
6943 e->connect_ack.call);
6946 chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel,
6947 e->connect_ack.call);
6952 sig_pri_lock_private(pri->
pvts[chanpos]);
6954 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6956 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.subcmds,
6957 e->connect_ack.call);
6958 sig_pri_open_media(pri->
pvts[chanpos]);
6959 sig_pri_unlock_private(pri->
pvts[chanpos]);
6960 sig_pri_span_devstate_changed(pri);
6963 case PRI_EVENT_HANGUP:
6964 if (sig_pri_is_cis_call(e->hangup.channel)) {
6965 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
6967 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6970 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
6976 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6979 sig_pri_lock_private(pri->
pvts[chanpos]);
6981 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6983 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
6985 switch (e->hangup.cause) {
6986 case PRI_CAUSE_INVALID_CALL_REFERENCE:
6991 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7000 switch (e->hangup.cause) {
7001 case PRI_CAUSE_USER_BUSY:
7002 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7003 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
7009 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP (%d)", e->hangup.cause);
7010 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7031 switch (e->hangup.cause) {
7032 case PRI_CAUSE_USER_BUSY:
7035 case PRI_CAUSE_CALL_REJECTED:
7036 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7037 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7038 case PRI_CAUSE_SWITCH_CONGESTION:
7039 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7040 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7051 sig_pri_queue_hangup(pri, chanpos);
7058 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7061 ast_verb(3,
"Span %d: Channel %d/%d got hangup, cause %d\n",
7066 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7069 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7074 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7078 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7080 if (e->hangup.aoc_units > -1)
7081 ast_verb(3,
"Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
7084#ifdef SUPPORT_USERUSER
7088 sig_pri_lock_owner(pri, chanpos);
7092 e->hangup.useruserinfo);
7098 sig_pri_unlock_private(pri->
pvts[chanpos]);
7099 sig_pri_span_devstate_changed(pri);
7101 case PRI_EVENT_HANGUP_REQ:
7102 if (sig_pri_is_cis_call(e->hangup.channel)) {
7103 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7105 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7108 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7114 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7117 sig_pri_lock_private(pri->
pvts[chanpos]);
7119 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7121 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
7123#if defined(HAVE_PRI_CALL_HOLD)
7124 if (e->hangup.call_active && e->hangup.call_held
7125 && pri->hold_disconnect_transfer) {
7127 sig_pri_unlock_private(pri->
pvts[chanpos]);
7128 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1,
7129 e->hangup.call_active, 0,
NULL)) {
7132 sig_pri_lock_private(pri->
pvts[chanpos]);
7135 switch (e->hangup.cause) {
7136 case PRI_CAUSE_USER_BUSY:
7137 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7138 sig_pri_cc_generic_check(pri, chanpos,
AST_CC_CCBS);
7140 case PRI_CAUSE_INVALID_CALL_REFERENCE:
7147 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7154 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP_REQ (%d)", e->hangup.cause);
7155 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7175 switch (e->hangup.cause) {
7176 case PRI_CAUSE_USER_BUSY:
7179 case PRI_CAUSE_CALL_REJECTED:
7180 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7181 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7182 case PRI_CAUSE_SWITCH_CONGESTION:
7183 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7184 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7195#if defined(HAVE_PRI_AOC_EVENTS)
7196 if (!pri->
pvts[chanpos]->holding_aoce
7197 && pri->aoce_delayhangup
7199 sig_pri_send_aoce_termination_request(pri, chanpos,
7200 pri_get_timer(pri->
pri, PRI_TIMER_T305) / 2);
7204 sig_pri_queue_hangup(pri, chanpos);
7207 ast_verb(3,
"Span %d: Channel %d/%d got hangup request, cause %d\n",
7215 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7218 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7223 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7227 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7230#ifdef SUPPORT_USERUSER
7234 sig_pri_lock_owner(pri, chanpos);
7238 e->hangup.useruserinfo);
7244 sig_pri_unlock_private(pri->
pvts[chanpos]);
7245 sig_pri_span_devstate_changed(pri);
7247 case PRI_EVENT_HANGUP_ACK:
7248 if (sig_pri_is_cis_call(e->hangup.channel)) {
7249 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7253 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7257 sig_pri_lock_private(pri->
pvts[chanpos]);
7259 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7263 ast_verb(3,
"Span %d: Channel %d/%d got hangup ACK\n", pri->
span,
7266#ifdef SUPPORT_USERUSER
7270 sig_pri_lock_owner(pri, chanpos);
7274 e->hangup.useruserinfo);
7279 sig_pri_unlock_private(pri->
pvts[chanpos]);
7280 sig_pri_span_devstate_changed(pri);
7282 case PRI_EVENT_CONFIG_ERR:
7285 case PRI_EVENT_RESTART_ACK:
7286 chanpos = pri_find_principle(pri, e->restartack.channel,
NULL);
7295 sig_pri_lock_private(pri->
pvts[chanpos]);
7297 "Span %d: Assuming restart ack is for channel %d/%d\n",
7302 "Span %d: Got restart ack on channel %d/%d with owner\n",
7309 "Span %d: Channel %d/%d successfully restarted\n",
7312 sig_pri_unlock_private(pri->
pvts[chanpos]);
7314 pri_check_restart(pri);
7320 "Span %d: Restart ACK on strange channel %d/%d\n",
7321 pri->
span, PRI_SPAN(e->restartack.channel),
7322 PRI_CHANNEL(e->restartack.channel));
7325 sig_pri_lock_private(pri->
pvts[chanpos]);
7329 "Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n",
7332 sig_pri_unlock_private(pri->
pvts[chanpos]);
7337 "Span %d: Got restart ack on channel %d/%d with owner\n",
7344 "Span %d: Channel %d/%d successfully restarted\n",
7347 sig_pri_unlock_private(pri->
pvts[chanpos]);
7349 pri_check_restart(pri);
7352 case PRI_EVENT_SETUP_ACK:
7353 if (sig_pri_is_cis_call(e->setup_ack.channel)) {
7354 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds,
7358 chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
7363 sig_pri_lock_private(pri->
pvts[chanpos]);
7365 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7367 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.subcmds,
7375 for (
x = 0;
x <
len; ++
x) {
7377 pri_information(pri->
pri, pri->
pvts[chanpos]->
call,
7385#
if defined(HAVE_PRI_SETUP_ACK_INBAND)
7403 && ((e->setup_ack.progressmask & PRI_PROG_INBAND_AVAILABLE)
7405 || pri->
pvts[chanpos]->no_dialed_digits)
7414 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
7415 sig_pri_open_media(pri->
pvts[chanpos]);
7417 sig_pri_unlock_private(pri->
pvts[chanpos]);
7419 case PRI_EVENT_NOTIFY:
7420 if (sig_pri_is_cis_call(e->notify.channel)) {
7421#if defined(HAVE_PRI_CALL_HOLD)
7422 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
7425 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
NULL);
7429#if defined(HAVE_PRI_CALL_HOLD)
7430 chanpos = pri_find_principle_by_call(pri, e->notify.call);
7442 chanpos = pri_find_principle(pri, e->notify.channel,
NULL);
7445 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->
span);
7449 sig_pri_lock_private(pri->
pvts[chanpos]);
7451 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7453#if defined(HAVE_PRI_CALL_HOLD)
7454 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
7457 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
NULL);
7459 switch (e->notify.info) {
7460 case PRI_NOTIFY_REMOTE_HOLD:
7462 sig_pri_queue_hold(pri, chanpos);
7465 case PRI_NOTIFY_REMOTE_RETRIEVAL:
7467 sig_pri_queue_unhold(pri, chanpos);
7471 sig_pri_unlock_private(pri->
pvts[chanpos]);
7473#if defined(HAVE_PRI_CALL_HOLD)
7474 case PRI_EVENT_HOLD:
7476 if (sig_pri_handle_hold(pri, e)) {
7477 pri_hold_rej(pri->
pri, e->hold.call,
7478 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
7480 pri_hold_ack(pri->
pri, e->hold.call);
7484#if defined(HAVE_PRI_CALL_HOLD)
7485 case PRI_EVENT_HOLD_ACK:
7487 sig_pri_handle_hold_ack(pri, e);
7490#if defined(HAVE_PRI_CALL_HOLD)
7491 case PRI_EVENT_HOLD_REJ:
7493 sig_pri_handle_hold_rej(pri, e);
7496#if defined(HAVE_PRI_CALL_HOLD)
7497 case PRI_EVENT_RETRIEVE:
7499 sig_pri_handle_retrieve(pri, e);
7502#if defined(HAVE_PRI_CALL_HOLD)
7503 case PRI_EVENT_RETRIEVE_ACK:
7505 sig_pri_handle_retrieve_ack(pri, e);
7508#if defined(HAVE_PRI_CALL_HOLD)
7509 case PRI_EVENT_RETRIEVE_REJ:
7511 sig_pri_handle_retrieve_rej(pri, e);
7515 ast_debug(1,
"Span: %d Unhandled event: %s(%d)\n",
7516 pri->
span, pri_event2str(e->e), e->e);
7568 (pri->
dchanavail[
x] & DCHAN_NOTINALARM) ?
"No" :
"Yes",
7581 memset(pri, 0,
sizeof(*pri));
7598 sig_pri_set_outgoing(p, 0);
7599 sig_pri_set_digital(p, 0);
7600#if defined(HAVE_PRI_CALL_WAITING)
7601 if (p->is_call_waiting) {
7602 p->is_call_waiting = 0;
7613 sig_pri_set_dialing(p, 0);
7616 pri_grab(p, p->
pri);
7619#if defined(SUPPORT_USERUSER)
7623 pri_call_set_useruser(p->
call, useruser);
7627#if defined(HAVE_PRI_TRANSFER)
7637 sig_pri_transfer_rsp(p->xfer_data, 1);
7641#if defined(HAVE_PRI_AOC_EVENTS)
7642 if (p->holding_aoce) {
7643 pri_aoc_e_send(p->
pri->
pri, p->
call, &p->aoc_e);
7648 ast_debug(1,
"Already hungup... Calling hangup once, and clearing call\n");
7659 icause = atoi(cause);
7663 "Not yet hungup... Calling hangup with cause %d, and clearing call\n",
7669#if defined(HAVE_PRI_TRANSFER)
7670 p->xfer_data =
NULL;
7672#if defined(HAVE_PRI_AOC_EVENTS)
7673 p->aoc_s_request_invoke_id_valid = 0;
7674 p->holding_aoce = 0;
7675 p->waiting_for_aoce = 0;
7681 sig_pri_span_devstate_changed(p->
pri);
7719 subaddr = strchr(
number,
':');
7743 deferred = strchr(
number,
'w');
7748 while (isalpha(*
number)) {
7756 snprintf(called, called_buff_size,
"%s",
number);
7759 snprintf(called, called_buff_size,
"%s:%s",
number, subaddr);
7763enum SIG_PRI_CALL_OPT_FLAGS {
7764 OPT_KEYPAD = (1 << 0),
7765 OPT_REVERSE_CHARGE = (1 << 1),
7766 OPT_AOC_REQUEST = (1 << 2),
7768enum SIG_PRI_CALL_OPT_ARGS {
7770 OPT_ARG_AOC_REQUEST,
7788 char *
c, *l, *n, *s;
7789#ifdef SUPPORT_USERUSER
7790 const char *useruser;
7795 int prilocaldialplan;
7798#if defined(HAVE_PRI_SETUP_KEYPAD)
7811 ast_debug(1,
"CALLER NAME: %s NUM: %s\n",
7826 sig_pri_set_outgoing(p, 1);
7854 dialed_subaddress.type = 2;
7862 dialed_subaddress.str = s;
7863 dialed_subaddress.valid = 1;
7874 for (l = connected_id.
number.
str; l && *l; l++) {
7875 if (strchr(
"0123456789", *l)) {
7907 pri_grab(p, p->
pri);
7908 if (!(p->
call = pri_new_call(p->
pri->
pri))) {
7913 if (!(sr = pri_sr_new())) {
7924#if defined(HAVE_PRI_CALL_WAITING)
7925 if (p->is_call_waiting) {
7930 pri_sr_set_channel(sr, 0, 0, 1);
7940 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
7947 pri_facility_enable(p->
pri->
pri);
7952 if (pridialplan == -2 || pridialplan == -3) {
7954 if (pridialplan == -2) {
7957 pridialplan = PRI_INTERNATIONAL_ISDN;
7959 if (pridialplan == -2) {
7962 pridialplan = PRI_NATIONAL_ISDN;
7964 pridialplan = PRI_LOCAL_ISDN;
7970 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
7973 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
7976 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
7979 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
7982 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
7985 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
7988 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
7991 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
7994 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
7997 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
8000 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
8003 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
8006 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
8009 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
8020#if defined(HAVE_PRI_SETUP_KEYPAD)
8024 keypad = opt_args[OPT_ARG_KEYPAD];
8025 pri_sr_set_keypad_digits(sr, keypad);
8032 char *called =
c + p->
stripmsd + dp_strip;
8034 pri_sr_set_called(sr, called, pridialplan, s ? 1 : 0);
8035#if defined(HAVE_PRI_SETUP_ACK_INBAND)
8036 p->no_dialed_digits = !called[0];
8040#if defined(HAVE_PRI_SUBADDR)
8041 if (dialed_subaddress.valid) {
8042 struct pri_party_subaddress subaddress;
8044 memset(&subaddress, 0,
sizeof(subaddress));
8045 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
8046 pri_sr_set_called_subaddress(sr, &subaddress);
8049#if defined(HAVE_PRI_REVERSE_CHARGE)
8051 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
8054#if defined(HAVE_PRI_AOC_EVENTS)
8057 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
's')) {
8058 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
8060 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'd')) {
8061 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
8063 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'e')) {
8064 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
8089 if ((l !=
NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) {
8091 if (prilocaldialplan == -2) {
8094 prilocaldialplan = PRI_INTERNATIONAL_ISDN;
8096 if (prilocaldialplan == -2) {
8099 prilocaldialplan = PRI_NATIONAL_ISDN;
8101 prilocaldialplan = PRI_LOCAL_ISDN;
8103 }
else if (prilocaldialplan == -1) {
8108 while (*l >
'9' && *l !=
'*' && *l !=
'#') {
8111 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
8114 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
8117 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
8120 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
8123 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
8126 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
8129 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
8132 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
8135 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
8138 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
8141 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
8144 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
8147 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
8150 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
8155 "Unrecognized prilocaldialplan %s modifier: %c\n",
8156 *l >
'Z' ?
"NPI" :
"TON", *l);
8163 pri_sr_set_caller(sr, l ? (l + ldp_strip) :
NULL, n, prilocaldialplan,
8166#if defined(HAVE_PRI_SUBADDR)
8168 struct pri_party_subaddress subaddress;
8170 memset(&subaddress, 0,
sizeof(subaddress));
8171 sig_pri_party_subaddress_from_ast(&subaddress, &connected_id.
subaddress);
8172 pri_sr_set_caller_subaddress(sr, &subaddress);
8176 sig_pri_redirecting_update(p, ast);
8178#ifdef SUPPORT_USERUSER
8182 pri_sr_set_useruser(sr, useruser);
8185#if defined(HAVE_PRI_CCSS)
8194 struct sig_pri_cc_monitor_instance *instance;
8201 if (pri_cc_call(p->
pri->
pri, instance->cc_id, p->
call, sr)) {
8221 if (core_id == -1 && pri_setup(p->
pri->
pri, p->
call, sr)) {
8233 sig_pri_set_dialing(p, 1);
8242 switch (condition) {
8255 pri_grab(p, p->
pri);
8256#ifdef HAVE_PRI_PROG_W_CAUSE
8259 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8269 pri_grab(p, p->
pri);
8270 pri_acknowledge(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p),
8286 pri_grab(p, p->
pri);
8287 pri_proceeding(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 0);
8296 sig_pri_set_digital(p, 0);
8301 pri_grab(p, p->
pri);
8302#ifdef HAVE_PRI_PROG_W_CAUSE
8303 pri_progress_with_cause(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1, -1);
8305 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8354 pri_grab(p, p->
pri);
8355#ifdef HAVE_PRI_PROG_W_CAUSE
8358 pri_progress(p->
pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8367 pri_grab(p, p->
pri);
8377 pri_grab(p, p->
pri);
8389 res = sig_pri_play_tone(p, -1);
8394 struct pri_party_connected_line
connected;
8397 int colp_allowed = 0;
8400 pri_grab(p, p->
pri);
8419 if (!colp_allowed) {
8421 ast_debug(1,
"Blocked AST_CONTROL_CONNECTED_LINE on %s\n",
8427 sig_pri_party_id_from_ast(&
connected.id, &connected_id);
8438 dialplan = PRI_INTERNATIONAL_ISDN;
8442 dialplan = PRI_NATIONAL_ISDN;
8444 dialplan = PRI_LOCAL_ISDN;
8452 strlen(
connected.id.number.str + prefix_strip) + 1);
8470 pri_grab(p, p->
pri);
8471 sig_pri_redirecting_update(p, chan);
8476#if defined(HAVE_PRI_AOC_EVENTS)
8481 if (decoded && p->
pri) {
8482 pri_grab(p, p->
pri);
8486 sig_pri_aoc_s_from_ast(p, decoded);
8491 sig_pri_aoc_d_from_ast(p, decoded);
8496 sig_pri_aoc_e_from_ast(p, decoded);
8504 if (p->waiting_for_aoce) {
8505 p->waiting_for_aoce = 0;
8507 "Received final AOC-E msg, continue with hangup on %s\n",
8528#if defined(HAVE_PRI_MCID)
8531 pri_grab(p, p->
pri);
8547 pri_grab(p, p->
pri);
8548#if defined(HAVE_PRI_AOC_EVENTS)
8549 if (p->aoc_s_request_invoke_id_valid) {
8553 pri_aoc_s_request_response_send(p->
pri->
pri, p->
call,
8554 p->aoc_s_request_invoke_id,
NULL);
8555 p->aoc_s_request_invoke_id_valid = 0;
8561 sig_pri_set_dialing(p, 0);
8562 sig_pri_open_media(p);
8579static int sig_pri_available_check(
struct sig_pri_chan *pvt)
8591#if defined(HAVE_PRI_CALL_WAITING)
8610 if (
pri->num_call_waiting_calls <
pri->max_call_waiting_calls) {
8611 if (!
pri->num_call_waiting_calls) {
8624 idx = pri_find_empty_nobch(
pri);
8628 cw->is_call_waiting = 1;
8629 sig_pri_init_config(cw,
pri);
8650#
if defined(HAVE_PRI_CALL_WAITING)
8657 !
pri->num_call_waiting_calls &&
8659 sig_pri_available_check(p)) {
8665#if defined(HAVE_PRI_CALL_WAITING)
8666 if (!is_specific_channel) {
8669 cw = sig_pri_cw_available(
pri);
8693 ast_debug(1,
"Queueing digit '%c' since setup_ack not yet received\n",
8699 "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
8705 pri_grab(pvt, pvt->
pri);
8712 "Span %d: Digit '%c' may be ignored by peer. (Call level:%u(%s))\n",
8735 sig_pri_open_media(pvt);
8746 sig_pri_set_dialing(pvt, 0);
8748 sig_pri_set_echocanceller(pvt, 1);
8752#if defined(HAVE_PRI_MWI)
8764static 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)
8766 struct pri_party_id voicemail;
8769 ast_debug(1,
"Send MWI indication for %s(%s) vm_number:%s num_messages:%d\n",
8770 vm_box, mbox_id,
S_OR(vm_number,
"<not-present>"), num_messages);
8774 mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8775 mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8778 memset(&voicemail, 0,
sizeof(voicemail));
8779 voicemail.number.valid = 1;
8780 voicemail.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8781 voicemail.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8783 ast_copy_string(voicemail.number.str, vm_number,
sizeof(voicemail.number.str));
8787#if defined(HAVE_PRI_MWI_V2)
8788 pri_mwi_indicate_v2(pri->
pri, &
mailbox, &voicemail, 1 , num_messages,
8797#if defined(HAVE_PRI_MWI)
8819 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8820 if (!pri->mbox[idx].sub) {
8825 if (!strcmp(pri->mbox[idx].uniqueid, mwi_state->
uniqueid)) {
8827 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number,
8828 pri->mbox[idx].vm_box, pri->mbox[idx].uniqueid, mwi_state->
new_msgs);
8835#if defined(HAVE_PRI_MWI)
8843static void sig_pri_mwi_cache_update(
struct sig_pri_span *pri)
8848 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8850 if (!pri->mbox[idx].sub) {
8856 pri->mbox[idx].uniqueid);
8863 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number, pri->mbox[idx].vm_box,
8864 pri->mbox[idx].uniqueid, mwi_state->
new_msgs);
8877#if defined(HAVE_PRI_MWI)
8881#if defined(HAVE_PRI_MWI)
8882 for (idx = 0; idx <
ARRAY_LEN(pri->mbox); ++idx) {
8883 if (pri->mbox[idx].sub) {
8902static int sig_pri_cmp_pri_chans(
const void *left,
const void *right)
8942#if defined(HAVE_PRI_MWI)
8944 char *prev_vm_number;
8947#if defined(HAVE_PRI_MWI)
8950 if (
pri->mbox[i].sub) {
8957 sig_pri_sort_pri_chans(
pri);
8959#if defined(HAVE_PRI_MWI)
8964 prev_vm_number =
NULL;
8965 saveptr =
pri->mwi_vm_numbers;
8969 vm_number =
strsep(&saveptr,
",");
8975 vm_number = prev_vm_number;
8978 prev_vm_number = vm_number;
8980 pri->mbox[i].vm_number = vm_number;
8987 saveptr =
pri->mwi_vm_boxes;
9005 saveptr =
pri->mwi_mailboxes;
9009 mbox_id =
strsep(&saveptr,
",");
9016 pri->mbox[i].uniqueid = mbox_id;
9017 if (!
pri->mbox[i].vm_box || !mbox_id) {
9019 ast_debug(1,
"%s span %d MWI position %d disabled. vm_box:%s mbox_id:%s.\n",
9020 sig_pri_cc_type_name,
pri->
span, i,
9021 pri->mbox[i].vm_box ?:
"<missing>",
9022 mbox_id ?:
"<missing>");
9027 if (!
pri->mbox[i].sub) {
9028 ast_log(
LOG_ERROR,
"%s span %d could not subscribe to MWI events for %s(%s).\n",
9029 sig_pri_cc_type_name,
pri->
span,
pri->mbox[i].vm_box, mbox_id);
9031#if defined(HAVE_PRI_MWI_V2)
9034 sig_pri_cc_type_name,
pri->
span,
pri->mbox[i].vm_box, mbox_id);
9054#if defined(HAVE_PRI_SERVICE_MESSAGES)
9055 if (
pri->enable_service_message_support) {
9056 pri_set_service_message_support(
pri->
dchans[i], 1);
9063#ifdef HAVE_PRI_PROG_W_CAUSE
9066#ifdef HAVE_PRI_INBANDDISCONNECT
9067 pri_set_inbanddisconnect(
pri->
dchans[i],
pri->inbanddisconnect);
9081#ifdef PRI_GETSET_TIMERS
9082 for (x = 0; x < PRI_MAX_TIMERS; x++) {
9092#if defined(HAVE_PRI_CALL_HOLD)
9093 pri_hold_enable(
pri->
pri, 1);
9095#if defined(HAVE_PRI_CALL_REROUTING)
9096 pri_reroute_enable(
pri->
pri, 1);
9098#if defined(HAVE_PRI_HANGUP_FIX)
9099 pri_hangup_fix_enable(
pri->
pri, 1);
9101#if defined(HAVE_PRI_CCSS)
9102 pri_cc_enable(
pri->
pri, 1);
9103 pri_cc_recall_mode(
pri->
pri,
pri->cc_ptmp_recall_mode);
9104 pri_cc_retain_signaling_req(
pri->
pri,
pri->cc_qsig_signaling_link_req);
9105 pri_cc_retain_signaling_rsp(
pri->
pri,
pri->cc_qsig_signaling_link_rsp);
9107#if defined(HAVE_PRI_TRANSFER)
9108 pri_transfer_enable(
pri->
pri, 1);
9110#if defined(HAVE_PRI_AOC_EVENTS)
9111 pri_aoc_events_enable(
pri->
pri, 1);
9113#if defined(HAVE_PRI_CALL_WAITING)
9114 pri_connect_ack_enable(
pri->
pri, 1);
9116#if defined(HAVE_PRI_MCID)
9117 pri_mcid_enable(
pri->
pri, 1);
9119#if defined(HAVE_PRI_DISPLAY_TEXT)
9120 pri_display_options_send(
pri->
pri,
pri->display_flags_send);
9121 pri_display_options_receive(
pri->
pri,
pri->display_flags_receive);
9123#if defined(HAVE_PRI_DATETIME_SEND)
9124 pri_date_time_send_option(
pri->
pri,
pri->datetime_send);
9126#if defined(HAVE_PRI_L2_PERSISTENCE)
9127 pri_persistent_layer2_option(
pri->
pri,
pri->l2_persistence);
9143#if defined(HAVE_PRI_MWI)
9152 sig_pri_mwi_cache_update(
pri);
9168 pri_grab(p, p->
pri);
9171 if (pri_get_timer(p->
pri->
pri, PRI_TIMER_T309) < 0) {
9181 sig_pri_span_devstate_changed(p->
pri);
9227#define SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n"
9228#define SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s"
9231 ast_cli(fd, SIG_PRI_SC_HEADER,
"PRI",
"",
"B",
"Chan",
"Call",
"PRI",
"Channel");
9232 ast_cli(fd, SIG_PRI_SC_HEADER,
"Span",
"Chan",
"Chan",
"Idle",
"Level",
"Call",
"Name");
9247 sig_pri_lock_private(pvt);
9248 sig_pri_lock_owner(
pri, idx);
9251 sig_pri_unlock_private(pvt);
9255 snprintf(line,
sizeof(line), SIG_PRI_SC_LINE,
9261 pvt->
call ?
"Yes" :
"No",
9267 sig_pri_unlock_private(pvt);
9276static void build_status(
char *s,
size_t len,
int status,
int active)
9278 if (!s ||
len < 1) {
9281 snprintf(s,
len,
"%s%s, %s",
9282 (
status & DCHAN_NOTINALARM) ?
"" :
"In Alarm, ",
9283 (
status & DCHAN_UP) ?
"Up" :
"Down",
9284 (active) ?
"Active" :
"Standby");
9306#ifdef PRI_DUMP_INFO_STR
9307 char *info_str =
NULL;
9309 ast_cli(fd,
"%s D-channel: %d\n", pri_order(x), dchannels[x]);
9313#ifdef PRI_DUMP_INFO_STR
9314 info_str = pri_dump_info_str(
pri->
pri);
9331 sig_pri_lock_private(p);
9334 ast_debug(1,
"Unable to find pri or call on channel!\n");
9335 sig_pri_unlock_private(p);
9339 pri_grab(p, p->
pri);
9340 pri_keypad_facility(p->
pri->
pri, p->
call, digits);
9343 sig_pri_unlock_private(p);
9352 sig_pri_lock_private(p);
9355 ast_debug(1,
"Unable to find pri or call on channel!\n");
9356 sig_pri_unlock_private(p);
9360 pri_grab(p, p->
pri);
9361 res = pri_callrerouting_facility(p->
pri->
pri, p->
call, destination, original, reason);
9364 sig_pri_unlock_private(p);
9369#if defined(HAVE_PRI_SERVICE_MESSAGES)
9370int pri_maintenance_bservice(
struct pri *
pri,
struct sig_pri_chan *p,
int changestatus)
9372 int channel = PVT_TO_CHANNEL(p);
9375 return pri_maintenance_service(
pri, span,
channel, changestatus);
9381 if (pchan->
owner == oldchan) {
9382 pchan->
owner = newchan;
9386#if defined(HAVE_PRI_DISPLAY_TEXT)
9396 struct pri_subcmd_display_txt display;
9400 display.length = strlen(display.text);
9401 display.char_set = 0;
9402 pri_grab(p, p->
pri);
9403 pri_display_text(p->
pri->
pri, p->
call, &display);
9409#if defined(HAVE_PRI_CCSS)
9428 struct sig_pri_cc_agent_prv *cc_pvt;
9436 cc_pvt->pri = pvt_chan->
pri;
9437 cc_pvt->cc_id = pri_cc_available(pvt_chan->
pri->
pri, pvt_chan->
call);
9439 if (cc_pvt->cc_id == -1) {
9448#if defined(HAVE_PRI_CCSS)
9477#if defined(HAVE_PRI_CCSS)
9498#if defined(HAVE_PRI_CCSS)
9519 struct sig_pri_cc_agent_prv *cc_pvt;
9522 const char *failed_msg;
9523 static const char *failed_to_send =
"Failed to send the CC request response.";
9524 static const char *not_accepted =
"The core declined the CC request.";
9528 if (cc_pvt->cc_request_response_pending) {
9529 cc_pvt->cc_request_response_pending = 0;
9545 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id,
status);
9549 failed_msg = failed_to_send;
9556 failed_msg = failed_to_send;
9558 failed_msg = not_accepted;
9571#if defined(HAVE_PRI_CCSS)
9589 struct sig_pri_cc_agent_prv *cc_pvt;
9593 pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
9599#if defined(HAVE_PRI_CCSS)
9624 struct sig_pri_cc_agent_prv *cc_pvt;
9628 pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
9634#if defined(HAVE_PRI_CCSS)
9658 struct sig_pri_cc_agent_prv *cc_pvt;
9662 pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
9668#if defined(HAVE_PRI_CCSS)
9692#if defined(HAVE_PRI_CCSS)
9714 struct sig_pri_cc_agent_prv *cc_pvt;
9718 pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
9724#if defined(HAVE_PRI_CCSS)
9741 struct sig_pri_cc_agent_prv *cc_pvt;
9751 if (cc_pvt->cc_request_response_pending) {
9752 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2);
9755 pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
9762#if defined(HAVE_PRI_CCSS)
9773static int sig_pri_cc_monitor_instance_hash_fn(
const void *obj,
const int flags)
9775 const struct sig_pri_cc_monitor_instance *monitor_instance = obj;
9777 return monitor_instance->core_id;
9781#if defined(HAVE_PRI_CCSS)
9793static int sig_pri_cc_monitor_instance_cmp_fn(
void *obj,
void *arg,
int flags)
9795 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
9796 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
9802#if defined(HAVE_PRI_CCSS)
9823 struct sig_pri_cc_monitor_instance *instance;
9843 res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
9850#if defined(HAVE_PRI_CCSS)
9866 struct sig_pri_cc_monitor_instance *instance;
9870 pri_cc_status(instance->pri->pri, instance->cc_id, 1);
9877#if defined(HAVE_PRI_CCSS)
9892 struct sig_pri_cc_monitor_instance *instance;
9896 pri_cc_status(instance->pri->pri, instance->cc_id, 0);
9903#if defined(HAVE_PRI_CCSS)
9922 struct sig_pri_cc_monitor_instance *instance;
9940 pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
9947#if defined(HAVE_PRI_CCSS)
9976#if defined(HAVE_PRI_CCSS)
9990 struct sig_pri_cc_monitor_instance *instance;
9992 instance = monitor_pvt;
10012#if defined(HAVE_PRI_MCID)
10018#if defined(HAVE_PRI_CCSS)
10019 sig_pri_cc_type_name = cc_type_name;
10021 sig_pri_cc_monitor_instance_hash_fn,
NULL, sig_pri_cc_monitor_instance_cmp_fn);
10022 if (!sig_pri_cc_monitors) {
10035#if defined(HAVE_PRI_CCSS)
10036 if (sig_pri_cc_monitors) {
10037 ao2_ref(sig_pri_cc_monitors, -1);
10038 sig_pri_cc_monitors =
NULL;
10042#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.
char * strsep(char **str, const char *delims)
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.
@ 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
char currency_name[AOC_CURRENCY_NAME_SIZE]
uint16_t granularity_time_scale
uint8_t charging_type
Charging interval type.
uint32_t granularity_time
char currency_name[AOC_CURRENCY_NAME_SIZE]
struct ast_aoc_flat_rate flat
union ast_aoc_s_entry::@182 rate
Charge rate being applied.
struct ast_aoc_volume_rate volume
struct ast_aoc_duration_rate duration
char currency_name[AOC_CURRENCY_NAME_SIZE]
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.
struct ast_channel::@333 fds
unsigned short transfercapability
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.
union ast_frame::@228 data
struct ast_frame_subclass subclass
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::@210 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)