38 #include <netinet/in.h>
65 #include "asterisk/stasis_channels.h"
67 #include "asterisk/features_config.h"
68 #include "asterisk/max_forwards.h"
663 static const char app[] =
"Dial";
664 static const char rapp[] =
"RetryDial";
667 OPT_ANNOUNCE = (1 << 0),
668 OPT_RESETCDR = (1 << 1),
669 OPT_DTMF_EXIT = (1 << 2),
670 OPT_SENDDTMF = (1 << 3),
671 OPT_FORCECLID = (1 << 4),
672 OPT_GO_ON = (1 << 5),
673 OPT_CALLEE_HANGUP = (1 << 6),
674 OPT_CALLER_HANGUP = (1 << 7),
675 OPT_ORIGINAL_CLID = (1 << 8),
676 OPT_DURATION_LIMIT = (1 << 9),
677 OPT_MUSICBACK = (1 << 10),
678 OPT_SCREEN_NOINTRO = (1 << 12),
679 OPT_SCREEN_NOCALLERID = (1 << 13),
680 OPT_IGNORE_CONNECTEDLINE = (1 << 14),
681 OPT_SCREENING = (1 << 15),
682 OPT_PRIVACY = (1 << 16),
683 OPT_RINGBACK = (1 << 17),
684 OPT_DURATION_STOP = (1 << 18),
685 OPT_CALLEE_TRANSFER = (1 << 19),
686 OPT_CALLER_TRANSFER = (1 << 20),
687 OPT_CALLEE_MONITOR = (1 << 21),
688 OPT_CALLER_MONITOR = (1 << 22),
689 OPT_GOTO = (1 << 23),
690 OPT_OPERMODE = (1 << 24),
691 OPT_CALLEE_PARK = (1 << 25),
692 OPT_CALLER_PARK = (1 << 26),
693 OPT_IGNORE_FORWARDING = (1 << 27),
694 OPT_CALLEE_GOSUB = (1 << 28),
695 OPT_CALLEE_MIXMONITOR = (1 << 29),
696 OPT_CALLER_MIXMONITOR = (1 << 30),
700 #define DIAL_STILLGOING (1LLU << 31)
701 #define DIAL_NOFORWARDHTML (1LLU << 32)
702 #define DIAL_CALLERID_ABSENT (1LLU << 33)
703 #define OPT_CANCEL_ELSEWHERE (1LLU << 34)
704 #define OPT_PEER_H (1LLU << 35)
705 #define OPT_CALLEE_GO_ON (1LLU << 36)
706 #define OPT_CANCEL_TIMEOUT (1LLU << 37)
707 #define OPT_FORCE_CID_TAG (1LLU << 38)
708 #define OPT_FORCE_CID_PRES (1LLU << 39)
709 #define OPT_CALLER_ANSWER (1LLU << 40)
710 #define OPT_PREDIAL_CALLEE (1LLU << 41)
711 #define OPT_PREDIAL_CALLER (1LLU << 42)
712 #define OPT_RING_WITH_EARLY_MEDIA (1LLU << 43)
713 #define OPT_HANGUPCAUSE (1LLU << 44)
714 #define OPT_HEARPULSING (1LLU << 45)
715 #define OPT_TOPOLOGY_PRESERVE (1LLU << 46)
718 OPT_ARG_ANNOUNCE = 0,
721 OPT_ARG_DURATION_LIMIT,
724 OPT_ARG_CALLEE_GOSUB,
725 OPT_ARG_CALLEE_GO_ON,
727 OPT_ARG_DURATION_STOP,
729 OPT_ARG_SCREEN_NOINTRO,
730 OPT_ARG_ORIGINAL_CLID,
732 OPT_ARG_FORCE_CID_TAG,
733 OPT_ARG_FORCE_CID_PRES,
734 OPT_ARG_PREDIAL_CALLEE,
735 OPT_ARG_PREDIAL_CALLER,
787 #define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
788 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
789 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | \
790 OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_GOSUB) && \
791 !ast_channel_audiohooks(chan) && !ast_channel_audiohooks(peer) && \
792 ast_framehook_list_is_empty(ast_channel_framehooks(chan)) && ast_framehook_list_is_empty(ast_channel_framehooks(peer)))
820 static void topology_ds_destroy(
void *data) {
826 .
type =
"app_dial_topology_preserve",
827 .destroy = topology_ds_destroy,
830 static int detect_disconnect(
struct ast_channel *chan,
char code,
struct ast_str **featurecode);
840 static void hanguptree(
struct dial_head *out_chans,
struct ast_channel *exception,
int hangupcause)
847 if (outgoing->chan && (outgoing->chan != exception)) {
848 if (hangupcause >= 0) {
850 ast_channel_hangupcause_set(outgoing->chan, hangupcause);
854 chanlist_free(outgoing);
858 #define AST_MAX_WATCHERS 256
870 static void handle_cause(
int cause,
struct cause_args *num)
876 case AST_CAUSE_CONGESTION:
879 case AST_CAUSE_NO_ROUTE_DESTINATION:
880 case AST_CAUSE_UNREGISTERED:
883 case AST_CAUSE_NO_ANSWER:
884 case AST_CAUSE_NORMAL_CLEARING:
894 char rexten[2] = {
exten,
'\0' };
907 static const char *get_cid_name(
char *
name,
int namelen,
struct ast_channel *chan)
912 ast_channel_lock(chan);
915 ast_channel_unlock(chan);
917 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name :
"";
938 struct ast_flags64 *peerflags,
int single,
int caller_entertained,
int *to,
952 ast_copy_string(tmpchan, ast_channel_call_forward(c),
sizeof(tmpchan));
953 if ((stuff = strchr(tmpchan,
'/'))) {
957 const char *forward_context;
960 if (ast_strlen_zero(forward_context)) {
961 forward_context = NULL;
963 snprintf(tmpchan,
sizeof(tmpchan),
"%s@%s", ast_channel_call_forward(c), forward_context ? forward_context : ast_channel_context(c));
964 ast_channel_unlock(c);
968 if (!strcasecmp(tech,
"Local")) {
974 ast_clear_flag64(o, OPT_IGNORE_CONNECTEDLINE);
978 ast_verb(3,
"Now forwarding %s to '%s/%s' (thanks to %s)\n", ast_channel_name(in), tech, stuff, ast_channel_name(c));
980 if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
981 ast_verb(3,
"Forwarding %s to '%s/%s' prevented.\n", ast_channel_name(in), tech, stuff);
983 ast_channel_call_forward(original));
985 cause = AST_CAUSE_BUSY;
989 ast_channel_lock(in);
991 ast_channel_unlock(in);
999 if (single && !caller_entertained) {
1006 ast_max_forwards_decrement(o->chan);
1007 ast_channel_unlock(in);
1008 ast_channel_unlock(o->chan);
1014 ast_verb(3,
"Not accepting call completion offers from call-forward recipient %s\n",
1015 ast_channel_name(o->chan));
1018 "Forwarding failed to create channel to dial '%s/%s' (cause = %d)\n",
1019 tech, stuff, cause);
1023 ast_clear_flag64(o, DIAL_STILLGOING);
1024 handle_cause(cause, num);
1029 ast_channel_redirecting(original));
1030 ast_channel_unlock(c);
1031 ast_channel_unlock(original);
1035 if (single && !caller_entertained && CAN_EARLY_BRIDGE(peerflags, c, in)) {
1039 if (!ast_channel_redirecting(c)->from.number.valid
1040 || ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
1056 if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
1057 caller.
id = *stored_clid;
1059 ast_set_flag64(o, DIAL_CALLERID_ABSENT);
1060 }
else if (ast_strlen_zero(
S_COR(ast_channel_caller(c)->
id.
number.valid,
1061 ast_channel_caller(c)->
id.
number.str, NULL))) {
1066 caller.
id = *stored_clid;
1068 ast_set_flag64(o, DIAL_CALLERID_ABSENT);
1070 ast_clear_flag64(o, DIAL_CALLERID_ABSENT);
1074 if (ast_test_flag64(o, OPT_FORCECLID)) {
1078 connected.
id = *forced_clid;
1086 ast_channel_appl_set(c,
"AppDial");
1087 ast_channel_data_set(c,
"(Outgoing Line)");
1090 ast_channel_unlock(in);
1091 if (single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1102 ast_channel_unlock(c);
1108 ast_channel_unlock(c);
1111 if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
1116 ast_log(LOG_NOTICE,
"Forwarding failed to dial '%s/%s'\n",
1119 ast_clear_flag64(o, DIAL_STILLGOING);
1126 ast_channel_call_forward(original));
1133 if (single && !caller_entertained) {
1144 char privintro[1024];
1153 if (!outgoing->chan || outgoing->chan == exception) {
1169 static void update_connected_line_from_peer(
struct ast_channel *chan,
struct ast_channel *peer,
int is_caller)
1175 ast_channel_lock(peer);
1177 ast_channel_unlock(peer);
1189 static void set_duration_var(
struct ast_channel *chan,
const char *var_base, int64_t duration)
1192 char full_var_name[128];
1194 snprintf(buf,
sizeof(buf),
"%" PRId64, duration / 1000);
1197 snprintf(full_var_name,
sizeof(full_var_name),
"%s_MS", var_base);
1198 snprintf(buf,
sizeof(buf),
"%" PRId64, duration);
1206 const struct cause_args *num_in,
int *result,
char *dtmf_progress,
1207 char *mf_progress,
char *mf_wink,
1208 char *sf_progress,
char *sf_wink,
1209 const int hearpulsing,
1210 const int ignore_cc,
1215 int prestart = num.busy + num.congestion + num.nochan;
1216 int orig_answer_to = *to_answer;
1217 int progress_to_dup = *to_progress;
1218 int orig_progress_to = *to_progress;
1223 int caller_entertained = outgoing
1224 && ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
1225 struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
1226 int cc_recall_core_id;
1228 int cc_frame_received = 0;
1229 int num_ringing = 0;
1231 int sent_progress = 0, sent_wink = 0;
1233 SCOPE_ENTER(3,
"%s\n", ast_channel_name(in));
1237 if (!caller_entertained) {
1247 strcpy(pa->status,
"CONGESTION");
1249 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: can't be made compat with %s\n",
1250 ast_channel_name(in), ast_channel_name(outgoing->chan));
1254 if (!ast_test_flag64(outgoing, OPT_IGNORE_CONNECTEDLINE)
1255 && !ast_test_flag64(outgoing, DIAL_CALLERID_ABSENT)) {
1256 update_connected_line_from_peer(in, outgoing->chan, 1);
1265 int numlines = prestart;
1269 watchers[pos++] = in;
1272 if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
1273 watchers[pos++] = o->chan;
1277 if (numlines == (num.busy + num.congestion + num.nochan)) {
1278 ast_verb(2,
"Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1280 strcpy(pa->status,
"BUSY");
1281 else if (num.congestion)
1282 strcpy(pa->status,
"CONGESTION");
1283 else if (num.nochan)
1284 strcpy(pa->status,
"CHANUNAVAIL");
1286 ast_verb(3,
"No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
1290 ast_cc_failed(cc_recall_core_id,
"Everyone is busy/congested for the recall. How sad");
1292 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: No outgoing channels available\n", ast_channel_name(in));
1304 ast_verb(3,
"%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1311 update_connected_line_from_peer(in, c, 1);
1312 }
else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1317 }
else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1318 update_connected_line_from_peer(in, c, 1);
1321 if (o->aoc_s_rate_list) {
1322 size_t encoded_size;
1324 if ((encoded =
ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1330 publish_dial_end_event(in, out_chans, peer,
"CANCEL");
1331 ast_copy_flags64(peerflags, o,
1332 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1333 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1334 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1335 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1336 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1337 DIAL_NOFORWARDHTML);
1338 ast_channel_dialcontext_set(c,
"");
1339 ast_channel_exten_set(c,
"");
1346 if (!ast_strlen_zero(ast_channel_call_forward(c))) {
1347 pa->sentringing = 0;
1348 if (!ignore_cc && (f =
ast_read(c))) {
1366 ast_channel_lock(in);
1368 ast_channel_unlock(in);
1371 do_forward(o, &num, peerflags, single, caller_entertained, &orig_answer_to,
1372 forced_clid, stored_clid);
1378 && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)
1379 && !ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1380 update_connected_line_from_peer(in, o->chan, 1);
1387 ast_channel_hangupcause_set(in, ast_channel_hangupcause(c));
1391 ast_clear_flag64(o, DIAL_STILLGOING);
1392 handle_cause(ast_channel_hangupcause(in), &num);
1401 ast_trace(-1,
"%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1402 ast_verb(3,
"%s answered %s\n", ast_channel_name(c), ast_channel_name(in));
1409 update_connected_line_from_peer(in, c, 1);
1410 }
else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1415 }
else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
1416 update_connected_line_from_peer(in, c, 1);
1419 if (o->aoc_s_rate_list) {
1420 size_t encoded_size;
1422 if ((encoded =
ast_aoc_encode(o->aoc_s_rate_list, &encoded_size, o->chan))) {
1435 ast_trace(-1,
"%s Found topology in frame: %p %p %s\n",
1444 publish_dial_end_event(in, out_chans, peer,
"CANCEL");
1445 ast_copy_flags64(peerflags, o,
1446 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1447 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1448 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1449 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1450 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1451 DIAL_NOFORWARDHTML);
1452 ast_channel_dialcontext_set(c,
"");
1453 ast_channel_exten_set(c,
"");
1454 if (CAN_EARLY_BRIDGE(peerflags, in, peer)) {
1460 ast_channel_hangupcause_set(in, AST_CAUSE_NORMAL_CLEARING);
1461 ast_channel_hangupcause_set(c, AST_CAUSE_NORMAL_CLEARING);
1464 ast_verb(3,
"%s is busy\n", ast_channel_name(c));
1465 ast_channel_hangupcause_set(in, ast_channel_hangupcause(c));
1469 ast_clear_flag64(o, DIAL_STILLGOING);
1470 handle_cause(AST_CAUSE_BUSY, &num);
1473 ast_verb(3,
"%s is circuit-busy\n", ast_channel_name(c));
1474 ast_channel_hangupcause_set(in, ast_channel_hangupcause(c));
1478 ast_clear_flag64(o, DIAL_STILLGOING);
1479 handle_cause(AST_CAUSE_CONGESTION, &num);
1509 progress_to_dup = -1;
1510 if (ignore_cc || cc_frame_received || num_ringing == numlines) {
1511 ast_verb(3,
"%s is ringing\n", ast_channel_name(c));
1513 if (single && !caller_entertained
1514 && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1517 if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK) && ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
1522 struct timeval now, then;
1527 ast_channel_lock(in);
1530 then = ast_channel_creationtime(c);
1532 set_duration_var(in,
"RINGTIME", diff);
1535 ast_channel_unlock(in);
1542 ast_verb(3,
"%s is making progress passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1544 if (single && !caller_entertained
1545 && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1548 if (!ast_test_flag64(outgoing, OPT_RINGBACK)) {
1549 if (single || (!single && !pa->sentringing)) {
1554 progress_to_dup = -1;
1555 if (!sent_progress) {
1556 struct timeval now, then;
1561 ast_channel_lock(in);
1564 then = ast_channel_creationtime(c);
1566 set_duration_var(in,
"PROGRESSTIME", diff);
1569 ast_channel_unlock(in);
1572 if (!ast_strlen_zero(mf_progress)) {
1574 "Sending MF '%s' to %s as result of "
1575 "receiving a PROGRESS message.\n",
1576 mf_progress, hearpulsing ?
"parties" :
"called party");
1578 (hearpulsing ? in : NULL), mf_progress, 50, 55, 120, 65, 0);
1580 if (!ast_strlen_zero(sf_progress)) {
1582 "Sending SF '%s' to %s as result of "
1583 "receiving a PROGRESS message.\n",
1584 sf_progress, (hearpulsing ?
"parties" :
"called party"));
1586 (hearpulsing ? in : NULL), sf_progress, 0, 0);
1588 if (!ast_strlen_zero(dtmf_progress)) {
1590 "Sending DTMF '%s' to the called party as result of "
1591 "receiving a PROGRESS message.\n",
1596 ast_log(LOG_WARNING,
"Called channel %s hung up post-progress before all digits could be sent\n", ast_channel_name(c));
1603 ast_verb(3,
"%s winked, passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1606 if (!ast_strlen_zero(mf_wink)) {
1608 "Sending MF '%s' to %s as result of "
1609 "receiving a WINK message.\n",
1610 mf_wink, (hearpulsing ?
"parties" :
"called party"));
1612 (hearpulsing ? in : NULL), mf_wink, 50, 55, 120, 65, 0);
1614 if (!ast_strlen_zero(sf_wink)) {
1616 "Sending SF '%s' to %s as result of "
1617 "receiving a WINK message.\n",
1618 sf_wink, (hearpulsing ?
"parties" :
"called party"));
1620 (hearpulsing ? in : NULL), sf_wink, 0, 0);
1623 ast_log(LOG_WARNING,
"Called channel %s hung up post-wink before all digits could be sent\n", ast_channel_name(c));
1632 if (!single || caller_entertained) {
1635 ast_verb(3,
"%s requested media update control %d, passing it to %s\n",
1640 if (ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1641 ast_verb(3,
"Connected line update to %s prevented.\n", ast_channel_name(in));
1647 ast_verb(3,
"%s connected line has changed. Saving it until answer for %s\n",
1648 ast_channel_name(c), ast_channel_name(in));
1665 o->aoc_s_rate_list = decoded;
1679 if (ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1680 ast_verb(3,
"Redirecting update to %s prevented.\n", ast_channel_name(in));
1683 ast_verb(3,
"%s redirecting info has changed, passing it to %s\n",
1684 ast_channel_name(c), ast_channel_name(in));
1688 pa->sentringing = 0;
1691 ast_verb(3,
"%s is proceeding passing it to %s\n", ast_channel_name(c), ast_channel_name(in));
1692 if (single && !caller_entertained
1693 && CAN_EARLY_BRIDGE(peerflags, in, c)) {
1696 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1702 ast_verb(3,
"Call on %s placed on hold\n", ast_channel_name(c));
1707 ast_verb(3,
"Call on %s left from hold\n", ast_channel_name(c));
1717 cc_frame_received = 1;
1724 if (single && !caller_entertained) {
1725 ast_verb(3,
"%s stopped sounds\n", ast_channel_name(c));
1727 pa->sentringing = 0;
1740 if (caller_entertained) {
1744 progress_to_dup = -1;
1748 ast_log(LOG_WARNING,
"Unable to write frametype: %u\n",
1753 if (single && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)
1755 ast_log(LOG_WARNING,
"Unable to send URL\n");
1769 printf(
"Hangup received on %s\n", in->
name);
1774 strcpy(pa->status,
"CANCEL");
1776 publish_dial_end_event(in, out_chans, NULL, pa->status);
1778 if (f->
data.uint32) {
1779 ast_channel_hangupcause_set(in, f->
data.uint32);
1784 ast_cc_completed(in,
"CC completed, although the caller hung up (cancelled)");
1786 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Caller hung up\n", ast_channel_name(in));
1791 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1792 const char *context;
1793 ast_channel_lock(in);
1796 ast_verb(3,
"User hit %c to disconnect call.\n", f->
subclass.
integer);
1799 strcpy(pa->status,
"CANCEL");
1801 publish_dial_end_event(in, out_chans, NULL, pa->status);
1803 ast_channel_unlock(in);
1807 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Caller pressed %c to end call\n",
1810 ast_channel_unlock(in);
1813 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1815 ast_verb(3,
"User requested call disconnect.\n");
1817 strcpy(pa->status,
"CANCEL");
1819 publish_dial_end_event(in, out_chans, NULL, pa->status);
1824 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Caller requested disconnect\n",
1825 ast_channel_name(in));
1831 if (!o->chan || !ast_test_flag64(o, DIAL_STILLGOING)) {
1838 if (!ast_test_flag64(o, DIAL_NOFORWARDHTML)
1840 ast_log(LOG_WARNING,
"Unable to send URL\n");
1846 if (!single || caller_entertained) {
1859 ast_log(LOG_WARNING,
"Unable to forward frametype: %u\n",
1866 ast_verb(3,
"Call on %s placed on hold\n", ast_channel_name(o->chan));
1870 ast_verb(3,
"Call on %s left from hold\n", ast_channel_name(o->chan));
1874 ast_verb(3,
"Hook flash on %s\n", ast_channel_name(o->chan));
1880 if (!single || caller_entertained) {
1888 ast_verb(3,
"%s requested media update control %d, passing it to %s\n",
1889 ast_channel_name(in), f->
subclass.
integer, ast_channel_name(o->chan));
1893 if (ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1894 ast_verb(3,
"Connected line update to %s prevented.\n", ast_channel_name(o->chan));
1902 if (ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
1903 ast_verb(3,
"Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
1927 ast_verb(3,
"Nobody picked up in %d ms\n", orig_answer_to);
1928 publish_dial_end_event(in, out_chans, NULL,
"NOANSWER");
1929 }
else if (!*to_progress) {
1930 ast_verb(3,
"No early media received in %d ms\n", orig_progress_to);
1931 publish_dial_end_event(in, out_chans, NULL,
"CHANUNAVAIL");
1932 strcpy(pa->status,
"CHANUNAVAIL");
1939 SCOPE_EXIT_RTN_VALUE(peer,
"%s: %s%s\n", ast_channel_name(in),
1940 peer ?
"Answered by " :
"No answer", peer ? ast_channel_name(peer) :
"");
1943 static int detect_disconnect(
struct ast_channel *chan,
char code,
struct ast_str **featurecode)
1945 char disconnect_code[AST_FEATURE_MAX_LEN];
1950 res = ast_get_builtin_feature(chan,
"disconnect", disconnect_code,
sizeof(disconnect_code));
1973 static int valid_priv_reply(
struct ast_flags64 *opts,
int res)
1977 if (ast_test_flag64(opts, OPT_PRIVACY) && res <=
'5')
1979 if (ast_test_flag64(opts, OPT_SCREENING) && res <=
'4')
1999 if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2000 char *original_moh =
ast_strdupa(ast_channel_musicclass(chan));
2002 ast_channel_musicclass_set(chan, opt_args[OPT_ARG_MUSICBACK]);
2004 ast_channel_musicclass_set(chan, original_moh);
2005 }
else if (ast_test_flag64(opts, OPT_RINGBACK) || ast_test_flag64(opts, OPT_RING_WITH_EARLY_MEDIA)) {
2013 for (loopcount = 0; loopcount < 3; loopcount++) {
2014 if (res2 && loopcount == 0)
2018 if (!valid_priv_reply(opts, res2))
2025 if (!valid_priv_reply(opts, res2))
2030 if (ast_test_flag64(opts, OPT_PRIVACY))
2032 if (ast_test_flag64(opts, OPT_SCREENING))
2052 if (valid_priv_reply(opts, res2))
2058 if (ast_test_flag64(opts, OPT_MUSICBACK)) {
2060 }
else if (ast_test_flag64(opts, OPT_RINGBACK) || ast_test_flag64(opts, OPT_RING_WITH_EARLY_MEDIA)) {
2062 pa->sentringing = 0;
2065 if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >=
'1' && res2 <=
'5')) {
2067 static const char *
const _val[] = {
"ALLOW",
"DENY",
"TORTURE",
"KILL",
"ALLOW" };
2068 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
2070 ast_verb(3,
"--Set privacy database entry %s/%s to %s\n",
2071 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
2072 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
2087 if (ast_test_flag64(opts, OPT_PRIVACY)) {
2097 ast_verb(3,
"privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
2106 if (strncmp(pa->privcid,
"NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
2109 ast_log(LOG_NOTICE,
"privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
2111 ast_verb(3,
"Successfully deleted %s intro file\n", pa->privintro);
2127 if (ast_channel_caller(chan)->
id.
number.valid
2128 && !ast_strlen_zero(ast_channel_caller(chan)->
id.
number.str)) {
2131 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
2132 ast_verb(3,
"Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
2133 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
2135 ast_verb(3,
"Privacy Screening, clid is '%s'\n", l);
2136 pa->privdb_val = AST_PRIVACY_UNKNOWN;
2143 for (tn2 = tnam; *tn2; tn2++) {
2147 ast_verb(3,
"Privacy-- callerid is empty\n");
2149 snprintf(callerid,
sizeof(callerid),
"NOCALLERID_%s%s", ast_channel_exten(chan), tnam);
2151 pa->privdb_val = AST_PRIVACY_UNKNOWN;
2156 if (strncmp(pa->privcid,
"NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
2158 ast_verb(3,
"CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
2159 pa->privdb_val = AST_PRIVACY_ALLOW;
2160 }
else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid,
"NOCALLERID", 10) == 0) {
2161 ast_verb(3,
"CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
2164 if (pa->privdb_val == AST_PRIVACY_DENY) {
2165 ast_verb(3,
"Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
2168 }
else if (pa->privdb_val == AST_PRIVACY_KILL) {
2171 }
else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
2174 }
else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
2180 snprintf(pa->privintro,
sizeof(pa->privintro),
"%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
2181 if ((res =
ast_mkdir(pa->privintro, 0755))) {
2182 ast_log(LOG_WARNING,
"privacy: can't create directory priv-callerintros: %s\n", strerror(res));
2186 snprintf(pa->privintro,
sizeof(pa->privintro),
"priv-callerintros/%s", pa->privcid);
2187 if (
ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid,
"NOCALLERID", 10) != 0) {
2200 res =
ast_play_and_record(chan,
"priv-recordintro", pa->privintro, 4,
"sln", &duration, NULL, silencethreshold, 2000, 0);
2207 ast_log(LOG_NOTICE,
"privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
2209 ast_verb(3,
"Successfully deleted %s intro file\n", pa->privintro);
2212 if (!
ast_streamfile(chan,
"vm-dialout", ast_channel_language(chan)) )
2219 static void end_bridge_callback(
void *
data)
2223 ast_channel_lock(chan);
2228 ast_channel_unlock(chan);
2235 static int dial_handle_playtones(
struct ast_channel *chan,
const char *data)
2239 const char *str =
data;
2241 if (ast_strlen_zero(str)) {
2248 if (ts && ts->
data[0]) {
2259 ast_log(LOG_WARNING,
"Unable to start playtone \'%s\'\n", str);
2277 const char *context;
2281 if (ast_test_flag64(opts, OPT_PEER_H)) {
2282 ast_channel_lock(chan);
2284 ast_channel_unlock(chan);
2286 }
else if (ast_test_flag64(opts, OPT_CALLEE_GO_ON)) {
2287 ast_channel_lock(chan);
2290 priority = ast_channel_priority(chan);
2291 ast_channel_unlock(chan);
2293 opt_args[OPT_ARG_CALLEE_GO_ON]);
2305 int to_answer, to_progress;
2307 int cause, hanguptreecause = -1;
2310 struct timeval calldurationlimit = { 0, };
2311 char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress = NULL;
2312 char *mf_progress = NULL, *mf_wink = NULL;
2313 char *sf_progress = NULL, *sf_wink = NULL;
2317 .status =
"INVALIDARGS",
2320 int sentringing = 0, moh = 0;
2321 const char *outbound_group = NULL;
2325 int delprivintro = 0;
2333 char *opt_args[OPT_ARG_ARRAY_SIZE];
2334 int fulldial = 0, num_dialed = 0;
2339 int force_forwards_only;
2362 SCOPE_ENTER(1,
"%s: Data: %s\n", ast_channel_name(chan), data);
2365 ast_channel_lock(chan);
2379 max_forwards = ast_max_forwards_get(chan);
2380 ast_channel_unlock(chan);
2382 if (max_forwards <= 0) {
2383 ast_log(LOG_WARNING,
"Cannot place outbound call from channel '%s'. Max forwards exceeded\n",
2384 ast_channel_name(chan));
2386 SCOPE_EXIT_RTN_VALUE(-1,
"%s: Max forwards exceeded\n", ast_channel_name(chan));
2389 if (ast_check_hangup_locked(chan)) {
2402 ast_verb(3,
"Caller hung up before dial.\n");
2404 SCOPE_EXIT_RTN_VALUE(-1,
"%s: Caller hung up before dial\n", ast_channel_name(chan));
2411 if (!ast_strlen_zero(args.options) &&
2421 if (ast_test_flag64(&opts, OPT_SCREEN_NOINTRO) && !ast_strlen_zero(opt_args[OPT_ARG_SCREEN_NOINTRO])) {
2422 delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
2424 if (delprivintro < 0 || delprivintro > 1) {
2425 ast_log(LOG_WARNING,
"Unknown argument %d specified to n option, ignoring\n", delprivintro);
2430 if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
2431 opt_args[OPT_ARG_RINGBACK] = NULL;
2434 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
2435 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
2436 ast_verb(3,
"Setting operator services mode to %d.\n", opermode);
2439 if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
2440 calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
2441 if (!calldurationlimit.tv_sec) {
2442 ast_log(LOG_WARNING,
"Dial does not accept S(%s)\n", opt_args[OPT_ARG_DURATION_STOP]);
2446 ast_verb(3,
"Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
2449 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
2450 sf_wink = opt_args[OPT_ARG_SENDDTMF];
2451 dtmfcalled = strsep(&sf_wink,
":");
2452 dtmfcalling = strsep(&sf_wink,
":");
2453 dtmf_progress = strsep(&sf_wink,
":");
2454 mf_progress = strsep(&sf_wink,
":");
2455 mf_wink = strsep(&sf_wink,
":");
2456 sf_progress = strsep(&sf_wink,
":");
2459 if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
2466 force_forwards_only = 0;
2467 if (ast_test_flag64(&opts, OPT_FORCECLID)) {
2468 if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
2469 ast_channel_lock(chan);
2471 ast_channel_unlock(chan);
2472 forced_clid_name[0] =
'\0';
2473 forced_clid.
name.
str = (
char *) get_cid_name(forced_clid_name,
2474 sizeof(forced_clid_name), chan);
2475 force_forwards_only = 1;
2481 if (!ast_strlen_zero(forced_clid.
name.
str)) {
2484 if (!ast_strlen_zero(forced_clid.
number.
str)) {
2488 if (ast_test_flag64(&opts, OPT_FORCE_CID_TAG)
2489 && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG])) {
2490 forced_clid.
tag = opt_args[OPT_ARG_FORCE_CID_TAG];
2493 if (ast_test_flag64(&opts, OPT_FORCE_CID_PRES)
2494 && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES])) {
2505 if (ast_test_flag64(&opts, OPT_ORIGINAL_CLID)) {
2506 if (ast_strlen_zero(opt_args[OPT_ARG_ORIGINAL_CLID])) {
2507 ast_channel_lock(chan);
2509 if (!ast_strlen_zero(ast_channel_caller(chan)->
id.name.str)) {
2512 if (!ast_strlen_zero(ast_channel_caller(chan)->
id.
number.str)) {
2515 if (!ast_strlen_zero(ast_channel_caller(chan)->
id.subaddress.str)) {
2518 if (!ast_strlen_zero(ast_channel_caller(chan)->
id.tag)) {
2521 ast_channel_unlock(chan);
2526 if (!ast_strlen_zero(stored_clid.
name.
str)) {
2529 if (!ast_strlen_zero(stored_clid.
number.
str)) {
2538 stored_clid_name[0] =
'\0';
2539 stored_clid.
name.
str = (
char *) get_cid_name(stored_clid_name,
2540 sizeof(stored_clid_name), chan);
2541 if (ast_strlen_zero(stored_clid.
name.
str)) {
2546 ast_channel_lock(chan);
2549 ast_channel_unlock(chan);
2552 if (ast_test_flag64(&opts, OPT_RESETCDR)) {
2555 if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
2556 opt_args[OPT_ARG_PRIVACY] =
ast_strdupa(ast_channel_exten(chan));
2558 if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
2570 ast_channel_lock(chan);
2577 ast_channel_unlock(chan);
2580 ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID
2581 | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_CANCEL_TIMEOUT
2582 | OPT_ANNOUNCE | OPT_CALLEE_GOSUB | OPT_FORCECLID);
2585 if (ast_test_flag64(&opts, OPT_PREDIAL_CALLER)
2586 && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
2593 while ((cur = strsep(&rest,
"&"))) {
2604 if (ast_strlen_zero(cur)) {
2611 tech = strsep(&number,
"/");
2614 if (ast_strlen_zero(number)) {
2615 ast_log(LOG_WARNING,
"Dial argument takes format (technology/resource)\n");
2619 tech_len = strlen(tech) + 1;
2620 number_len = strlen(number) + 1;
2621 tmp =
ast_calloc(1,
sizeof(*tmp) + (2 * tech_len) + number_len);
2632 cur[tech_len - 1] =
'/';
2635 strcpy(cur, number);
2640 ast_copy_flags64(tmp, &opts,
2641 OPT_CANCEL_ELSEWHERE |
2642 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
2643 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
2644 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
2645 OPT_CALLEE_PARK | OPT_CALLER_PARK |
2646 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
2647 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID | OPT_IGNORE_CONNECTEDLINE |
2648 OPT_RING_WITH_EARLY_MEDIA);
2649 ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
2654 ast_channel_lock(chan);
2663 if (ast_test_flag64(&opts, OPT_TOPOLOGY_PRESERVE)) {
2666 if (!topology_ds && (topology_ds = ast_datastore_alloc(&topology_ds_info, NULL))) {
2674 topology = topology_ds->
data;
2679 ast_channel_unlock(chan);
2703 ast_log(LOG_NOTICE,
"Unable to create channel of type '%s' (cause %d - %s)\n",
2705 handle_cause(cause, &num);
2708 ast_channel_hangupcause_set(chan, cause);
2710 if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
2730 if (!
AST_LIST_FIRST(&out_chans) && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
2738 ast_max_forwards_decrement(tc);
2740 ast_channel_appl_set(tc,
"AppDial");
2741 ast_channel_data_set(tc,
"(Outgoing Line)");
2743 memset(ast_channel_whentohangup(tc), 0,
sizeof(*ast_channel_whentohangup(tc)));
2747 if (ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
2748 caller.
id = stored_clid;
2750 ast_set_flag64(tmp, DIAL_CALLERID_ABSENT);
2751 }
else if (ast_strlen_zero(
S_COR(ast_channel_caller(tc)->
id.number.valid,
2752 ast_channel_caller(tc)->
id.number.str, NULL))) {
2757 caller.
id = stored_clid;
2759 && !ast_strlen_zero(
S_COR(ast_channel_connected(chan)->
id.name.valid,
2760 ast_channel_connected(chan)->
id.name.str, NULL))) {
2769 ast_set_flag64(tmp, DIAL_CALLERID_ABSENT);
2770 }
else if (ast_strlen_zero(
S_COR(ast_channel_caller(tc)->
id.name.valid, ast_channel_caller(tc)->
id.name.str,
2773 if (!ast_strlen_zero(
S_COR(ast_channel_connected(chan)->
id.name.valid,
2774 ast_channel_connected(chan)->
id.name.str, NULL))) {
2786 if (ast_test_flag64(peerflags, OPT_FORCECLID) && !force_forwards_only) {
2790 connected.
id = forced_clid;
2801 if (ast_strlen_zero(ast_channel_musicclass(tc))) {
2802 ast_channel_musicclass_set(tc, ast_channel_musicclass(chan));
2806 ast_channel_adsicpe_set(tc, ast_channel_adsicpe(chan));
2807 ast_channel_transfercapability_set(tc, ast_channel_transfercapability(chan));
2813 if (ast_channel_hangupcause(chan) == AST_CAUSE_ANSWERED_ELSEWHERE)
2814 ast_channel_hangupcause_set(tc, AST_CAUSE_ANSWERED_ELSEWHERE);
2817 if (ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE))
2818 ast_channel_hangupcause_set(tc, AST_CAUSE_ANSWERED_ELSEWHERE);
2822 ast_channel_dialcontext_set(tc, ast_channel_context(chan));
2823 ast_channel_exten_set(tc, ast_channel_exten(chan));
2830 ast_channel_unlock(tc);
2831 ast_channel_unlock(chan);
2841 ast_verb(3,
"No devices or endpoints to dial (technology/resource)\n");
2842 if (continue_exec) {
2846 strcpy(pa.status,
"CHANUNAVAIL");
2863 if (ast_test_flag64(&opts, OPT_PREDIAL_CALLEE)
2864 && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLEE])
2866 const char *predial_callee;
2870 if (predial_callee) {
2876 ast_free((
char *) predial_callee);
2883 ast_channel_lock(chan);
2888 ast_debug(1,
"ast call on peer returned %d\n", res);
2889 ast_verb(3,
"Couldn't call %s\n", tmp->
interface);
2890 if (ast_channel_hangupcause(tmp->chan)) {
2891 ast_channel_hangupcause_set(chan, ast_channel_hangupcause(tmp->chan));
2893 ast_channel_unlock(chan);
2903 ast_channel_unlock(chan);
2905 ast_verb(3,
"Called %s\n", tmp->
interface);
2906 ast_set_flag64(tmp, DIAL_STILLGOING);
2915 if (ast_strlen_zero(args.timeout)) {
2919 char *anstimeout = strsep(&args.timeout,
"^");
2920 if (!ast_strlen_zero(anstimeout)) {
2921 to_answer = atoi(anstimeout);
2922 if (to_answer > 0) {
2925 ast_log(LOG_WARNING,
"Invalid answer timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2931 if (!ast_strlen_zero(args.timeout)) {
2932 to_progress = atoi(args.timeout);
2933 if (to_progress > 0) {
2934 to_progress *= 1000;
2936 ast_log(LOG_WARNING,
"Invalid progress timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
2946 strcpy(pa.status,
"CHANUNAVAIL");
2947 if (fulldial == num_dialed) {
2953 strcpy(pa.status,
"NOANSWER");
2954 if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
2956 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2957 char *original_moh =
ast_strdupa(ast_channel_musicclass(chan));
2958 ast_channel_musicclass_set(chan, opt_args[OPT_ARG_MUSICBACK]);
2960 ast_channel_musicclass_set(chan, original_moh);
2965 }
else if (ast_test_flag64(outgoing, OPT_RINGBACK) || ast_test_flag64(outgoing, OPT_RING_WITH_EARLY_MEDIA)) {
2966 if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
2967 if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
2980 peer =
wait_for_answer(chan, &out_chans, &to_answer, &to_progress, peerflags, opt_args, &pa, &num, &result,
2981 dtmf_progress, mf_progress, mf_wink, sf_progress, sf_wink,
2982 (ast_test_flag64(&opts, OPT_HEARPULSING) ? 1 : 0),
2983 ignore_cc, &forced_clid, &stored_clid, &config);
2988 }
else if (to_answer) {
2996 int dial_end_raised = 0;
2999 if (ast_test_flag64(&opts, OPT_CALLER_ANSWER)) {
3007 if (ast_test_flag64(&opts, OPT_HANGUPCAUSE)
3008 && !ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
3011 if (!strcasecmp(opt_args[OPT_ARG_HANGUPCAUSE],
"NONE")) {
3013 }
else if (sscanf(opt_args[OPT_ARG_HANGUPCAUSE],
"%30d", &cause) != 1
3015 ast_log(LOG_WARNING,
"Invalid cause given to Dial(...Q(<cause>)): \"%s\"\n",
3016 opt_args[OPT_ARG_HANGUPCAUSE]);
3021 hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
3025 ast_channel_lock(peer);
3029 if (ast_strlen_zero(number)) {
3034 ast_channel_unlock(peer);
3036 ast_channel_lock(chan);
3039 strcpy(pa.status,
"ANSWER");
3046 ast_channel_unlock(chan);
3049 ast_debug(1,
"app_dial: sendurl=%s.\n", args.url);
3052 if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
3053 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
3061 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
3067 char *calledfile = NULL, *callerfile = NULL;
3068 int calledstream = 0, callerstream = 0;
3074 callerfile = opt_args[OPT_ARG_ANNOUNCE];
3075 calledfile = strsep(&callerfile,
":");
3078 if (!ast_strlen_zero(calledfile)) {
3079 res =
ast_streamfile(peer, calledfile, ast_channel_language(peer));
3082 ast_log(LOG_ERROR,
"error streaming file '%s' to callee\n", calledfile);
3087 if (!ast_strlen_zero(callerfile)) {
3088 res =
ast_streamfile(chan, callerfile, ast_channel_language(chan));
3091 ast_log(LOG_ERROR,
"error streaming file '%s' to caller\n", callerfile);
3101 while (ast_channel_stream(peer) || ast_channel_stream(chan)) {
3108 if (mspeer < 0 && !ast_channel_timingfunc(peer)) {
3114 if (mschan < 0 && !ast_channel_timingfunc(chan)) {
3120 if (!calledstream && !callerstream) {
3131 active_chan =
ast_waitfor_n(chans, 2, (mspeer > mschan ? &mschan : &mspeer));
3144 if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
3158 if (active_chan == chan) {
3184 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
3192 ast_channel_lock(peer);
3195 ast_channel_context_set(peer, ast_channel_context(chan));
3196 ast_channel_exten_set(peer, ast_channel_exten(chan));
3197 ast_channel_priority_set(peer, ast_channel_priority(chan) + 2);
3199 ast_channel_unlock(peer);
3210 if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
3211 const char *gosub_result_peer;
3212 char *gosub_argstart;
3213 char *gosub_args = NULL;
3217 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB],
',');
3218 if (gosub_argstart) {
3219 const char *what_is_s =
"s";
3220 *gosub_argstart = 0;
3221 if (!
ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB],
"s", 1,
S_COR(ast_channel_caller(peer)->
id.number.valid, ast_channel_caller(peer)->
id.number.str, NULL)) &&
3222 ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB],
"~~s~~", 1,
S_COR(ast_channel_caller(peer)->
id.number.valid, ast_channel_caller(peer)->
id.number.str, NULL))) {
3223 what_is_s =
"~~s~~";
3225 if (
ast_asprintf(&gosub_args,
"%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
3228 *gosub_argstart =
',';
3230 const char *what_is_s =
"s";
3231 if (!
ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB],
"s", 1,
S_COR(ast_channel_caller(peer)->
id.number.valid, ast_channel_caller(peer)->
id.number.str, NULL)) &&
3232 ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB],
"~~s~~", 1,
S_COR(ast_channel_caller(peer)->
id.number.valid, ast_channel_caller(peer)->
id.number.str, NULL))) {
3233 what_is_s =
"~~s~~";
3235 if (
ast_asprintf(&gosub_args,
"%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
3241 ast_free(gosub_args);
3243 ast_log(LOG_ERROR,
"Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
3249 char *gosub_transfer_dest;
3250 char *gosub_result =
ast_strdupa(gosub_result_peer);
3258 ast_channel_unlock(peer);
3259 ast_channel_unlock(chan);
3261 if (!strcasecmp(gosub_result,
"BUSY")) {
3263 ast_set_flag64(peerflags, OPT_GO_ON);
3265 }
else if (!strcasecmp(gosub_result,
"CONGESTION") || !strcasecmp(gosub_result,
"CHANUNAVAIL")) {
3267 ast_set_flag64(peerflags, OPT_GO_ON);
3269 }
else if (!strcasecmp(gosub_result,
"CONTINUE")) {
3271 ast_set_flag64(peerflags, OPT_GO_ON);
3273 }
else if (!strcasecmp(gosub_result,
"ABORT")) {
3276 }
else if (!strncasecmp(gosub_result,
"GOTO:", 5)) {
3277 gosub_transfer_dest = gosub_result + 5;
3280 if (strchr(gosub_transfer_dest,
'^')) {
3284 ast_set_flag64(peerflags, OPT_GO_ON);
3289 if (!dial_end_raised) {
3291 dial_end_raised = 1;
3295 ast_channel_unlock(peer);
3296 ast_channel_unlock(chan);
3305 if (!dial_end_raised) {
3307 dial_end_raised = 1;
3312 ast_channel_lock(peer);
3314 ast_channel_unlock(peer);
3316 if (!ast_strlen_zero(dtmfcalled)) {
3317 ast_verb(3,
"Sending DTMF '%s' to the called party.\n", dtmfcalled);
3320 if (!ast_strlen_zero(dtmfcalling)) {
3321 ast_verb(3,
"Sending DTMF '%s' to the calling party.\n", dtmfcalling);
3328 ast_channel_hangupcause_set(chan, ast_channel_hangupcause(peer));
3330 setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3337 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
3338 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
3339 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
3340 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
3341 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
3342 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
3343 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
3344 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
3345 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
3346 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
3347 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
3348 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
3349 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
3350 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
3351 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
3352 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
3353 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
3354 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
3355 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
3356 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
3365 }
else if (sentringing) {
3371 ast_channel_visible_indication_set(chan, 0);
3375 ast_log(LOG_WARNING,
"Had to drop call because I couldn't make %s compatible with %s\n", ast_channel_name(chan), ast_channel_name(peer));
3383 oprmode.peer = peer;
3384 oprmode.mode = opermode;
3388 setup_peer_after_bridge_goto(chan, peer, &opts, opt_args);
3397 }
else if (sentringing) {
3402 if (delprivintro &&
ast_fileexists(pa.privintro, NULL, NULL) > 0) {
3405 ast_log(LOG_NOTICE,
"privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
3407 ast_verb(3,
"Successfully deleted %s intro file\n", pa.privintro);
3413 if (ast_channel_hangupcause(chan) == AST_CAUSE_ANSWERED_ELSEWHERE || ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE)) {
3414 hanguptreecause = AST_CAUSE_ANSWERED_ELSEWHERE;
3415 }
else if (pa.canceled) {
3416 if (ast_channel_hangupcause(chan))
3417 hanguptreecause = ast_channel_hangupcause(chan);
3419 hanguptreecause = AST_CAUSE_NORMAL_CLEARING;
3421 hanguptree(&out_chans, NULL, hanguptreecause);
3423 ast_debug(1,
"Exiting with DIALSTATUS=%s.\n", pa.status);
3427 memset(ast_channel_whentohangup(chan), 0,
sizeof(*ast_channel_whentohangup(chan)));
3433 ast_trace(2,
"%s Cleaning up topology: %p %s\n",
3434 peer ? ast_channel_name(peer) :
"<no channel>", &config.
answer_topology,
3444 if (config.warning_sound) {
3445 ast_free((
char *)config.warning_sound);
3447 if (config.end_sound) {
3448 ast_free((
char *)config.end_sound);
3450 if (config.start_sound) {
3451 ast_free((
char *)config.start_sound);
3454 SCOPE_EXIT_RTN_VALUE(res,
"%s: Done\n", ast_channel_name(chan));
3457 static int dial_exec(
struct ast_channel *chan,
const char *data)
3461 memset(&peerflags, 0,
sizeof(peerflags));
3466 static int retrydial_exec(
struct ast_channel *chan,
const char *data)
3469 const char *context = NULL;
3470 int sleepms = 0, loops = 0, res = -1;
3479 if (ast_strlen_zero(data)) {
3480 ast_log(LOG_WARNING,
"RetryDial requires an argument!\n");
3487 if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
3490 if (!ast_strlen_zero(args.retries)) {
3491 loops = atoi(args.retries);
3494 if (!args.dialdata) {
3495 ast_log(LOG_ERROR,
"%s requires a 4th argument (dialdata)\n", rapp);
3505 ast_channel_lock(chan);
3507 context = !ast_strlen_zero(context) ?
ast_strdupa(context) : NULL;
3508 ast_channel_unlock(chan);
3514 ast_channel_data_set(chan,
"Retrying");
3515 if (ast_test_flag(ast_channel_flags(chan),
AST_FLAG_MOH))
3518 res =
dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
3523 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
3524 if (!ast_strlen_zero(args.announce)) {
3525 if (
ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3526 if (!(res =
ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3529 ast_log(LOG_WARNING,
"Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3531 if (!res && sleepms) {
3532 if (!ast_test_flag(ast_channel_flags(chan),
AST_FLAG_MOH))
3537 if (!ast_strlen_zero(args.announce)) {
3538 if (
ast_fileexists(args.announce, NULL, ast_channel_language(chan)) > 0) {
3539 if (!(res =
ast_streamfile(chan, args.announce, ast_channel_language(chan))))
3542 ast_log(LOG_WARNING,
"Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
3545 if (!ast_test_flag(ast_channel_flags(chan),
AST_FLAG_MOH))
3555 }
else if (res > 0) {
3556 if (onedigit_goto(chan, context, (
char) res, 1)) {
3568 if (ast_test_flag(ast_channel_flags(chan),
AST_FLAG_MOH))
3574 static int unload_module(
void)
3584 static int load_module(
void)
3594 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,
"Dialing Application",
3595 .support_level = AST_MODULE_SUPPORT_CORE,
3596 .load = load_module,
3597 .unload = unload_module,
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
Bridge two channels together (early)
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 ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
int64_t ast_channel_get_duration_ms(struct ast_channel *chan)
Obtain how long it's been, in milliseconds, since the channel was created.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
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...
void ast_channel_whentohangup_set(struct ast_channel *chan, struct timeval *value)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
int ast_cc_failed(int core_id, const char *const debug,...)
Indicate failure has occurred.
unsigned int pending_connected_update
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
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...
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
struct ast_stream_topology * answer_topology
struct ast_party_id id
Connected party ID.
const char * ast_app_expand_sub_args(struct ast_channel *chan, const char *args)
Add missing context/exten to subroutine argument string.
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
Support for translation of data formats. translate.c.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
struct ast_party_name name
Subscriber name.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Indicate that the redirecting id has changed.
int64_t ast_channel_get_up_time_ms(struct ast_channel *chan)
Obtain how long it has been since the channel was answered in ms.
Convenient Signal Processing routines.
char context[AST_MAX_CONTEXT]
int ast_channel_supports_html(struct ast_channel *channel)
Checks for HTML support on a channel.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
Persistent data storage (akin to *doze registry)
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Structure for a data store type.
ast_channel_state
ast_channel states
char * str
Subscriber name (Malloced)
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
Bridge a call, optionally allowing redirection.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
const char * ast_hangup_cause_to_dial_status(int hangup_cause)
Convert a hangup cause to a publishable dial status.
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
char * str
Malloced subaddress string.
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Structure used to handle a large number of boolean flags == used only in app_dial?
int ast_unregister_application(const char *app)
Unregister an application.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define AST_MAX_WATCHERS
Maximum number of channels we can watch at a time.
void ast_bridge_set_after_h(struct ast_channel *chan, const char *context)
Set channel to run the h exten after the bridge.
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.
void ast_handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
Properly react to a CC control frame.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
void ast_cc_call_failed(struct ast_channel *incoming, struct ast_channel *outgoing, const char *const dialstring)
Make CCBS available in the case that ast_call fails.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
int ast_cc_completed(struct ast_channel *chan, const char *const debug,...)
Indicate recall has been acknowledged.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
const struct ast_channel_tech * tech
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
static struct callattempt * wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
Wait for a member to answer the call.
struct ast_party_id id
Caller party ID.
Configuration File Parser.
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
static int setup_privacy_args(struct privacy_args *pa, struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
returns 1 if successful, 0 or <0 if the caller should 'goto out'
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
void ast_cc_extension_monitor_add_dialstring(struct ast_channel *incoming, const char *const dialstring, const char *const device_name)
Add a child dialstring to an extension monitor.
Generic Advice of Charge encode and decode routines.
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
struct ast_aoc_decoded * ast_aoc_decode(struct ast_aoc_encoded *encoded, size_t size, struct ast_channel *chan)
decodes an encoded aoc payload.
General Asterisk PBX channel definitions.
Asterisk file paths, configured in asterisk.conf.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
#define ast_strdupa(s)
duplicate a string in memory from the stack
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
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
#define AST_MAX_EXTENSION
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel's redirecting information.
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
void * end_bridge_callback_data
Caller Party information.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
structure to hold extensions
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
int ast_cdr_reset(const char *channel_name, int keep_variables)
Reset the detail record.
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
struct ast_channel * ast_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel (specifying stream topology)
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Core PBX routines and definitions.
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
struct ast_party_connected_line connected
int ast_cc_callback(struct ast_channel *inbound, const char *const tech, const char *const dest, ast_cc_callback_fn callback)
Run a callback for potential matching destinations.
int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
Start the CC process on a call.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_PBX_INCOMPLETE
struct ast_party_subaddress subaddress
Subscriber subaddress.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
Parse connected line indication frame data.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
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.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel's connected line information...
Channel datastore data for max forwards.
void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
Set the connected line information based on another connected line source.
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Connected Line/Party information.
int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path)
Record a file based on input from a channel. Use default accept and cancel DTMF. This function will p...
const ast_string_field name
void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
Initialize the given party id structure using the given guide for a set update operation.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
int ast_channel_sendhtml(struct ast_channel *channel, int subclass, const char *data, int datalen)
Sends HTML on given channel Send HTML or URL on link.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
int ast_channel_sendurl(struct ast_channel *channel, const char *url)
Sends a URL on a given link Send URL on link.
int ast_sf_stream(struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, const char *digits, int frequency, int is_external)
Send a string of SF digits to a channel.
Set when the stream is sending media only.
union ast_frame::@224 data
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
#define ast_calloc(num, len)
A wrapper for calloc()
Call Completion Supplementary Services API.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
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_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
void(* end_bridge_callback)(void *)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
void ast_ignore_cc(struct ast_channel *chan)
Mark the channel to ignore further CC activity.
char * tag
User-set "tag".
void ast_deactivate_generator(struct ast_channel *chan)
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
int transit_network_select
Transit Network Select.
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
After Bridge Execution API.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
int ast_answer(struct ast_channel *chan)
Answer a channel.
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
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.
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
Data structure associated with a single frame of data.
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Internal Asterisk hangup causes.
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
const char * data
Description of a tone.
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
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
static void do_forward(struct chanlist *o, struct cause_args *num, struct ast_flags64 *peerflags, int single, int caller_entertained, int *to, struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
int ast_str2cause(const char *name) attribute_pure
Convert the string form of a cause code to a number.
unsigned char valid
TRUE if the name information is valid/present.
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
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...
Say numbers and dates (maybe words one day too)
#define ASTERISK_GPL_KEY
The text the key() function should return.
void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c_dst, struct ast_channel *c_src)
Make two channels compatible for early bridging.
Pluggable RTP Architecture.
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
int ast_mf_stream(struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
Send a string of MF digits to a channel.
struct ast_stream_topology * topology
Asterisk module definitions.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#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...
unsigned char valid
TRUE if the number information is valid/present.
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Set when the stream is receiving media only.
void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Set the connected line information in the Asterisk channel.
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
int ast_app_group_set_channel(struct ast_channel *chan, const char *data)
Set the group for a channel, splitting the provided data into group and category, if specified...
char exten[AST_MAX_EXTENSION]
int ast_stopstream(struct ast_channel *c)
Stops a stream.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
#define AST_APP_ARG(name)
Define an application argument.
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *config, char *parse, struct timeval *calldurationlimit)
parse L option and read associated channel variables to set warning, warning frequency, and timelimit
struct ast_party_number number
Subscriber phone number.