00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "asterisk.h"
00034
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 305253 $")
00036
00037 #include <sys/time.h>
00038 #include <sys/signal.h>
00039 #include <sys/stat.h>
00040 #include <netinet/in.h>
00041
00042 #include "asterisk/paths.h"
00043 #include "asterisk/lock.h"
00044 #include "asterisk/file.h"
00045 #include "asterisk/channel.h"
00046 #include "asterisk/pbx.h"
00047 #include "asterisk/module.h"
00048 #include "asterisk/translate.h"
00049 #include "asterisk/say.h"
00050 #include "asterisk/config.h"
00051 #include "asterisk/features.h"
00052 #include "asterisk/musiconhold.h"
00053 #include "asterisk/callerid.h"
00054 #include "asterisk/utils.h"
00055 #include "asterisk/app.h"
00056 #include "asterisk/causes.h"
00057 #include "asterisk/rtp.h"
00058 #include "asterisk/cdr.h"
00059 #include "asterisk/manager.h"
00060 #include "asterisk/privacy.h"
00061 #include "asterisk/stringfields.h"
00062 #include "asterisk/global_datastores.h"
00063 #include "asterisk/dsp.h"
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 static char *app = "Dial";
00466 static char *rapp = "RetryDial";
00467
00468 enum {
00469 OPT_ANNOUNCE = (1 << 0),
00470 OPT_RESETCDR = (1 << 1),
00471 OPT_DTMF_EXIT = (1 << 2),
00472 OPT_SENDDTMF = (1 << 3),
00473 OPT_FORCECLID = (1 << 4),
00474 OPT_GO_ON = (1 << 5),
00475 OPT_CALLEE_HANGUP = (1 << 6),
00476 OPT_CALLER_HANGUP = (1 << 7),
00477 OPT_DURATION_LIMIT = (1 << 9),
00478 OPT_MUSICBACK = (1 << 10),
00479 OPT_CALLEE_MACRO = (1 << 11),
00480 OPT_SCREEN_NOINTRO = (1 << 12),
00481 OPT_SCREEN_NOCLID = (1 << 13),
00482 OPT_ORIGINAL_CLID = (1 << 14),
00483 OPT_SCREENING = (1 << 15),
00484 OPT_PRIVACY = (1 << 16),
00485 OPT_RINGBACK = (1 << 17),
00486 OPT_DURATION_STOP = (1 << 18),
00487 OPT_CALLEE_TRANSFER = (1 << 19),
00488 OPT_CALLER_TRANSFER = (1 << 20),
00489 OPT_CALLEE_MONITOR = (1 << 21),
00490 OPT_CALLER_MONITOR = (1 << 22),
00491 OPT_GOTO = (1 << 23),
00492 OPT_OPERMODE = (1 << 24),
00493 OPT_CALLEE_PARK = (1 << 25),
00494 OPT_CALLER_PARK = (1 << 26),
00495 OPT_IGNORE_FORWARDING = (1 << 27),
00496 OPT_CALLEE_GOSUB = (1 << 28),
00497 OPT_CALLEE_MIXMONITOR = (1 << 29),
00498 OPT_CALLER_MIXMONITOR = (1 << 30),
00499 };
00500
00501 #define DIAL_STILLGOING (1 << 31)
00502 #define DIAL_NOFORWARDHTML ((uint64_t)1 << 32)
00503 #define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 33)
00504 #define OPT_PEER_H ((uint64_t)1 << 34)
00505 #define OPT_CALLEE_GO_ON ((uint64_t)1 << 35)
00506
00507 enum {
00508 OPT_ARG_ANNOUNCE = 0,
00509 OPT_ARG_SENDDTMF,
00510 OPT_ARG_GOTO,
00511 OPT_ARG_DURATION_LIMIT,
00512 OPT_ARG_MUSICBACK,
00513 OPT_ARG_CALLEE_MACRO,
00514 OPT_ARG_CALLEE_GOSUB,
00515 OPT_ARG_CALLEE_GO_ON,
00516 OPT_ARG_PRIVACY,
00517 OPT_ARG_DURATION_STOP,
00518 OPT_ARG_OPERMODE,
00519 OPT_ARG_SCREEN_NOINTRO,
00520
00521 OPT_ARG_ARRAY_SIZE,
00522 };
00523
00524 AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
00525 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
00526 AST_APP_OPTION('C', OPT_RESETCDR),
00527 AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
00528 AST_APP_OPTION('d', OPT_DTMF_EXIT),
00529 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
00530 AST_APP_OPTION('e', OPT_PEER_H),
00531 AST_APP_OPTION('f', OPT_FORCECLID),
00532 AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
00533 AST_APP_OPTION('g', OPT_GO_ON),
00534 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
00535 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
00536 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
00537 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
00538 AST_APP_OPTION('k', OPT_CALLEE_PARK),
00539 AST_APP_OPTION('K', OPT_CALLER_PARK),
00540 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
00541 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
00542 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
00543 AST_APP_OPTION_ARG('n', OPT_SCREEN_NOINTRO, OPT_ARG_SCREEN_NOINTRO),
00544 AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
00545 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
00546 AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
00547 AST_APP_OPTION('p', OPT_SCREENING),
00548 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
00549 AST_APP_OPTION('r', OPT_RINGBACK),
00550 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
00551 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
00552 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
00553 AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
00554 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
00555 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
00556 AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
00557 AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
00558 END_OPTIONS );
00559
00560 #define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
00561 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
00562 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | \
00563 OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB) && \
00564 !chan->audiohooks && !peer->audiohooks)
00565
00566
00567
00568
00569 struct chanlist {
00570 struct chanlist *next;
00571 struct ast_channel *chan;
00572 uint64_t flags;
00573 };
00574
00575
00576 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
00577 {
00578
00579 struct chanlist *oo;
00580 while (outgoing) {
00581
00582 if (outgoing->chan && (outgoing->chan != exception)) {
00583 if (answered_elsewhere) {
00584
00585 ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
00586
00587 outgoing->chan->hangupcause = AST_CAUSE_ANSWERED_ELSEWHERE;
00588 }
00589 ast_hangup(outgoing->chan);
00590 }
00591 oo = outgoing;
00592 outgoing = outgoing->next;
00593 ast_free(oo);
00594 }
00595 }
00596
00597 #define AST_MAX_WATCHERS 256
00598
00599
00600
00601
00602 struct cause_args {
00603 struct ast_channel *chan;
00604 int busy;
00605 int congestion;
00606 int nochan;
00607 };
00608
00609 static void handle_cause(int cause, struct cause_args *num)
00610 {
00611 struct ast_cdr *cdr = num->chan->cdr;
00612
00613 switch(cause) {
00614 case AST_CAUSE_BUSY:
00615 if (cdr)
00616 ast_cdr_busy(cdr);
00617 num->busy++;
00618 break;
00619
00620 case AST_CAUSE_CONGESTION:
00621 if (cdr)
00622 ast_cdr_failed(cdr);
00623 num->congestion++;
00624 break;
00625
00626 case AST_CAUSE_NO_ROUTE_DESTINATION:
00627 case AST_CAUSE_UNREGISTERED:
00628 if (cdr)
00629 ast_cdr_failed(cdr);
00630 num->nochan++;
00631 break;
00632
00633 case AST_CAUSE_NO_ANSWER:
00634 if (cdr) {
00635 ast_cdr_noanswer(cdr);
00636 }
00637 break;
00638 case AST_CAUSE_NORMAL_CLEARING:
00639 break;
00640
00641 default:
00642 num->nochan++;
00643 break;
00644 }
00645 }
00646
00647
00648 #define S_REPLACE(s, new_val) \
00649 do { \
00650 if (s) \
00651 ast_free(s); \
00652 s = (new_val); \
00653 } while (0)
00654
00655 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
00656 {
00657 char rexten[2] = { exten, '\0' };
00658
00659 if (context) {
00660 if (!ast_goto_if_exists(chan, context, rexten, pri))
00661 return 1;
00662 } else {
00663 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
00664 return 1;
00665 else if (!ast_strlen_zero(chan->macrocontext)) {
00666 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
00667 return 1;
00668 }
00669 }
00670 return 0;
00671 }
00672
00673
00674 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
00675 {
00676 const char *context = S_OR(chan->macrocontext, chan->context);
00677 const char *exten = S_OR(chan->macroexten, chan->exten);
00678
00679 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
00680 }
00681
00682 static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
00683 {
00684 manager_event(EVENT_FLAG_CALL, "Dial",
00685 "SubEvent: Begin\r\n"
00686 "Channel: %s\r\n"
00687 "Destination: %s\r\n"
00688 "CallerIDNum: %s\r\n"
00689 "CallerIDName: %s\r\n"
00690 "UniqueID: %s\r\n"
00691 "DestUniqueID: %s\r\n"
00692 "Dialstring: %s\r\n",
00693 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
00694 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
00695 dst->uniqueid, dialstring ? dialstring : "");
00696 }
00697
00698 static void senddialendevent(const struct ast_channel *src, const char *dialstatus)
00699 {
00700 manager_event(EVENT_FLAG_CALL, "Dial",
00701 "SubEvent: End\r\n"
00702 "Channel: %s\r\n"
00703 "UniqueID: %s\r\n"
00704 "DialStatus: %s\r\n",
00705 src->name, src->uniqueid, dialstatus);
00706 }
00707
00708
00709
00710
00711
00712
00713
00714 static void do_forward(struct chanlist *o,
00715 struct cause_args *num, struct ast_flags64 *peerflags, int single)
00716 {
00717 char tmpchan[256];
00718 struct ast_channel *original = o->chan;
00719 struct ast_channel *c = o->chan;
00720 struct ast_channel *in = num->chan;
00721 char *stuff;
00722 char *tech;
00723 int cause;
00724
00725 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
00726 if ((stuff = strchr(tmpchan, '/'))) {
00727 *stuff++ = '\0';
00728 tech = tmpchan;
00729 } else {
00730 const char *forward_context;
00731 ast_channel_lock(c);
00732 forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
00733 if (ast_strlen_zero(forward_context)) {
00734 forward_context = NULL;
00735 }
00736 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
00737 ast_channel_unlock(c);
00738 stuff = tmpchan;
00739 tech = "Local";
00740 }
00741
00742 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
00743
00744 if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
00745 ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
00746 c = o->chan = NULL;
00747 cause = AST_CAUSE_BUSY;
00748 } else {
00749
00750 c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
00751 if (c) {
00752 if (single)
00753 ast_channel_make_compatible(o->chan, in);
00754 ast_channel_inherit_variables(in, o->chan);
00755 ast_channel_datastore_inherit(in, o->chan);
00756 } else
00757 ast_log(LOG_NOTICE,
00758 "Forwarding failed to create channel to dial '%s/%s' (cause = %d)\n",
00759 tech, stuff, cause);
00760 }
00761 if (!c) {
00762 ast_clear_flag64(o, DIAL_STILLGOING);
00763 handle_cause(cause, num);
00764 ast_hangup(original);
00765 } else {
00766 char *new_cid_num, *new_cid_name;
00767 struct ast_channel *src;
00768
00769 if (CAN_EARLY_BRIDGE(peerflags, c, in)) {
00770 ast_rtp_make_compatible(c, in, single);
00771 }
00772 if (ast_test_flag64(o, OPT_FORCECLID)) {
00773 new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
00774 new_cid_name = NULL;
00775 src = c;
00776 } else {
00777 new_cid_num = ast_strdup(in->cid.cid_num);
00778 new_cid_name = ast_strdup(in->cid.cid_name);
00779 src = in;
00780 }
00781 ast_string_field_set(c, accountcode, src->accountcode);
00782 c->cdrflags = src->cdrflags;
00783 S_REPLACE(c->cid.cid_num, new_cid_num);
00784 S_REPLACE(c->cid.cid_name, new_cid_name);
00785
00786 if (in->cid.cid_ani) {
00787 S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
00788 }
00789 S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
00790 if (ast_call(c, stuff, 0)) {
00791 ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
00792 tech, stuff);
00793 ast_clear_flag64(o, DIAL_STILLGOING);
00794 ast_hangup(original);
00795 ast_hangup(c);
00796 c = o->chan = NULL;
00797 num->nochan++;
00798 } else {
00799 senddialevent(in, c, stuff);
00800
00801 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
00802 char cidname[AST_MAX_EXTENSION] = "";
00803 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
00804 }
00805
00806 ast_hangup(original);
00807 }
00808 if (single) {
00809 ast_indicate(in, -1);
00810 }
00811 }
00812 }
00813
00814
00815 struct privacy_args {
00816 int sentringing;
00817 int privdb_val;
00818 char privcid[256];
00819 char privintro[1024];
00820 char status[256];
00821 };
00822
00823 static struct ast_channel *wait_for_answer(struct ast_channel *in,
00824 struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags,
00825 struct privacy_args *pa,
00826 const struct cause_args *num_in, int *result)
00827 {
00828 struct cause_args num = *num_in;
00829 int prestart = num.busy + num.congestion + num.nochan;
00830 int orig = *to;
00831 struct ast_channel *peer = NULL;
00832
00833 int single = outgoing && !outgoing->next && !ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
00834 #ifdef HAVE_EPOLL
00835 struct chanlist *epollo;
00836 #endif
00837
00838 if (single) {
00839
00840 ast_deactivate_generator(in);
00841
00842 if (ast_channel_make_compatible(outgoing->chan, in) < 0) {
00843
00844
00845
00846
00847 *to = -1;
00848 strcpy(pa->status, "CONGESTION");
00849 ast_cdr_failed(in->cdr);
00850 return NULL;
00851 }
00852 }
00853
00854 #ifdef HAVE_EPOLL
00855 for (epollo = outgoing; epollo; epollo = epollo->next)
00856 ast_poll_channel_add(in, epollo->chan);
00857 #endif
00858
00859 while (*to && !peer) {
00860 struct chanlist *o;
00861 int pos = 0;
00862 int numlines = prestart;
00863 struct ast_channel *winner;
00864 struct ast_channel *watchers[AST_MAX_WATCHERS];
00865
00866 watchers[pos++] = in;
00867 for (o = outgoing; o; o = o->next) {
00868
00869 if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
00870 watchers[pos++] = o->chan;
00871 numlines++;
00872 }
00873 if (pos == 1) {
00874 if (numlines == (num.busy + num.congestion + num.nochan)) {
00875 ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
00876 if (num.busy)
00877 strcpy(pa->status, "BUSY");
00878 else if (num.congestion)
00879 strcpy(pa->status, "CONGESTION");
00880 else if (num.nochan)
00881 strcpy(pa->status, "CHANUNAVAIL");
00882 } else {
00883 ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
00884 }
00885 *to = 0;
00886 return NULL;
00887 }
00888 winner = ast_waitfor_n(watchers, pos, to);
00889 for (o = outgoing; o; o = o->next) {
00890 struct ast_frame *f;
00891 struct ast_channel *c = o->chan;
00892
00893 if (c == NULL)
00894 continue;
00895 if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
00896 if (!peer) {
00897 ast_verb(3, "%s answered %s\n", c->name, in->name);
00898 peer = c;
00899 ast_copy_flags64(peerflags, o,
00900 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00901 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00902 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00903 OPT_CALLEE_PARK | OPT_CALLER_PARK |
00904 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
00905 DIAL_NOFORWARDHTML);
00906 ast_string_field_set(c, dialcontext, "");
00907 ast_copy_string(c->exten, "", sizeof(c->exten));
00908 }
00909 continue;
00910 }
00911 if (c != winner)
00912 continue;
00913
00914 if (!ast_strlen_zero(c->call_forward)) {
00915 do_forward(o, &num, peerflags, single);
00916 continue;
00917 }
00918 f = ast_read(winner);
00919 if (!f) {
00920 in->hangupcause = c->hangupcause;
00921 #ifdef HAVE_EPOLL
00922 ast_poll_channel_del(in, c);
00923 #endif
00924 ast_hangup(c);
00925 c = o->chan = NULL;
00926 ast_clear_flag64(o, DIAL_STILLGOING);
00927 handle_cause(in->hangupcause, &num);
00928 continue;
00929 }
00930 if (f->frametype == AST_FRAME_CONTROL) {
00931 switch(f->subclass) {
00932 case AST_CONTROL_ANSWER:
00933
00934 if (!peer) {
00935 ast_verb(3, "%s answered %s\n", c->name, in->name);
00936 peer = c;
00937 if (peer->cdr) {
00938 peer->cdr->answer = ast_tvnow();
00939 peer->cdr->disposition = AST_CDR_ANSWERED;
00940 }
00941 ast_copy_flags64(peerflags, o,
00942 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00943 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00944 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00945 OPT_CALLEE_PARK | OPT_CALLER_PARK |
00946 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
00947 DIAL_NOFORWARDHTML);
00948 ast_string_field_set(c, dialcontext, "");
00949 ast_copy_string(c->exten, "", sizeof(c->exten));
00950 if (CAN_EARLY_BRIDGE(peerflags, in, peer))
00951
00952 ast_channel_early_bridge(in, peer);
00953 }
00954
00955 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00956 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00957 break;
00958 case AST_CONTROL_BUSY:
00959 ast_verb(3, "%s is busy\n", c->name);
00960 in->hangupcause = c->hangupcause;
00961 ast_hangup(c);
00962 c = o->chan = NULL;
00963 ast_clear_flag64(o, DIAL_STILLGOING);
00964 handle_cause(AST_CAUSE_BUSY, &num);
00965 break;
00966 case AST_CONTROL_CONGESTION:
00967 ast_verb(3, "%s is circuit-busy\n", c->name);
00968 in->hangupcause = c->hangupcause;
00969 ast_hangup(c);
00970 c = o->chan = NULL;
00971 ast_clear_flag64(o, DIAL_STILLGOING);
00972 handle_cause(AST_CAUSE_CONGESTION, &num);
00973 break;
00974 case AST_CONTROL_RINGING:
00975 ast_verb(3, "%s is ringing\n", c->name);
00976
00977 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00978 ast_channel_early_bridge(in, c);
00979 if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
00980 ast_indicate(in, AST_CONTROL_RINGING);
00981 pa->sentringing++;
00982 }
00983 break;
00984 case AST_CONTROL_PROGRESS:
00985 ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
00986
00987 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00988 ast_channel_early_bridge(in, c);
00989 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
00990 if (single || (!single && !pa->sentringing)) {
00991 ast_indicate(in, AST_CONTROL_PROGRESS);
00992 }
00993 break;
00994 case AST_CONTROL_VIDUPDATE:
00995 ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
00996 ast_indicate(in, AST_CONTROL_VIDUPDATE);
00997 break;
00998 case AST_CONTROL_SRCUPDATE:
00999 ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
01000 ast_indicate(in, AST_CONTROL_SRCUPDATE);
01001 break;
01002 case AST_CONTROL_PROCEEDING:
01003 ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
01004 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
01005 ast_channel_early_bridge(in, c);
01006 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
01007 ast_indicate(in, AST_CONTROL_PROCEEDING);
01008 break;
01009 case AST_CONTROL_HOLD:
01010 ast_verb(3, "Call on %s placed on hold\n", c->name);
01011 ast_indicate(in, AST_CONTROL_HOLD);
01012 break;
01013 case AST_CONTROL_UNHOLD:
01014 ast_verb(3, "Call on %s left from hold\n", c->name);
01015 ast_indicate(in, AST_CONTROL_UNHOLD);
01016 break;
01017 case AST_CONTROL_OFFHOOK:
01018 case AST_CONTROL_FLASH:
01019
01020 break;
01021 case -1:
01022 if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
01023 ast_verb(3, "%s stopped sounds\n", c->name);
01024 ast_indicate(in, -1);
01025 pa->sentringing = 0;
01026 }
01027 break;
01028 default:
01029 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
01030 }
01031 } else if (single) {
01032 switch (f->frametype) {
01033 case AST_FRAME_VOICE:
01034 case AST_FRAME_IMAGE:
01035 case AST_FRAME_TEXT:
01036 if (ast_write(in, f)) {
01037 ast_log(LOG_WARNING, "Unable to write frame\n");
01038 }
01039 break;
01040 case AST_FRAME_HTML:
01041 if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass, f->data.ptr, f->datalen) == -1) {
01042 ast_log(LOG_WARNING, "Unable to send URL\n");
01043 }
01044 break;
01045 default:
01046 break;
01047 }
01048 }
01049 ast_frfree(f);
01050 }
01051 if (winner == in) {
01052 struct ast_frame *f = ast_read(in);
01053 #if 0
01054 if (f && (f->frametype != AST_FRAME_VOICE))
01055 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
01056 else if (!f || (f->frametype != AST_FRAME_VOICE))
01057 printf("Hangup received on %s\n", in->name);
01058 #endif
01059 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
01060
01061 *to = -1;
01062 strcpy(pa->status, "CANCEL");
01063 ast_cdr_noanswer(in->cdr);
01064 if (f) {
01065 if (f->data.uint32) {
01066 in->hangupcause = f->data.uint32;
01067 }
01068 ast_frfree(f);
01069 }
01070 return NULL;
01071 }
01072
01073
01074 if (f->frametype == AST_FRAME_DTMF) {
01075 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
01076 const char *context;
01077 ast_channel_lock(in);
01078 context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
01079 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
01080 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
01081 *to = 0;
01082 ast_cdr_noanswer(in->cdr);
01083 *result = f->subclass;
01084 strcpy(pa->status, "CANCEL");
01085 ast_frfree(f);
01086 ast_channel_unlock(in);
01087 return NULL;
01088 }
01089 ast_channel_unlock(in);
01090 }
01091
01092 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
01093 (f->subclass == '*')) {
01094 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
01095 *to = 0;
01096 strcpy(pa->status, "CANCEL");
01097 ast_cdr_noanswer(in->cdr);
01098 ast_frfree(f);
01099 return NULL;
01100 }
01101 }
01102
01103
01104 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
01105 if (ast_channel_sendhtml(outgoing->chan, f->subclass, f->data.ptr, f->datalen) == -1)
01106 ast_log(LOG_WARNING, "Unable to send URL\n");
01107
01108 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
01109 if (ast_write(outgoing->chan, f))
01110 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
01111 }
01112 if (single && (f->frametype == AST_FRAME_CONTROL) &&
01113 ((f->subclass == AST_CONTROL_HOLD) ||
01114 (f->subclass == AST_CONTROL_UNHOLD) ||
01115 (f->subclass == AST_CONTROL_VIDUPDATE) ||
01116 (f->subclass == AST_CONTROL_SRCUPDATE))) {
01117 ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
01118 ast_indicate_data(outgoing->chan, f->subclass, f->data.ptr, f->datalen);
01119 }
01120 ast_frfree(f);
01121 }
01122 if (!*to)
01123 ast_verb(3, "Nobody picked up in %d ms\n", orig);
01124 if (!*to || ast_check_hangup(in))
01125 ast_cdr_noanswer(in->cdr);
01126 }
01127
01128 #ifdef HAVE_EPOLL
01129 for (epollo = outgoing; epollo; epollo = epollo->next) {
01130 if (epollo->chan)
01131 ast_poll_channel_del(in, epollo->chan);
01132 }
01133 #endif
01134
01135 return peer;
01136 }
01137
01138 static void replace_macro_delimiter(char *s)
01139 {
01140 for (; *s; s++)
01141 if (*s == '^')
01142 *s = ',';
01143 }
01144
01145
01146 static int valid_priv_reply(struct ast_flags64 *opts, int res)
01147 {
01148 if (res < '1')
01149 return 0;
01150 if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
01151 return 1;
01152 if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
01153 return 1;
01154 return 0;
01155 }
01156
01157 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
01158 char *parse, struct timeval *calldurationlimit)
01159 {
01160 char *stringp = ast_strdupa(parse);
01161 char *limit_str, *warning_str, *warnfreq_str;
01162 const char *var;
01163 int play_to_caller = 0, play_to_callee = 0;
01164 int delta;
01165
01166 limit_str = strsep(&stringp, ":");
01167 warning_str = strsep(&stringp, ":");
01168 warnfreq_str = strsep(&stringp, ":");
01169
01170 config->timelimit = atol(limit_str);
01171 if (warning_str)
01172 config->play_warning = atol(warning_str);
01173 if (warnfreq_str)
01174 config->warning_freq = atol(warnfreq_str);
01175
01176 if (!config->timelimit) {
01177 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
01178 config->timelimit = config->play_warning = config->warning_freq = 0;
01179 config->warning_sound = NULL;
01180 return -1;
01181 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
01182 int w = config->warning_freq;
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 if (w == 0) {
01197 config->play_warning = 0;
01198 } else {
01199 config->play_warning -= w * ( 1 + (delta-1)/w );
01200 if (config->play_warning < 1)
01201 config->play_warning = config->warning_freq = 0;
01202 }
01203 }
01204
01205 ast_channel_lock(chan);
01206
01207 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
01208
01209 play_to_caller = var ? ast_true(var) : 1;
01210
01211 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
01212 play_to_callee = var ? ast_true(var) : 0;
01213
01214 if (!play_to_caller && !play_to_callee)
01215 play_to_caller = 1;
01216
01217 var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
01218 config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
01219
01220
01221
01222
01223
01224
01225
01226 var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
01227 config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
01228
01229 var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
01230 config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
01231
01232 ast_channel_unlock(chan);
01233
01234
01235 calldurationlimit->tv_sec = 0;
01236 calldurationlimit->tv_usec = 0;
01237
01238
01239 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
01240 calldurationlimit->tv_sec = config->timelimit / 1000;
01241 calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
01242 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
01243 calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
01244 config->timelimit = play_to_caller = play_to_callee =
01245 config->play_warning = config->warning_freq = 0;
01246 } else {
01247 ast_verb(3, "Limit Data for this call:\n");
01248 ast_verb(4, "timelimit = %ld\n", config->timelimit);
01249 ast_verb(4, "play_warning = %ld\n", config->play_warning);
01250 ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
01251 ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
01252 ast_verb(4, "warning_freq = %ld\n", config->warning_freq);
01253 ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
01254 ast_verb(4, "warning_sound = %s\n", config->warning_sound);
01255 ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
01256 }
01257 if (play_to_caller)
01258 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
01259 if (play_to_callee)
01260 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
01261 return 0;
01262 }
01263
01264 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
01265 struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
01266 {
01267
01268 int res2;
01269 int loopcount = 0;
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279 if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01280 char *original_moh = ast_strdupa(chan->musicclass);
01281 ast_indicate(chan, -1);
01282 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01283 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01284 ast_string_field_set(chan, musicclass, original_moh);
01285 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01286 ast_indicate(chan, AST_CONTROL_RINGING);
01287 pa->sentringing++;
01288 }
01289
01290
01291 res2 = ast_autoservice_start(chan);
01292
01293 for (loopcount = 0; loopcount < 3; loopcount++) {
01294 if (res2 && loopcount == 0)
01295 break;
01296 if (!res2)
01297 res2 = ast_play_and_wait(peer, "priv-callpending");
01298 if (!valid_priv_reply(opts, res2))
01299 res2 = 0;
01300
01301
01302
01303 if (!res2)
01304 res2 = ast_play_and_wait(peer, pa->privintro);
01305 if (!valid_priv_reply(opts, res2))
01306 res2 = 0;
01307
01308 if (!res2) {
01309
01310 if (ast_test_flag64(opts, OPT_PRIVACY))
01311 res2 = ast_play_and_wait(peer, "priv-callee-options");
01312 if (ast_test_flag64(opts, OPT_SCREENING))
01313 res2 = ast_play_and_wait(peer, "screen-callee-options");
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 if (valid_priv_reply(opts, res2))
01332 break;
01333
01334 res2 = ast_play_and_wait(peer, "vm-sorry");
01335 }
01336
01337 if (ast_test_flag64(opts, OPT_MUSICBACK)) {
01338 ast_moh_stop(chan);
01339 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01340 ast_indicate(chan, -1);
01341 pa->sentringing = 0;
01342 }
01343 ast_autoservice_stop(chan);
01344 if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
01345
01346 static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
01347 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
01348 int i = res2 - '1';
01349 ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
01350 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
01351 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
01352 }
01353 switch (res2) {
01354 case '1':
01355 break;
01356 case '2':
01357 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01358 break;
01359 case '3':
01360 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01361 break;
01362 case '4':
01363 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01364 break;
01365 case '5':
01366
01367 if (ast_test_flag64(opts, OPT_PRIVACY))
01368 break;
01369
01370 default:
01371
01372
01373
01374
01375 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
01376
01377
01378 break;
01379 }
01380
01381 if (res2 == '1') {
01382
01383
01384 if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
01385 ast_filedelete(pa->privintro, NULL);
01386 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01387 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01388 else
01389 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01390 }
01391 return 0;
01392 } else {
01393 ast_hangup(peer);
01394 return -1;
01395 }
01396 }
01397
01398
01399 static int setup_privacy_args(struct privacy_args *pa,
01400 struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
01401 {
01402 char callerid[60];
01403 int res;
01404 char *l;
01405 int silencethreshold;
01406
01407 if (!ast_strlen_zero(chan->cid.cid_num)) {
01408 l = ast_strdupa(chan->cid.cid_num);
01409 ast_shrink_phone_number(l);
01410 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
01411 ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
01412 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
01413 } else {
01414 ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
01415 pa->privdb_val = AST_PRIVACY_UNKNOWN;
01416 }
01417 } else {
01418 char *tnam, *tn2;
01419
01420 tnam = ast_strdupa(chan->name);
01421
01422 for (tn2 = tnam; *tn2; tn2++) {
01423 if (*tn2 == '/')
01424 *tn2 = '=';
01425 }
01426 ast_verb(3, "Privacy-- callerid is empty\n");
01427
01428 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
01429 l = callerid;
01430 pa->privdb_val = AST_PRIVACY_UNKNOWN;
01431 }
01432
01433 ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
01434
01435 if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCLID)) {
01436
01437 ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
01438 pa->privdb_val = AST_PRIVACY_ALLOW;
01439 } else if (ast_test_flag64(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
01440 ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
01441 }
01442
01443 if (pa->privdb_val == AST_PRIVACY_DENY) {
01444 ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
01445 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01446 return 0;
01447 } else if (pa->privdb_val == AST_PRIVACY_KILL) {
01448 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01449 return 0;
01450 } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
01451 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01452 return 0;
01453 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
01454
01455
01456
01457
01458
01459 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
01460 if ((res = ast_mkdir(pa->privintro, 0755))) {
01461 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
01462 return -1;
01463 }
01464
01465 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
01466 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
01467
01468
01469
01470 } else {
01471 int duration;
01472
01473
01474
01475
01476
01477
01478
01479 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
01480 ast_answer(chan);
01481 res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "sln", &duration, silencethreshold, 2000, 0);
01482
01483
01484 if (res == -1) {
01485
01486 ast_filedelete(pa->privintro, NULL);
01487 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01488 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01489 else
01490 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01491 return -1;
01492 }
01493 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
01494 ast_waitstream(chan, "");
01495 }
01496 }
01497 return 1;
01498 }
01499
01500 static void end_bridge_callback(void *data)
01501 {
01502 char buf[80];
01503 time_t end;
01504 struct ast_channel *chan = data;
01505
01506 if (!chan->cdr) {
01507 return;
01508 }
01509
01510 time(&end);
01511
01512 ast_channel_lock(chan);
01513 if (chan->cdr->answer.tv_sec) {
01514 snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->answer.tv_sec);
01515 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
01516 }
01517
01518 if (chan->cdr->start.tv_sec) {
01519 snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->start.tv_sec);
01520 pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
01521 }
01522 ast_channel_unlock(chan);
01523 }
01524
01525 static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) {
01526 bconfig->end_bridge_callback_data = originator;
01527 }
01528
01529 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec)
01530 {
01531 int res = -1;
01532 char *rest, *cur;
01533 struct chanlist *outgoing = NULL;
01534 struct ast_channel *peer;
01535 int to;
01536 struct cause_args num = { chan, 0, 0, 0 };
01537 int cause;
01538 char numsubst[256];
01539 char cidname[AST_MAX_EXTENSION] = "";
01540
01541 struct ast_bridge_config config = { { 0, } };
01542 struct timeval calldurationlimit = { 0, };
01543 char *dtmfcalled = NULL, *dtmfcalling = NULL;
01544 struct privacy_args pa = {
01545 .sentringing = 0,
01546 .privdb_val = 0,
01547 .status = "INVALIDARGS",
01548 };
01549 int sentringing = 0, moh = 0;
01550 const char *outbound_group = NULL;
01551 int result = 0;
01552 char *parse;
01553 int opermode = 0;
01554 int delprivintro = 0;
01555 AST_DECLARE_APP_ARGS(args,
01556 AST_APP_ARG(peers);
01557 AST_APP_ARG(timeout);
01558 AST_APP_ARG(options);
01559 AST_APP_ARG(url);
01560 );
01561 struct ast_flags64 opts = { 0, };
01562 char *opt_args[OPT_ARG_ARRAY_SIZE];
01563 struct ast_datastore *datastore = NULL;
01564 int fulldial = 0, num_dialed = 0;
01565
01566
01567 pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
01568 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
01569 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
01570 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
01571 pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
01572
01573 if (ast_strlen_zero(data)) {
01574 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01575 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01576 return -1;
01577 }
01578
01579 parse = ast_strdupa(data);
01580
01581 AST_STANDARD_APP_ARGS(args, parse);
01582
01583 if (!ast_strlen_zero(args.options) &&
01584 ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
01585 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01586 goto done;
01587 }
01588
01589 if (ast_strlen_zero(args.peers)) {
01590 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01591 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01592 goto done;
01593 }
01594
01595
01596 if (ast_test_flag64(&opts, OPT_SCREEN_NOINTRO) && !ast_strlen_zero(opt_args[OPT_ARG_SCREEN_NOINTRO])) {
01597 delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
01598
01599 if (delprivintro < 0 || delprivintro > 1) {
01600 ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
01601 delprivintro = 0;
01602 }
01603 }
01604
01605 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
01606 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
01607 ast_verb(3, "Setting operator services mode to %d.\n", opermode);
01608 }
01609
01610 if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
01611 calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
01612 if (!calldurationlimit.tv_sec) {
01613 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
01614 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01615 goto done;
01616 }
01617 ast_verb(3, "Setting call duration limit to %.3lf milliseconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
01618 }
01619
01620 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
01621 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
01622 dtmfcalled = strsep(&dtmfcalling, ":");
01623 }
01624
01625 if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
01626 if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
01627 goto done;
01628 }
01629
01630 if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
01631 ast_cdr_reset(chan->cdr, NULL);
01632 if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
01633 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
01634
01635 if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
01636 res = setup_privacy_args(&pa, &opts, opt_args, chan);
01637 if (res <= 0)
01638 goto out;
01639 res = -1;
01640 }
01641
01642 if (ast_test_flag64(&opts, OPT_DTMF_EXIT)) {
01643 __ast_answer(chan, 0, 0);
01644 }
01645
01646 if (continue_exec)
01647 *continue_exec = 0;
01648
01649
01650
01651 ast_channel_lock(chan);
01652 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
01653 outbound_group = ast_strdupa(outbound_group);
01654 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
01655 } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
01656 outbound_group = ast_strdupa(outbound_group);
01657 }
01658 ast_channel_unlock(chan);
01659 ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB);
01660
01661
01662 rest = args.peers;
01663 while ((cur = strsep(&rest, "&")) ) {
01664 struct chanlist *tmp;
01665 struct ast_channel *tc;
01666
01667 char *number = cur;
01668 char *interface = ast_strdupa(number);
01669 char *tech = strsep(&number, "/");
01670
01671 struct ast_dialed_interface *di;
01672 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
01673 num_dialed++;
01674 if (ast_strlen_zero(number)) {
01675 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
01676 goto out;
01677 }
01678 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01679 goto out;
01680 if (opts.flags) {
01681 ast_copy_flags64(tmp, &opts,
01682 OPT_CANCEL_ELSEWHERE |
01683 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
01684 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
01685 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
01686 OPT_CALLEE_PARK | OPT_CALLER_PARK |
01687 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
01688 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
01689 ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
01690 }
01691 ast_copy_string(numsubst, number, sizeof(numsubst));
01692
01693
01694 ast_channel_lock(chan);
01695 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
01696 ast_channel_unlock(chan);
01697
01698 if (datastore)
01699 dialed_interfaces = datastore->data;
01700 else {
01701 if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
01702 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
01703 ast_free(tmp);
01704 goto out;
01705 }
01706
01707 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
01708
01709 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
01710 ast_datastore_free(datastore);
01711 ast_free(tmp);
01712 goto out;
01713 }
01714
01715 datastore->data = dialed_interfaces;
01716 AST_LIST_HEAD_INIT(dialed_interfaces);
01717
01718 ast_channel_lock(chan);
01719 ast_channel_datastore_add(chan, datastore);
01720 ast_channel_unlock(chan);
01721 }
01722
01723 AST_LIST_LOCK(dialed_interfaces);
01724 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
01725 if (!strcasecmp(di->interface, interface)) {
01726 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
01727 di->interface);
01728 break;
01729 }
01730 }
01731 AST_LIST_UNLOCK(dialed_interfaces);
01732
01733 if (di) {
01734 fulldial++;
01735 ast_free(tmp);
01736 continue;
01737 }
01738
01739
01740
01741
01742
01743 if (strcasecmp(tech, "Local")) {
01744 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
01745 AST_LIST_UNLOCK(dialed_interfaces);
01746 ast_free(tmp);
01747 goto out;
01748 }
01749 strcpy(di->interface, interface);
01750
01751 AST_LIST_LOCK(dialed_interfaces);
01752 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
01753 AST_LIST_UNLOCK(dialed_interfaces);
01754 }
01755
01756 tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
01757 if (!tc) {
01758
01759 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
01760 tech, cause, ast_cause2str(cause));
01761 handle_cause(cause, &num);
01762 if (!rest)
01763 chan->hangupcause = cause;
01764 ast_free(tmp);
01765 continue;
01766 }
01767 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
01768
01769
01770 if (CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
01771 ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
01772 }
01773
01774
01775 ast_channel_inherit_variables(chan, tc);
01776 ast_channel_datastore_inherit(chan, tc);
01777
01778 tc->appl = "AppDial";
01779 tc->data = "(Outgoing Line)";
01780 memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
01781
01782 S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
01783 S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
01784 S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
01785 S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
01786
01787 ast_string_field_set(tc, accountcode, chan->accountcode);
01788 tc->cdrflags = chan->cdrflags;
01789 if (ast_strlen_zero(tc->musicclass))
01790 ast_string_field_set(tc, musicclass, chan->musicclass);
01791
01792 tc->cid.cid_pres = chan->cid.cid_pres;
01793 tc->cid.cid_ton = chan->cid.cid_ton;
01794 tc->cid.cid_tns = chan->cid.cid_tns;
01795 tc->cid.cid_ani2 = chan->cid.cid_ani2;
01796 tc->adsicpe = chan->adsicpe;
01797 tc->transfercapability = chan->transfercapability;
01798
01799
01800 if (outbound_group)
01801 ast_app_group_set_channel(tc, outbound_group);
01802
01803 if (ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE))
01804 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
01805
01806
01807 if (ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE))
01808 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
01809
01810
01811
01812 ast_string_field_set(tc, dialcontext, ast_strlen_zero(chan->macrocontext) ? chan->context : chan->macrocontext);
01813 if (!ast_strlen_zero(chan->macroexten))
01814 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
01815 else
01816 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
01817
01818 res = ast_call(tc, numsubst, 0);
01819
01820
01821 if (chan->cdr)
01822 ast_cdr_setdestchan(chan->cdr, tc->name);
01823
01824
01825 if (res) {
01826
01827 ast_debug(1, "ast call on peer returned %d\n", res);
01828 ast_verb(3, "Couldn't call %s\n", numsubst);
01829 if (tc->hangupcause) {
01830 chan->hangupcause = tc->hangupcause;
01831 }
01832 ast_hangup(tc);
01833 tc = NULL;
01834 ast_free(tmp);
01835 continue;
01836 } else {
01837 senddialevent(chan, tc, numsubst);
01838 ast_verb(3, "Called %s\n", numsubst);
01839 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID))
01840 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
01841 }
01842
01843
01844
01845 ast_set_flag64(tmp, DIAL_STILLGOING);
01846 tmp->chan = tc;
01847 tmp->next = outgoing;
01848 outgoing = tmp;
01849
01850 if (outgoing->chan->_state == AST_STATE_UP)
01851 break;
01852 }
01853
01854 if (ast_strlen_zero(args.timeout)) {
01855 to = -1;
01856 } else {
01857 to = atoi(args.timeout);
01858 if (to > 0)
01859 to *= 1000;
01860 else {
01861 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
01862 to = -1;
01863 }
01864 }
01865
01866 if (!outgoing) {
01867 strcpy(pa.status, "CHANUNAVAIL");
01868 if (fulldial == num_dialed) {
01869 res = -1;
01870 goto out;
01871 }
01872 } else {
01873
01874 strcpy(pa.status, "NOANSWER");
01875 if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
01876 moh = 1;
01877 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01878 char *original_moh = ast_strdupa(chan->musicclass);
01879 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01880 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01881 ast_string_field_set(chan, musicclass, original_moh);
01882 } else {
01883 ast_moh_start(chan, NULL, NULL);
01884 }
01885 ast_indicate(chan, AST_CONTROL_PROGRESS);
01886 } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
01887 ast_indicate(chan, AST_CONTROL_RINGING);
01888 sentringing++;
01889 }
01890 }
01891
01892 peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
01893
01894
01895
01896
01897
01898
01899
01900 if (!ast_channel_datastore_remove(chan, datastore))
01901 ast_datastore_free(datastore);
01902 if (!peer) {
01903 if (result) {
01904 res = result;
01905 } else if (to) {
01906 res = -1;
01907 } else {
01908 res = 0;
01909 }
01910
01911
01912
01913 if (chan->hangupcause == AST_CAUSE_INVALID_NUMBER_FORMAT) {
01914 res = AST_PBX_INCOMPLETE;
01915 }
01916
01917
01918 } else {
01919 const char *number;
01920
01921 strcpy(pa.status, "ANSWER");
01922 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01923
01924
01925
01926 hanguptree(outgoing, peer, 1);
01927 outgoing = NULL;
01928
01929 if (chan->cdr)
01930 ast_cdr_setdestchan(chan->cdr, peer->name);
01931 if (peer->name)
01932 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
01933
01934 ast_channel_lock(peer);
01935 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
01936 if (!number)
01937 number = numsubst;
01938 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
01939 ast_channel_unlock(peer);
01940
01941 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
01942 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
01943 ast_channel_sendurl( peer, args.url );
01944 }
01945 if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
01946 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
01947 res = 0;
01948 goto out;
01949 }
01950 }
01951 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
01952 res = 0;
01953 } else {
01954 int digit = 0;
01955 struct ast_channel *chans[2];
01956 struct ast_channel *active_chan;
01957
01958 chans[0] = chan;
01959 chans[1] = peer;
01960
01961
01962
01963
01964 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
01965 if (res) {
01966 res = 0;
01967 ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
01968 }
01969
01970 ast_set_flag(peer, AST_FLAG_END_DTMF_ONLY);
01971 while (peer->stream) {
01972 int ms;
01973
01974 ms = ast_sched_wait(peer->sched);
01975
01976 if (ms < 0 && !peer->timingfunc) {
01977 ast_stopstream(peer);
01978 break;
01979 }
01980 if (ms < 0)
01981 ms = 1000;
01982
01983 active_chan = ast_waitfor_n(chans, 2, &ms);
01984 if (active_chan) {
01985 struct ast_frame *fr = ast_read(active_chan);
01986 if (!fr) {
01987 ast_hangup(peer);
01988 res = -1;
01989 goto done;
01990 }
01991 switch(fr->frametype) {
01992 case AST_FRAME_DTMF_END:
01993 digit = fr->subclass;
01994 if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
01995 ast_stopstream(peer);
01996 res = ast_senddigit(chan, digit, 0);
01997 }
01998 break;
01999 case AST_FRAME_CONTROL:
02000 switch (fr->subclass) {
02001 case AST_CONTROL_HANGUP:
02002 ast_frfree(fr);
02003 ast_hangup(peer);
02004 res = -1;
02005 goto done;
02006 default:
02007 break;
02008 }
02009 break;
02010 default:
02011
02012 break;
02013 }
02014 ast_frfree(fr);
02015 }
02016 ast_sched_runq(peer->sched);
02017 }
02018 ast_clear_flag(peer, AST_FLAG_END_DTMF_ONLY);
02019 }
02020
02021 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
02022
02023
02024 ast_clear_flag(chan->cdr, AST_CDR_FLAG_DIALED);
02025 ast_clear_flag(peer->cdr, AST_CDR_FLAG_DIALED);
02026
02027 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
02028 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
02029
02030 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02031 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02032 peer->priority = chan->priority + 2;
02033 ast_pbx_start(peer);
02034 hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
02035 if (continue_exec)
02036 *continue_exec = 1;
02037 res = 0;
02038 goto done;
02039 }
02040
02041 if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
02042 struct ast_app *theapp;
02043 const char *macro_result;
02044
02045 res = ast_autoservice_start(chan);
02046 if (res) {
02047 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02048 res = -1;
02049 }
02050
02051 theapp = pbx_findapp("Macro");
02052
02053 if (theapp && !res) {
02054
02055 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02056 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02057
02058 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
02059 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
02060 ast_debug(1, "Macro exited with status %d\n", res);
02061 res = 0;
02062 } else {
02063 ast_log(LOG_ERROR, "Could not find application Macro\n");
02064 res = -1;
02065 }
02066
02067 if (ast_autoservice_stop(chan) < 0) {
02068 res = -1;
02069 }
02070
02071 ast_channel_lock(peer);
02072
02073 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
02074 char *macro_transfer_dest;
02075
02076 if (!strcasecmp(macro_result, "BUSY")) {
02077 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02078 ast_set_flag64(peerflags, OPT_GO_ON);
02079 res = -1;
02080 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
02081 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02082 ast_set_flag64(peerflags, OPT_GO_ON);
02083 res = -1;
02084 } else if (!strcasecmp(macro_result, "CONTINUE")) {
02085
02086
02087
02088
02089 ast_set_flag64(peerflags, OPT_GO_ON);
02090 res = -1;
02091 } else if (!strcasecmp(macro_result, "ABORT")) {
02092
02093 res = -1;
02094 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
02095 res = -1;
02096
02097 if (strchr(macro_transfer_dest, '^')) {
02098 replace_macro_delimiter(macro_transfer_dest);
02099 if (!ast_parseable_goto(chan, macro_transfer_dest))
02100 ast_set_flag64(peerflags, OPT_GO_ON);
02101 }
02102 }
02103 }
02104
02105 ast_channel_unlock(peer);
02106 }
02107
02108 if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
02109 struct ast_app *theapp;
02110 const char *gosub_result;
02111 char *gosub_args, *gosub_argstart;
02112 int res9 = -1;
02113
02114 res9 = ast_autoservice_start(chan);
02115 if (res9) {
02116 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02117 res9 = -1;
02118 }
02119
02120 theapp = pbx_findapp("Gosub");
02121
02122 if (theapp && !res9) {
02123 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
02124
02125
02126 ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
02127 ast_copy_string(peer->exten, "s", sizeof(peer->exten));
02128 peer->priority = 0;
02129
02130 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
02131 if (gosub_argstart) {
02132 *gosub_argstart = 0;
02133 if (asprintf(&gosub_args, "%s,s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1) < 0) {
02134 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02135 gosub_args = NULL;
02136 }
02137 *gosub_argstart = ',';
02138 } else {
02139 if (asprintf(&gosub_args, "%s,s,1", opt_args[OPT_ARG_CALLEE_GOSUB]) < 0) {
02140 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02141 gosub_args = NULL;
02142 }
02143 }
02144
02145 if (gosub_args) {
02146 res9 = pbx_exec(peer, theapp, gosub_args);
02147 if (!res9) {
02148 struct ast_pbx_args args;
02149
02150 memset(&args, 0, sizeof(args));
02151 args.no_hangup_chan = 1;
02152 ast_pbx_run_args(peer, &args);
02153 }
02154 ast_free(gosub_args);
02155 ast_debug(1, "Gosub exited with status %d\n", res9);
02156 } else {
02157 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
02158 }
02159
02160 } else if (!res9) {
02161 ast_log(LOG_ERROR, "Could not find application Gosub\n");
02162 res9 = -1;
02163 }
02164
02165 if (ast_autoservice_stop(chan) < 0) {
02166 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
02167 res9 = -1;
02168 }
02169
02170 ast_channel_lock(peer);
02171
02172 if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
02173 char *gosub_transfer_dest;
02174
02175 if (!strcasecmp(gosub_result, "BUSY")) {
02176 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02177 ast_set_flag64(peerflags, OPT_GO_ON);
02178 res = -1;
02179 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
02180 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02181 ast_set_flag64(peerflags, OPT_GO_ON);
02182 res = -1;
02183 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
02184
02185
02186
02187
02188 ast_set_flag64(peerflags, OPT_GO_ON);
02189 res = -1;
02190 } else if (!strcasecmp(gosub_result, "ABORT")) {
02191
02192 res = -1;
02193 } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
02194 res = -1;
02195
02196 if (strchr(gosub_transfer_dest, '^')) {
02197 replace_macro_delimiter(gosub_transfer_dest);
02198 if (!ast_parseable_goto(chan, gosub_transfer_dest))
02199 ast_set_flag64(peerflags, OPT_GO_ON);
02200 }
02201 }
02202 }
02203
02204 ast_channel_unlock(peer);
02205 }
02206
02207 if (!res) {
02208 if (!ast_tvzero(calldurationlimit)) {
02209 struct timeval whentohangup = calldurationlimit;
02210 peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
02211 }
02212 if (!ast_strlen_zero(dtmfcalled)) {
02213 ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
02214 res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
02215 }
02216 if (!ast_strlen_zero(dtmfcalling)) {
02217 ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
02218 res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
02219 }
02220 }
02221
02222 if (res) {
02223 res = -1;
02224 } else {
02225 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
02226 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
02227 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
02228 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
02229 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
02230 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
02231 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
02232 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
02233 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
02234 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
02235 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
02236 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
02237 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
02238 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
02239 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
02240 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
02241 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
02242 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
02243 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
02244 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
02245 if (ast_test_flag64(peerflags, OPT_GO_ON))
02246 ast_set_flag(&(config.features_caller), AST_FEATURE_NO_H_EXTEN);
02247
02248 config.end_bridge_callback = end_bridge_callback;
02249 config.end_bridge_callback_data = chan;
02250 config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
02251
02252 if (moh) {
02253 moh = 0;
02254 ast_moh_stop(chan);
02255 } else if (sentringing) {
02256 sentringing = 0;
02257 ast_indicate(chan, -1);
02258 }
02259
02260 ast_deactivate_generator(chan);
02261 chan->visible_indication = 0;
02262
02263 res = ast_channel_make_compatible(chan, peer);
02264 if (res < 0) {
02265 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
02266 ast_hangup(peer);
02267 res = -1;
02268 goto done;
02269 }
02270 if (opermode) {
02271 struct oprmode oprmode;
02272
02273 oprmode.peer = peer;
02274 oprmode.mode = opermode;
02275
02276 ast_channel_setoption(chan, AST_OPTION_OPRMODE, &oprmode, sizeof(oprmode), 0);
02277 }
02278 res = ast_bridge_call(chan, peer, &config);
02279 }
02280
02281 strcpy(peer->context, chan->context);
02282
02283 if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
02284 int autoloopflag;
02285 int found;
02286 int res9;
02287
02288 strcpy(peer->exten, "h");
02289 peer->priority = 1;
02290 autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP);
02291 ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
02292
02293 while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
02294 peer->priority++;
02295
02296 if (found && res9) {
02297
02298 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02299 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02300 }
02301 ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);
02302 }
02303 if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
02304 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
02305 ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
02306 ast_pbx_start(peer);
02307 } else {
02308 if (!ast_check_hangup(chan))
02309 chan->hangupcause = peer->hangupcause;
02310 ast_hangup(peer);
02311 }
02312 }
02313 out:
02314 if (moh) {
02315 moh = 0;
02316 ast_moh_stop(chan);
02317 } else if (sentringing) {
02318 sentringing = 0;
02319 ast_indicate(chan, -1);
02320 }
02321
02322 if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02323 ast_filedelete(pa.privintro, NULL);
02324 if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02325 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
02326 } else {
02327 ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
02328 }
02329 }
02330
02331 ast_channel_early_bridge(chan, NULL);
02332 hanguptree(outgoing, NULL, 0);
02333 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
02334 senddialendevent(chan, pa.status);
02335 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
02336
02337 if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
02338 if (!ast_tvzero(calldurationlimit))
02339 memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
02340 res = 0;
02341 }
02342
02343 done:
02344 if (config.warning_sound) {
02345 ast_free((char *)config.warning_sound);
02346 }
02347 if (config.end_sound) {
02348 ast_free((char *)config.end_sound);
02349 }
02350 if (config.start_sound) {
02351 ast_free((char *)config.start_sound);
02352 }
02353 return res;
02354 }
02355
02356 static int dial_exec(struct ast_channel *chan, void *data)
02357 {
02358 struct ast_flags64 peerflags;
02359
02360 memset(&peerflags, 0, sizeof(peerflags));
02361
02362 return dial_exec_full(chan, data, &peerflags, NULL);
02363 }
02364
02365 static int retrydial_exec(struct ast_channel *chan, void *data)
02366 {
02367 char *parse;
02368 const char *context = NULL;
02369 int sleepms = 0, loops = 0, res = -1;
02370 struct ast_flags64 peerflags = { 0, };
02371 AST_DECLARE_APP_ARGS(args,
02372 AST_APP_ARG(announce);
02373 AST_APP_ARG(sleep);
02374 AST_APP_ARG(retries);
02375 AST_APP_ARG(dialdata);
02376 );
02377
02378 if (ast_strlen_zero(data)) {
02379 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
02380 return -1;
02381 }
02382
02383 parse = ast_strdupa(data);
02384 AST_STANDARD_APP_ARGS(args, parse);
02385
02386 if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
02387 sleepms *= 1000;
02388
02389 if (!ast_strlen_zero(args.retries)) {
02390 loops = atoi(args.retries);
02391 }
02392
02393 if (!args.dialdata) {
02394 ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
02395 goto done;
02396 }
02397
02398 if (sleepms < 1000)
02399 sleepms = 10000;
02400
02401 if (!loops)
02402 loops = -1;
02403
02404 ast_channel_lock(chan);
02405 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
02406 context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
02407 ast_channel_unlock(chan);
02408
02409 res = 0;
02410 while (loops) {
02411 int continue_exec;
02412
02413 chan->data = "Retrying";
02414 if (ast_test_flag(chan, AST_FLAG_MOH))
02415 ast_moh_stop(chan);
02416
02417 res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
02418 if (continue_exec)
02419 break;
02420
02421 if (res == 0) {
02422 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
02423 if (!ast_strlen_zero(args.announce)) {
02424 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02425 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02426 ast_waitstream(chan, AST_DIGIT_ANY);
02427 } else
02428 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02429 }
02430 if (!res && sleepms) {
02431 if (!ast_test_flag(chan, AST_FLAG_MOH))
02432 ast_moh_start(chan, NULL, NULL);
02433 res = ast_waitfordigit(chan, sleepms);
02434 }
02435 } else {
02436 if (!ast_strlen_zero(args.announce)) {
02437 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02438 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02439 res = ast_waitstream(chan, "");
02440 } else
02441 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02442 }
02443 if (sleepms) {
02444 if (!ast_test_flag(chan, AST_FLAG_MOH))
02445 ast_moh_start(chan, NULL, NULL);
02446 if (!res)
02447 res = ast_waitfordigit(chan, sleepms);
02448 }
02449 }
02450 }
02451
02452 if (res < 0 || res == AST_PBX_INCOMPLETE) {
02453 break;
02454 } else if (res > 0) {
02455 if (onedigit_goto(chan, context, (char) res, 1)) {
02456 res = 0;
02457 break;
02458 }
02459 }
02460 loops--;
02461 }
02462 if (loops == 0)
02463 res = 0;
02464 else if (res == 1)
02465 res = 0;
02466
02467 if (ast_test_flag(chan, AST_FLAG_MOH))
02468 ast_moh_stop(chan);
02469 done:
02470 return res;
02471 }
02472
02473 static int unload_module(void)
02474 {
02475 int res;
02476 struct ast_context *con;
02477
02478 res = ast_unregister_application(app);
02479 res |= ast_unregister_application(rapp);
02480
02481 if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
02482 ast_context_remove_extension2(con, "s", 1, NULL, 0);
02483 ast_context_destroy(con, "app_dial");
02484 }
02485
02486 return res;
02487 }
02488
02489 static int load_module(void)
02490 {
02491 int res;
02492 struct ast_context *con;
02493
02494 con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
02495 if (!con)
02496 ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
02497 else
02498 ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial");
02499
02500 res = ast_register_application_xml(app, dial_exec);
02501 res |= ast_register_application_xml(rapp, retrydial_exec);
02502
02503 return res;
02504 }
02505
02506 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");