117 #include "asterisk/stasis_channels.h"
120 #ifndef PRI_EVENT_FACILITY
121 #error "Upgrade your libpri"
129 #undef SUPPORT_USERUSER
137 #if defined(HAVE_PRI_CCSS)
164 static int pri_matchdigittimeout = 3000;
166 static int pri_gendigittimeout = 8000;
168 #define DCHAN_NOTINALARM (1 << 0)
169 #define DCHAN_UP (1 << 1)
172 #define PRI_CHANNEL(p) ((p) & 0xff)
173 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
174 #define PRI_EXPLICIT (1 << 16)
175 #define PRI_CIS_CALL (1 << 17)
176 #define PRI_HELD_CALL (1 << 18)
179 #define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP)
181 static int pri_active_dchan_index(
struct sig_pri_span *pri);
206 ast_mutex_unlock(&pri->
lock);
209 static unsigned int PVT_TO_CHANNEL(
struct sig_pri_chan *p)
211 int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->
mastertrunkgroup ? PRI_EXPLICIT : 0));
212 ast_debug(5,
"prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n",
218 static void sig_pri_handle_dchan_exception(
struct sig_pri_span *pri,
int index)
225 static void sig_pri_set_dialing(
struct sig_pri_chan *p,
int is_dialing)
232 static void sig_pri_set_digital(
struct sig_pri_chan *p,
int is_digital)
234 p->digital = is_digital;
240 static void sig_pri_set_outgoing(
struct sig_pri_chan *p,
int is_outgoing)
242 p->outgoing = is_outgoing;
248 void sig_pri_set_alarm(
struct sig_pri_chan *p,
int in_alarm)
262 p->inalarm = in_alarm;
268 static const char *sig_pri_get_orig_dialstring(
struct sig_pri_chan *p)
273 ast_log(LOG_ERROR,
"get_orig_dialstring callback not defined\n");
277 #if defined(HAVE_PRI_CCSS)
278 static void sig_pri_make_cc_dialstring(
struct sig_pri_chan *p,
char *buf,
size_t buf_size)
283 ast_log(LOG_ERROR,
"make_cc_dialstring callback not defined\n");
289 static void sig_pri_dial_digits(
struct sig_pri_chan *p,
const char *dial_string)
305 static void sig_pri_span_devstate_changed(
struct sig_pri_span *pri)
319 static void sig_pri_set_caller_id(
struct sig_pri_chan *p)
326 caller.id.name.str = p->cid_name;
328 caller.id.name.valid = 1;
330 caller.id.number.str = p->cid_num;
331 caller.id.number.plan = p->
cid_ton;
333 caller.id.number.valid = 1;
335 if (!ast_strlen_zero(p->cid_subaddr)) {
336 caller.id.subaddress.valid = 1;
339 caller.id.subaddress.str = p->cid_subaddr;
343 caller.ani.number.str = p->cid_ani;
346 caller.ani.number.valid = 1;
361 static void sig_pri_set_dnid(
struct sig_pri_chan *p,
const char *dnid)
376 static void sig_pri_set_rdnis(
struct sig_pri_chan *p,
const char *rdnis)
383 static void sig_pri_unlock_private(
struct sig_pri_chan *p)
390 static void sig_pri_lock_private(
struct sig_pri_chan *p)
397 static void sig_pri_deadlock_avoidance_private(
struct sig_pri_chan *p)
403 sig_pri_unlock_private(p);
405 sig_pri_lock_private(p);
412 while (ast_mutex_trylock(&pri->
lock)) {
414 sig_pri_deadlock_avoidance_private(p);
417 if (pri->
master != AST_PTHREADT_NULL) {
418 pthread_kill(pri->
master, SIGURG);
435 switch (pri_reason) {
436 case PRI_REDIR_FORWARD_ON_BUSY:
437 ast_reason = AST_REDIRECTING_REASON_USER_BUSY;
439 case PRI_REDIR_FORWARD_ON_NO_REPLY:
440 ast_reason = AST_REDIRECTING_REASON_NO_ANSWER;
442 case PRI_REDIR_DEFLECTION:
443 ast_reason = AST_REDIRECTING_REASON_DEFLECTION;
445 case PRI_REDIR_UNCONDITIONAL:
446 ast_reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
448 case PRI_REDIR_UNKNOWN:
450 ast_reason = AST_REDIRECTING_REASON_UNKNOWN;
470 switch (ast_reason) {
471 case AST_REDIRECTING_REASON_USER_BUSY:
472 pri_reason = PRI_REDIR_FORWARD_ON_BUSY;
474 case AST_REDIRECTING_REASON_NO_ANSWER:
475 pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY;
477 case AST_REDIRECTING_REASON_UNCONDITIONAL:
478 pri_reason = PRI_REDIR_UNCONDITIONAL;
480 case AST_REDIRECTING_REASON_DEFLECTION:
481 pri_reason = PRI_REDIR_DEFLECTION;
483 case AST_REDIRECTING_REASON_UNKNOWN:
485 pri_reason = PRI_REDIR_UNKNOWN;
501 static int pri_to_ast_presentation(
int pri_presentation)
503 int ast_presentation;
505 switch (pri_presentation) {
506 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED:
507 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED;
509 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
510 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN;
512 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
513 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN;
515 case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER:
516 ast_presentation = AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER;
519 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED:
520 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
522 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
523 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN;
525 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
526 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN;
528 case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER:
529 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER;
532 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED:
533 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
534 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
535 case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER:
536 ast_presentation = AST_PRES_NUMBER_NOT_AVAILABLE;
540 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
544 return ast_presentation;
556 static int ast_to_pri_presentation(
int ast_presentation)
558 int pri_presentation;
560 switch (ast_presentation) {
561 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED:
562 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
564 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN:
565 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
567 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN:
568 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
570 case AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER:
571 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER;
574 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED:
575 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
577 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN:
578 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
580 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN:
581 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
583 case AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER:
584 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER;
587 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_UNSCREENED:
588 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_PASSED_SCREEN:
589 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_FAILED_SCREEN:
590 case AST_PRES_UNAVAILABLE | AST_PRES_NETWORK_NUMBER:
591 pri_presentation = PRES_NUMBER_NOT_AVAILABLE;
595 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
599 return pri_presentation;
615 switch (pri_char_set) {
617 case PRI_CHAR_SET_UNKNOWN:
618 ast_char_set = AST_PARTY_CHAR_SET_UNKNOWN;
620 case PRI_CHAR_SET_ISO8859_1:
621 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_1;
623 case PRI_CHAR_SET_WITHDRAWN:
624 ast_char_set = AST_PARTY_CHAR_SET_WITHDRAWN;
626 case PRI_CHAR_SET_ISO8859_2:
627 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_2;
629 case PRI_CHAR_SET_ISO8859_3:
630 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_3;
632 case PRI_CHAR_SET_ISO8859_4:
633 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_4;
635 case PRI_CHAR_SET_ISO8859_5:
636 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_5;
638 case PRI_CHAR_SET_ISO8859_7:
639 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_7;
641 case PRI_CHAR_SET_ISO10646_BMPSTRING:
642 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_BMPSTRING;
644 case PRI_CHAR_SET_ISO10646_UTF_8STRING:
645 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING;
665 switch (ast_char_set) {
667 case AST_PARTY_CHAR_SET_UNKNOWN:
668 pri_char_set = PRI_CHAR_SET_UNKNOWN;
670 case AST_PARTY_CHAR_SET_ISO8859_1:
671 pri_char_set = PRI_CHAR_SET_ISO8859_1;
673 case AST_PARTY_CHAR_SET_WITHDRAWN:
674 pri_char_set = PRI_CHAR_SET_WITHDRAWN;
676 case AST_PARTY_CHAR_SET_ISO8859_2:
677 pri_char_set = PRI_CHAR_SET_ISO8859_2;
679 case AST_PARTY_CHAR_SET_ISO8859_3:
680 pri_char_set = PRI_CHAR_SET_ISO8859_3;
682 case AST_PARTY_CHAR_SET_ISO8859_4:
683 pri_char_set = PRI_CHAR_SET_ISO8859_4;
685 case AST_PARTY_CHAR_SET_ISO8859_5:
686 pri_char_set = PRI_CHAR_SET_ISO8859_5;
688 case AST_PARTY_CHAR_SET_ISO8859_7:
689 pri_char_set = PRI_CHAR_SET_ISO8859_7;
691 case AST_PARTY_CHAR_SET_ISO10646_BMPSTRING:
692 pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
694 case AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING:
695 pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
702 #if defined(HAVE_PRI_SUBADDR)
711 static void sig_pri_set_subaddress(
struct ast_party_subaddress *ast_subaddress,
const struct pri_party_subaddress *pri_subaddress)
713 ast_free(ast_subaddress->
str);
714 if (pri_subaddress->length <= 0) {
719 if (!pri_subaddress->type) {
721 ast_subaddress->
str =
ast_strdup((
char *) pri_subaddress->data);
729 cnum =
ast_malloc(2 * pri_subaddress->length + 1);
736 len = pri_subaddress->length - 1;
737 for (x = 0; x < len; ++x) {
738 ptr += sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[x]);
741 if (pri_subaddress->odd_even_indicator) {
743 sprintf(ptr,
"%01hhx", (
unsigned char)((pri_subaddress->data[len]) >> 4));
746 sprintf(ptr,
"%02hhx", (
unsigned char)pri_subaddress->data[len]);
748 ast_subaddress->
str = cnum;
750 ast_subaddress->
type = pri_subaddress->type;
752 ast_subaddress->
valid = 1;
756 #if defined(HAVE_PRI_SUBADDR)
757 static unsigned char ast_pri_pack_hex_char(
char c)
763 }
else if (c < (
'9' + 1)) {
765 }
else if (c <
'A') {
767 }
else if (c < (
'F' + 1)) {
769 }
else if (c <
'a') {
771 }
else if (c < (
'f' + 1)) {
780 #if defined(HAVE_PRI_SUBADDR)
796 static int ast_pri_pack_hex_string(
unsigned char *dst,
char *src,
int maxlen)
799 int len = strlen(src);
801 if (len > (2 * maxlen)) {
805 res = len / 2 + len % 2;
808 *dst = ast_pri_pack_hex_char(*src) << 4;
810 *dst |= ast_pri_pack_hex_char(*src);
815 *dst = ast_pri_pack_hex_char(*src) << 4;
821 #if defined(HAVE_PRI_SUBADDR)
832 static void sig_pri_party_subaddress_from_ast(
struct pri_party_subaddress *pri_subaddress,
const struct ast_party_subaddress *ast_subaddress)
834 if (ast_subaddress->
valid && !ast_strlen_zero(ast_subaddress->
str)) {
835 pri_subaddress->type = ast_subaddress->
type;
836 if (!ast_subaddress->
type) {
839 sizeof(pri_subaddress->data));
840 pri_subaddress->length = strlen((
char *) pri_subaddress->data);
841 pri_subaddress->odd_even_indicator = 0;
842 pri_subaddress->valid = 1;
849 int length = ast_pri_pack_hex_string(pri_subaddress->data,
850 ast_subaddress->
str,
sizeof(pri_subaddress->data));
852 pri_subaddress->length = length;
854 length = strlen(ast_subaddress->
str);
855 if (length > 2 *
sizeof(pri_subaddress->data)) {
856 pri_subaddress->odd_even_indicator = 0;
858 pri_subaddress->odd_even_indicator = (length & 1);
860 pri_subaddress->valid = 1;
876 static void sig_pri_party_name_from_ast(
struct pri_party_name *pri_name,
const struct ast_party_name *ast_name)
878 if (!ast_name->
valid) {
882 pri_name->presentation = ast_to_pri_presentation(ast_name->
presentation);
883 pri_name->char_set = ast_to_pri_char_set(ast_name->
char_set);
884 if (!ast_strlen_zero(ast_name->
str)) {
899 static void sig_pri_party_number_from_ast(
struct pri_party_number *pri_number,
const struct ast_party_number *ast_number)
901 if (!ast_number->
valid) {
904 pri_number->valid = 1;
905 pri_number->presentation = ast_to_pri_presentation(ast_number->
presentation);
906 pri_number->plan = ast_number->
plan;
907 if (!ast_strlen_zero(ast_number->
str)) {
922 static void sig_pri_party_id_from_ast(
struct pri_party_id *pri_id,
const struct ast_party_id *ast_id)
924 sig_pri_party_name_from_ast(&pri_id->name, &ast_id->
name);
925 sig_pri_party_number_from_ast(&pri_id->number, &ast_id->
number);
926 #if defined(HAVE_PRI_SUBADDR)
927 sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->
subaddress);
943 struct pri_party_redirecting pri_redirecting;
945 struct ast_party_id redirecting_from = ast_channel_redirecting_effective_from(ast);
946 struct ast_party_id redirecting_to = ast_channel_redirecting_effective_to(ast);
947 struct ast_party_id redirecting_orig = ast_channel_redirecting_effective_orig(ast);
949 memset(&pri_redirecting, 0,
sizeof(pri_redirecting));
950 ast_redirecting = ast_channel_redirecting(ast);
951 sig_pri_party_id_from_ast(&pri_redirecting.from, &redirecting_from);
952 sig_pri_party_id_from_ast(&pri_redirecting.to, &redirecting_to);
953 sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &redirecting_orig);
954 pri_redirecting.count = ast_redirecting->
count;
955 pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->
orig_reason.
code);
956 pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->
reason.
code);
958 pri_redirecting_update(pvt->pri->
pri, pvt->
call, &pri_redirecting);
968 static void sig_pri_dsp_reset_and_flush_digits(
struct sig_pri_chan *p)
975 static int sig_pri_set_echocanceller(
struct sig_pri_chan *p,
int enable)
991 static int sig_pri_play_tone(
struct sig_pri_chan *p,
enum sig_pri_tone tone)
1015 ast_assert(p->owner == NULL || p->owner == c);
1019 ast_channel_transfercapability_set(c, transfercapability);
1022 if (transfercapability & AST_TRANS_CAP_DIGITAL) {
1023 sig_pri_set_digital(p, 1);
1026 ast_mutex_lock(&p->pri->
lock);
1027 sig_pri_span_devstate_changed(p->pri);
1028 ast_mutex_unlock(&p->pri->
lock);
1061 static void sig_pri_ami_channel_event(
struct sig_pri_chan *p)
1070 int transfercapability)
1076 sig_pri_set_outgoing(p, 1);
1078 p->exten, assignedids, requestor);
1080 sig_pri_set_outgoing(p, 0);
1095 static const char *pri_order(
int level)
1105 return "Quaternary";
1112 static int pri_active_dchan_index(
struct sig_pri_span *pri)
1121 ast_log(LOG_WARNING,
"No active dchan found!\n");
1138 if (pri->
dchans[idx] == old) {
1141 if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) {
1155 if (old && oldslot != newslot) {
1156 ast_log(LOG_WARNING,
1157 "Span %d: No D-channels up! Switching selected D-channel from %s to %s.\n",
1158 pri->
span, pri_order(oldslot), pri_order(newslot));
1160 ast_log(LOG_WARNING,
"Span %d: No D-channels up!\n", pri->
span);
1166 if (old && oldslot != newslot) {
1168 "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n",
1169 pri_order(oldslot), pri->
fds[oldslot],
1170 pri_order(newslot), pri->
fds[newslot]);
1184 if (pri->
sig != SIG_BRI_PTMP) {
1185 ast_log(LOG_WARNING,
"Span %d: D-channel is down!\n", pri->
span);
1204 static int sig_pri_is_chan_in_use(
struct sig_pri_chan *pvt)
1206 return pvt->owner || pvt->
call || pvt->
allocated || pvt->inalarm
1220 return !sig_pri_is_chan_in_use(pvt)
1221 #if defined(HAVE_PRI_SERVICE_MESSAGES)
1239 static void sig_pri_lock_owner(
struct sig_pri_span *pri,
int chanpos)
1242 if (!pri->
pvts[chanpos]->owner) {
1246 if (!ast_channel_trylock(pri->
pvts[chanpos]->owner)) {
1252 sig_pri_unlock_private(pri->
pvts[chanpos]);
1253 DEADLOCK_AVOIDANCE(&pri->
lock);
1254 sig_pri_lock_private(pri->
pvts[chanpos]);
1272 sig_pri_lock_owner(pri, chanpos);
1273 if (pri->
pvts[chanpos]->owner) {
1275 ast_channel_unlock(pri->
pvts[chanpos]->owner);
1290 static void sig_pri_queue_hold(
struct sig_pri_span *pri,
int chanpos)
1292 sig_pri_lock_owner(pri, chanpos);
1293 if (pri->
pvts[chanpos]->owner) {
1295 ast_channel_unlock(pri->
pvts[chanpos]->owner);
1310 static void sig_pri_queue_unhold(
struct sig_pri_span *pri,
int chanpos)
1312 sig_pri_lock_owner(pri, chanpos);
1313 if (pri->
pvts[chanpos]->owner) {
1315 ast_channel_unlock(pri->
pvts[chanpos]->owner);
1331 static void pri_queue_control(
struct sig_pri_span *pri,
int chanpos,
int subclass)
1340 pri_queue_frame(pri, chanpos, &f);
1357 static void sig_pri_queue_hangup(
struct sig_pri_span *pri,
int chanpos)
1365 sig_pri_lock_owner(pri, chanpos);
1366 owner = pri->
pvts[chanpos]->owner;
1370 ast_channel_unlock(owner);
1372 sig_pri_unlock_private(pri->
pvts[chanpos]);
1373 ast_mutex_unlock(&pri->
lock);
1376 ast_mutex_lock(&pri->
lock);
1377 sig_pri_lock_private(pri->
pvts[chanpos]);
1396 static void pri_queue_pvt_cause_data(
struct sig_pri_span *pri,
int chanpos,
const char *cause,
int ast_cause)
1401 sig_pri_lock_owner(pri, chanpos);
1402 chan = pri->
pvts[chanpos]->owner;
1404 int datalen =
sizeof(*cause_code) + strlen(cause);
1406 memset(cause_code, 0, datalen);
1412 ast_channel_unlock(chan);
1429 static int pri_find_principle_by_call(
struct sig_pri_span *pri, q931_call *call)
1437 for (idx = 0; idx < pri->
numchans; ++idx) {
1457 static void pri_destroy_later(
struct sig_pri_span *pri)
1476 static void sig_pri_kill_call(
struct sig_pri_span *pri, q931_call *call,
int cause)
1480 chanpos = pri_find_principle_by_call(pri, call);
1482 pri_hangup(pri->
pri, call, cause);
1485 sig_pri_lock_private(pri->
pvts[chanpos]);
1486 if (!pri->
pvts[chanpos]->owner) {
1487 pri_hangup(pri->
pri, call, cause);
1489 sig_pri_unlock_private(pri->
pvts[chanpos]);
1490 sig_pri_span_devstate_changed(pri);
1493 ast_channel_hangupcause_set(pri->
pvts[chanpos]->owner, cause);
1495 sig_pri_unlock_private(pri->
pvts[chanpos]);
1511 static int pri_find_principle(
struct sig_pri_span *pri,
int channel, q931_call *call)
1523 prioffset = PRI_CHANNEL(channel);
1524 if (!prioffset || (channel & PRI_HELD_CALL)) {
1526 return pri_find_principle_by_call(pri, call);
1529 span = PRI_SPAN(channel);
1530 if (!(channel & PRI_EXPLICIT)) {
1533 index = pri_active_dchan_index(pri);
1541 for (x = 0; x < pri->
numchans; x++) {
1567 static int pri_fixup_principle(
struct sig_pri_span *pri,
int principle, q931_call *call)
1571 if (principle < 0 || pri->numchans <= principle) {
1579 if (pri->
pvts[principle] && pri->
pvts[principle]->
call == call) {
1585 for (x = 0; x < pri->
numchans; x++) {
1594 new_chan = pri->
pvts[principle];
1595 old_chan = pri->
pvts[x];
1598 sig_pri_lock_private(old_chan);
1599 sig_pri_lock_owner(pri, x);
1600 sig_pri_lock_private(new_chan);
1602 ast_verb(3,
"Moving call (%s) from channel %d to %d.\n",
1603 old_chan->owner ? ast_channel_name(old_chan->owner) :
"",
1606 ast_log(LOG_WARNING,
1607 "Can't move call (%s) from channel %d to %d. It is already in use.\n",
1608 old_chan->owner ? ast_channel_name(old_chan->owner) :
"",
1610 sig_pri_unlock_private(new_chan);
1611 if (old_chan->owner) {
1612 ast_channel_unlock(old_chan->owner);
1614 sig_pri_unlock_private(old_chan);
1618 sig_pri_fixup_chans(old_chan, new_chan);
1621 new_chan->owner = old_chan->owner;
1622 old_chan->owner = NULL;
1625 old_chan->
call = NULL;
1628 #if defined(HAVE_PRI_AOC_EVENTS)
1637 new_chan->outgoing = old_chan->outgoing;
1638 new_chan->digital = old_chan->digital;
1639 #if defined(HAVE_PRI_CALL_WAITING)
1642 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
1646 #if defined(HAVE_PRI_AOC_EVENTS)
1655 old_chan->outgoing = 0;
1656 old_chan->digital = 0;
1657 #if defined(HAVE_PRI_CALL_WAITING)
1660 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
1667 #if defined(HAVE_PRI_REVERSE_CHARGE)
1670 #if defined(HAVE_PRI_SETUP_KEYPAD)
1675 new_chan->moh_state = old_chan->moh_state;
1677 #if defined(HAVE_PRI_TRANSFER)
1682 #if defined(HAVE_PRI_AOC_EVENTS)
1684 new_chan->aoc_e = old_chan->aoc_e;
1690 new_chan->hidecallerid = old_chan->hidecallerid;
1694 new_chan->priindication_oob = old_chan->priindication_oob;
1697 new_chan->stripmsd = old_chan->stripmsd;
1698 strcpy(new_chan->context, old_chan->context);
1699 strcpy(new_chan->mohinterpret, old_chan->mohinterpret);
1711 sig_pri_open_media(new_chan);
1714 if (new_chan->owner) {
1715 sig_pri_ami_channel_event(new_chan);
1718 sig_pri_unlock_private(old_chan);
1719 if (new_chan->owner) {
1720 ast_channel_unlock(new_chan->owner);
1722 sig_pri_unlock_private(new_chan);
1726 ast_verb(3,
"Call specified, but not found.\n");
1748 static int pri_find_fixup_principle(
struct sig_pri_span *pri,
int channel, q931_call *call)
1752 chanpos = pri_find_principle(pri, channel, call);
1754 ast_log(LOG_WARNING,
"Span %d: PRI requested channel %d/%d is unconfigured.\n",
1755 pri->
span, PRI_SPAN(channel), PRI_CHANNEL(channel));
1756 sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
1759 chanpos = pri_fixup_principle(pri, chanpos, call);
1761 ast_log(LOG_WARNING,
"Span %d: PRI requested channel %d/%d is not available.\n",
1762 pri->
span, PRI_SPAN(channel), PRI_CHANNEL(channel));
1770 sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
1776 static char * redirectingreason2str(
int redirectingreason)
1778 switch (redirectingreason) {
1786 return "UNCONDITIONAL";
1788 return "NOREDIRECT";
1792 static char *dialplan2str(
int dialplan)
1794 if (dialplan == -1) {
1795 return(
"Dynamically set dialplan in ISDN");
1797 return (pri_plan2str(dialplan));
1810 static void apply_plan_to_number(
char *buf,
size_t size,
const struct sig_pri_span *pri,
const char *
number,
int plan)
1813 case PRI_INTERNATIONAL_ISDN:
1816 case PRI_NATIONAL_ISDN:
1819 case PRI_LOCAL_ISDN:
1820 snprintf(buf, size,
"%s%s", pri->
localprefix, number);
1829 snprintf(buf, size,
"%s", number);
1844 static void apply_plan_to_existing_number(
char *buf,
size_t size,
const struct sig_pri_span *pri,
const char *number,
int plan)
1847 if (ast_strlen_zero(number)) {
1853 apply_plan_to_number(buf, size, pri, number, plan);
1864 static void pri_check_restart(
struct sig_pri_span *pri)
1866 #if defined(HAVE_PRI_SERVICE_MESSAGES)
1876 #if defined(HAVE_PRI_SERVICE_MESSAGES)
1880 "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n",
1895 sig_pri_span_devstate_changed(pri);
1899 #if defined(HAVE_PRI_CALL_WAITING)
1912 pvt->stripmsd = pri->ch_cfg.stripmsd;
1913 pvt->hidecallerid = pri->ch_cfg.hidecallerid;
1917 pvt->priindication_oob = pri->ch_cfg.priindication_oob;
1920 ast_copy_string(pvt->context, pri->ch_cfg.context,
sizeof(pvt->context));
1921 ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret,
sizeof(pvt->mohinterpret));
1941 static int pri_find_empty_chan(
struct sig_pri_span *pri,
int backwards)
1949 if (backwards && (x < 0))
1951 if (!backwards && (x >= pri->
numchans))
1956 ast_debug(1,
"Found empty available channel %d/%d\n",
1968 #if defined(HAVE_PRI_CALL_HOLD)
1981 static int pri_find_empty_nobch(
struct sig_pri_span *pri)
1985 for (idx = 0; idx < pri->
numchans; ++idx) {
1989 ast_debug(1,
"Found empty available no B channel interface\n");
2004 static void *do_idle_thread(
void *v_pvt)
2011 int timeout_ms = 30000;
2013 struct timeval start;
2016 if ((callid = ast_channel_callid(chan))) {
2020 ast_verb(3,
"Initiating idle call on channel %s\n", ast_channel_name(chan));
2023 ast_log(LOG_WARNING,
"Idle dial failed on '%s' to '%s'\n", ast_channel_name(chan), ex);
2042 ast_channel_exten_set(chan, pvt->pri->
idleext);
2043 ast_channel_context_set(chan, pvt->pri->
idlecontext);
2044 ast_channel_priority_set(chan, 1);
2045 ast_verb(4,
"Idle channel '%s' answered, sending to %s@%s\n", ast_channel_name(chan), ast_channel_exten(chan), ast_channel_context(chan));
2050 ast_verb(4,
"Idle channel '%s' busy, waiting...\n", ast_channel_name(chan));
2053 ast_verb(4,
"Idle channel '%s' congested, waiting...\n", ast_channel_name(chan));
2064 static void *pri_ss_thread(
void *data)
2079 if ((callid = ast_channel_callid(chan))) {
2087 if (!ast_channel_tech_pvt(chan)) {
2088 ast_log(LOG_WARNING,
"Channel became a zombie before simple switch could be started (%s)\n", ast_channel_name(chan));
2093 ast_verb(3,
"Starting simple switch on '%s'\n", ast_channel_name(chan));
2095 sig_pri_dsp_reset_and_flush_digits(p);
2099 len = strlen(exten);
2103 sig_pri_play_tone(p, -1);
2105 sig_pri_play_tone(p, SIG_PRI_TONE_DIALTONE);
2107 timeout = pri_matchdigittimeout;
2109 timeout = pri_gendigittimeout;
2112 ast_debug(1,
"waitfordigit returned < 0...\n");
2122 if (ast_strlen_zero(exten)) {
2123 ast_verb(3,
"Going to extension s|1 because of empty extension received on overlap call\n");
2127 ast_free(ast_channel_dialed(chan)->number.
str);
2137 ast_free(ast_channel_caller(chan)->
id.tag);
2141 sig_pri_play_tone(p, -1);
2144 ast_channel_exten_set(chan, exten);
2145 sig_pri_dsp_reset_and_flush_digits(p);
2146 #if defined(JIRA_ASTERISK_15594)
2159 if ((p->pri->
overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
2161 sig_pri_lock_private(p);
2163 pri_grab(p, p->pri);
2167 pri_proceeding(p->pri->
pri, p->
call, PVT_TO_CHANNEL(p), 0);
2170 sig_pri_unlock_private(p);
2174 sig_pri_set_echocanceller(p, 1);
2175 ast_channel_lock(chan);
2177 ast_channel_unlock(chan);
2180 ast_log(LOG_WARNING,
"PBX exited non-zero!\n");
2183 ast_debug(1,
"No such possible extension '%s' in context '%s'\n", exten, ast_channel_context(chan));
2184 ast_channel_hangupcause_set(chan, AST_CAUSE_UNALLOCATED);
2189 ast_mutex_lock(&p->pri->
lock);
2190 sig_pri_span_devstate_changed(p->pri);
2191 ast_mutex_unlock(&p->pri->
lock);
2196 void pri_event_alarm(
struct sig_pri_span *pri,
int index,
int before_start_pri)
2199 if (!before_start_pri) {
2200 pri_find_dchan(pri);
2204 void pri_event_noalarm(
struct sig_pri_span *pri,
int index,
int before_start_pri)
2207 if (!before_start_pri)
2208 pri_restart(pri->
dchans[index]);
2222 static void sig_pri_party_name_convert(
struct ast_party_name *ast_name,
const struct pri_party_name *pri_name)
2225 ast_name->
char_set = pri_to_ast_char_set(pri_name->char_set);
2226 ast_name->
presentation = pri_to_ast_presentation(pri_name->presentation);
2227 ast_name->
valid = 1;
2242 static void sig_pri_party_number_convert(
struct ast_party_number *ast_number,
const struct pri_party_number *pri_number,
struct sig_pri_span *pri)
2246 apply_plan_to_existing_number(number,
sizeof(number), pri, pri_number->str,
2249 ast_number->
plan = pri_number->plan;
2250 ast_number->
presentation = pri_to_ast_presentation(pri_number->presentation);
2251 ast_number->
valid = 1;
2266 static void sig_pri_party_id_convert(
struct ast_party_id *ast_id,
const struct pri_party_id *pri_id,
struct sig_pri_span *pri)
2268 if (pri_id->name.valid) {
2269 sig_pri_party_name_convert(&ast_id->
name, &pri_id->name);
2271 if (pri_id->number.valid) {
2272 sig_pri_party_number_convert(&ast_id->
number, &pri_id->number, pri);
2274 #if defined(HAVE_PRI_SUBADDR)
2275 if (pri_id->subaddress.valid) {
2276 sig_pri_set_subaddress(&ast_id->
subaddress, &pri_id->subaddress);
2295 const struct pri_party_redirecting *pri_redirecting,
2301 sig_pri_party_id_convert(&ast_redirecting->
orig, &pri_redirecting->orig_called, pri);
2302 sig_pri_party_id_convert(&ast_redirecting->
from, &pri_redirecting->from, pri);
2303 sig_pri_party_id_convert(&ast_redirecting->
to, &pri_redirecting->to, pri);
2304 ast_redirecting->
count = pri_redirecting->count;
2305 ast_redirecting->
reason.
code = pri_to_ast_reason(pri_redirecting->reason);
2306 ast_redirecting->
orig_reason.
code = pri_to_ast_reason(pri_redirecting->orig_reason);
2320 static int sig_pri_msn_match(
const char *msn_patterns,
const char *exten)
2329 pattern = strtok_r(msn_list,
",", &list_tail);
2336 pattern = strtok_r(NULL,
",", &list_tail);
2342 #if defined(HAVE_PRI_MCID)
2343 static void party_number_json_to_ami(
struct ast_str **msg,
const char *prefix,
struct ast_json *number)
2345 const char *num_txt, *pres_txt;
2352 prefix, prefix, prefix);
2365 ast_str_append(msg, 0,
"%sNumPres: %d (%s)\r\n", prefix, pres, pres_txt);
2368 static void party_name_json_to_ami(
struct ast_str **msg,
const char *prefix,
struct ast_json *
name)
2370 const char *name_txt, *pres_txt, *charset;
2374 "%sNameValid: 0\r\n"
2387 ast_str_append(msg, 0,
"%sNameCharSet: %s\r\n", prefix, charset);
2388 ast_str_append(msg, 0,
"%sNamePres: %d (%s)\r\n", prefix, pres, pres_txt);
2391 static void party_subaddress_json_to_ami(
struct ast_str **msg,
const char *prefix,
struct ast_json *subaddress)
2393 const char *subaddress_txt, *type_txt;
2403 ast_str_append(msg, 0,
"%sSubaddr: %s\r\n", prefix, subaddress_txt);
2404 ast_str_append(msg, 0,
"%sSubaddrType: %s\r\n", prefix, type_txt);
2417 static void party_json_to_ami(
struct ast_str **msg,
const char *prefix,
struct ast_json *party)
2431 party_number_json_to_ami(msg, prefix, number);
2434 party_name_json_to_ami(msg, prefix, name);
2437 party_subaddress_json_to_ami(msg, prefix, subaddress);
2448 if (!channel_string) {
2463 .to_ami = mcid_to_ami,
2470 ast_assert(caller != NULL);
2471 ast_assert(connected != NULL);
2496 static void sig_pri_mcid_event(
struct sig_pri_span *pri,
const struct pri_subcmd_mcid_req *mcid,
struct ast_channel *owner)
2503 sig_pri_party_id_convert(&connected_party, &mcid->answerer, pri);
2511 send_mcid(owner, &ast_channel_connected(owner)->
id, &connected_party);
2518 sig_pri_party_id_convert(&caller_party, &mcid->originator, pri);
2519 send_mcid(owner, &caller_party, &connected_party);
2526 #if defined(HAVE_PRI_TRANSFER)
2538 #if defined(HAVE_PRI_TRANSFER)
2549 static void sig_pri_transfer_rsp(
struct xfer_rsp_data *rsp,
int is_successful)
2560 #if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
2578 static int sig_pri_attempt_transfer(
struct sig_pri_span *pri, q931_call *call_1_pri,
int call_1_held, q931_call *call_2_pri,
int call_2_held,
struct xfer_rsp_data *xfer_data)
2580 struct attempt_xfer_call {
2588 struct attempt_xfer_call *call_1;
2589 struct attempt_xfer_call *call_2;
2590 struct attempt_xfer_call c1;
2591 struct attempt_xfer_call c2;
2593 c1.pri = call_1_pri;
2594 c1.held = call_1_held;
2597 c2.pri = call_2_pri;
2598 c2.held = call_2_held;
2601 call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri);
2602 call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri);
2603 if (call_1->chanpos < 0 || call_2->chanpos < 0) {
2605 #if defined(HAVE_PRI_TRANSFER)
2608 sig_pri_transfer_rsp(xfer_data, 0);
2615 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2616 sig_pri_lock_owner(pri, call_1->chanpos);
2617 call_1->ast = pri->
pvts[call_1->chanpos]->owner;
2620 ast_channel_unlock(call_1->ast);
2622 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2625 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2626 sig_pri_lock_owner(pri, call_2->chanpos);
2627 call_2->ast = pri->
pvts[call_2->chanpos]->owner;
2630 ast_channel_unlock(call_2->ast);
2632 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2634 if (!call_1->ast || !call_2->ast) {
2642 #if defined(HAVE_PRI_TRANSFER)
2645 sig_pri_transfer_rsp(xfer_data, 0);
2651 ast_verb(3,
"TRANSFERRING %s to %s\n",
2652 ast_channel_name(call_1->ast), ast_channel_name(call_2->ast));
2654 #if defined(HAVE_PRI_TRANSFER)
2661 sig_pri_lock_private(pri->
pvts[call_1->chanpos]);
2663 sig_pri_unlock_private(pri->
pvts[call_1->chanpos]);
2664 sig_pri_lock_private(pri->
pvts[call_2->chanpos]);
2666 sig_pri_unlock_private(pri->
pvts[call_2->chanpos]);
2670 ast_mutex_unlock(&pri->
lock);
2672 ast_mutex_lock(&pri->
lock);
2675 #if defined(HAVE_PRI_TRANSFER)
2684 rsp_chanpos = pri_find_principle_by_call(pri, call_1->pri);
2685 if (0 <= rsp_chanpos) {
2686 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2688 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2690 rsp_chanpos = pri_find_principle_by_call(pri, call_2->pri);
2691 if (0 <= rsp_chanpos) {
2692 sig_pri_lock_private(pri->
pvts[rsp_chanpos]);
2694 sig_pri_unlock_private(pri->
pvts[rsp_chanpos]);
2698 sig_pri_transfer_rsp(xfer_data, retval ? 0 : 1);
2707 #if defined(HAVE_PRI_CCSS)
2719 static int sig_pri_cc_agent_cmp_cc_id(
void *obj,
void *arg,
int flags)
2725 return (agent_prv_1 && agent_prv_1->
pri == agent_prv_2->
pri
2730 #if defined(HAVE_PRI_CCSS)
2759 #if defined(HAVE_PRI_CCSS)
2771 static int sig_pri_cc_monitor_cmp_cc_id(
void *obj,
void *arg,
int flags)
2776 return (monitor_1->
pri == monitor_2->
pri
2781 #if defined(HAVE_PRI_CCSS)
2805 return ao2_callback(sig_pri_cc_monitors, 0, sig_pri_cc_monitor_cmp_cc_id, &finder);
2809 #if defined(HAVE_PRI_CCSS)
2817 static void sig_pri_cc_monitor_instance_destroy(
void *data)
2821 if (monitor_instance->
cc_id != -1) {
2822 ast_mutex_lock(&monitor_instance->
pri->
lock);
2823 pri_cc_cancel(monitor_instance->
pri->
pri, monitor_instance->
cc_id);
2824 ast_mutex_unlock(&monitor_instance->
pri->
lock);
2830 #if defined(HAVE_PRI_CCSS)
2857 monitor_instance = ao2_alloc(
sizeof(*monitor_instance) + strlen(device_name),
2858 sig_pri_cc_monitor_instance_destroy);
2859 if (!monitor_instance) {
2864 monitor_instance->
pri =
pri;
2866 strcpy(monitor_instance->
name, device_name);
2870 ao2_link(sig_pri_cc_monitors, monitor_instance);
2871 return monitor_instance;
2875 #if defined(HAVE_PRI_CCSS)
2893 static int sig_pri_cc_available(
struct sig_pri_span *pri,
int chanpos,
long cc_id,
enum ast_cc_service_type service)
2904 pvt = pri->
pvts[chanpos];
2907 if (core_id == -1) {
2918 switch (monitor_policy) {
2922 case AST_CC_MONITOR_NATIVE:
2929 sig_pri_make_cc_dialstring(pvt, dialstring,
sizeof(dialstring));
2930 monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
2937 monitor->
cc_id = -1;
2944 sig_pri_get_orig_dialstring(pvt), service, NULL);
2964 static void sig_pri_cc_generic_check(
struct sig_pri_span *pri,
int chanpos,
enum ast_cc_service_type service)
2968 #if defined(HAVE_PRI_CCSS)
2975 if (!pri->
pvts[chanpos]->outgoing) {
2980 sig_pri_lock_owner(pri, chanpos);
2981 owner = pri->
pvts[chanpos]->owner;
2986 if (core_id == -1) {
2997 #if defined(HAVE_PRI_CCSS)
3008 switch (monitor_policy) {
3012 case AST_CC_MONITOR_NATIVE:
3013 if (pri->
sig == SIG_BRI_PTMP && pri->
nodetype == PRI_NETWORK) {
3016 sig_pri_get_orig_dialstring(pri->
pvts[chanpos]), service, NULL);
3020 if (pri->
sig == SIG_BRI_PTMP && pri->
nodetype != PRI_NETWORK) {
3034 sig_pri_get_orig_dialstring(pri->
pvts[chanpos]), service, NULL);
3037 if (pri->
sig == SIG_BRI_PTMP && pri->
nodetype == PRI_NETWORK) {
3040 sig_pri_get_orig_dialstring(pri->
pvts[chanpos]), service, NULL);
3046 ast_channel_unlock(owner);
3049 #if defined(HAVE_PRI_CCSS)
3059 static void sig_pri_cc_link_canceled(
struct sig_pri_span *pri,
long cc_id,
int is_agent)
3064 agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
3074 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
3078 monitor->
cc_id = -1;
3086 #if defined(HAVE_PRI_AOC_EVENTS)
3096 static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri(
enum PRI_AOC_CHARGED_ITEM value)
3099 case AST_AOC_CHARGED_ITEM_NA:
3100 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3101 case AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
3102 return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
3103 case AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
3104 return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
3105 case AST_AOC_CHARGED_ITEM_CALL_ATTEMPT:
3106 return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
3107 case AST_AOC_CHARGED_ITEM_CALL_SETUP:
3108 return PRI_AOC_CHARGED_ITEM_CALL_SETUP;
3109 case AST_AOC_CHARGED_ITEM_USER_USER_INFO:
3110 return PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
3111 case AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
3112 return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
3114 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
3118 #if defined(HAVE_PRI_AOC_EVENTS)
3128 static enum ast_aoc_s_charged_item sig_pri_aoc_charged_item_to_ast(
enum PRI_AOC_CHARGED_ITEM value)
3131 case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE:
3132 return AST_AOC_CHARGED_ITEM_NA;
3133 case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
3134 return AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
3135 case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
3136 return AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
3137 case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
3138 return AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
3139 case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
3140 return AST_AOC_CHARGED_ITEM_CALL_SETUP;
3141 case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
3142 return AST_AOC_CHARGED_ITEM_USER_USER_INFO;
3143 case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
3144 return AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
3146 return AST_AOC_CHARGED_ITEM_NA;
3150 #if defined(HAVE_PRI_AOC_EVENTS)
3161 case AST_AOC_MULT_ONETHOUSANDTH:
3162 return PRI_AOC_MULTIPLIER_THOUSANDTH;
3163 case AST_AOC_MULT_ONEHUNDREDTH:
3164 return PRI_AOC_MULTIPLIER_HUNDREDTH;
3165 case AST_AOC_MULT_ONETENTH:
3166 return PRI_AOC_MULTIPLIER_TENTH;
3167 case AST_AOC_MULT_ONE:
3168 return PRI_AOC_MULTIPLIER_ONE;
3169 case AST_AOC_MULT_TEN:
3170 return PRI_AOC_MULTIPLIER_TEN;
3171 case AST_AOC_MULT_HUNDRED:
3172 return PRI_AOC_MULTIPLIER_HUNDRED;
3173 case AST_AOC_MULT_THOUSAND:
3174 return PRI_AOC_MULTIPLIER_THOUSAND;
3176 return PRI_AOC_MULTIPLIER_ONE;
3181 #if defined(HAVE_PRI_AOC_EVENTS)
3189 static int sig_pri_aoc_multiplier_from_pri(
const int mult)
3192 case PRI_AOC_MULTIPLIER_THOUSANDTH:
3193 return AST_AOC_MULT_ONETHOUSANDTH;
3194 case PRI_AOC_MULTIPLIER_HUNDREDTH:
3195 return AST_AOC_MULT_ONEHUNDREDTH;
3196 case PRI_AOC_MULTIPLIER_TENTH:
3197 return AST_AOC_MULT_ONETENTH;
3198 case PRI_AOC_MULTIPLIER_ONE:
3199 return AST_AOC_MULT_ONE;
3200 case PRI_AOC_MULTIPLIER_TEN:
3201 return AST_AOC_MULT_TEN;
3202 case PRI_AOC_MULTIPLIER_HUNDRED:
3203 return AST_AOC_MULT_HUNDRED;
3204 case PRI_AOC_MULTIPLIER_THOUSAND:
3205 return AST_AOC_MULT_THOUSAND;
3207 return AST_AOC_MULT_ONE;
3212 #if defined(HAVE_PRI_AOC_EVENTS)
3222 static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri(
enum ast_aoc_time_scale value)
3226 case AST_AOC_TIME_SCALE_HUNDREDTH_SECOND:
3227 return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
3228 case AST_AOC_TIME_SCALE_TENTH_SECOND:
3229 return PRI_AOC_TIME_SCALE_TENTH_SECOND;
3230 case AST_AOC_TIME_SCALE_SECOND:
3231 return PRI_AOC_TIME_SCALE_SECOND;
3232 case AST_AOC_TIME_SCALE_TEN_SECOND:
3233 return PRI_AOC_TIME_SCALE_TEN_SECOND;
3234 case AST_AOC_TIME_SCALE_MINUTE:
3235 return PRI_AOC_TIME_SCALE_MINUTE;
3236 case AST_AOC_TIME_SCALE_HOUR:
3237 return PRI_AOC_TIME_SCALE_HOUR;
3238 case AST_AOC_TIME_SCALE_DAY:
3239 return PRI_AOC_TIME_SCALE_DAY;
3244 #if defined(HAVE_PRI_AOC_EVENTS)
3254 static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast(
enum PRI_AOC_TIME_SCALE value)
3258 case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND:
3259 return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
3260 case PRI_AOC_TIME_SCALE_TENTH_SECOND:
3261 return AST_AOC_TIME_SCALE_TENTH_SECOND;
3262 case PRI_AOC_TIME_SCALE_SECOND:
3263 return AST_AOC_TIME_SCALE_SECOND;
3264 case PRI_AOC_TIME_SCALE_TEN_SECOND:
3265 return AST_AOC_TIME_SCALE_TEN_SECOND;
3266 case PRI_AOC_TIME_SCALE_MINUTE:
3267 return AST_AOC_TIME_SCALE_MINUTE;
3268 case PRI_AOC_TIME_SCALE_HOUR:
3269 return AST_AOC_TIME_SCALE_HOUR;
3270 case PRI_AOC_TIME_SCALE_DAY:
3271 return AST_AOC_TIME_SCALE_DAY;
3273 return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
3277 #if defined(HAVE_PRI_AOC_EVENTS)
3291 static void sig_pri_aoc_s_from_pri(
const struct pri_subcmd_aoc_s *aoc_s,
struct ast_channel *owner,
int passthrough)
3295 size_t encoded_size = 0;
3298 if (!owner || !aoc_s) {
3306 for (idx = 0; idx < aoc_s->num_items; ++idx) {
3307 enum ast_aoc_s_charged_item charged_item;
3309 charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable);
3310 if (charged_item == AST_AOC_CHARGED_ITEM_NA) {
3314 switch (aoc_s->item[idx].rate_type) {
3315 case PRI_AOC_RATE_TYPE_DURATION:
3318 aoc_s->item[idx].rate.duration.amount.cost,
3319 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier),
3320 aoc_s->item[idx].rate.duration.currency,
3321 aoc_s->item[idx].rate.duration.time.length,
3322 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale),
3323 aoc_s->item[idx].rate.duration.granularity.length,
3324 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale),
3325 aoc_s->item[idx].rate.duration.charging_type);
3327 case PRI_AOC_RATE_TYPE_FLAT:
3330 aoc_s->item[idx].rate.flat.amount.cost,
3331 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier),
3332 aoc_s->item[idx].rate.flat.currency);
3334 case PRI_AOC_RATE_TYPE_VOLUME:
3337 aoc_s->item[idx].rate.volume.unit,
3338 aoc_s->item[idx].rate.volume.amount.cost,
3339 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier),
3340 aoc_s->item[idx].rate.volume.currency);
3342 case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
3345 aoc_s->item[idx].rate.special);
3347 case PRI_AOC_RATE_TYPE_FREE:
3350 case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
3359 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3370 #if defined(HAVE_PRI_AOC_EVENTS)
3382 static void sig_pri_aoc_request_from_pri(
const struct pri_subcmd_aoc_request *aoc_request,
struct sig_pri_chan *pvt, q931_call *call)
3390 request = aoc_request->charging_request;
3392 if (request & PRI_AOC_REQUEST_S) {
3400 pri_aoc_s_request_response_send(pvt->pri->
pri,
3402 aoc_request->invoke_id,
3407 if (request & PRI_AOC_REQUEST_D) {
3409 pri_aoc_de_request_response_send(pvt->pri->
pri,
3411 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3412 aoc_request->invoke_id);
3414 pri_aoc_de_request_response_send(pvt->pri->
pri,
3416 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3417 aoc_request->invoke_id);
3421 if (request & PRI_AOC_REQUEST_E) {
3423 pri_aoc_de_request_response_send(pvt->pri->
pri,
3425 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
3426 aoc_request->invoke_id);
3428 pri_aoc_de_request_response_send(pvt->pri->
pri,
3430 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
3431 aoc_request->invoke_id);
3437 #if defined(HAVE_PRI_AOC_EVENTS)
3451 static void sig_pri_aoc_d_from_pri(
const struct pri_subcmd_aoc_d *aoc_d,
struct ast_channel *owner,
int passthrough)
3455 size_t encoded_size = 0;
3456 enum ast_aoc_charge_type type;
3458 if (!owner || !aoc_d) {
3462 switch (aoc_d->charge) {
3463 case PRI_AOC_DE_CHARGE_CURRENCY:
3464 type = AST_AOC_CHARGE_CURRENCY;
3466 case PRI_AOC_DE_CHARGE_UNITS:
3467 type = AST_AOC_CHARGE_UNIT;
3469 case PRI_AOC_DE_CHARGE_FREE:
3470 type = AST_AOC_CHARGE_FREE;
3473 type = AST_AOC_CHARGE_NA;
3481 switch (aoc_d->billing_accumulation) {
3483 ast_debug(1,
"AOC-D billing accumulation has unknown value: %d\n",
3484 aoc_d->billing_accumulation);
3494 switch (aoc_d->billing_id) {
3495 case PRI_AOC_D_BILLING_ID_NORMAL:
3498 case PRI_AOC_D_BILLING_ID_REVERSE:
3501 case PRI_AOC_D_BILLING_ID_CREDIT_CARD:
3504 case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE:
3510 switch (aoc_d->charge) {
3511 case PRI_AOC_DE_CHARGE_CURRENCY:
3513 aoc_d->recorded.money.amount.cost,
3514 sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier),
3515 aoc_d->recorded.money.currency);
3517 case PRI_AOC_DE_CHARGE_UNITS:
3520 for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) {
3523 (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0),
3524 aoc_d->recorded.unit.item[i].number,
3525 (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0),
3526 aoc_d->recorded.unit.item[i].type);
3532 if (passthrough && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3543 #if defined(HAVE_PRI_AOC_EVENTS)
3558 static void sig_pri_aoc_e_from_pri(
const struct pri_subcmd_aoc_e *aoc_e,
struct ast_channel *owner,
int passthrough)
3562 size_t encoded_size = 0;
3563 enum ast_aoc_charge_type type;
3569 switch (aoc_e->charge) {
3570 case PRI_AOC_DE_CHARGE_CURRENCY:
3571 type = AST_AOC_CHARGE_CURRENCY;
3573 case PRI_AOC_DE_CHARGE_UNITS:
3574 type = AST_AOC_CHARGE_UNIT;
3576 case PRI_AOC_DE_CHARGE_FREE:
3577 type = AST_AOC_CHARGE_FREE;
3580 type = AST_AOC_CHARGE_NA;
3588 switch (aoc_e->associated.charging_type) {
3589 case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER:
3590 if (!aoc_e->associated.charge.number.valid) {
3595 case PRI_AOC_E_CHARGING_ASSOCIATION_ID:
3602 switch (aoc_e->billing_id) {
3603 case PRI_AOC_E_BILLING_ID_NORMAL:
3606 case PRI_AOC_E_BILLING_ID_REVERSE:
3609 case PRI_AOC_E_BILLING_ID_CREDIT_CARD:
3612 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL:
3615 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY:
3618 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY:
3621 case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION:
3624 case PRI_AOC_E_BILLING_ID_CALL_TRANSFER:
3627 case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE:
3633 switch (aoc_e->charge) {
3634 case PRI_AOC_DE_CHARGE_CURRENCY:
3636 aoc_e->recorded.money.amount.cost,
3637 sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier),
3638 aoc_e->recorded.money.currency);
3640 case PRI_AOC_DE_CHARGE_UNITS:
3643 for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) {
3646 (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0),
3647 aoc_e->recorded.unit.item[i].number,
3648 (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0),
3649 aoc_e->recorded.unit.item[i].type);
3654 if (passthrough && owner && (encoded =
ast_aoc_encode(decoded, &encoded_size, owner))) {
3665 #if defined(HAVE_PRI_AOC_EVENTS)
3677 struct pri_subcmd_aoc_s aoc_s = { 0, };
3686 aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(entry->charged_item);
3688 switch (entry->rate_type) {
3689 case AST_AOC_RATE_TYPE_DURATION:
3690 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
3691 aoc_s.item[idx].rate.duration.amount.cost = entry->
rate.duration.amount;
3692 aoc_s.item[idx].rate.duration.amount.multiplier =
3693 sig_pri_aoc_multiplier_from_ast(entry->
rate.duration.multiplier);
3694 aoc_s.item[idx].rate.duration.time.length = entry->
rate.duration.time;
3695 aoc_s.item[idx].rate.duration.time.scale =
3696 sig_pri_aoc_scale_to_pri(entry->
rate.duration.time_scale);
3698 aoc_s.item[idx].rate.duration.granularity.scale =
3699 sig_pri_aoc_scale_to_pri(entry->
rate.duration.granularity_time_scale);
3700 aoc_s.item[idx].rate.duration.charging_type = entry->
rate.duration.
charging_type;
3705 sizeof(aoc_s.item[idx].rate.duration.currency));
3708 case AST_AOC_RATE_TYPE_FLAT:
3709 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
3710 aoc_s.item[idx].rate.flat.amount.cost = entry->
rate.flat.amount;
3711 aoc_s.item[idx].rate.flat.amount.multiplier =
3712 sig_pri_aoc_multiplier_from_ast(entry->
rate.flat.multiplier);
3717 sizeof(aoc_s.item[idx].rate.flat.currency));
3720 case AST_AOC_RATE_TYPE_VOLUME:
3721 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
3722 aoc_s.item[idx].rate.volume.unit = entry->
rate.volume.volume_unit;
3723 aoc_s.item[idx].rate.volume.amount.cost = entry->
rate.volume.amount;
3724 aoc_s.item[idx].rate.volume.amount.multiplier =
3725 sig_pri_aoc_multiplier_from_ast(entry->
rate.volume.multiplier);
3727 if (!ast_strlen_zero(entry->
rate.volume.currency_name)) {
3729 entry->
rate.volume.currency_name,
3730 sizeof(aoc_s.item[idx].rate.volume.currency));
3733 case AST_AOC_RATE_TYPE_SPECIAL_CODE:
3734 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
3735 aoc_s.item[idx].rate.special = entry->
rate.special_code;
3737 case AST_AOC_RATE_TYPE_FREE:
3738 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
3740 case AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
3741 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
3744 case AST_AOC_RATE_TYPE_NA:
3745 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
3749 aoc_s.num_items = idx;
3757 pri_aoc_s_send(pvt->pri->
pri, pvt->
call, &aoc_s);
3762 #if defined(HAVE_PRI_AOC_EVENTS)
3774 struct pri_subcmd_aoc_d aoc_d = { 0, };
3779 case AST_AOC_BILLING_NORMAL:
3780 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL;
3782 case AST_AOC_BILLING_REVERSE_CHARGE:
3783 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE;
3785 case AST_AOC_BILLING_CREDIT_CARD:
3786 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
3788 case AST_AOC_BILLING_NA:
3790 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
3795 case AST_AOC_CHARGE_FREE:
3796 aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
3798 case AST_AOC_CHARGE_CURRENCY:
3801 aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
3804 if (!ast_strlen_zero(currency_name)) {
3805 ast_copy_string(aoc_d.recorded.money.currency, currency_name,
sizeof(aoc_d.recorded.money.currency));
3809 case AST_AOC_CHARGE_UNIT:
3813 aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
3816 if (entry->valid_amount) {
3817 aoc_d.recorded.unit.item[i].number = entry->amount;
3819 aoc_d.recorded.unit.item[i].number = -1;
3821 if (entry->valid_type) {
3822 aoc_d.recorded.unit.item[i].type = entry->type;
3824 aoc_d.recorded.unit.item[i].type = -1;
3826 aoc_d.recorded.unit.num_items++;
3833 case AST_AOC_CHARGE_NA:
3835 aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3839 pri_aoc_d_send(pvt->pri->
pri, pvt->
call, &aoc_d);
3843 #if defined(HAVE_PRI_AOC_EVENTS)
3855 struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
3858 memset(aoc_e, 0,
sizeof(*aoc_e));
3862 case AST_AOC_CHARGING_ASSOCIATION_NUMBER:
3863 aoc_e->associated.charge.number.valid = 1;
3865 ca->charge.number.number,
3866 sizeof(aoc_e->associated.charge.number.str));
3867 aoc_e->associated.charge.number.plan = ca->charge.number.plan;
3868 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
3870 case AST_AOC_CHARGING_ASSOCIATION_ID:
3871 aoc_e->associated.charge.id = ca->charge.id;
3872 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
3874 case AST_AOC_CHARGING_ASSOCIATION_NA:
3880 case AST_AOC_BILLING_NORMAL:
3881 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL;
3883 case AST_AOC_BILLING_REVERSE_CHARGE:
3884 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE;
3886 case AST_AOC_BILLING_CREDIT_CARD:
3887 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
3889 case AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL:
3890 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
3892 case AST_AOC_BILLING_CALL_FWD_BUSY:
3893 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
3895 case AST_AOC_BILLING_CALL_FWD_NO_REPLY:
3896 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
3898 case AST_AOC_BILLING_CALL_DEFLECTION:
3899 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
3901 case AST_AOC_BILLING_CALL_TRANSFER:
3902 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
3904 case AST_AOC_BILLING_NA:
3906 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
3911 case AST_AOC_CHARGE_FREE:
3912 aoc_e->charge = PRI_AOC_DE_CHARGE_FREE;
3914 case AST_AOC_CHARGE_CURRENCY:
3917 aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY;
3920 if (!ast_strlen_zero(currency_name)) {
3921 ast_copy_string(aoc_e->recorded.money.currency, currency_name,
sizeof(aoc_e->recorded.money.currency));
3925 case AST_AOC_CHARGE_UNIT:
3929 aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS;
3932 if (entry->valid_amount) {
3933 aoc_e->recorded.unit.item[i].number = entry->amount;
3935 aoc_e->recorded.unit.item[i].number = -1;
3937 if (entry->valid_type) {
3938 aoc_e->recorded.unit.item[i].type = entry->type;
3940 aoc_e->recorded.unit.item[i].type = -1;
3942 aoc_e->recorded.unit.num_items++;
3947 case AST_AOC_CHARGE_NA:
3949 aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
3955 #if defined(HAVE_PRI_AOC_EVENTS)
3968 static void sig_pri_send_aoce_termination_request(
struct sig_pri_span *pri,
int chanpos,
unsigned int ms)
3973 size_t encoded_size;
3974 struct timeval whentohangup = { 0, };
3976 sig_pri_lock_owner(pri, chanpos);
3977 pvt = pri->
pvts[chanpos];
3982 if (!(decoded =
ast_aoc_create(AST_AOC_REQUEST, 0, AST_AOC_REQUEST_E))) {
3984 goto cleanup_termination_request;
3989 if (!(encoded =
ast_aoc_encode(decoded, &encoded_size, pvt->owner))) {
3991 goto cleanup_termination_request;
3995 whentohangup.tv_usec = (ms % 1000) * 1000;
3996 whentohangup.tv_sec = ms / 1000;
4000 goto cleanup_termination_request;
4005 ast_debug(1,
"Delaying hangup on %s for aoc-e msg\n", ast_channel_name(pvt->owner));
4007 cleanup_termination_request:
4008 ast_channel_unlock(pvt->owner);
4023 static int sig_pri_is_cis_call(
int channel)
4025 return channel != -1 && (channel & PRI_CIS_CALL);
4043 static void sig_pri_handle_cis_subcmds(
struct sig_pri_span *pri,
int event_id,
4044 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4047 #if defined(HAVE_PRI_CCSS)
4056 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4057 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4059 switch (subcmd->cmd) {
4060 #if defined(STATUS_REQUEST_PLACE_HOLDER)
4061 case PRI_SUBCMD_STATUS_REQ:
4062 case PRI_SUBCMD_STATUS_REQ_RSP:
4066 #if defined(HAVE_PRI_CCSS)
4067 case PRI_SUBCMD_CC_REQ:
4068 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id);
4070 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4074 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4076 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4088 if (pri_cc_req_rsp(pri->
pri, subcmd->u.cc_request.cc_id,
4090 pri_cc_cancel(pri->
pri, subcmd->u.cc_request.cc_id);
4098 #if defined(HAVE_PRI_CCSS)
4099 case PRI_SUBCMD_CC_REQ_RSP:
4100 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4101 subcmd->u.cc_request_rsp.cc_id);
4103 pri_cc_cancel(pri->
pri, subcmd->u.cc_request_rsp.cc_id);
4106 switch (subcmd->u.cc_request_rsp.status) {
4112 ast_verb(2,
"core_id:%d %s CC request timeout\n", monitor->
core_id,
4118 ast_verb(2,
"core_id:%d %s CC request error: %s\n", monitor->
core_id,
4120 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
4125 ast_verb(2,
"core_id:%d %s CC request reject: %s\n", monitor->
core_id,
4127 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
4132 ast_verb(2,
"core_id:%d %s CC request unknown status %d\n",
4134 subcmd->u.cc_request_rsp.status);
4142 #if defined(HAVE_PRI_CCSS)
4143 case PRI_SUBCMD_CC_REMOTE_USER_FREE:
4144 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4145 subcmd->u.cc_remote_user_free.cc_id);
4147 pri_cc_cancel(pri->
pri, subcmd->u.cc_remote_user_free.cc_id);
4155 #if defined(HAVE_PRI_CCSS)
4156 case PRI_SUBCMD_CC_B_FREE:
4157 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4158 subcmd->u.cc_b_free.cc_id);
4160 pri_cc_cancel(pri->
pri, subcmd->u.cc_b_free.cc_id);
4167 #if defined(HAVE_PRI_CCSS)
4168 case PRI_SUBCMD_CC_STATUS_REQ:
4169 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4170 subcmd->u.cc_status_req.cc_id);
4172 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req.cc_id);
4179 #if defined(HAVE_PRI_CCSS)
4180 case PRI_SUBCMD_CC_STATUS_REQ_RSP:
4181 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
4183 pri_cc_cancel(pri->
pri, subcmd->u.cc_status_req_rsp.cc_id);
4192 #if defined(HAVE_PRI_CCSS)
4193 case PRI_SUBCMD_CC_STATUS:
4194 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
4196 pri_cc_cancel(pri->
pri, subcmd->u.cc_status.cc_id);
4199 if (subcmd->u.cc_status.status) {
4209 #if defined(HAVE_PRI_CCSS)
4210 case PRI_SUBCMD_CC_CANCEL:
4211 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4212 subcmd->u.cc_cancel.is_agent);
4215 #if defined(HAVE_PRI_CCSS)
4216 case PRI_SUBCMD_CC_STOP_ALERTING:
4217 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
4218 subcmd->u.cc_stop_alerting.cc_id);
4220 pri_cc_cancel(pri->
pri, subcmd->u.cc_stop_alerting.cc_id);
4227 #if defined(HAVE_PRI_AOC_EVENTS)
4228 case PRI_SUBCMD_AOC_E:
4230 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0);
4234 ast_debug(2,
"Span %d: Unknown CIS subcommand(%d) in %s event.\n", pri->
span,
4235 subcmd->cmd, pri_event2str(event_id));
4258 static void sig_pri_handle_subcmds(
struct sig_pri_span *pri,
int chanpos,
int event_id,
4259 const struct pri_subcommands *subcmds, q931_call *call_rsp)
4264 #if defined(HAVE_PRI_TRANSFER)
4271 for (index = 0; index < subcmds->counter_subcmd; ++index) {
4272 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
4274 switch (subcmd->cmd) {
4275 case PRI_SUBCMD_CONNECTED_LINE:
4276 sig_pri_lock_owner(pri, chanpos);
4277 owner = pri->
pvts[chanpos]->owner;
4280 int caller_id_update;
4284 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id,
4288 caller_id_update = 0;
4289 if (ast_connected.id.name.str) {
4292 ast_connected.id.name.str,
sizeof(pri->
pvts[chanpos]->cid_name));
4293 caller_id_update = 1;
4295 if (ast_connected.id.number.str) {
4298 ast_connected.id.number.str,
sizeof(pri->
pvts[chanpos]->cid_num));
4299 pri->
pvts[chanpos]->
cid_ton = ast_connected.id.number.plan;
4300 caller_id_update = 1;
4304 pri->
pvts[chanpos]->cid_subaddr[0] =
'\0';
4305 #if defined(HAVE_PRI_SUBADDR)
4306 if (ast_connected.id.subaddress.str) {
4308 ast_connected.id.subaddress.str,
4309 sizeof(pri->
pvts[chanpos]->cid_subaddr));
4310 caller_id_update = 1;
4313 if (caller_id_update) {
4318 sig_pri_set_caller_id(pri->
pvts[chanpos]);
4321 ast_caller.id = ast_connected.id;
4322 ast_caller.ani = ast_connected.id;
4326 if (event_id != PRI_EVENT_RING) {
4334 ast_channel_unlock(owner);
4337 case PRI_SUBCMD_REDIRECTING:
4338 sig_pri_lock_owner(pri, chanpos);
4339 owner = pri->
pvts[chanpos]->owner;
4341 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
4342 ast_channel_redirecting(owner), pri);
4347 if (event_id != PRI_EVENT_RING) {
4359 ast_channel_unlock(owner);
4362 #if defined(HAVE_PRI_CALL_REROUTING)
4363 case PRI_SUBCMD_REROUTING:
4364 sig_pri_lock_owner(pri, chanpos);
4365 owner = pri->
pvts[chanpos]->owner;
4367 struct pri_party_redirecting pri_deflection;
4370 ast_log(LOG_WARNING,
4371 "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
4372 pri->
span, ast_channel_name(owner), subcmd->u.rerouting.deflection.to.number.str);
4373 ast_channel_unlock(owner);
4376 if (ast_strlen_zero(subcmd->u.rerouting.deflection.to.number.str)) {
4377 ast_log(LOG_WARNING,
4378 "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
4379 pri->
span, ast_channel_name(owner));
4380 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4381 PRI_REROUTING_RSP_INVALID_NUMBER);
4382 ast_channel_unlock(owner);
4386 ast_verb(3,
"Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
4387 pri->
span, ast_channel_name(owner), subcmd->u.rerouting.deflection.to.number.str);
4395 pri_rerouting_rsp(pri->
pri, call_rsp, subcmd->u.rerouting.invoke_id,
4396 PRI_REROUTING_RSP_OK_CLEAR);
4398 pri_deflection = subcmd->u.rerouting.deflection;
4401 switch (subcmd->u.rerouting.subscription_option) {
4405 pri_deflection.to.number.presentation =
4406 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
4407 pri_deflection.to.number.plan =
4408 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
4409 pri_deflection.to.number.str[0] =
'\0';
4417 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
4418 ast_channel_redirecting(owner), pri);
4426 ast_channel_call_forward_set(owner, subcmd->u.rerouting.deflection.to.number.str);
4431 ast_channel_unlock(owner);
4435 #if defined(HAVE_PRI_CCSS)
4436 case PRI_SUBCMD_CC_AVAILABLE:
4437 sig_pri_lock_owner(pri, chanpos);
4438 owner = pri->
pvts[chanpos]->owner;
4440 enum ast_cc_service_type service;
4443 case PRI_EVENT_RINGING:
4444 service = AST_CC_CCNR;
4446 case PRI_EVENT_HANGUP_REQ:
4448 service = AST_CC_CCBS;
4451 service = AST_CC_NONE;
4454 if (service == AST_CC_NONE
4455 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id,
4457 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4459 ast_channel_unlock(owner);
4462 pri_cc_cancel(pri->
pri, subcmd->u.cc_available.cc_id);
4466 #if defined(HAVE_PRI_CCSS)
4467 case PRI_SUBCMD_CC_CALL:
4468 sig_pri_lock_owner(pri, chanpos);
4469 owner = pri->
pvts[chanpos]->owner;
4473 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
4482 ast_channel_unlock(owner);
4486 #if defined(HAVE_PRI_CCSS)
4487 case PRI_SUBCMD_CC_CANCEL:
4488 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
4489 subcmd->u.cc_cancel.is_agent);
4492 #if defined(HAVE_PRI_TRANSFER)
4493 case PRI_SUBCMD_TRANSFER_CALL:
4497 "Call transfer subcommand without call to send response!\n");
4501 sig_pri_unlock_private(pri->
pvts[chanpos]);
4503 xfer_rsp.call = call_rsp;
4504 xfer_rsp.invoke_id = subcmd->u.
transfer.invoke_id;
4505 xfer_rsp.responded = 0;
4506 sig_pri_attempt_transfer(pri,
4507 subcmd->u.
transfer.call_1, subcmd->u.transfer.is_call_1_held,
4508 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held,
4510 sig_pri_lock_private(pri->
pvts[chanpos]);
4513 #if defined(HAVE_PRI_AOC_EVENTS)
4514 case PRI_SUBCMD_AOC_S:
4515 sig_pri_lock_owner(pri, chanpos);
4516 owner = pri->
pvts[chanpos]->owner;
4518 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
4520 ast_channel_unlock(owner);
4524 #if defined(HAVE_PRI_AOC_EVENTS)
4525 case PRI_SUBCMD_AOC_D:
4526 sig_pri_lock_owner(pri, chanpos);
4527 owner = pri->
pvts[chanpos]->owner;
4530 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
4532 ast_channel_unlock(owner);
4536 #if defined(HAVE_PRI_AOC_EVENTS)
4537 case PRI_SUBCMD_AOC_E:
4538 sig_pri_lock_owner(pri, chanpos);
4539 owner = pri->
pvts[chanpos]->owner;
4541 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
4544 ast_channel_unlock(owner);
4548 #if defined(HAVE_PRI_AOC_EVENTS)
4549 case PRI_SUBCMD_AOC_CHARGING_REQ:
4550 sig_pri_lock_owner(pri, chanpos);
4551 owner = pri->
pvts[chanpos]->owner;
4553 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->
pvts[chanpos],
4555 ast_channel_unlock(owner);
4559 #if defined(HAVE_PRI_AOC_EVENTS)
4560 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
4566 if (subcmd->u.aoc_request_response.valid_aoc_s) {
4567 sig_pri_lock_owner(pri, chanpos);
4568 owner = pri->
pvts[chanpos]->owner;
4570 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
4572 ast_channel_unlock(owner);
4577 #if defined(HAVE_PRI_MCID)
4578 case PRI_SUBCMD_MCID_REQ:
4579 sig_pri_lock_owner(pri, chanpos);
4580 owner = pri->
pvts[chanpos]->owner;
4581 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
4583 ast_channel_unlock(owner);
4587 #if defined(HAVE_PRI_MCID)
4588 case PRI_SUBCMD_MCID_RSP:
4592 #if defined(HAVE_PRI_DISPLAY_TEXT)
4593 case PRI_SUBCMD_DISPLAY_TEXT:
4594 if (event_id != PRI_EVENT_RING) {
4599 sig_pri_lock_owner(pri, chanpos);
4600 owner = pri->
pvts[chanpos]->owner;
4605 memset(&f, 0,
sizeof(f));
4609 f.
data.ptr = (
void *)&subcmd->u.display.text;
4610 f.
datalen = subcmd->u.display.length + 1;
4612 ast_channel_unlock(owner);
4618 ast_debug(2,
"Span %d: Unknown call subcommand(%d) in %s event.\n",
4619 pri->
span, subcmd->cmd, pri_event2str(event_id));
4641 str =
"SIG_PRI_MOH_STATE_IDLE";
4644 str =
"SIG_PRI_MOH_STATE_NOTIFY";
4647 str =
"SIG_PRI_MOH_STATE_MOH";
4649 #if defined(HAVE_PRI_CALL_HOLD)
4651 str =
"SIG_PRI_MOH_STATE_HOLD_REQ";
4654 str =
"SIG_PRI_MOH_STATE_PEND_UNHOLD";
4657 str =
"SIG_PRI_MOH_STATE_HOLD";
4660 str =
"SIG_PRI_MOH_STATE_RETRIEVE_REQ";
4663 str =
"SIG_PRI_MOH_STATE_PEND_HOLD";
4666 str =
"SIG_PRI_MOH_STATE_RETRIEVE_FAIL";
4692 str =
"SIG_PRI_MOH_EVENT_RESET";
4695 str =
"SIG_PRI_MOH_EVENT_HOLD";
4698 str =
"SIG_PRI_MOH_EVENT_UNHOLD";
4700 #if defined(HAVE_PRI_CALL_HOLD)
4702 str =
"SIG_PRI_MOH_EVENT_HOLD_ACK";
4705 str =
"SIG_PRI_MOH_EVENT_HOLD_REJ";
4708 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_ACK";
4711 str =
"SIG_PRI_MOH_EVENT_RETRIEVE_REJ";
4714 str =
"SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK";
4724 #if defined(HAVE_PRI_CALL_HOLD)
4742 if (pvt->pri->
nodetype == PRI_NETWORK) {
4744 chanpos = pri_find_empty_chan(pvt->pri, 1);
4749 channel = PVT_TO_CHANNEL(pvt->pri->
pvts[chanpos]);
4760 if (pri_retrieve(pvt->pri->
pri, pvt->
call, channel)) {
4785 next_state = pvt->moh_state;
4788 if (!strcasecmp(pvt->mohinterpret,
"passthrough")) {
4793 pri_notify(pvt->pri->
pri, pvt->
call, pvt->
prioffset, PRI_NOTIFY_REMOTE_HOLD);
4798 switch (pvt->pri->moh_signaling) {
4808 pri_notify(pvt->pri->
pri, pvt->
call, pvt->
prioffset, PRI_NOTIFY_REMOTE_HOLD);
4811 #if defined(HAVE_PRI_CALL_HOLD)
4813 if (pri_hold(pvt->pri->
pri, pvt->
call)) {
4827 pvt->moh_state = next_state;
4849 next_state = pvt->moh_state;
4852 if (strcasecmp(pvt->mohinterpret,
"passthrough")) {
4858 pri_notify(pvt->pri->
pri, pvt->
call, pvt->
prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
4867 pvt->moh_state = next_state;
4889 next_state = pvt->moh_state;
4903 pvt->moh_state = next_state;
4907 #if defined(HAVE_PRI_CALL_HOLD)
4926 next_state = pvt->moh_state;
4947 pvt->moh_state = next_state;
4952 #if defined(HAVE_PRI_CALL_HOLD)
4971 next_state = pvt->moh_state;
4983 next_state = sig_pri_moh_retrieve_call(pvt);
4988 pvt->moh_state = next_state;
4993 #if defined(HAVE_PRI_CALL_HOLD)
5012 next_state = pvt->moh_state;
5018 next_state = sig_pri_moh_retrieve_call(pvt);
5030 pvt->moh_state = next_state;
5035 #if defined(HAVE_PRI_CALL_HOLD)
5054 next_state = pvt->moh_state;
5072 pvt->moh_state = next_state;
5077 #if defined(HAVE_PRI_CALL_HOLD)
5096 next_state = pvt->moh_state;
5110 switch (pvt->pri->moh_signaling) {
5124 pri_notify(pvt->pri->
pri, pvt->
call, pvt->
prioffset, PRI_NOTIFY_REMOTE_HOLD);
5128 if (pri_hold(pvt->pri->
pri, pvt->
call)) {
5150 pvt->moh_state = next_state;
5155 #if defined(HAVE_PRI_CALL_HOLD)
5174 next_state = pvt->moh_state;
5183 next_state = sig_pri_moh_retrieve_call(pvt);
5191 pvt->moh_state = next_state;
5218 #if defined(HAVE_PRI_CALL_HOLD)
5245 const char *chan_name;
5250 chan_name =
"Unknown";
5252 orig_state = pvt->moh_state;
5253 ast_debug(2,
"Channel '%s' MOH-Event: %s in state %s\n", chan_name,
5254 sig_pri_moh_event_str(event), sig_pri_moh_state_str(orig_state));
5256 || !sig_pri_moh_fsm[orig_state]) {
5258 ast_log(LOG_ERROR,
"MOH state not implemented: %s(%u)\n",
5259 sig_pri_moh_state_str(orig_state), orig_state);
5263 next_state = sig_pri_moh_fsm[orig_state](chan, pvt, event);
5264 ast_debug(2,
"Channel '%s' MOH-Next-State: %s\n", chan_name,
5265 (orig_state == next_state) ?
"$" : sig_pri_moh_state_str(next_state));
5275 static ast_callid func_pri_dchannel_new_callid(
void)
5299 static ast_callid func_pri_dchannel_chanpos_callid(
struct sig_pri_span *pri,
int chanpos)
5305 sig_pri_lock_owner(pri, chanpos);
5306 if (pri->
pvts[chanpos]->owner) {
5308 callid = ast_channel_callid(pri->
pvts[chanpos]->owner);
5309 ast_channel_unlock(pri->
pvts[chanpos]->owner);
5319 #if defined(HAVE_PRI_CALL_HOLD)
5333 static int sig_pri_handle_hold(
struct sig_pri_span *pri, pri_event *ev)
5339 ast_callid callid = 0;
5341 chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
5342 if (chanpos_old < 0) {
5343 ast_log(LOG_WARNING,
"Span %d: Received HOLD for unknown call.\n", pri->
span);
5353 sig_pri_lock_private(pri->
pvts[chanpos_old]);
5354 sig_pri_lock_owner(pri, chanpos_old);
5355 owner = pri->
pvts[chanpos_old]->owner;
5357 goto done_with_private;
5360 callid = ast_channel_callid(owner);
5371 goto done_with_owner;
5373 chanpos_new = pri_find_empty_nobch(pri);
5374 if (chanpos_new < 0) {
5376 goto done_with_owner;
5378 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.subcmds, ev->hold.call);
5379 sig_pri_queue_hold(pri, chanpos_old);
5380 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
5381 if (chanpos_new < 0) {
5383 sig_pri_queue_unhold(pri, chanpos_old);
5387 ast_channel_unlock(owner);
5389 sig_pri_unlock_private(pri->
pvts[chanpos_old]);
5391 if (chanpos_new < 0) {
5394 sig_pri_span_devstate_changed(pri);
5406 #if defined(HAVE_PRI_CALL_HOLD)
5417 static void sig_pri_handle_hold_ack(
struct sig_pri_span *pri, pri_event *ev)
5426 chanpos = pri_find_empty_nobch(pri);
5430 "Span %d: No hold channel available for held call that is on %d/%d\n",
5431 pri->
span, PRI_SPAN(ev->hold_ack.channel), PRI_CHANNEL(ev->hold_ack.channel));
5432 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5435 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_ack.call);
5438 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5442 sig_pri_lock_private(pri->
pvts[chanpos]);
5443 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5445 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_ack.subcmds, ev->hold_ack.call);
5446 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->owner, pri->
pvts[chanpos],
5448 sig_pri_unlock_private(pri->
pvts[chanpos]);
5449 sig_pri_span_devstate_changed(pri);
5457 #if defined(HAVE_PRI_CALL_HOLD)
5468 static void sig_pri_handle_hold_rej(
struct sig_pri_span *pri, pri_event *ev)
5473 chanpos = pri_find_principle(pri, ev->hold_rej.channel, ev->hold_rej.call);
5475 ast_log(LOG_WARNING,
"Span %d: Could not find principle for HOLD_REJECT\n",
5477 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5480 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_rej.call);
5483 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5487 ast_debug(1,
"Span %d: HOLD_REJECT cause: %d(%s)\n", pri->
span,
5488 ev->hold_rej.cause, pri_cause2str(ev->hold_rej.cause));
5490 sig_pri_lock_private(pri->
pvts[chanpos]);
5491 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5493 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_rej.subcmds, ev->hold_rej.call);
5494 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->owner, pri->
pvts[chanpos],
5496 sig_pri_unlock_private(pri->
pvts[chanpos]);
5504 #if defined(HAVE_PRI_CALL_HOLD)
5515 static void sig_pri_handle_retrieve(
struct sig_pri_span *pri, pri_event *ev)
5520 if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
5522 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5523 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5526 if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) {
5527 ast_log(LOG_WARNING,
"Span %d: Received RETRIEVE for unknown call.\n", pri->
span);
5528 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5529 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
5532 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) {
5533 chanpos = pri_find_empty_chan(pri, 1);
5535 chanpos = pri_find_principle(pri,
5536 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call);
5537 if (ev->retrieve.flexible
5543 chanpos = pri_find_empty_chan(pri, 1);
5547 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5548 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
5549 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5552 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call);
5555 pri_retrieve_rej(pri->
pri, ev->retrieve.call,
5556 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5559 sig_pri_lock_private(pri->
pvts[chanpos]);
5560 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5561 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.subcmds, ev->retrieve.call);
5562 sig_pri_queue_unhold(pri, chanpos);
5563 pri_retrieve_ack(pri->
pri, ev->retrieve.call,
5564 PVT_TO_CHANNEL(pri->
pvts[chanpos]));
5565 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->owner, pri->
pvts[chanpos],
5567 sig_pri_unlock_private(pri->
pvts[chanpos]);
5568 sig_pri_span_devstate_changed(pri);
5576 #if defined(HAVE_PRI_CALL_HOLD)
5587 static void sig_pri_handle_retrieve_ack(
struct sig_pri_span *pri, pri_event *ev)
5592 chanpos = pri_find_fixup_principle(pri, ev->retrieve_ack.channel,
5593 ev->retrieve_ack.call);
5598 sig_pri_lock_private(pri->
pvts[chanpos]);
5599 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5601 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_ack.subcmds,
5602 ev->retrieve_ack.call);
5603 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->owner, pri->
pvts[chanpos],
5605 sig_pri_unlock_private(pri->
pvts[chanpos]);
5606 sig_pri_span_devstate_changed(pri);
5614 #if defined(HAVE_PRI_CALL_HOLD)
5625 static void sig_pri_handle_retrieve_rej(
struct sig_pri_span *pri, pri_event *ev)
5630 chanpos = pri_find_principle(pri, ev->retrieve_rej.channel, ev->retrieve_rej.call);
5632 ast_log(LOG_WARNING,
"Span %d: Could not find principle for RETRIEVE_REJECT\n",
5634 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5637 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve_rej.call);
5640 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5644 ast_debug(1,
"Span %d: RETRIEVE_REJECT cause: %d(%s)\n", pri->
span,
5645 ev->retrieve_rej.cause, pri_cause2str(ev->retrieve_rej.cause));
5647 sig_pri_lock_private(pri->
pvts[chanpos]);
5648 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
5650 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_rej.subcmds,
5651 ev->retrieve_rej.call);
5652 sig_pri_moh_fsm_event(pri->
pvts[chanpos]->owner, pri->
pvts[chanpos],
5654 sig_pri_unlock_private(pri->
pvts[chanpos]);
5673 static void setup_incoming_channel(
struct sig_pri_span *pri,
int chanpos, pri_event *ev)
5677 char calledtonstr[10];
5679 sig_pri_lock_owner(pri, chanpos);
5680 owner = pri->
pvts[chanpos]->owner;
5687 #if defined(HAVE_PRI_SUBADDR)
5688 if (ev->ring.calling.subaddress.valid) {
5690 sig_pri_set_subaddress(&ast_channel_caller(owner)->
id.subaddress,
5691 &ev->ring.calling.subaddress);
5692 if (!ev->ring.calling.subaddress.type
5693 && !ast_strlen_zero((
char *) ev->ring.calling.subaddress.data)) {
5696 (
char *) ev->ring.calling.subaddress.
data);
5699 if (ev->ring.called_subaddress.valid) {
5701 sig_pri_set_subaddress(&ast_channel_dialed(owner)->subaddress,
5702 &ev->ring.called_subaddress);
5703 if (!ev->ring.called_subaddress.type
5704 && !ast_strlen_zero((
char *) ev->ring.called_subaddress.data)) {
5707 (
char *) ev->ring.called_subaddress.
data);
5711 if (!ast_strlen_zero(ev->ring.callingsubaddr)) {
5715 if (ev->ring.ani2 >= 0) {
5716 ast_channel_caller(owner)->
ani2 = ev->ring.ani2;
5717 snprintf(ani2str,
sizeof(ani2str),
"%d", ev->ring.ani2);
5721 #ifdef SUPPORT_USERUSER
5722 if (!ast_strlen_zero(ev->ring.useruserinfo)) {
5727 snprintf(calledtonstr,
sizeof(calledtonstr),
"%d", ev->ring.calledplan);
5729 ast_channel_dialed(owner)->
number.
plan = ev->ring.calledplan;
5731 if (ev->ring.redirectingreason >= 0) {
5734 redirectingreason2str(ev->ring.redirectingreason));
5736 #if defined(HAVE_PRI_REVERSE_CHARGE)
5739 #if defined(HAVE_PRI_SETUP_KEYPAD)
5749 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->ring.subcmds,
5753 ast_channel_unlock(owner);
5765 static void sig_pri_handle_setup(
struct sig_pri_span *pri, pri_event *e)
5767 int exten_exists_or_can_exist;
5768 int could_match_more;
5770 enum sig_pri_law law;
5772 ast_callid callid = 0;
5778 if (!ast_strlen_zero(pri->
msn_list)
5779 && !sig_pri_msn_match(pri->
msn_list, e->ring.callednum)) {
5782 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n",
5784 pri_destroycall(pri->
pri, e->ring.call);
5787 if (sig_pri_is_cis_call(e->ring.channel)) {
5788 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds, e->ring.call);
5791 chanpos = pri_find_principle_by_call(pri, e->ring.call);
5794 ast_log(LOG_WARNING,
5795 "Span %d: Got SETUP with duplicate call ptr (%p). Dropping call.\n",
5796 pri->
span, e->ring.call);
5797 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
5800 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
5802 chanpos = pri_find_empty_chan(pri, 1);
5804 callid = func_pri_dchannel_new_callid();
5806 }
else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
5808 #if defined(HAVE_PRI_CALL_WAITING)
5813 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5816 #if defined(HAVE_PRI_CALL_WAITING)
5817 chanpos = pri_find_empty_nobch(pri);
5820 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5824 callid = func_pri_dchannel_new_callid();
5827 sig_pri_init_config(pri->
pvts[chanpos], pri);
5831 callid = func_pri_dchannel_new_callid();
5832 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
5834 ast_log(LOG_WARNING,
5835 "Span %d: SETUP on unconfigured channel %d/%d\n",
5836 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5851 "Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n",
5852 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5858 pri_check_restart(pri);
5865 "Span %d: SETUP requested unavailable channel %d/%d. Attempting to renegotiate.\n",
5866 pri->
span, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel));
5870 #if defined(ALWAYS_PICK_CHANNEL)
5871 if (e->ring.flexible) {
5875 if (chanpos < 0 && e->ring.flexible) {
5877 chanpos = pri_find_empty_chan(pri, 1);
5881 if (e->ring.flexible) {
5882 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
5884 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
5889 sig_pri_lock_private(pri->
pvts[chanpos]);
5892 pri->
pvts[chanpos]->
call = e->ring.call;
5895 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
5896 e->ring.redirectingnum, e->ring.callingplanrdnis);
5897 sig_pri_set_rdnis(pri->
pvts[chanpos], plancallingnum);
5900 apply_plan_to_existing_number(plancallingnum,
sizeof(plancallingnum), pri,
5901 e->ring.callingnum, e->ring.callingplan);
5906 sizeof(pri->
pvts[chanpos]->cid_num));
5908 apply_plan_to_existing_number(plancallingani,
sizeof(plancallingani),
5909 pri, e->ring.callingani, e->ring.callingplanani);
5912 sizeof(pri->
pvts[chanpos]->cid_ani));
5914 pri->
pvts[chanpos]->cid_subaddr[0] =
'\0';
5915 #if defined(HAVE_PRI_SUBADDR)
5916 if (e->ring.calling.subaddress.valid) {
5920 sig_pri_set_subaddress(&calling_subaddress,
5921 &e->ring.calling.subaddress);
5922 if (calling_subaddress.str) {
5924 calling_subaddress.str,
5925 sizeof(pri->
pvts[chanpos]->cid_subaddr));
5931 sizeof(pri->
pvts[chanpos]->cid_name));
5933 pri->
pvts[chanpos]->
cid_ton = e->ring.callingplan;
5935 if (e->ring.ani2 >= 0) {
5939 pri->
pvts[chanpos]->cid_num[0] =
'\0';
5940 pri->
pvts[chanpos]->cid_subaddr[0] =
'\0';
5941 pri->
pvts[chanpos]->cid_ani[0] =
'\0';
5942 pri->
pvts[chanpos]->cid_name[0] =
'\0';
5953 ? plancallingnum : e->ring.callednum);
5955 ast_log(LOG_WARNING,
"user_tag '%s' truncated\n", pri->
pvts[chanpos]->
user_tag);
5962 sig_pri_set_caller_id(pri->
pvts[chanpos]);
5965 sig_pri_set_dnid(pri->
pvts[chanpos], e->ring.callednum);
5969 ast_verb(3,
"Going to extension s|1 because of immediate=yes\n");
5970 pri->
pvts[chanpos]->exten[0] =
's';
5971 pri->
pvts[chanpos]->exten[1] =
'\0';
5972 }
else if (!ast_strlen_zero(e->ring.callednum)) {
5975 sizeof(pri->
pvts[chanpos]->exten));
5977 pri->
pvts[chanpos]->exten[0] =
'\0';
5980 pri->
pvts[chanpos]->exten[0] =
's';
5981 pri->
pvts[chanpos]->exten[1] =
'\0';
5984 if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
5985 ast_verb(3,
"Going to extension s|1 because of Complete received\n");
5986 pri->
pvts[chanpos]->exten[0] =
's';
5987 pri->
pvts[chanpos]->exten[1] =
'\0';
5991 exten_exists_or_can_exist = ((pri->
overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
5993 pri->
pvts[chanpos]->exten, 1, pri->
pvts[chanpos]->cid_num))
5995 pri->
pvts[chanpos]->exten, 1, pri->
pvts[chanpos]->cid_num);
5996 if (!exten_exists_or_can_exist) {
5998 "Span %d: Extension %s@%s does not exist. Rejecting call from '%s'.\n",
5999 pri->
span, pri->
pvts[chanpos]->exten, pri->
pvts[chanpos]->context,
6000 pri->
pvts[chanpos]->cid_num);
6001 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
6003 pri->
pvts[chanpos]->exten[0] =
'\0';
6004 sig_pri_unlock_private(pri->
pvts[chanpos]);
6005 sig_pri_span_devstate_changed(pri);
6010 switch (e->ring.layer1) {
6011 case PRI_LAYER_1_ALAW:
6014 case PRI_LAYER_1_ULAW:
6019 law = SIG_PRI_DEFLAW;
6023 could_match_more = !e->ring.complete
6024 && (pri->
overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
6026 pri->
pvts[chanpos]->exten, 1, pri->
pvts[chanpos]->cid_num);
6028 need_dialtone = could_match_more
6034 && !(e->ring.ctype & AST_TRANS_CAP_DIGITAL)
6036 && (!strlen(pri->
pvts[chanpos]->exten)
6038 pri->
pvts[chanpos]->exten));
6040 if (e->ring.complete || !(pri->
overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
6043 pri_proceeding(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 0);
6044 }
else if (pri->
switchtype == PRI_SWITCH_GR303_TMC) {
6046 pri_answer(pri->
pri, e->ring.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6049 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
6050 pri_setup_ack(pri->
pri, e->ring.call,
6051 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, need_dialtone);
6053 pri_need_more_info(pri->
pri, e->ring.call,
6054 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6064 sig_pri_unlock_private(pri->
pvts[chanpos]);
6065 ast_mutex_unlock(&pri->
lock);
6066 c = sig_pri_new_ast_channel(pri->
pvts[chanpos],
6068 pri->
pvts[chanpos]->exten, NULL, NULL);
6069 ast_mutex_lock(&pri->
lock);
6070 sig_pri_lock_private(pri->
pvts[chanpos]);
6073 setup_incoming_channel(pri, chanpos, e);
6076 if (could_match_more) {
6077 #if !defined(HAVE_PRI_SETUP_ACK_INBAND)
6078 if (need_dialtone) {
6081 #ifdef HAVE_PRI_PROG_W_CAUSE
6082 pri_progress_with_cause(pri->
pri, e->ring.call,
6083 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1, -1);
6085 pri_progress(pri->
pri, e->ring.call,
6086 PVT_TO_CHANNEL(pri->
pvts[chanpos]), 1);
6091 if (!ast_pthread_create_detached(&threadid, NULL, pri_ss_thread,
6092 pri->
pvts[chanpos])) {
6093 ast_verb(3,
"Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
6094 plancallingnum,
S_OR(pri->
pvts[chanpos]->exten,
"<unspecified>"),
6097 sig_pri_unlock_private(pri->
pvts[chanpos]);
6102 ast_verb(3,
"Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
6103 plancallingnum, pri->
pvts[chanpos]->exten,
6106 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6107 sig_pri_unlock_private(pri->
pvts[chanpos]);
6112 ast_log(LOG_WARNING,
"Unable to start PBX on channel %d/%d, span %d\n",
6116 sig_pri_unlock_private(pri->
pvts[chanpos]);
6117 ast_mutex_unlock(&pri->
lock);
6119 ast_mutex_lock(&pri->
lock);
6121 pri_hangup(pri->
pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
6123 sig_pri_unlock_private(pri->
pvts[chanpos]);
6124 sig_pri_span_devstate_changed(pri);
6133 static void *pri_dchannel(
void *vpri)
6137 struct pollfd fds[SIG_PRI_NUM_DCHANS];
6140 struct timeval tv, lowest, *next;
6146 struct timeval lastidle = { 0, 0 };
6155 gettimeofday(&lastidle, NULL);
6156 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
6158 if (!ast_strlen_zero(pri->
idledial) && !ast_strlen_zero(pri->
idleext)) {
6160 cc = strchr(pri->
idleext,
'@');
6168 ast_log(LOG_WARNING,
"Extension '%s @ %s' does not exist\n", pri->
idleext, pri->
idlecontext);
6173 ast_log(LOG_WARNING,
"Idle dial string '%s' lacks '@context'\n", pri->
idleext);
6176 ast_callid callid = 0;
6182 fds[i].events = POLLIN | POLLPRI;
6187 ast_mutex_lock(&pri->
lock);
6191 pri_check_restart(pri);
6193 sig_pri_span_devstate_changed(pri);
6204 if (doidling && pri_is_up(pri)) {
6208 for (x = pri->
numchans; x >= 0; x--) {
6211 if (haveidles < pri->minunused) {
6222 if (nextidle > -1) {
6231 ast_mutex_unlock(&pri->
lock);
6237 sig_pri_lock_private(pri->
pvts[nextidle]);
6238 sig_pri_unlock_private(pri->
pvts[nextidle]);
6239 idle = sig_pri_request(pri->
pvts[nextidle], SIG_PRI_ULAW, NULL, NULL, 0);
6240 ast_mutex_lock(&pri->
lock);
6243 if (ast_pthread_create_background(&p, NULL, do_idle_thread, pri->
pvts[nextidle])) {
6244 ast_log(LOG_WARNING,
"Unable to start new thread for idle channel '%s'\n", ast_channel_name(idle));
6245 ast_mutex_unlock(&pri->
lock);
6247 ast_mutex_lock(&pri->
lock);
6251 ast_log(LOG_WARNING,
"Unable to request channel 'DAHDI/%s' for idle call\n", idlen);
6253 gettimeofday(&lastidle, NULL);
6255 }
else if ((haveidles < pri->minunused) &&
6256 (activeidles > pri->
minidle)) {
6259 for (x = pri->
numchans; x >= 0; x--) {
6267 (activeidles <= pri->minidle))
6289 next = pri_schedule_next(pri->
dchans[i]);
6293 if (tv.tv_sec < 0) {
6306 ast_mutex_unlock(&pri->
lock);
6308 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
6309 pthread_testcancel();
6311 res = poll(
fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
6312 pthread_testcancel();
6313 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
6315 ast_mutex_lock(&pri->
lock);
6321 e = pri_schedule_run(pri->
dchans[which]);
6325 }
else if (res > -1) {
6329 if (
fds[which].revents & POLLPRI) {
6330 sig_pri_handle_dchan_exception(pri, which);
6331 }
else if (
fds[which].revents & POLLIN) {
6332 e = pri_check_event(pri->
dchans[which]);
6337 if ((errno != 0) && (errno != EINTR)) {
6338 ast_log(LOG_NOTICE,
"pri_check_event returned error %d (%s)\n",
6339 errno, strerror(errno));
6341 if (errno == ENODEV) {
6342 pri_destroy_later(pri);
6345 }
else if (errno != EINTR)
6346 ast_log(LOG_WARNING,
"pri_event returned error %d (%s)\n", errno, strerror(errno));
6353 ast_verbose(
"Span %d: Processing event %s(%d)\n",
6354 pri->
span, pri_event2str(e->e), e->e);
6357 if (e->e != PRI_EVENT_DCHAN_DOWN) {
6359 ast_verb(2,
"%s D-Channel on span %d up\n", pri_order(which), pri->
span);
6364 ast_verb(2,
"%s D-Channel on span %d down\n", pri_order(which), pri->
span);
6369 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->
pri != pri->
dchans[which]))
6374 case PRI_EVENT_DCHAN_UP:
6377 pri_find_dchan(pri);
6390 for (i = 0; i < pri->
numchans; i++) {
6392 sig_pri_set_alarm(pri->
pvts[i], 0);
6395 sig_pri_span_devstate_changed(pri);
6397 case PRI_EVENT_DCHAN_DOWN:
6398 pri_find_dchan(pri);
6399 if (!pri_is_up(pri)) {
6400 if (pri->
sig == SIG_BRI_PTMP) {
6409 for (i = 0; i < pri->
numchans; i++) {
6413 if (pri_get_timer(p->pri->
pri, PRI_TIMER_T309) < 0) {
6416 pri_destroycall(p->pri->
pri, p->
call);
6422 sig_pri_set_alarm(p, 1);
6425 sig_pri_span_devstate_changed(pri);
6428 case PRI_EVENT_RESTART:
6429 if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) {
6430 chanpos = pri_find_principle(pri, e->restart.channel, NULL);
6432 ast_log(LOG_WARNING,
6433 "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
6434 pri->
span, PRI_SPAN(e->restart.channel),
6435 PRI_CHANNEL(e->restart.channel));
6438 #if defined(HAVE_PRI_SERVICE_MESSAGES)
6444 "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n",
6445 pri->
span, PRI_SPAN(e->restart.channel),
6446 PRI_CHANNEL(e->restart.channel),
6451 sig_pri_lock_private(pri->
pvts[chanpos]);
6453 ast_verb(3,
"Span %d: Channel %d/%d restarted\n", pri->
span,
6454 PRI_SPAN(e->restart.channel),
6455 PRI_CHANNEL(e->restart.channel));
6457 pri_destroycall(pri->
pri, pri->
pvts[chanpos]->
call);
6462 sig_pri_queue_hangup(pri, chanpos);
6463 sig_pri_unlock_private(pri->
pvts[chanpos]);
6466 ast_verb(3,
"Restart requested on entire span %d\n", pri->
span);
6467 for (x = 0; x < pri->
numchans; x++)
6469 sig_pri_lock_private(pri->
pvts[x]);
6475 sig_pri_queue_hangup(pri, x);
6476 sig_pri_unlock_private(pri->
pvts[x]);
6479 sig_pri_span_devstate_changed(pri);
6481 case PRI_EVENT_KEYPAD_DIGIT:
6482 if (sig_pri_is_cis_call(e->digit.channel)) {
6483 sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds,
6487 chanpos = pri_find_principle_by_call(pri, e->digit.call);
6489 ast_log(LOG_WARNING,
6490 "Span %d: Received keypad digits for unknown call.\n", pri->
span);
6493 sig_pri_lock_private(pri->
pvts[chanpos]);
6495 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6497 sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.subcmds,
6500 if ((pri->
overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
6501 && pri->
pvts[chanpos]->owner) {
6503 int digitlen = strlen(e->digit.digits);
6506 for (i = 0; i < digitlen; i++) {
6507 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->digit.digits[i], };
6509 pri_queue_frame(pri, chanpos, &f);
6512 sig_pri_unlock_private(pri->
pvts[chanpos]);
6515 case PRI_EVENT_INFO_RECEIVED:
6516 if (sig_pri_is_cis_call(e->ring.channel)) {
6517 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
6521 chanpos = pri_find_principle_by_call(pri, e->ring.call);
6523 ast_log(LOG_WARNING,
6524 "Span %d: Received INFORMATION for unknown call.\n", pri->
span);
6527 sig_pri_lock_private(pri->
pvts[chanpos]);
6529 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6531 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, e->ring.call);
6533 if ((pri->
overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
6534 && pri->
pvts[chanpos]->owner) {
6536 int digitlen = strlen(e->ring.callednum);
6539 for (i = 0; i < digitlen; i++) {
6540 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->ring.callednum[i], };
6542 pri_queue_frame(pri, chanpos, &f);
6545 sig_pri_unlock_private(pri->
pvts[chanpos]);
6547 #if defined(HAVE_PRI_SERVICE_MESSAGES)
6548 case PRI_EVENT_SERVICE:
6549 chanpos = pri_find_principle(pri, e->service.channel, NULL);
6551 ast_log(LOG_WARNING,
"Received service change status %d on unconfigured channel %d/%d span %d\n",
6552 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6554 char db_chan_name[20];
6560 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d",
dahdi_db, pri->
span, ch);
6562 switch (e->service.changestatus) {
6568 snprintf(db_answer,
sizeof(db_answer),
"%s:%u",
6572 sig_pri_span_devstate_changed(pri);
6582 sig_pri_span_devstate_changed(pri);
6585 ast_log(LOG_ERROR,
"Huh? changestatus is: %d\n", e->service.changestatus);
6588 ast_log(LOG_NOTICE,
"Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n",
6589 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->
span, ch, e->service.changestatus);
6592 case PRI_EVENT_SERVICE_ACK:
6593 chanpos = pri_find_principle(pri, e->service_ack.channel, NULL);
6595 ast_log(LOG_WARNING,
"Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
6596 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span);
6598 ast_debug(2,
"Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n",
6599 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->
span, e->service_ack.changestatus);
6603 case PRI_EVENT_RING:
6604 sig_pri_handle_setup(pri, e);
6606 case PRI_EVENT_RINGING:
6607 if (sig_pri_is_cis_call(e->ringing.channel)) {
6608 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds,
6612 chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
6617 sig_pri_lock_private(pri->
pvts[chanpos]);
6619 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6621 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.subcmds,
6623 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCNR);
6624 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6625 sig_pri_lock_owner(pri, chanpos);
6626 if (pri->
pvts[chanpos]->owner) {
6628 ast_channel_unlock(pri->
pvts[chanpos]->owner);
6637 #ifdef PRI_PROGRESS_MASK
6638 && (e->ringing.progressmask
6639 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6641 && e->ringing.progress == 8
6647 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6648 sig_pri_open_media(pri->
pvts[chanpos]);
6651 #ifdef SUPPORT_USERUSER
6652 if (!ast_strlen_zero(e->ringing.useruserinfo)) {
6655 sig_pri_lock_owner(pri, chanpos);
6656 owner = pri->
pvts[chanpos]->owner;
6659 e->ringing.useruserinfo);
6660 ast_channel_unlock(owner);
6665 sig_pri_unlock_private(pri->
pvts[chanpos]);
6667 case PRI_EVENT_PROGRESS:
6668 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6669 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6670 e->proceeding.call);
6673 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6674 e->proceeding.call);
6678 sig_pri_lock_private(pri->
pvts[chanpos]);
6680 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6682 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6683 e->proceeding.call);
6685 if (e->proceeding.cause > -1) {
6686 if (pri->
pvts[chanpos]->owner) {
6687 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_PROGRESS (%d)", e->proceeding.cause);
6688 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->proceeding.cause);
6691 ast_verb(3,
"PROGRESS with cause code %d received\n", e->proceeding.cause);
6694 if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
6695 if (pri->
pvts[chanpos]->owner) {
6696 ast_verb(3,
"PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
6698 ast_channel_hangupcause_set(pri->
pvts[chanpos]->owner, e->proceeding.cause);
6706 #ifdef PRI_PROGRESS_MASK
6707 && (e->proceeding.progressmask
6708 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
6710 && e->proceeding.progress == 8
6715 "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
6720 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6721 sig_pri_open_media(pri->
pvts[chanpos]);
6723 sig_pri_unlock_private(pri->
pvts[chanpos]);
6725 case PRI_EVENT_PROCEEDING:
6726 if (sig_pri_is_cis_call(e->proceeding.channel)) {
6727 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
6728 e->proceeding.call);
6731 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
6732 e->proceeding.call);
6736 sig_pri_lock_private(pri->
pvts[chanpos]);
6738 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6740 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
6741 e->proceeding.call);
6745 "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
6752 #ifdef PRI_PROGRESS_MASK
6761 && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
6763 && e->proceeding.progress == 8
6769 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6770 sig_pri_open_media(pri->
pvts[chanpos]);
6778 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6780 sig_pri_unlock_private(pri->
pvts[chanpos]);
6782 case PRI_EVENT_FACILITY:
6783 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) {
6785 #if defined(HAVE_PRI_CALL_REROUTING)
6786 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6787 e->facility.subcall);
6789 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
6794 chanpos = pri_find_principle_by_call(pri, e->facility.call);
6796 ast_log(LOG_WARNING,
"Span %d: Received facility for unknown call.\n",
6800 sig_pri_lock_private(pri->
pvts[chanpos]);
6802 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6804 #if defined(HAVE_PRI_CALL_REROUTING)
6805 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6806 e->facility.subcall);
6808 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
6811 sig_pri_unlock_private(pri->
pvts[chanpos]);
6813 case PRI_EVENT_ANSWER:
6814 if (sig_pri_is_cis_call(e->answer.channel)) {
6815 #if defined(HAVE_PRI_CALL_WAITING)
6817 pri_connect_ack(pri->
pri, e->answer.call, 0);
6819 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds,
6823 chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
6827 #if defined(HAVE_PRI_CALL_WAITING)
6836 new_chanpos = pri_find_empty_chan(pri, 1);
6837 if (0 <= new_chanpos) {
6838 new_chanpos = pri_fixup_principle(pri, new_chanpos,
6841 if (new_chanpos < 0) {
6847 "Span %d: Channel not available for call waiting call.\n",
6849 sig_pri_lock_private(pri->
pvts[chanpos]);
6850 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
6852 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
6853 sig_pri_lock_owner(pri, chanpos);
6854 if (pri->
pvts[chanpos]->owner) {
6855 ast_channel_hangupcause_set(pri->
pvts[chanpos]->owner, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
6865 ast_channel_unlock(pri->
pvts[chanpos]->owner);
6869 pri_hangup(pri->
pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
6872 sig_pri_unlock_private(pri->
pvts[chanpos]);
6873 sig_pri_span_devstate_changed(pri);
6876 chanpos = new_chanpos;
6878 pri_connect_ack(pri->
pri, e->answer.call, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
6879 sig_pri_span_devstate_changed(pri);
6882 pri_connect_ack(pri->
pri, e->answer.call, 0);
6885 sig_pri_lock_private(pri->
pvts[chanpos]);
6887 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6889 #if defined(HAVE_PRI_CALL_WAITING)
6895 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
6900 "Span %d: Channel %d/%d dialing deferred digit string: %s\n",
6907 sig_pri_dial_digits(pri->
pvts[chanpos],
6913 sig_pri_open_media(pri->
pvts[chanpos]);
6915 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
6917 sig_pri_set_echocanceller(pri->
pvts[chanpos], 1);
6920 #ifdef SUPPORT_USERUSER
6921 if (!ast_strlen_zero(e->answer.useruserinfo)) {
6924 sig_pri_lock_owner(pri, chanpos);
6925 owner = pri->
pvts[chanpos]->owner;
6928 e->answer.useruserinfo);
6929 ast_channel_unlock(owner);
6934 sig_pri_unlock_private(pri->
pvts[chanpos]);
6936 #if defined(HAVE_PRI_CALL_WAITING)
6937 case PRI_EVENT_CONNECT_ACK:
6938 if (sig_pri_is_cis_call(e->connect_ack.channel)) {
6939 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds,
6940 e->connect_ack.call);
6943 chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel,
6944 e->connect_ack.call);
6949 sig_pri_lock_private(pri->
pvts[chanpos]);
6951 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6953 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.subcmds,
6954 e->connect_ack.call);
6955 sig_pri_open_media(pri->
pvts[chanpos]);
6956 sig_pri_unlock_private(pri->
pvts[chanpos]);
6957 sig_pri_span_devstate_changed(pri);
6960 case PRI_EVENT_HANGUP:
6961 if (sig_pri_is_cis_call(e->hangup.channel)) {
6962 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
6964 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6967 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
6973 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6976 sig_pri_lock_private(pri->
pvts[chanpos]);
6978 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
6980 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
6982 switch (e->hangup.cause) {
6983 case PRI_CAUSE_INVALID_CALL_REFERENCE:
6988 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
6997 switch (e->hangup.cause) {
6998 case PRI_CAUSE_USER_BUSY:
6999 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7000 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
7005 if (pri->
pvts[chanpos]->owner) {
7006 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP (%d)", e->hangup.cause);
7007 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7009 if (pri->
pvts[chanpos]->owner) {
7013 ast_channel_hangupcause_set(pri->
pvts[chanpos]->owner, e->hangup.cause);
7020 if (!pri->
pvts[chanpos]->outgoing) {
7028 switch (e->hangup.cause) {
7029 case PRI_CAUSE_USER_BUSY:
7032 case PRI_CAUSE_CALL_REJECTED:
7033 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7034 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7035 case PRI_CAUSE_SWITCH_CONGESTION:
7036 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7037 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7048 sig_pri_queue_hangup(pri, chanpos);
7055 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7058 ast_verb(3,
"Span %d: Channel %d/%d got hangup, cause %d\n",
7063 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7066 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7071 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7075 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7077 if (e->hangup.aoc_units > -1)
7078 ast_verb(3,
"Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
7081 #ifdef SUPPORT_USERUSER
7082 if (!ast_strlen_zero(e->hangup.useruserinfo)) {
7085 sig_pri_lock_owner(pri, chanpos);
7086 owner = pri->
pvts[chanpos]->owner;
7089 e->hangup.useruserinfo);
7090 ast_channel_unlock(owner);
7095 sig_pri_unlock_private(pri->
pvts[chanpos]);
7096 sig_pri_span_devstate_changed(pri);
7098 case PRI_EVENT_HANGUP_REQ:
7099 if (sig_pri_is_cis_call(e->hangup.channel)) {
7100 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7102 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7105 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7111 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7114 sig_pri_lock_private(pri->
pvts[chanpos]);
7116 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7118 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
7120 #if defined(HAVE_PRI_CALL_HOLD)
7121 if (e->hangup.call_active && e->hangup.call_held
7124 sig_pri_unlock_private(pri->
pvts[chanpos]);
7125 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1,
7126 e->hangup.call_active, 0, NULL)) {
7129 sig_pri_lock_private(pri->
pvts[chanpos]);
7132 switch (e->hangup.cause) {
7133 case PRI_CAUSE_USER_BUSY:
7134 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7135 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
7137 case PRI_CAUSE_INVALID_CALL_REFERENCE:
7144 pri_hangup(pri->
pri, e->hangup.call, e->hangup.cause);
7150 if (pri->
pvts[chanpos]->owner) {
7151 snprintf(cause_str,
sizeof(cause_str),
"PRI PRI_EVENT_HANGUP_REQ (%d)", e->hangup.cause);
7152 pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
7154 if (pri->
pvts[chanpos]->owner) {
7157 ast_channel_hangupcause_set(pri->
pvts[chanpos]->owner, e->hangup.cause);
7164 if (!pri->
pvts[chanpos]->outgoing) {
7172 switch (e->hangup.cause) {
7173 case PRI_CAUSE_USER_BUSY:
7176 case PRI_CAUSE_CALL_REJECTED:
7177 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
7178 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
7179 case PRI_CAUSE_SWITCH_CONGESTION:
7180 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
7181 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
7192 #if defined(HAVE_PRI_AOC_EVENTS)
7196 sig_pri_send_aoce_termination_request(pri, chanpos,
7197 pri_get_timer(pri->
pri, PRI_TIMER_T305) / 2);
7201 sig_pri_queue_hangup(pri, chanpos);
7204 ast_verb(3,
"Span %d: Channel %d/%d got hangup request, cause %d\n",
7212 pri_hangup(pri->
pri, pri->
pvts[chanpos]->
call, e->hangup.cause);
7215 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
7220 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
7224 pri_reset(pri->
pri, PVT_TO_CHANNEL(pri->
pvts[chanpos]));
7227 #ifdef SUPPORT_USERUSER
7228 if (!ast_strlen_zero(e->hangup.useruserinfo)) {
7231 sig_pri_lock_owner(pri, chanpos);
7232 owner = pri->
pvts[chanpos]->owner;
7235 e->hangup.useruserinfo);
7236 ast_channel_unlock(owner);
7241 sig_pri_unlock_private(pri->
pvts[chanpos]);
7242 sig_pri_span_devstate_changed(pri);
7244 case PRI_EVENT_HANGUP_ACK:
7245 if (sig_pri_is_cis_call(e->hangup.channel)) {
7246 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
7250 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
7254 sig_pri_lock_private(pri->
pvts[chanpos]);
7256 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7259 if (pri->
pvts[chanpos]->owner) {
7260 ast_verb(3,
"Span %d: Channel %d/%d got hangup ACK\n", pri->
span,
7263 #ifdef SUPPORT_USERUSER
7264 if (!ast_strlen_zero(e->hangup.useruserinfo)) {
7267 sig_pri_lock_owner(pri, chanpos);
7268 owner = pri->
pvts[chanpos]->owner;
7271 e->hangup.useruserinfo);
7272 ast_channel_unlock(owner);
7276 sig_pri_unlock_private(pri->
pvts[chanpos]);
7277 sig_pri_span_devstate_changed(pri);
7279 case PRI_EVENT_CONFIG_ERR:
7280 ast_log(LOG_WARNING,
"PRI Error on span %d: %s\n", pri->
span, e->err.err);
7282 case PRI_EVENT_RESTART_ACK:
7283 chanpos = pri_find_principle(pri, e->restartack.channel, NULL);
7288 for (x = 0; x < pri->
numchans; x++) {
7292 sig_pri_lock_private(pri->
pvts[chanpos]);
7294 "Span %d: Assuming restart ack is for channel %d/%d\n",
7297 if (pri->
pvts[chanpos]->owner) {
7298 ast_log(LOG_WARNING,
7299 "Span %d: Got restart ack on channel %d/%d with owner\n",
7306 "Span %d: Channel %d/%d successfully restarted\n",
7309 sig_pri_unlock_private(pri->
pvts[chanpos]);
7311 pri_check_restart(pri);
7316 ast_log(LOG_WARNING,
7317 "Span %d: Restart ACK on strange channel %d/%d\n",
7318 pri->
span, PRI_SPAN(e->restartack.channel),
7319 PRI_CHANNEL(e->restartack.channel));
7322 sig_pri_lock_private(pri->
pvts[chanpos]);
7326 "Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n",
7329 sig_pri_unlock_private(pri->
pvts[chanpos]);
7332 if (pri->
pvts[chanpos]->owner) {
7333 ast_log(LOG_WARNING,
7334 "Span %d: Got restart ack on channel %d/%d with owner\n",
7341 "Span %d: Channel %d/%d successfully restarted\n",
7344 sig_pri_unlock_private(pri->
pvts[chanpos]);
7346 pri_check_restart(pri);
7349 case PRI_EVENT_SETUP_ACK:
7350 if (sig_pri_is_cis_call(e->setup_ack.channel)) {
7351 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds,
7355 chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
7360 sig_pri_lock_private(pri->
pvts[chanpos]);
7362 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7364 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.subcmds,
7371 len = strlen(pri->
pvts[chanpos]->dialdest);
7372 for (x = 0; x < len; ++x) {
7373 ast_debug(1,
"Sending pending digit '%c'\n", pri->
pvts[chanpos]->dialdest[x]);
7374 pri_information(pri->
pri, pri->
pvts[chanpos]->
call,
7375 pri->
pvts[chanpos]->dialdest[x]);
7379 && (pri->
overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)
7380 && !pri->
pvts[chanpos]->digital
7382 #
if defined(HAVE_PRI_SETUP_ACK_INBAND)
7400 && ((e->setup_ack.progressmask & PRI_PROG_INBAND_AVAILABLE)
7411 sig_pri_set_dialing(pri->
pvts[chanpos], 0);
7412 sig_pri_open_media(pri->
pvts[chanpos]);
7414 sig_pri_unlock_private(pri->
pvts[chanpos]);
7416 case PRI_EVENT_NOTIFY:
7417 if (sig_pri_is_cis_call(e->notify.channel)) {
7418 #if defined(HAVE_PRI_CALL_HOLD)
7419 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
7422 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, NULL);
7426 #if defined(HAVE_PRI_CALL_HOLD)
7427 chanpos = pri_find_principle_by_call(pri, e->notify.call);
7429 ast_log(LOG_WARNING,
"Span %d: Received NOTIFY for unknown call.\n",
7439 chanpos = pri_find_principle(pri, e->notify.channel, NULL);
7441 ast_log(LOG_WARNING,
"Received NOTIFY on unconfigured channel %d/%d span %d\n",
7442 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->
span);
7446 sig_pri_lock_private(pri->
pvts[chanpos]);
7448 callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
7450 #if defined(HAVE_PRI_CALL_HOLD)
7451 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
7454 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds, NULL);
7456 switch (e->notify.info) {
7457 case PRI_NOTIFY_REMOTE_HOLD:
7459 sig_pri_queue_hold(pri, chanpos);
7462 case PRI_NOTIFY_REMOTE_RETRIEVAL:
7464 sig_pri_queue_unhold(pri, chanpos);
7468 sig_pri_unlock_private(pri->
pvts[chanpos]);
7470 #if defined(HAVE_PRI_CALL_HOLD)
7471 case PRI_EVENT_HOLD:
7473 if (sig_pri_handle_hold(pri, e)) {
7474 pri_hold_rej(pri->
pri, e->hold.call,
7475 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
7477 pri_hold_ack(pri->
pri, e->hold.call);
7481 #if defined(HAVE_PRI_CALL_HOLD)
7482 case PRI_EVENT_HOLD_ACK:
7484 sig_pri_handle_hold_ack(pri, e);
7487 #if defined(HAVE_PRI_CALL_HOLD)
7488 case PRI_EVENT_HOLD_REJ:
7490 sig_pri_handle_hold_rej(pri, e);
7493 #if defined(HAVE_PRI_CALL_HOLD)
7494 case PRI_EVENT_RETRIEVE:
7496 sig_pri_handle_retrieve(pri, e);
7499 #if defined(HAVE_PRI_CALL_HOLD)
7500 case PRI_EVENT_RETRIEVE_ACK:
7502 sig_pri_handle_retrieve_ack(pri, e);
7505 #if defined(HAVE_PRI_CALL_HOLD)
7506 case PRI_EVENT_RETRIEVE_REJ:
7508 sig_pri_handle_retrieve_rej(pri, e);
7512 ast_debug(1,
"Span: %d Unhandled event: %s(%d)\n",
7513 pri->
span, pri_event2str(e->e), e->e);
7522 ast_mutex_unlock(&pri->
lock);
7546 for (x = 0; x < ARRAY_LEN(pri->
dchans); ++x) {
7564 (pri->
dchans[x] == pri->
pri) ?
"Yes" :
"No",
7565 (pri->
dchanavail[x] & DCHAN_NOTINALARM) ?
"No" :
"Yes",
7566 (pri->
dchanavail[x] & DCHAN_UP) ?
"Yes" :
"No",
7578 memset(pri, 0,
sizeof(*pri));
7580 ast_mutex_init(&pri->
lock);
7582 pri->
master = AST_PTHREADT_NULL;
7590 if (!ast_channel_tech_pvt(ast)) {
7591 ast_log(LOG_WARNING,
"Asked to hangup channel not connected\n");
7595 sig_pri_set_outgoing(p, 0);
7596 sig_pri_set_digital(p, 0);
7597 #if defined(HAVE_PRI_CALL_WAITING)
7605 p->cid_num[0] =
'\0';
7606 p->cid_subaddr[0] =
'\0';
7607 p->cid_name[0] =
'\0';
7610 sig_pri_set_dialing(p, 0);
7613 pri_grab(p, p->pri);
7616 #if defined(SUPPORT_USERUSER)
7619 if (!ast_strlen_zero(useruser)) {
7620 pri_call_set_useruser(p->
call, useruser);
7624 #if defined(HAVE_PRI_TRANSFER)
7638 #if defined(HAVE_PRI_AOC_EVENTS)
7640 pri_aoc_e_send(p->pri->
pri, p->
call, &p->aoc_e);
7645 ast_debug(1,
"Already hungup... Calling hangup once, and clearing call\n");
7647 pri_hangup(p->pri->
pri, p->
call, -1);
7651 int icause = ast_channel_hangupcause(ast) ? ast_channel_hangupcause(ast) : -1;
7654 if (!ast_strlen_zero(cause)) {
7656 icause = atoi(cause);
7660 "Not yet hungup... Calling hangup with cause %d, and clearing call\n",
7663 pri_hangup(p->pri->
pri, p->
call, icause);
7666 #if defined(HAVE_PRI_TRANSFER)
7669 #if defined(HAVE_PRI_AOC_EVENTS)
7678 sig_pri_span_devstate_changed(p->pri);
7716 subaddr = strchr(number,
':');
7734 if (strlen(number) < p->stripmsd) {
7739 number += p->stripmsd;
7740 deferred = strchr(number,
'w');
7745 while (isalpha(*number)) {
7751 if (ast_strlen_zero(subaddr)) {
7753 snprintf(called, called_buff_size,
"%s", number);
7756 snprintf(called, called_buff_size,
"%s:%s", number, subaddr);
7760 enum SIG_PRI_CALL_OPT_FLAGS {
7761 OPT_KEYPAD = (1 << 0),
7762 OPT_REVERSE_CHARGE = (1 << 1),
7763 OPT_AOC_REQUEST = (1 << 2),
7765 enum SIG_PRI_CALL_OPT_ARGS {
7767 OPT_ARG_AOC_REQUEST,
7785 char *c, *l, *n, *s;
7786 #ifdef SUPPORT_USERUSER
7787 const char *useruser;
7792 int prilocaldialplan;
7795 #if defined(HAVE_PRI_SETUP_KEYPAD)
7805 char *opt_args[OPT_ARG_ARRAY_SIZE];
7806 struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
7808 ast_debug(1,
"CALLER NAME: %s NUM: %s\n",
7813 ast_log(LOG_ERROR,
"Could not find pri on channel %d\n", p->
channel);
7818 ast_log(LOG_WARNING,
"sig_pri_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
7822 p->dialdest[0] =
'\0';
7823 sig_pri_set_outgoing(p, 1);
7851 dialed_subaddress.
type = 2;
7859 dialed_subaddress.
str = s;
7860 dialed_subaddress.
valid = 1;
7865 if (!p->hidecallerid) {
7871 for (l = connected_id.
number.
str; l && *l; l++) {
7872 if (strchr(
"0123456789", *l)) {
7885 if (strlen(c) < p->stripmsd) {
7886 ast_log(LOG_WARNING,
"Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
7891 s = strchr(c + p->stripmsd,
'w');
7904 pri_grab(p, p->pri);
7905 if (!(p->
call = pri_new_call(p->pri->
pri))) {
7906 ast_log(LOG_WARNING,
"Unable to create call on channel %d\n", p->
channel);
7910 if (!(sr = pri_sr_new())) {
7911 ast_log(LOG_WARNING,
"Failed to allocate setup request on channel %d\n",
7913 pri_destroycall(p->pri->
pri, p->
call);
7919 sig_pri_set_digital(p, IS_DIGITAL(ast_channel_transfercapability(ast)));
7921 #if defined(HAVE_PRI_CALL_WAITING)
7927 pri_sr_set_channel(sr, 0, 0, 1);
7937 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
7940 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast_channel_transfercapability(ast),
7941 (p->digital ? -1 : layer1));
7944 pri_facility_enable(p->pri->
pri);
7946 ast_verb(3,
"Requested transfer capability: 0x%02hx - %s\n", ast_channel_transfercapability(ast),
ast_transfercapability2str(ast_channel_transfercapability(ast)));
7948 pridialplan = p->pri->
dialplan - 1;
7949 if (pridialplan == -2 || pridialplan == -3) {
7951 if (pridialplan == -2) {
7954 pridialplan = PRI_INTERNATIONAL_ISDN;
7956 if (pridialplan == -2) {
7959 pridialplan = PRI_NATIONAL_ISDN;
7961 pridialplan = PRI_LOCAL_ISDN;
7964 while (c[p->stripmsd] >
'9' && c[p->stripmsd] !=
'*' && c[p->stripmsd] !=
'#') {
7965 switch (c[p->stripmsd]) {
7967 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
7970 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
7973 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
7976 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
7979 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
7982 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
7985 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
7988 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
7991 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
7994 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
7997 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
8000 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
8003 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
8006 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
8009 if (isalpha(c[p->stripmsd])) {
8010 ast_log(LOG_WARNING,
"Unrecognized pridialplan %s modifier: %c\n",
8011 c[p->stripmsd] >
'Z' ?
"NPI" :
"TON", c[p->stripmsd]);
8017 #if defined(HAVE_PRI_SETUP_KEYPAD)
8018 if (ast_test_flag(&opts, OPT_KEYPAD)
8019 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) {
8021 keypad = opt_args[OPT_ARG_KEYPAD];
8022 pri_sr_set_keypad_digits(sr, keypad);
8026 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip))
8029 char *called = c + p->stripmsd + dp_strip;
8031 pri_sr_set_called(sr, called, pridialplan, s ? 1 : 0);
8032 #if defined(HAVE_PRI_SETUP_ACK_INBAND)
8037 #if defined(HAVE_PRI_SUBADDR)
8038 if (dialed_subaddress.
valid) {
8039 struct pri_party_subaddress subaddress;
8041 memset(&subaddress, 0,
sizeof(subaddress));
8042 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
8043 pri_sr_set_called_subaddress(sr, &subaddress);
8046 #if defined(HAVE_PRI_REVERSE_CHARGE)
8047 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) {
8048 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
8051 #if defined(HAVE_PRI_AOC_EVENTS)
8052 if (ast_test_flag(&opts, OPT_AOC_REQUEST)
8053 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) {
8054 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
's')) {
8055 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
8057 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'd')) {
8058 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
8060 if (strchr(opt_args[OPT_ARG_AOC_REQUEST],
'e')) {
8061 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
8070 ? c + p->stripmsd + dp_strip
8071 :
S_COR(ast_channel_connected(ast)->
id.number.valid,
8072 ast_channel_connected(ast)->
id.number.str,
""));
8081 ast_free(ast_channel_caller(ast)->
id.tag);
8086 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) {
8088 if (prilocaldialplan == -2) {
8091 prilocaldialplan = PRI_INTERNATIONAL_ISDN;
8093 if (prilocaldialplan == -2) {
8096 prilocaldialplan = PRI_NATIONAL_ISDN;
8098 prilocaldialplan = PRI_LOCAL_ISDN;
8100 }
else if (prilocaldialplan == -1) {
8105 while (*l >
'9' && *l !=
'*' && *l !=
'#') {
8108 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
8111 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
8114 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
8117 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
8120 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
8123 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
8126 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
8129 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
8132 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
8135 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
8138 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
8141 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
8144 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
8147 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
8151 ast_log(LOG_WARNING,
8152 "Unrecognized prilocaldialplan %s modifier: %c\n",
8153 *l >
'Z' ?
"NPI" :
"TON", *l);
8160 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
8163 #if defined(HAVE_PRI_SUBADDR)
8165 struct pri_party_subaddress subaddress;
8167 memset(&subaddress, 0,
sizeof(subaddress));
8168 sig_pri_party_subaddress_from_ast(&subaddress, &connected_id.
subaddress);
8169 pri_sr_set_caller_subaddress(sr, &subaddress);
8173 sig_pri_redirecting_update(p, ast);
8175 #ifdef SUPPORT_USERUSER
8179 pri_sr_set_useruser(sr, useruser);
8182 #if defined(HAVE_PRI_CCSS)
8196 ast_assert(p->pri == instance->
pri);
8198 if (pri_cc_call(p->pri->
pri, instance->
cc_id, p->
call, sr)) {
8200 ast_log(LOG_WARNING,
"Unable to setup CC recall call to device %s\n",
8203 pri_destroycall(p->pri->
pri, p->
call);
8218 if (core_id == -1 && pri_setup(p->pri->
pri, p->
call, sr)) {
8219 ast_log(LOG_WARNING,
"Unable to setup call to %s (using %s)\n",
8220 c + p->stripmsd + dp_strip, dialplan2str(p->pri->
dialplan));
8221 pri_destroycall(p->pri->
pri, p->
call);
8230 sig_pri_set_dialing(p, 1);
8235 int sig_pri_indicate(
struct sig_pri_chan *p,
struct ast_channel *chan,
int condition,
const void *data,
size_t datalen)
8239 switch (condition) {
8242 ast_channel_hangupcause_set(chan, AST_CAUSE_USER_BUSY);
8247 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY);
8249 ast_channel_hangupcause_set(chan, AST_CAUSE_USER_BUSY);
8251 if (p->pri && p->pri->
pri) {
8252 pri_grab(p, p->pri);
8253 #ifdef HAVE_PRI_PROG_W_CAUSE
8254 pri_progress_with_cause(p->pri->
pri, p->
call, PVT_TO_CHANNEL(p), 1, ast_channel_hangupcause(chan));
8256 pri_progress(p->pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8265 if (p->pri && p->pri->
pri) {
8266 pri_grab(p, p->pri);
8267 pri_acknowledge(p->pri->
pri,p->
call, PVT_TO_CHANNEL(p),
8272 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE);
8279 ast_debug(1,
"Received AST_CONTROL_PROCEEDING on %s\n",ast_channel_name(chan));
8282 if (p->pri && p->pri->
pri) {
8283 pri_grab(p, p->pri);
8284 pri_proceeding(p->pri->
pri,p->
call, PVT_TO_CHANNEL(p), 0);
8292 ast_debug(1,
"Received AST_CONTROL_PROGRESS on %s\n",ast_channel_name(chan));
8293 sig_pri_set_digital(p, 0);
8297 if (p->pri && p->pri->
pri) {
8298 pri_grab(p, p->pri);
8299 #ifdef HAVE_PRI_PROG_W_CAUSE
8300 pri_progress_with_cause(p->pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1, -1);
8302 pri_progress(p->pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8317 ast_channel_hangupcause_set(chan, AST_CAUSE_INVALID_NUMBER_FORMAT);
8322 switch (ast_channel_hangupcause(chan)) {
8323 case AST_CAUSE_USER_BUSY:
8324 case AST_CAUSE_NORMAL_CLEARING:
8327 ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
8336 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION);
8339 switch (ast_channel_hangupcause(chan)) {
8340 case AST_CAUSE_USER_BUSY:
8341 case AST_CAUSE_NORMAL_CLEARING:
8344 ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
8350 if (p->pri && p->pri->
pri) {
8351 pri_grab(p, p->pri);
8352 #ifdef HAVE_PRI_PROG_W_CAUSE
8353 pri_progress_with_cause(p->pri->
pri, p->
call, PVT_TO_CHANNEL(p), 1, ast_channel_hangupcause(chan));
8355 pri_progress(p->pri->
pri,p->
call, PVT_TO_CHANNEL(p), 1);
8364 pri_grab(p, p->pri);
8374 pri_grab(p, p->pri);
8386 res = sig_pri_play_tone(p, -1);
8389 ast_debug(1,
"Received AST_CONTROL_CONNECTED_LINE on %s\n", ast_channel_name(chan));
8391 struct pri_party_connected_line connected;
8394 int colp_allowed = 0;
8395 struct ast_party_id connected_id = ast_channel_connected_effective_id(chan);
8397 pri_grab(p, p->pri);
8416 if (!colp_allowed) {
8418 ast_debug(1,
"Blocked AST_CONTROL_CONNECTED_LINE on %s\n",
8419 ast_channel_name(chan));
8423 memset(&connected, 0,
sizeof(connected));
8424 sig_pri_party_id_from_ast(&connected.id, &connected_id);
8435 dialplan = PRI_INTERNATIONAL_ISDN;
8439 dialplan = PRI_NATIONAL_ISDN;
8441 dialplan = PRI_LOCAL_ISDN;
8449 strlen(connected.id.
number.
str + prefix_strip) + 1);
8460 pri_connected_line_update(p->pri->
pri, p->
call, &connected);
8465 ast_debug(1,
"Received AST_CONTROL_REDIRECTING on %s\n", ast_channel_name(chan));
8467 pri_grab(p, p->pri);
8468 sig_pri_redirecting_update(p, chan);
8473 #if defined(HAVE_PRI_AOC_EVENTS)
8477 ast_debug(1,
"Received AST_CONTROL_AOC on %s\n", ast_channel_name(chan));
8478 if (decoded && p->pri) {
8479 pri_grab(p, p->pri);
8483 sig_pri_aoc_s_from_ast(p, decoded);
8488 sig_pri_aoc_d_from_ast(p, decoded);
8493 sig_pri_aoc_e_from_ast(p, decoded);
8504 "Received final AOC-E msg, continue with hangup on %s\n",
8505 ast_channel_name(chan));
8509 case AST_AOC_REQUEST:
8513 pri_hangup(p->pri->
pri, p->
call, -1);
8525 #if defined(HAVE_PRI_MCID)
8528 pri_grab(p, p->pri);
8529 pri_mcid_req_send(p->pri->
pri, p->
call);
8544 pri_grab(p, p->pri);
8545 #if defined(HAVE_PRI_AOC_EVENTS)
8550 pri_aoc_s_request_response_send(p->pri->
pri, p->
call,
8558 sig_pri_set_dialing(p, 0);
8559 sig_pri_open_media(p);
8560 res = pri_answer(p->pri->
pri, p->
call, 0, !p->digital);
8576 static int sig_pri_available_check(
struct sig_pri_chan *pvt)
8588 #if defined(HAVE_PRI_CALL_WAITING)
8614 for (idx = 0; idx < pri->
numchans; ++idx) {
8615 if (pri->
pvts[idx] && sig_pri_available_check(pri->
pvts[idx])) {
8621 idx = pri_find_empty_nobch(pri);
8624 cw = pri->
pvts[idx];
8626 sig_pri_init_config(cw, pri);
8634 int sig_pri_available(
struct sig_pri_chan **pvt,
int is_specific_channel)
8645 ast_mutex_lock(&pri->
lock);
8647 #
if defined(HAVE_PRI_CALL_WAITING)
8656 sig_pri_available_check(p)) {
8658 ast_mutex_unlock(&pri->
lock);
8662 #if defined(HAVE_PRI_CALL_WAITING)
8663 if (!is_specific_channel) {
8666 cw = sig_pri_cw_available(pri);
8671 ast_mutex_unlock(&pri->
lock);
8676 ast_mutex_unlock(&pri->
lock);
8688 len = strlen(pvt->dialdest);
8689 if (len <
sizeof(pvt->dialdest) - 1) {
8690 ast_debug(1,
"Queueing digit '%c' since setup_ack not yet received\n",
8692 pvt->dialdest[len++] = digit;
8693 pvt->dialdest[len] =
'\0';
8695 ast_log(LOG_WARNING,
8696 "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
8697 pvt->pri->
span, digit);
8702 pri_grab(pvt, pvt->pri);
8703 pri_information(pvt->pri->
pri, pvt->
call, digit);
8708 ast_log(LOG_WARNING,
8709 "Span %d: Digit '%c' may be ignored by peer. (Call level:%u(%s))\n",
8732 sig_pri_open_media(pvt);
8743 sig_pri_set_dialing(pvt, 0);
8745 sig_pri_set_echocanceller(pvt, 1);
8749 #if defined(HAVE_PRI_MWI)
8761 static void sig_pri_send_mwi_indication(
struct sig_pri_span *pri,
const char *vm_number,
const char *vm_box,
const char *mbox_id,
int num_messages)
8763 struct pri_party_id voicemail;
8764 struct pri_party_id mailbox;
8766 ast_debug(1,
"Send MWI indication for %s(%s) vm_number:%s num_messages:%d\n",
8767 vm_box, mbox_id,
S_OR(vm_number,
"<not-present>"), num_messages);
8769 memset(&mailbox, 0,
sizeof(mailbox));
8770 mailbox.number.valid = 1;
8771 mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8772 mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8773 ast_copy_string(mailbox.number.str, vm_box,
sizeof(mailbox.number.str));
8775 memset(&voicemail, 0,
sizeof(voicemail));
8776 voicemail.number.valid = 1;
8777 voicemail.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
8778 voicemail.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
8780 ast_copy_string(voicemail.number.str, vm_number,
sizeof(voicemail.number.str));
8783 ast_mutex_lock(&pri->
lock);
8784 #if defined(HAVE_PRI_MWI_V2)
8785 pri_mwi_indicate_v2(pri->
pri, &mailbox, &voicemail, 1 , num_messages,
8788 pri_mwi_indicate(pri->
pri, &mailbox, 1 , num_messages, NULL, NULL, -1, 0);
8790 ast_mutex_unlock(&pri->
lock);
8794 #if defined(HAVE_PRI_MWI)
8816 for (idx = 0; idx < ARRAY_LEN(pri->
mbox); ++idx) {
8832 #if defined(HAVE_PRI_MWI)
8840 static void sig_pri_mwi_cache_update(
struct sig_pri_span *pri)
8845 for (idx = 0; idx < ARRAY_LEN(pri->
mbox); ++idx) {
8874 #if defined(HAVE_PRI_MWI)
8878 #if defined(HAVE_PRI_MWI)
8879 for (idx = 0; idx < ARRAY_LEN(pri->
mbox); ++idx) {
8899 static int sig_pri_cmp_pri_chans(
const void *left,
const void *right)
8930 static void sig_pri_sort_pri_chans(
struct sig_pri_span *pri)
8932 qsort(&pri->
pvts, pri->
numchans,
sizeof(pri->
pvts[0]), sig_pri_cmp_pri_chans);
8939 #if defined(HAVE_PRI_MWI)
8941 char *prev_vm_number;
8944 #if defined(HAVE_PRI_MWI)
8946 for (i = 0; i < ARRAY_LEN(pri->
mbox); ++i) {
8953 ast_mutex_init(&pri->
lock);
8954 sig_pri_sort_pri_chans(pri);
8956 #if defined(HAVE_PRI_MWI)
8961 prev_vm_number = NULL;
8963 for (i = 0; i < ARRAY_LEN(pri->
mbox); ++i) {
8966 vm_number = strsep(&saveptr,
",");
8970 if (ast_strlen_zero(vm_number)) {
8972 vm_number = prev_vm_number;
8975 prev_vm_number = vm_number;
8985 for (i = 0; i < ARRAY_LEN(pri->
mbox); ++i) {
8988 vm_box = strsep(&saveptr,
",");
8991 if (ast_strlen_zero(vm_box)) {
9003 for (i = 0; i < ARRAY_LEN(pri->
mbox); ++i) {
9006 mbox_id = strsep(&saveptr,
",");
9009 if (ast_strlen_zero(mbox_id)) {
9016 ast_debug(1,
"%s span %d MWI position %d disabled. vm_box:%s mbox_id:%s.\n",
9019 mbox_id ?:
"<missing>");
9025 ast_log(LOG_ERROR,
"%s span %d could not subscribe to MWI events for %s(%s).\n",
9028 #if defined(HAVE_PRI_MWI_V2)
9030 ast_log(LOG_WARNING,
"%s span %d MWI voicemail number for %s(%s) is empty.\n",
9038 if (pri->
fds[i] == -1) {
9051 #if defined(HAVE_PRI_SERVICE_MESSAGES)
9053 pri_set_service_message_support(pri->
dchans[i], 1);
9059 pri_set_overlapdial(pri->
dchans[i], (pri->
overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
9060 #ifdef HAVE_PRI_PROG_W_CAUSE
9063 #ifdef HAVE_PRI_INBANDDISCONNECT
9070 if (pri->
fds[i] > 0)
9073 ast_log(LOG_ERROR,
"Unable to create PRI structure\n");
9078 #ifdef PRI_GETSET_TIMERS
9079 for (x = 0; x < PRI_MAX_TIMERS; x++) {
9080 if (pri->pritimers[x] != 0)
9081 pri_set_timer(pri->
dchans[i], x, pri->pritimers[x]);
9089 #if defined(HAVE_PRI_CALL_HOLD)
9090 pri_hold_enable(pri->
pri, 1);
9092 #if defined(HAVE_PRI_CALL_REROUTING)
9093 pri_reroute_enable(pri->
pri, 1);
9095 #if defined(HAVE_PRI_HANGUP_FIX)
9096 pri_hangup_fix_enable(pri->
pri, 1);
9098 #if defined(HAVE_PRI_CCSS)
9099 pri_cc_enable(pri->
pri, 1);
9104 #if defined(HAVE_PRI_TRANSFER)
9105 pri_transfer_enable(pri->
pri, 1);
9107 #if defined(HAVE_PRI_AOC_EVENTS)
9108 pri_aoc_events_enable(pri->
pri, 1);
9110 #if defined(HAVE_PRI_CALL_WAITING)
9111 pri_connect_ack_enable(pri->
pri, 1);
9113 #if defined(HAVE_PRI_MCID)
9114 pri_mcid_enable(pri->
pri, 1);
9116 #if defined(HAVE_PRI_DISPLAY_TEXT)
9120 #if defined(HAVE_PRI_DATETIME_SEND)
9123 #if defined(HAVE_PRI_L2_PERSISTENCE)
9128 if (ast_pthread_create_background(&pri->
master, NULL, pri_dchannel, pri)) {
9132 if (pri->
fds[i] > 0)
9136 ast_log(LOG_ERROR,
"Unable to spawn D-channel: %s\n", strerror(errno));
9140 #if defined(HAVE_PRI_MWI)
9149 sig_pri_mwi_cache_update(pri);
9165 pri_grab(p, p->pri);
9166 sig_pri_set_alarm(p, !noalarm);
9168 if (pri_get_timer(p->pri->
pri, PRI_TIMER_T309) < 0) {
9171 pri_destroycall(p->pri->
pri, p->
call);
9178 sig_pri_span_devstate_changed(p->pri);
9224 #define SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n"
9225 #define SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s"
9226 void sig_pri_cli_show_channels_header(
int fd)
9228 ast_cli(fd, SIG_PRI_SC_HEADER,
"PRI",
"",
"B",
"Chan",
"Call",
"PRI",
"Channel");
9229 ast_cli(fd, SIG_PRI_SC_HEADER,
"Span",
"Chan",
"Chan",
"Idle",
"Level",
"Call",
"Name");
9232 void sig_pri_cli_show_channels(
int fd,
struct sig_pri_span *pri)
9238 ast_mutex_lock(&pri->
lock);
9239 for (idx = 0; idx < pri->
numchans; ++idx) {
9240 if (!pri->
pvts[idx]) {
9243 pvt = pri->
pvts[idx];
9244 sig_pri_lock_private(pvt);
9245 sig_pri_lock_owner(pri, idx);
9248 sig_pri_unlock_private(pvt);
9252 snprintf(line,
sizeof(line), SIG_PRI_SC_LINE,
9258 pvt->
call ?
"Yes" :
"No",
9259 pvt->owner ? ast_channel_name(pvt->owner) :
"");
9262 ast_channel_unlock(pvt->owner);
9264 sig_pri_unlock_private(pvt);
9266 ast_mutex_unlock(&pri->
lock);
9267 ast_cli(fd,
"%s\n", line);
9268 ast_mutex_lock(&pri->
lock);
9270 ast_mutex_unlock(&pri->
lock);
9273 static void build_status(
char *s,
size_t len,
int status,
int active)
9275 if (!s || len < 1) {
9278 snprintf(s, len,
"%s%s, %s",
9279 (status & DCHAN_NOTINALARM) ?
"" :
"In Alarm, ",
9280 (status & DCHAN_UP) ?
"Up" :
"Down",
9281 (active) ?
"Active" :
"Standby");
9284 void sig_pri_cli_show_spans(
int fd,
int span,
struct sig_pri_span *pri)
9291 ast_cli(fd,
"PRI span %d/%d: %s\n", span, x, status);
9296 void sig_pri_cli_show_span(
int fd,
int *dchannels,
struct sig_pri_span *pri)
9303 #ifdef PRI_DUMP_INFO_STR
9304 char *info_str = NULL;
9306 ast_cli(fd,
"%s D-channel: %d\n", pri_order(x), dchannels[x]);
9308 ast_cli(fd,
"Status: %s\n", status);
9309 ast_mutex_lock(&pri->
lock);
9310 #ifdef PRI_DUMP_INFO_STR
9311 info_str = pri_dump_info_str(pri->
pri);
9313 ast_cli(fd,
"%s", info_str);
9314 ast_std_free(info_str);
9317 pri_dump_info(pri->
pri);
9319 ast_mutex_unlock(&pri->
lock);
9320 ast_cli(fd,
"Overlap Recv: %s\n\n", (pri->
overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?
"Yes":
"No");
9326 int pri_send_keypad_facility_exec(
struct sig_pri_chan *p,
const char *digits)
9328 sig_pri_lock_private(p);
9330 if (!p->pri || !p->
call) {
9331 ast_debug(1,
"Unable to find pri or call on channel!\n");
9332 sig_pri_unlock_private(p);
9336 pri_grab(p, p->pri);
9337 pri_keypad_facility(p->pri->
pri, p->
call, digits);
9340 sig_pri_unlock_private(p);
9345 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)
9349 sig_pri_lock_private(p);
9351 if (!p->pri || !p->
call) {
9352 ast_debug(1,
"Unable to find pri or call on channel!\n");
9353 sig_pri_unlock_private(p);
9357 pri_grab(p, p->pri);
9358 res = pri_callrerouting_facility(p->pri->
pri, p->
call, destination, original, reason);
9361 sig_pri_unlock_private(p);
9366 #if defined(HAVE_PRI_SERVICE_MESSAGES)
9367 int pri_maintenance_bservice(
struct pri *pri,
struct sig_pri_chan *p,
int changestatus)
9369 int channel = PVT_TO_CHANNEL(p);
9370 int span = PRI_SPAN(channel);
9372 return pri_maintenance_service(pri, span, channel, changestatus);
9378 if (pchan->owner == oldchan) {
9379 pchan->owner = newchan;
9383 #if defined(HAVE_PRI_DISPLAY_TEXT)
9393 struct pri_subcmd_display_txt display;
9395 if (p->pri && p->pri->
pri) {
9397 display.length = strlen(display.text);
9398 display.char_set = 0;
9399 pri_grab(p, p->pri);
9400 pri_display_text(p->pri->
pri, p->
call, &display);
9406 #if defined(HAVE_PRI_CCSS)
9432 ast_mutex_lock(&pvt_chan->pri->
lock);
9433 cc_pvt->
pri = pvt_chan->pri;
9434 cc_pvt->
cc_id = pri_cc_available(pvt_chan->pri->
pri, pvt_chan->
call);
9435 ast_mutex_unlock(&pvt_chan->pri->
lock);
9436 if (cc_pvt->
cc_id == -1) {
9445 #if defined(HAVE_PRI_CCSS)
9474 #if defined(HAVE_PRI_CCSS)
9495 #if defined(HAVE_PRI_CCSS)
9519 const char *failed_msg;
9520 static const char *failed_to_send =
"Failed to send the CC request response.";
9521 static const char *not_accepted =
"The core declined the CC request.";
9524 ast_mutex_lock(&cc_pvt->
pri->
lock);
9542 res = pri_cc_req_rsp(cc_pvt->
pri->
pri, cc_pvt->
cc_id, status);
9546 failed_msg = failed_to_send;
9553 failed_msg = failed_to_send;
9555 failed_msg = not_accepted;
9561 ast_mutex_unlock(&cc_pvt->
pri->
lock);
9568 #if defined(HAVE_PRI_CCSS)
9589 ast_mutex_lock(&cc_pvt->
pri->
lock);
9590 pri_cc_status_req(cc_pvt->
pri->
pri, cc_pvt->
cc_id);
9591 ast_mutex_unlock(&cc_pvt->
pri->
lock);
9596 #if defined(HAVE_PRI_CCSS)
9624 ast_mutex_lock(&cc_pvt->
pri->
lock);
9625 pri_cc_stop_alerting(cc_pvt->
pri->
pri, cc_pvt->
cc_id);
9626 ast_mutex_unlock(&cc_pvt->
pri->
lock);
9631 #if defined(HAVE_PRI_CCSS)
9658 ast_mutex_lock(&cc_pvt->
pri->
lock);
9660 ast_mutex_unlock(&cc_pvt->
pri->
lock);
9665 #if defined(HAVE_PRI_CCSS)
9689 #if defined(HAVE_PRI_CCSS)
9714 ast_mutex_lock(&cc_pvt->
pri->
lock);
9715 pri_cc_remote_user_free(cc_pvt->
pri->
pri, cc_pvt->
cc_id);
9716 ast_mutex_unlock(&cc_pvt->
pri->
lock);
9721 #if defined(HAVE_PRI_CCSS)
9746 ast_mutex_lock(&cc_pvt->
pri->
lock);
9749 res = pri_cc_req_rsp(cc_pvt->
pri->
pri, cc_pvt->
cc_id, 2);
9754 ast_mutex_unlock(&cc_pvt->
pri->
lock);
9759 #if defined(HAVE_PRI_CCSS)
9770 static int sig_pri_cc_monitor_instance_hash_fn(
const void *obj,
const int flags)
9774 return monitor_instance->
core_id;
9778 #if defined(HAVE_PRI_CCSS)
9790 static int sig_pri_cc_monitor_instance_cmp_fn(
void *obj,
void *arg,
int flags)
9799 #if defined(HAVE_PRI_CCSS)
9839 ast_mutex_lock(&instance->
pri->
lock);
9840 res = pri_cc_req(instance->
pri->
pri, instance->
cc_id, cc_mode);
9841 ast_mutex_unlock(&instance->
pri->
lock);
9847 #if defined(HAVE_PRI_CCSS)
9866 ast_mutex_lock(&instance->
pri->
lock);
9867 pri_cc_status(instance->
pri->
pri, instance->
cc_id, 1);
9868 ast_mutex_unlock(&instance->
pri->
lock);
9874 #if defined(HAVE_PRI_CCSS)
9892 ast_mutex_lock(&instance->
pri->
lock);
9893 pri_cc_status(instance->
pri->
pri, instance->
cc_id, 0);
9894 ast_mutex_unlock(&instance->
pri->
lock);
9900 #if defined(HAVE_PRI_CCSS)
9936 ast_mutex_lock(&instance->
pri->
lock);
9937 pri_cc_status_req_rsp(instance->
pri->
pri, instance->
cc_id, cc_status);
9938 ast_mutex_unlock(&instance->
pri->
lock);
9944 #if defined(HAVE_PRI_CCSS)
9973 #if defined(HAVE_PRI_CCSS)
9989 instance = monitor_pvt;
10009 #if defined(HAVE_PRI_MCID)
10015 #if defined(HAVE_PRI_CCSS)
10018 sig_pri_cc_monitor_instance_hash_fn, NULL, sig_pri_cc_monitor_instance_cmp_fn);
10019 if (!sig_pri_cc_monitors) {
10032 #if defined(HAVE_PRI_CCSS)
10033 if (sig_pri_cc_monitors) {
10034 ao2_ref(sig_pri_cc_monitors, -1);
10035 sig_pri_cc_monitors = NULL;
10039 #if defined(HAVE_PRI_MCID)
int aoc_s_request_invoke_id
int max_call_waiting_calls
Number of extra outgoing calls to allow on a span before considering that span congested.
int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char *const debug,...)
Indicate that a failure has occurred on a specific monitor.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Struct containing info for an AMI event to send out.
Information needed to identify an endpoint in a call.
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
int presentation
Q.931 encoded presentation-indicator encoded field.
int dchan_logical_span[SIG_PRI_NUM_DCHANS]
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) ...
char user_tag[AST_MAX_EXTENSION *2]
User tag for party id's sent from this device driver.
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name, unsigned long time, enum ast_aoc_time_scale time_scale, unsigned long granularity_time, enum ast_aoc_time_scale granularity_time_scale, int step_function)
Add AOC-S duration rate entry.
Main Channel structure associated with a channel.
unsigned long display_flags_send
ast_device_state
Device States.
unsigned int alreadyhungup
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
char * str
Subscriber phone number (Malloced)
General Asterisk channel transcoding definitions.
unsigned int priexclusive
char keypad_digits[AST_MAX_EXTENSION]
Keypad digits that came in with the SETUP message.
int cc_qsig_signaling_link_req
void astman_append(struct mansession *s, const char *fmt,...)
Asterisk main include file. File version handling, generic pbx functions.
void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
DTMF dial string complete.
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
struct sig_pri_callback sig_pri_callbacks
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
struct ast_party_id priv_to
Call is redirecting to a new party (Sent to the caller) - private representation. ...
char * str
Subscriber phone number (Malloced)
char chan_name[AST_CHANNEL_NAME]
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
int reverse_charging_indication
Reverse charging indication.
static const char dahdi_db[]
The AstDB family.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
int ast_aoc_set_termination_request(struct ast_aoc_decoded *decoded)
Mark the AST_AOC_REQUEST message as a termination request.
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
unsigned int use_callingpres
struct ast_channel::@335 fds
struct ast_json * ast_json_party_id(struct ast_party_id *party)
Construct an ast_party_id as JSON.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
const char * vm_box
Mailbox number sent to span.
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.
int ast_cc_get_current_core_id(struct ast_channel *chan)
Get the core id for the current call.
int sig_pri_cc_agent_start_offer_timer(struct ast_cc_agent *agent)
Start the offer timer.
#define ast_channel_unref(c)
Decrease channel reference count.
struct ast_party_id priv_orig
Who originally redirected the call (Sent to the party the call is redirected toward) - private repres...
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
unsigned int use_callerid
char idleext[AST_MAX_EXTENSION]
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_party_name name
Subscriber name.
union ast_aoc_s_entry::@180 rate
Charge rate being applied.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
unsigned int hold_disconnect_transfer
TRUE if held calls are transferred on disconnect.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
struct ast_channel_snapshot * snapshot
char mwi_vm_boxes[SIG_PRI_MAX_MWI_VM_NUMBER_STR]
Comma separated list of mailbox numbers sent over ISDN span for MWI.
unsigned int transfer
TRUE if call transfer is enabled for the span.
unsigned int allow_call_waiting_calls
TRUE if we will allow incoming ISDN call waiting calls.
Interface header for PRI signaling module.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
int sig_pri_cc_monitor_status_rsp(struct ast_cc_monitor *monitor, enum ast_device_state devstate)
Status response to an ast_cc_monitor_status_request().
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int sig_pri_cc_agent_callee_available(struct ast_cc_agent *agent)
Alert the caller that it is time to try recalling.
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S flat rate entry.
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
struct ast_party_id priv_from
Who is redirecting the call (Sent to the party the call is redirected toward) - private representatio...
int ast_cc_agent_caller_busy(int core_id, const char *const debug,...)
Indicate that the caller is busy.
char idlecontext[AST_MAX_CONTEXT]
#define SRVST_TYPE_OOS
The out-of-service SERVICE state.
int ast_json_is_true(const struct ast_json *value)
Check if value is JSON true.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
const char * vm_number
Voicemail access controlling number sent to span.
int ast_cc_agent_status_response(int core_id, enum ast_device_state devstate)
Response with a caller's current status.
enum ast_aoc_total_type ast_aoc_get_total_type(struct ast_aoc_decoded *decoded)
get the type of total for a AOC-D message
int ast_cc_monitor_request_acked(int core_id, const char *const debug,...)
Indicate that an outbound entity has accepted our CC request.
unsigned int mcid_send
TRUE if allow sending MCID request on this span.
unsigned int aoc_s_request_invoke_id_valid
unsigned int hidecalleridname
int sig_pri_cc_agent_status_req(struct ast_cc_agent *agent)
Request the status of the agent's device.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
int ast_cc_monitor_party_b_free(int core_id)
Alert a caller that though the callee has become free, the caller himself is not and may not call bac...
int char_set
Character set the name is using.
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
Structure to pass both assignedid values to channel drivers.
unsigned int enable_service_message_support
unsigned int aoce_delayhangup
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
ast_channel_state
ast_channel states
char * str
Subscriber name (Malloced)
enum sig_pri_reset_state resetting
Channel reset/restart state.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
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_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
unsigned char valid
TRUE if the subaddress information is valid/present.
unsigned int no_b_channel
TRUE if this interface has no B channel. (call hold and call waiting)
The channel is not being RESTARTed.
int sig_pri_cc_agent_party_b_free(struct ast_cc_agent *agent)
Let the caller know that the callee has become free but that the caller cannot attempt to call back b...
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
uint8_t charging_type
Charging interval type.
unsigned short transfercapability
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
#define ast_strdup(str)
A wrapper for strdup()
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, enum ast_aoc_volume_unit volume_unit, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S volume rate entry.
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
ast_cc_agent_response_reason
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
int dchanavail[SIG_PRI_NUM_DCHANS]
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
generate AOC manager event for an AOC-S, AOC-D, or AOC-E msg
int ast_queue_cc_frame(struct ast_channel *chan, const char *const monitor_type, const char *const dialstring, enum ast_cc_service_type service, void *private_data)
Queue an AST_CONTROL_CC frame.
char * str
Malloced subaddress string.
int ast_cc_agent_accept_request(int core_id, const char *const debug,...)
Accept inbound CC request.
unsigned service_status
Active SRVST_DBKEY out-of-service status value.
char mwi_vm_numbers[SIG_PRI_MAX_MWI_VM_NUMBER_STR]
Comma separated list of voicemail access controlling numbers for MWI.
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.
int sig_pri_load(const char *cc_type_name)
Load the sig_pri submodule.
enum sig_pri_colp_signaling colp_send
int ast_cc_agent_recalling(int core_id, const char *const debug,...)
Tell the CC core that a caller is currently recalling.
void sig_pri_chan_delete(struct sig_pri_chan *doomed)
Delete the sig_pri private channel structure.
unsigned int inband_on_setup_ack
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
int code
enum AST_REDIRECTING_REASON value for redirection
unsigned char odd_even_indicator
TRUE if odd number of address signals.
int ast_cc_is_recall(struct ast_channel *chan, int *core_id, const char *const monitor_type)
Decide if a call to a particular channel is a CC recall.
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
struct sig_pri_span * pri
Asterisk span D channel control structure.
ast_cc_monitor_policies
The various possibilities for cc_monitor_policy values.
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
const struct ast_aoc_s_entry * ast_aoc_s_get_rate_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific AOC-S rate entry.
struct ast_frame_subclass subclass
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Blob of data associated with a channel.
unsigned int no_d_channels
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
void(* destroy_later)(struct sig_pri_span *pri)
struct ast_party_id orig
Who originally redirected the call (Sent to the party the call is redirected toward) ...
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
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 cc_qsig_signaling_link_rsp
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
struct ast_party_id id
Caller party ID.
void sig_pri_cc_agent_destructor(struct ast_cc_agent *agent)
Destroy private data on the agent.
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
Generic Advice of Charge encode and decode routines.
struct sig_pri_mbox mbox[SIG_PRI_MAX_MWI_MAILBOXES]
Active MWI mailboxes.
struct ast_mwi_subscriber * sub
MWI mailbox event subscription.
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
int ast_cc_agent_set_interfaces_chanvar(struct ast_channel *chan)
Set the first level CC_INTERFACES channel variable for a channel.
unsigned int inband_on_proceeding
int sig_pri_cc_monitor_unsuspend(struct ast_cc_monitor *monitor)
Unsuspend monitoring.
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
#define SRVST_DBKEY
Persistent Service State.
struct ast_party_redirecting_reason orig_reason
Reason for the redirection by the original party.
int ast_setup_cc_recall_datastore(struct ast_channel *chan, const int core_id)
Set up a CC recall datastore on a channel.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
Destroy the party subaddress contents.
#define ast_strdupa(s)
duplicate a string in memory from the stack
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.
enum sig_pri_call_level call_level
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
Determine if a private channel structure is available.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define AST_MAX_EXTENSION
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Caller Party information.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
int ast_cc_agent_caller_available(int core_id, const char *const debug,...)
Indicate that a previously unavailable caller has become available.
char internationalprefix[10]
char currency_name[AOC_CURRENCY_NAME_SIZE]
void sig_pri_cc_monitor_destructor(void *monitor_pvt)
Destroy PRI private data on the monitor.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
The channel is being RESTARTed.
#define ast_malloc(len)
A wrapper for malloc()
struct sig_pri_span * pri
int sig_pri_cc_agent_start_monitoring(struct ast_cc_agent *agent)
Begin monitoring a busy device.
#define ast_debug(level,...)
Log a DEBUG message.
const char * uniqueid
Mailbox uniqueid.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
void(*const ami_channel_event)(void *pvt, struct ast_channel *chan)
Post an AMI B channel association event.
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
void sig_pri_cc_agent_req_rsp(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
Response to a CC request.
AST_REDIRECTING_REASON
redirecting reason codes.
unsigned int holding_aoce
Core PBX routines and definitions.
unsigned int ast_aoc_get_currency_amount(struct ast_aoc_decoded *decoded)
get the currency amount for AOC-D and AOC-E messages
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)
Determine if layer 1 alarms are ignored.
#define AST_CC_GENERIC_MONITOR_TYPE
unsigned int use_callingpres
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
struct xfer_rsp_data * xfer_data
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
char moh_suggested[MAX_MUSICCLASS]
struct ast_party_subaddress subaddress
Subscriber subaddress.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
void sig_pri_stop_pri(struct sig_pri_span *pri)
Stop PRI span.
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_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
static struct ao2_container * sig_pri_cc_monitors
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.
Support for dynamic strings.
unsigned int force_restart_unavailable_chans
TRUE if forcing RESTART when receive cause 44 on this span.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define ao2_unlink(container, obj)
Remove an object from a container.
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
void sig_pri_unload(void)
Unload the sig_pri submodule.
const struct ast_aoc_unit_entry * ast_aoc_get_unit_info(struct ast_aoc_decoded *decoded, unsigned int entry_number)
get a specific unit entry.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
int ani2
Automatic Number Identification 2 (Info Digits)
unsigned int inbanddisconnect
struct ast_cc_agent * ast_cc_agent_callback(int flags, ao2_callback_fn *function, void *arg, const char *const type)
Call a callback on all agents of a specific type.
#define SIG_PRI_NUM_DCHANS
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
Connected Line/Party information.
const ast_string_field name
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
struct sig_pri_chan * pvts[SIG_PRI_MAX_CHANNELS]
int ast_aoc_get_termination_request(struct ast_aoc_decoded *decoded)
get whether or not the AST_AOC_REQUEST message as a termination request.
char idledial[AST_MAX_EXTENSION]
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
uint32_t granularity_time
unsigned long display_flags_receive
enum ast_aoc_billing_id ast_aoc_get_billing_id(struct ast_aoc_decoded *decoded)
get the billing id for AOC-D and AOC-E messages
int ast_cc_monitor_status_request(int core_id)
Request the status of a caller or callers.
union ast_frame::@224 data
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)
Output AMI show spans response events for the given PRI span.
unsigned int hidecalleridname
#define ast_calloc(num, len)
A wrapper for calloc()
int sig_pri_cc_agent_stop_ringing(struct ast_cc_agent *agent)
Request for an agent's phone to stop ringing.
unsigned int append_msn_to_user_tag
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
char initial_user_tag[AST_MAX_EXTENSION]
Initial user tag for party id's sent from this device driver.
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type)
Sets the type of total for a AOC-D message.
char mwi_mailboxes[SIG_PRI_MAX_MWI_MAILBOX_STR]
Comma separated list of mailboxes to indicate MWI.
void * ast_mwi_unsubscribe_and_join(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic, block until the final message is received, and then unsubscribe fr...
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
char currency_name[AOC_CURRENCY_NAME_SIZE]
const char * ast_aoc_get_currency_name(struct ast_aoc_decoded *decoded)
get the currency name for AOC-D and AOC-E messages
int ast_cc_request_is_within_limits(void)
Check if the incoming CC request is within the bounds set by the cc_max_requests configuration option...
char msn_list[AST_MAX_EXTENSION]
struct ast_party_redirecting_reason reason
Reason for the redirection.
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
unsigned char cc_request_response_pending
char deferred_digits[AST_MAX_EXTENSION]
Structure used to handle boolean flags.
const ast_string_field uniqueid
static const sig_pri_moh_fsm_state sig_pri_moh_fsm[SIG_PRI_MOH_STATE_NUM]
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
struct ast_frame ast_null_frame
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
enum ast_aoc_charge_type ast_aoc_get_charge_type(struct ast_aoc_decoded *decoded)
get the charging type for an AOC-D or AOC-E message
int sig_pri_cc_monitor_req_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
Request CCSS.
char * tag
User-set "tag".
int type
Q.931 subaddress type.
STASIS_MESSAGE_TYPE_DEFN_LOCAL(cdr_sync_message_type)
A message type used to synchronize with the CDR topic.
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
unsigned int is_call_waiting
TRUE if this is a call waiting call.
#define ast_channel_ref(c)
Increase channel reference count.
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
int sig_pri_cc_agent_init(struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
PRI CC agent initialization.
int count
Number of times the call was redirected.
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
Notify new alarm status.
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
void ast_party_id_invalidate(struct ast_party_id *id)
Invalidate all components of the given party id.
unsigned int priexclusive
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Peer may not be sending the expected RESTART ACKNOWLEDGE.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
void ast_party_subaddress_init(struct ast_party_subaddress *init)
Initialize the given subaddress structure.
int num_call_waiting_calls
Number of outstanding call waiting calls.
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
void sig_pri_sendtext(struct sig_pri_chan *p, const char *text)
Send display text.
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
int sig_pri_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
Cancel the running available timer.
Information needed to specify a number in a call.
struct ast_party_dialed::@206 number
Dialed/Called number.
int discardremoteholdretrieval
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
unsigned int use_callerid
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
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.
Abstract JSON element (object, array, string, int, ...).
static const char * sig_pri_cc_type_name
Options provided by main asterisk program.
unsigned int layer1_ignored
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id)
set the charging association id for an AST_AOC_E message
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
enum ast_aoc_type ast_aoc_get_msg_type(struct ast_aoc_decoded *decoded)
get the message type, AOC-D, AOC-E, or AOC Request
enum ast_frame_type frametype
void * private_data
Data that is private to a monitor technology.
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
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
unsigned char valid
TRUE if the name information is valid/present.
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
Information needed to specify a subaddress in a call.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
The structure that contains MWI state.
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
enum ast_cc_service_type service_offered
Say numbers and dates (maybe words one day too)
unsigned int ast_aoc_get_unit_count(struct ast_aoc_decoded *decoded)
get the number of unit entries for AOC-D and AOC-E messages
unsigned int allocated
TRUE when this channel is allocated.
struct ast_cc_monitor * ast_cc_get_monitor_by_recall_core_id(const int core_id, const char *const device_name)
Get the associated monitor given the device name and core_id.
struct pri * dchans[SIG_PRI_NUM_DCHANS]
unsigned int no_dialed_digits
#define SRVST_NEAREND
SRVST_NEAREND is used to indicate that the near end was put out-of-service.
#define SIG_PRI_DEBUG_DEFAULT
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
int sig_pri_cc_agent_stop_offer_timer(struct ast_cc_agent *agent)
Stop the offer timer.
int ast_cc_monitor_stop_ringing(int core_id)
Alert a caller to stop ringing.
void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
Extract the called number and subaddress from the dial string.
Persistent data storage (akin to *doze registry)
Information needed to specify a name in a call.
void(* module_unref)(void)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int datetime_send
Configured date/time ie send policy option.
unsigned int waiting_for_aoce
unsigned char valid
TRUE if the number information is valid/present.
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
char exten[AST_MAX_EXTENSION]
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 fds[SIG_PRI_NUM_DCHANS]
int sig_pri_cc_monitor_suspend(struct ast_cc_monitor *monitor)
Suspend monitoring.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define SRVST_FAREND
SRVST_FAREND is used to indicate that the far end was taken out-of-service.
#define AST_APP_ARG(name)
Define an application argument.
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 sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rdest, int timeout, int layer1)
const struct ast_aoc_charging_association * ast_aoc_get_association_info(struct ast_aoc_decoded *decoded)
get the charging association info for AOC-E messages
struct ast_party_number number
Subscriber phone number.
#define ao2_link(container, obj)
Add an object to a container.