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: 281567 $")
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 ast_channel_make_compatible(outgoing->chan, in);
00843 }
00844
00845 #ifdef HAVE_EPOLL
00846 for (epollo = outgoing; epollo; epollo = epollo->next)
00847 ast_poll_channel_add(in, epollo->chan);
00848 #endif
00849
00850 while (*to && !peer) {
00851 struct chanlist *o;
00852 int pos = 0;
00853 int numlines = prestart;
00854 struct ast_channel *winner;
00855 struct ast_channel *watchers[AST_MAX_WATCHERS];
00856
00857 watchers[pos++] = in;
00858 for (o = outgoing; o; o = o->next) {
00859
00860 if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
00861 watchers[pos++] = o->chan;
00862 numlines++;
00863 }
00864 if (pos == 1) {
00865 if (numlines == (num.busy + num.congestion + num.nochan)) {
00866 ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
00867 if (num.busy)
00868 strcpy(pa->status, "BUSY");
00869 else if (num.congestion)
00870 strcpy(pa->status, "CONGESTION");
00871 else if (num.nochan)
00872 strcpy(pa->status, "CHANUNAVAIL");
00873 } else {
00874 ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
00875 }
00876 *to = 0;
00877 return NULL;
00878 }
00879 winner = ast_waitfor_n(watchers, pos, to);
00880 for (o = outgoing; o; o = o->next) {
00881 struct ast_frame *f;
00882 struct ast_channel *c = o->chan;
00883
00884 if (c == NULL)
00885 continue;
00886 if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
00887 if (!peer) {
00888 ast_verb(3, "%s answered %s\n", c->name, in->name);
00889 peer = c;
00890 ast_copy_flags64(peerflags, o,
00891 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00892 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00893 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00894 OPT_CALLEE_PARK | OPT_CALLER_PARK |
00895 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
00896 DIAL_NOFORWARDHTML);
00897 ast_string_field_set(c, dialcontext, "");
00898 ast_copy_string(c->exten, "", sizeof(c->exten));
00899 }
00900 continue;
00901 }
00902 if (c != winner)
00903 continue;
00904
00905 if (!ast_strlen_zero(c->call_forward)) {
00906 do_forward(o, &num, peerflags, single);
00907 continue;
00908 }
00909 f = ast_read(winner);
00910 if (!f) {
00911 in->hangupcause = c->hangupcause;
00912 #ifdef HAVE_EPOLL
00913 ast_poll_channel_del(in, c);
00914 #endif
00915 ast_hangup(c);
00916 c = o->chan = NULL;
00917 ast_clear_flag64(o, DIAL_STILLGOING);
00918 handle_cause(in->hangupcause, &num);
00919 continue;
00920 }
00921 if (f->frametype == AST_FRAME_CONTROL) {
00922 switch(f->subclass) {
00923 case AST_CONTROL_ANSWER:
00924
00925 if (!peer) {
00926 ast_verb(3, "%s answered %s\n", c->name, in->name);
00927 peer = c;
00928 if (peer->cdr) {
00929 peer->cdr->answer = ast_tvnow();
00930 peer->cdr->disposition = AST_CDR_ANSWERED;
00931 }
00932 ast_copy_flags64(peerflags, o,
00933 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00934 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00935 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00936 OPT_CALLEE_PARK | OPT_CALLER_PARK |
00937 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
00938 DIAL_NOFORWARDHTML);
00939 ast_string_field_set(c, dialcontext, "");
00940 ast_copy_string(c->exten, "", sizeof(c->exten));
00941 if (CAN_EARLY_BRIDGE(peerflags, in, peer))
00942
00943 ast_channel_early_bridge(in, peer);
00944 }
00945
00946 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00947 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00948 break;
00949 case AST_CONTROL_BUSY:
00950 ast_verb(3, "%s is busy\n", c->name);
00951 in->hangupcause = c->hangupcause;
00952 ast_hangup(c);
00953 c = o->chan = NULL;
00954 ast_clear_flag64(o, DIAL_STILLGOING);
00955 handle_cause(AST_CAUSE_BUSY, &num);
00956 break;
00957 case AST_CONTROL_CONGESTION:
00958 ast_verb(3, "%s is circuit-busy\n", c->name);
00959 in->hangupcause = c->hangupcause;
00960 ast_hangup(c);
00961 c = o->chan = NULL;
00962 ast_clear_flag64(o, DIAL_STILLGOING);
00963 handle_cause(AST_CAUSE_CONGESTION, &num);
00964 break;
00965 case AST_CONTROL_RINGING:
00966 ast_verb(3, "%s is ringing\n", c->name);
00967
00968 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00969 ast_channel_early_bridge(in, c);
00970 if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
00971 ast_indicate(in, AST_CONTROL_RINGING);
00972 pa->sentringing++;
00973 }
00974 break;
00975 case AST_CONTROL_PROGRESS:
00976 ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
00977
00978 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00979 ast_channel_early_bridge(in, c);
00980 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
00981 if (single || (!single && !pa->sentringing)) {
00982 ast_indicate(in, AST_CONTROL_PROGRESS);
00983 }
00984 break;
00985 case AST_CONTROL_VIDUPDATE:
00986 ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
00987 ast_indicate(in, AST_CONTROL_VIDUPDATE);
00988 break;
00989 case AST_CONTROL_SRCUPDATE:
00990 ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
00991 ast_indicate(in, AST_CONTROL_SRCUPDATE);
00992 break;
00993 case AST_CONTROL_PROCEEDING:
00994 ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
00995 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00996 ast_channel_early_bridge(in, c);
00997 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
00998 ast_indicate(in, AST_CONTROL_PROCEEDING);
00999 break;
01000 case AST_CONTROL_HOLD:
01001 ast_verb(3, "Call on %s placed on hold\n", c->name);
01002 ast_indicate(in, AST_CONTROL_HOLD);
01003 break;
01004 case AST_CONTROL_UNHOLD:
01005 ast_verb(3, "Call on %s left from hold\n", c->name);
01006 ast_indicate(in, AST_CONTROL_UNHOLD);
01007 break;
01008 case AST_CONTROL_OFFHOOK:
01009 case AST_CONTROL_FLASH:
01010
01011 break;
01012 case -1:
01013 if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
01014 ast_verb(3, "%s stopped sounds\n", c->name);
01015 ast_indicate(in, -1);
01016 pa->sentringing = 0;
01017 }
01018 break;
01019 default:
01020 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
01021 }
01022 } else if (single) {
01023 switch (f->frametype) {
01024 case AST_FRAME_VOICE:
01025 case AST_FRAME_IMAGE:
01026 case AST_FRAME_TEXT:
01027 if (ast_write(in, f)) {
01028 ast_log(LOG_WARNING, "Unable to write frame\n");
01029 }
01030 break;
01031 case AST_FRAME_HTML:
01032 if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass, f->data.ptr, f->datalen) == -1) {
01033 ast_log(LOG_WARNING, "Unable to send URL\n");
01034 }
01035 break;
01036 default:
01037 break;
01038 }
01039 }
01040 ast_frfree(f);
01041 }
01042 if (winner == in) {
01043 struct ast_frame *f = ast_read(in);
01044 #if 0
01045 if (f && (f->frametype != AST_FRAME_VOICE))
01046 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
01047 else if (!f || (f->frametype != AST_FRAME_VOICE))
01048 printf("Hangup received on %s\n", in->name);
01049 #endif
01050 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
01051
01052 *to = -1;
01053 strcpy(pa->status, "CANCEL");
01054 ast_cdr_noanswer(in->cdr);
01055 if (f) {
01056 if (f->data.uint32) {
01057 in->hangupcause = f->data.uint32;
01058 }
01059 ast_frfree(f);
01060 }
01061 return NULL;
01062 }
01063
01064
01065 if (f->frametype == AST_FRAME_DTMF) {
01066 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
01067 const char *context;
01068 ast_channel_lock(in);
01069 context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
01070 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
01071 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
01072 *to = 0;
01073 ast_cdr_noanswer(in->cdr);
01074 *result = f->subclass;
01075 strcpy(pa->status, "CANCEL");
01076 ast_frfree(f);
01077 ast_channel_unlock(in);
01078 return NULL;
01079 }
01080 ast_channel_unlock(in);
01081 }
01082
01083 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
01084 (f->subclass == '*')) {
01085 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
01086 *to = 0;
01087 strcpy(pa->status, "CANCEL");
01088 ast_cdr_noanswer(in->cdr);
01089 ast_frfree(f);
01090 return NULL;
01091 }
01092 }
01093
01094
01095 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
01096 if (ast_channel_sendhtml(outgoing->chan, f->subclass, f->data.ptr, f->datalen) == -1)
01097 ast_log(LOG_WARNING, "Unable to send URL\n");
01098
01099 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
01100 if (ast_write(outgoing->chan, f))
01101 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
01102 }
01103 if (single && (f->frametype == AST_FRAME_CONTROL) &&
01104 ((f->subclass == AST_CONTROL_HOLD) ||
01105 (f->subclass == AST_CONTROL_UNHOLD) ||
01106 (f->subclass == AST_CONTROL_VIDUPDATE) ||
01107 (f->subclass == AST_CONTROL_SRCUPDATE))) {
01108 ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
01109 ast_indicate_data(outgoing->chan, f->subclass, f->data.ptr, f->datalen);
01110 }
01111 ast_frfree(f);
01112 }
01113 if (!*to)
01114 ast_verb(3, "Nobody picked up in %d ms\n", orig);
01115 if (!*to || ast_check_hangup(in))
01116 ast_cdr_noanswer(in->cdr);
01117 }
01118
01119 #ifdef HAVE_EPOLL
01120 for (epollo = outgoing; epollo; epollo = epollo->next) {
01121 if (epollo->chan)
01122 ast_poll_channel_del(in, epollo->chan);
01123 }
01124 #endif
01125
01126 return peer;
01127 }
01128
01129 static void replace_macro_delimiter(char *s)
01130 {
01131 for (; *s; s++)
01132 if (*s == '^')
01133 *s = ',';
01134 }
01135
01136
01137 static int valid_priv_reply(struct ast_flags64 *opts, int res)
01138 {
01139 if (res < '1')
01140 return 0;
01141 if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
01142 return 1;
01143 if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
01144 return 1;
01145 return 0;
01146 }
01147
01148 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
01149 char *parse, struct timeval *calldurationlimit)
01150 {
01151 char *stringp = ast_strdupa(parse);
01152 char *limit_str, *warning_str, *warnfreq_str;
01153 const char *var;
01154 int play_to_caller = 0, play_to_callee = 0;
01155 int delta;
01156
01157 limit_str = strsep(&stringp, ":");
01158 warning_str = strsep(&stringp, ":");
01159 warnfreq_str = strsep(&stringp, ":");
01160
01161 config->timelimit = atol(limit_str);
01162 if (warning_str)
01163 config->play_warning = atol(warning_str);
01164 if (warnfreq_str)
01165 config->warning_freq = atol(warnfreq_str);
01166
01167 if (!config->timelimit) {
01168 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
01169 config->timelimit = config->play_warning = config->warning_freq = 0;
01170 config->warning_sound = NULL;
01171 return -1;
01172 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
01173 int w = config->warning_freq;
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187 if (w == 0) {
01188 config->play_warning = 0;
01189 } else {
01190 config->play_warning -= w * ( 1 + (delta-1)/w );
01191 if (config->play_warning < 1)
01192 config->play_warning = config->warning_freq = 0;
01193 }
01194 }
01195
01196 ast_channel_lock(chan);
01197
01198 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
01199
01200 play_to_caller = var ? ast_true(var) : 1;
01201
01202 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
01203 play_to_callee = var ? ast_true(var) : 0;
01204
01205 if (!play_to_caller && !play_to_callee)
01206 play_to_caller = 1;
01207
01208 var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
01209 config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
01210
01211
01212
01213
01214
01215
01216
01217 var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
01218 config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
01219
01220 var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
01221 config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
01222
01223 ast_channel_unlock(chan);
01224
01225
01226 calldurationlimit->tv_sec = 0;
01227 calldurationlimit->tv_usec = 0;
01228
01229
01230 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
01231 calldurationlimit->tv_sec = config->timelimit / 1000;
01232 calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
01233 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
01234 calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
01235 config->timelimit = play_to_caller = play_to_callee =
01236 config->play_warning = config->warning_freq = 0;
01237 } else {
01238 ast_verb(3, "Limit Data for this call:\n");
01239 ast_verb(4, "timelimit = %ld\n", config->timelimit);
01240 ast_verb(4, "play_warning = %ld\n", config->play_warning);
01241 ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
01242 ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
01243 ast_verb(4, "warning_freq = %ld\n", config->warning_freq);
01244 ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
01245 ast_verb(4, "warning_sound = %s\n", config->warning_sound);
01246 ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
01247 }
01248 if (play_to_caller)
01249 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
01250 if (play_to_callee)
01251 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
01252 return 0;
01253 }
01254
01255 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
01256 struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
01257 {
01258
01259 int res2;
01260 int loopcount = 0;
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270 if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01271 char *original_moh = ast_strdupa(chan->musicclass);
01272 ast_indicate(chan, -1);
01273 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01274 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01275 ast_string_field_set(chan, musicclass, original_moh);
01276 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01277 ast_indicate(chan, AST_CONTROL_RINGING);
01278 pa->sentringing++;
01279 }
01280
01281
01282 res2 = ast_autoservice_start(chan);
01283
01284 for (loopcount = 0; loopcount < 3; loopcount++) {
01285 if (res2 && loopcount == 0)
01286 break;
01287 if (!res2)
01288 res2 = ast_play_and_wait(peer, "priv-callpending");
01289 if (!valid_priv_reply(opts, res2))
01290 res2 = 0;
01291
01292
01293
01294 if (!res2)
01295 res2 = ast_play_and_wait(peer, pa->privintro);
01296 if (!valid_priv_reply(opts, res2))
01297 res2 = 0;
01298
01299 if (!res2) {
01300
01301 if (ast_test_flag64(opts, OPT_PRIVACY))
01302 res2 = ast_play_and_wait(peer, "priv-callee-options");
01303 if (ast_test_flag64(opts, OPT_SCREENING))
01304 res2 = ast_play_and_wait(peer, "screen-callee-options");
01305 }
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 if (valid_priv_reply(opts, res2))
01323 break;
01324
01325 res2 = ast_play_and_wait(peer, "vm-sorry");
01326 }
01327
01328 if (ast_test_flag64(opts, OPT_MUSICBACK)) {
01329 ast_moh_stop(chan);
01330 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01331 ast_indicate(chan, -1);
01332 pa->sentringing = 0;
01333 }
01334 ast_autoservice_stop(chan);
01335 if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
01336
01337 static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
01338 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
01339 int i = res2 - '1';
01340 ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
01341 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
01342 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
01343 }
01344 switch (res2) {
01345 case '1':
01346 break;
01347 case '2':
01348 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01349 break;
01350 case '3':
01351 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01352 break;
01353 case '4':
01354 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01355 break;
01356 case '5':
01357
01358 if (ast_test_flag64(opts, OPT_PRIVACY))
01359 break;
01360
01361 default:
01362
01363
01364
01365
01366 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
01367
01368
01369 break;
01370 }
01371
01372 if (res2 == '1') {
01373
01374
01375 if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
01376 ast_filedelete(pa->privintro, NULL);
01377 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01378 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01379 else
01380 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01381 }
01382 return 0;
01383 } else {
01384 ast_hangup(peer);
01385 return -1;
01386 }
01387 }
01388
01389
01390 static int setup_privacy_args(struct privacy_args *pa,
01391 struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
01392 {
01393 char callerid[60];
01394 int res;
01395 char *l;
01396 int silencethreshold;
01397
01398 if (!ast_strlen_zero(chan->cid.cid_num)) {
01399 l = ast_strdupa(chan->cid.cid_num);
01400 ast_shrink_phone_number(l);
01401 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
01402 ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
01403 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
01404 } else {
01405 ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
01406 pa->privdb_val = AST_PRIVACY_UNKNOWN;
01407 }
01408 } else {
01409 char *tnam, *tn2;
01410
01411 tnam = ast_strdupa(chan->name);
01412
01413 for (tn2 = tnam; *tn2; tn2++) {
01414 if (*tn2 == '/')
01415 *tn2 = '=';
01416 }
01417 ast_verb(3, "Privacy-- callerid is empty\n");
01418
01419 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
01420 l = callerid;
01421 pa->privdb_val = AST_PRIVACY_UNKNOWN;
01422 }
01423
01424 ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
01425
01426 if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCLID)) {
01427
01428 ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
01429 pa->privdb_val = AST_PRIVACY_ALLOW;
01430 } else if (ast_test_flag64(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
01431 ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
01432 }
01433
01434 if (pa->privdb_val == AST_PRIVACY_DENY) {
01435 ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
01436 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01437 return 0;
01438 } else if (pa->privdb_val == AST_PRIVACY_KILL) {
01439 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01440 return 0;
01441 } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
01442 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01443 return 0;
01444 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
01445
01446
01447
01448
01449
01450 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
01451 if ((res = ast_mkdir(pa->privintro, 0755))) {
01452 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
01453 return -1;
01454 }
01455
01456 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
01457 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
01458
01459
01460
01461 } else {
01462 int duration;
01463
01464
01465
01466
01467
01468
01469
01470 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
01471 ast_answer(chan);
01472 res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, silencethreshold, 2000, 0);
01473
01474
01475 if (res == -1) {
01476
01477 ast_filedelete(pa->privintro, NULL);
01478 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01479 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01480 else
01481 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01482 return -1;
01483 }
01484 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
01485 ast_waitstream(chan, "");
01486 }
01487 }
01488 return 1;
01489 }
01490
01491 static void end_bridge_callback(void *data)
01492 {
01493 char buf[80];
01494 time_t end;
01495 struct ast_channel *chan = data;
01496
01497 if (!chan->cdr) {
01498 return;
01499 }
01500
01501 time(&end);
01502
01503 ast_channel_lock(chan);
01504 if (chan->cdr->answer.tv_sec) {
01505 snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->answer.tv_sec);
01506 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
01507 }
01508
01509 if (chan->cdr->start.tv_sec) {
01510 snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->start.tv_sec);
01511 pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
01512 }
01513 ast_channel_unlock(chan);
01514 }
01515
01516 static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) {
01517 bconfig->end_bridge_callback_data = originator;
01518 }
01519
01520 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec)
01521 {
01522 int res = -1;
01523 char *rest, *cur;
01524 struct chanlist *outgoing = NULL;
01525 struct ast_channel *peer;
01526 int to;
01527 struct cause_args num = { chan, 0, 0, 0 };
01528 int cause;
01529 char numsubst[256];
01530 char cidname[AST_MAX_EXTENSION] = "";
01531
01532 struct ast_bridge_config config = { { 0, } };
01533 struct timeval calldurationlimit = { 0, };
01534 char *dtmfcalled = NULL, *dtmfcalling = NULL;
01535 struct privacy_args pa = {
01536 .sentringing = 0,
01537 .privdb_val = 0,
01538 .status = "INVALIDARGS",
01539 };
01540 int sentringing = 0, moh = 0;
01541 const char *outbound_group = NULL;
01542 int result = 0;
01543 char *parse;
01544 int opermode = 0;
01545 int delprivintro = 0;
01546 AST_DECLARE_APP_ARGS(args,
01547 AST_APP_ARG(peers);
01548 AST_APP_ARG(timeout);
01549 AST_APP_ARG(options);
01550 AST_APP_ARG(url);
01551 );
01552 struct ast_flags64 opts = { 0, };
01553 char *opt_args[OPT_ARG_ARRAY_SIZE];
01554 struct ast_datastore *datastore = NULL;
01555 int fulldial = 0, num_dialed = 0;
01556
01557
01558 pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
01559 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
01560 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
01561 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
01562 pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
01563
01564 if (ast_strlen_zero(data)) {
01565 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01566 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01567 return -1;
01568 }
01569
01570 parse = ast_strdupa(data);
01571
01572 AST_STANDARD_APP_ARGS(args, parse);
01573
01574 if (!ast_strlen_zero(args.options) &&
01575 ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
01576 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01577 goto done;
01578 }
01579
01580 if (ast_strlen_zero(args.peers)) {
01581 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01582 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01583 goto done;
01584 }
01585
01586
01587 if (ast_test_flag64(&opts, OPT_SCREEN_NOINTRO) && !ast_strlen_zero(opt_args[OPT_ARG_SCREEN_NOINTRO])) {
01588 delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
01589
01590 if (delprivintro < 0 || delprivintro > 1) {
01591 ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
01592 delprivintro = 0;
01593 }
01594 }
01595
01596 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
01597 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
01598 ast_verb(3, "Setting operator services mode to %d.\n", opermode);
01599 }
01600
01601 if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
01602 calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
01603 if (!calldurationlimit.tv_sec) {
01604 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
01605 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01606 goto done;
01607 }
01608 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
01609 }
01610
01611 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
01612 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
01613 dtmfcalled = strsep(&dtmfcalling, ":");
01614 }
01615
01616 if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
01617 if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
01618 goto done;
01619 }
01620
01621 if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
01622 ast_cdr_reset(chan->cdr, NULL);
01623 if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
01624 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
01625
01626 if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
01627 res = setup_privacy_args(&pa, &opts, opt_args, chan);
01628 if (res <= 0)
01629 goto out;
01630 res = -1;
01631 }
01632
01633 if (ast_test_flag64(&opts, OPT_DTMF_EXIT)) {
01634 __ast_answer(chan, 0, 0);
01635 }
01636
01637 if (continue_exec)
01638 *continue_exec = 0;
01639
01640
01641
01642 ast_channel_lock(chan);
01643 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
01644 outbound_group = ast_strdupa(outbound_group);
01645 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
01646 } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
01647 outbound_group = ast_strdupa(outbound_group);
01648 }
01649 ast_channel_unlock(chan);
01650 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);
01651
01652
01653 rest = args.peers;
01654 while ((cur = strsep(&rest, "&")) ) {
01655 struct chanlist *tmp;
01656 struct ast_channel *tc;
01657
01658 char *number = cur;
01659 char *interface = ast_strdupa(number);
01660 char *tech = strsep(&number, "/");
01661
01662 struct ast_dialed_interface *di;
01663 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
01664 num_dialed++;
01665 if (!number) {
01666 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
01667 goto out;
01668 }
01669 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01670 goto out;
01671 if (opts.flags) {
01672 ast_copy_flags64(tmp, &opts,
01673 OPT_CANCEL_ELSEWHERE |
01674 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
01675 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
01676 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
01677 OPT_CALLEE_PARK | OPT_CALLER_PARK |
01678 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
01679 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
01680 ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
01681 }
01682 ast_copy_string(numsubst, number, sizeof(numsubst));
01683
01684
01685 ast_channel_lock(chan);
01686 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
01687 ast_channel_unlock(chan);
01688
01689 if (datastore)
01690 dialed_interfaces = datastore->data;
01691 else {
01692 if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
01693 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
01694 ast_free(tmp);
01695 goto out;
01696 }
01697
01698 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
01699
01700 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
01701 ast_datastore_free(datastore);
01702 ast_free(tmp);
01703 goto out;
01704 }
01705
01706 datastore->data = dialed_interfaces;
01707 AST_LIST_HEAD_INIT(dialed_interfaces);
01708
01709 ast_channel_lock(chan);
01710 ast_channel_datastore_add(chan, datastore);
01711 ast_channel_unlock(chan);
01712 }
01713
01714 AST_LIST_LOCK(dialed_interfaces);
01715 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
01716 if (!strcasecmp(di->interface, interface)) {
01717 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
01718 di->interface);
01719 break;
01720 }
01721 }
01722 AST_LIST_UNLOCK(dialed_interfaces);
01723
01724 if (di) {
01725 fulldial++;
01726 ast_free(tmp);
01727 continue;
01728 }
01729
01730
01731
01732
01733
01734 if (strcasecmp(tech, "Local")) {
01735 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
01736 AST_LIST_UNLOCK(dialed_interfaces);
01737 ast_free(tmp);
01738 goto out;
01739 }
01740 strcpy(di->interface, interface);
01741
01742 AST_LIST_LOCK(dialed_interfaces);
01743 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
01744 AST_LIST_UNLOCK(dialed_interfaces);
01745 }
01746
01747 tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
01748 if (!tc) {
01749
01750 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
01751 tech, cause, ast_cause2str(cause));
01752 handle_cause(cause, &num);
01753 if (!rest)
01754 chan->hangupcause = cause;
01755 ast_free(tmp);
01756 continue;
01757 }
01758 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
01759
01760
01761 if (CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
01762 ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
01763 }
01764
01765
01766 ast_channel_inherit_variables(chan, tc);
01767 ast_channel_datastore_inherit(chan, tc);
01768
01769 tc->appl = "AppDial";
01770 tc->data = "(Outgoing Line)";
01771 memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
01772
01773 S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
01774 S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
01775 S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
01776 S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
01777
01778 ast_string_field_set(tc, accountcode, chan->accountcode);
01779 tc->cdrflags = chan->cdrflags;
01780 if (ast_strlen_zero(tc->musicclass))
01781 ast_string_field_set(tc, musicclass, chan->musicclass);
01782
01783 tc->cid.cid_pres = chan->cid.cid_pres;
01784 tc->cid.cid_ton = chan->cid.cid_ton;
01785 tc->cid.cid_tns = chan->cid.cid_tns;
01786 tc->cid.cid_ani2 = chan->cid.cid_ani2;
01787 tc->adsicpe = chan->adsicpe;
01788 tc->transfercapability = chan->transfercapability;
01789
01790
01791 if (outbound_group)
01792 ast_app_group_set_channel(tc, outbound_group);
01793
01794 if (ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE))
01795 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
01796
01797
01798 if (ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE))
01799 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
01800
01801
01802
01803 ast_string_field_set(tc, dialcontext, ast_strlen_zero(chan->macrocontext) ? chan->context : chan->macrocontext);
01804 if (!ast_strlen_zero(chan->macroexten))
01805 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
01806 else
01807 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
01808
01809 res = ast_call(tc, numsubst, 0);
01810
01811
01812 if (chan->cdr)
01813 ast_cdr_setdestchan(chan->cdr, tc->name);
01814
01815
01816 if (res) {
01817
01818 ast_debug(1, "ast call on peer returned %d\n", res);
01819 ast_verb(3, "Couldn't call %s\n", numsubst);
01820 if (tc->hangupcause) {
01821 chan->hangupcause = tc->hangupcause;
01822 }
01823 ast_hangup(tc);
01824 tc = NULL;
01825 ast_free(tmp);
01826 continue;
01827 } else {
01828 senddialevent(chan, tc, numsubst);
01829 ast_verb(3, "Called %s\n", numsubst);
01830 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID))
01831 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
01832 }
01833
01834
01835
01836 ast_set_flag64(tmp, DIAL_STILLGOING);
01837 tmp->chan = tc;
01838 tmp->next = outgoing;
01839 outgoing = tmp;
01840
01841 if (outgoing->chan->_state == AST_STATE_UP)
01842 break;
01843 }
01844
01845 if (ast_strlen_zero(args.timeout)) {
01846 to = -1;
01847 } else {
01848 to = atoi(args.timeout);
01849 if (to > 0)
01850 to *= 1000;
01851 else {
01852 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
01853 to = -1;
01854 }
01855 }
01856
01857 if (!outgoing) {
01858 strcpy(pa.status, "CHANUNAVAIL");
01859 if (fulldial == num_dialed) {
01860 res = -1;
01861 goto out;
01862 }
01863 } else {
01864
01865 strcpy(pa.status, "NOANSWER");
01866 if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
01867 moh = 1;
01868 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01869 char *original_moh = ast_strdupa(chan->musicclass);
01870 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01871 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01872 ast_string_field_set(chan, musicclass, original_moh);
01873 } else {
01874 ast_moh_start(chan, NULL, NULL);
01875 }
01876 ast_indicate(chan, AST_CONTROL_PROGRESS);
01877 } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
01878 ast_indicate(chan, AST_CONTROL_RINGING);
01879 sentringing++;
01880 }
01881 }
01882
01883 peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
01884
01885
01886
01887
01888
01889
01890
01891 if (!ast_channel_datastore_remove(chan, datastore))
01892 ast_datastore_free(datastore);
01893 if (!peer) {
01894 if (result) {
01895 res = result;
01896 } else if (to) {
01897 res = -1;
01898 } else {
01899 res = 0;
01900 }
01901
01902
01903
01904 if (chan->hangupcause == AST_CAUSE_INVALID_NUMBER_FORMAT) {
01905 res = AST_PBX_INCOMPLETE;
01906 }
01907
01908
01909 } else {
01910 const char *number;
01911
01912 strcpy(pa.status, "ANSWER");
01913 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01914
01915
01916
01917 hanguptree(outgoing, peer, 1);
01918 outgoing = NULL;
01919
01920 if (chan->cdr)
01921 ast_cdr_setdestchan(chan->cdr, peer->name);
01922 if (peer->name)
01923 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
01924
01925 ast_channel_lock(peer);
01926 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
01927 if (!number)
01928 number = numsubst;
01929 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
01930 ast_channel_unlock(peer);
01931
01932 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
01933 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
01934 ast_channel_sendurl( peer, args.url );
01935 }
01936 if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
01937 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
01938 res = 0;
01939 goto out;
01940 }
01941 }
01942 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
01943 res = 0;
01944 } else {
01945 int digit = 0;
01946 struct ast_channel *chans[2];
01947 struct ast_channel *active_chan;
01948
01949 chans[0] = chan;
01950 chans[1] = peer;
01951
01952
01953
01954
01955 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
01956 if (res) {
01957 res = 0;
01958 ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
01959 }
01960
01961 ast_set_flag(peer, AST_FLAG_END_DTMF_ONLY);
01962 while (peer->stream) {
01963 int ms;
01964
01965 ms = ast_sched_wait(peer->sched);
01966
01967 if (ms < 0 && !peer->timingfunc) {
01968 ast_stopstream(peer);
01969 break;
01970 }
01971 if (ms < 0)
01972 ms = 1000;
01973
01974 active_chan = ast_waitfor_n(chans, 2, &ms);
01975 if (active_chan) {
01976 struct ast_frame *fr = ast_read(active_chan);
01977 if (!fr) {
01978 ast_hangup(peer);
01979 res = -1;
01980 goto done;
01981 }
01982 switch(fr->frametype) {
01983 case AST_FRAME_DTMF_END:
01984 digit = fr->subclass;
01985 if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
01986 ast_stopstream(peer);
01987 res = ast_senddigit(chan, digit, 0);
01988 }
01989 break;
01990 case AST_FRAME_CONTROL:
01991 switch (fr->subclass) {
01992 case AST_CONTROL_HANGUP:
01993 ast_frfree(fr);
01994 ast_hangup(peer);
01995 res = -1;
01996 goto done;
01997 default:
01998 break;
01999 }
02000 break;
02001 default:
02002
02003 break;
02004 }
02005 ast_frfree(fr);
02006 }
02007 ast_sched_runq(peer->sched);
02008 }
02009 ast_clear_flag(peer, AST_FLAG_END_DTMF_ONLY);
02010 }
02011
02012 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
02013
02014
02015 ast_clear_flag(chan->cdr, AST_CDR_FLAG_DIALED);
02016 ast_clear_flag(peer->cdr, AST_CDR_FLAG_DIALED);
02017
02018 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
02019 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
02020
02021 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02022 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02023 peer->priority = chan->priority + 2;
02024 ast_pbx_start(peer);
02025 hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
02026 if (continue_exec)
02027 *continue_exec = 1;
02028 res = 0;
02029 goto done;
02030 }
02031
02032 if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
02033 struct ast_app *theapp;
02034 const char *macro_result;
02035
02036 res = ast_autoservice_start(chan);
02037 if (res) {
02038 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02039 res = -1;
02040 }
02041
02042 theapp = pbx_findapp("Macro");
02043
02044 if (theapp && !res) {
02045
02046 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02047 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02048
02049 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
02050 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
02051 ast_debug(1, "Macro exited with status %d\n", res);
02052 res = 0;
02053 } else {
02054 ast_log(LOG_ERROR, "Could not find application Macro\n");
02055 res = -1;
02056 }
02057
02058 if (ast_autoservice_stop(chan) < 0) {
02059 res = -1;
02060 }
02061
02062 ast_channel_lock(peer);
02063
02064 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
02065 char *macro_transfer_dest;
02066
02067 if (!strcasecmp(macro_result, "BUSY")) {
02068 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02069 ast_set_flag64(peerflags, OPT_GO_ON);
02070 res = -1;
02071 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
02072 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02073 ast_set_flag64(peerflags, OPT_GO_ON);
02074 res = -1;
02075 } else if (!strcasecmp(macro_result, "CONTINUE")) {
02076
02077
02078
02079
02080 ast_set_flag64(peerflags, OPT_GO_ON);
02081 res = -1;
02082 } else if (!strcasecmp(macro_result, "ABORT")) {
02083
02084 res = -1;
02085 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
02086 res = -1;
02087
02088 if (strchr(macro_transfer_dest, '^')) {
02089 replace_macro_delimiter(macro_transfer_dest);
02090 if (!ast_parseable_goto(chan, macro_transfer_dest))
02091 ast_set_flag64(peerflags, OPT_GO_ON);
02092 }
02093 }
02094 }
02095
02096 ast_channel_unlock(peer);
02097 }
02098
02099 if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
02100 struct ast_app *theapp;
02101 const char *gosub_result;
02102 char *gosub_args, *gosub_argstart;
02103 int res9 = -1;
02104
02105 res9 = ast_autoservice_start(chan);
02106 if (res9) {
02107 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02108 res9 = -1;
02109 }
02110
02111 theapp = pbx_findapp("Gosub");
02112
02113 if (theapp && !res9) {
02114 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
02115
02116
02117 ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
02118 ast_copy_string(peer->exten, "s", sizeof(peer->exten));
02119 peer->priority = 0;
02120
02121 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
02122 if (gosub_argstart) {
02123 *gosub_argstart = 0;
02124 if (asprintf(&gosub_args, "%s,s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1) < 0) {
02125 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02126 gosub_args = NULL;
02127 }
02128 *gosub_argstart = ',';
02129 } else {
02130 if (asprintf(&gosub_args, "%s,s,1", opt_args[OPT_ARG_CALLEE_GOSUB]) < 0) {
02131 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02132 gosub_args = NULL;
02133 }
02134 }
02135
02136 if (gosub_args) {
02137 res9 = pbx_exec(peer, theapp, gosub_args);
02138 if (!res9) {
02139 struct ast_pbx_args args;
02140
02141 memset(&args, 0, sizeof(args));
02142 args.no_hangup_chan = 1;
02143 ast_pbx_run_args(peer, &args);
02144 }
02145 ast_free(gosub_args);
02146 ast_debug(1, "Gosub exited with status %d\n", res9);
02147 } else {
02148 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
02149 }
02150
02151 } else if (!res9) {
02152 ast_log(LOG_ERROR, "Could not find application Gosub\n");
02153 res9 = -1;
02154 }
02155
02156 if (ast_autoservice_stop(chan) < 0) {
02157 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
02158 res9 = -1;
02159 }
02160
02161 ast_channel_lock(peer);
02162
02163 if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
02164 char *gosub_transfer_dest;
02165
02166 if (!strcasecmp(gosub_result, "BUSY")) {
02167 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02168 ast_set_flag64(peerflags, OPT_GO_ON);
02169 res = -1;
02170 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
02171 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02172 ast_set_flag64(peerflags, OPT_GO_ON);
02173 res = -1;
02174 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
02175
02176
02177
02178
02179 ast_set_flag64(peerflags, OPT_GO_ON);
02180 res = -1;
02181 } else if (!strcasecmp(gosub_result, "ABORT")) {
02182
02183 res = -1;
02184 } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
02185 res = -1;
02186
02187 if (strchr(gosub_transfer_dest, '^')) {
02188 replace_macro_delimiter(gosub_transfer_dest);
02189 if (!ast_parseable_goto(chan, gosub_transfer_dest))
02190 ast_set_flag64(peerflags, OPT_GO_ON);
02191 }
02192 }
02193 }
02194
02195 ast_channel_unlock(peer);
02196 }
02197
02198 if (!res) {
02199 if (!ast_tvzero(calldurationlimit)) {
02200 struct timeval whentohangup = calldurationlimit;
02201 peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
02202 }
02203 if (!ast_strlen_zero(dtmfcalled)) {
02204 ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
02205 res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
02206 }
02207 if (!ast_strlen_zero(dtmfcalling)) {
02208 ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
02209 res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
02210 }
02211 }
02212
02213 if (res) {
02214 res = -1;
02215 } else {
02216 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
02217 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
02218 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
02219 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
02220 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
02221 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
02222 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
02223 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
02224 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
02225 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
02226 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
02227 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
02228 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
02229 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
02230 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
02231 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
02232 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
02233 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
02234 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
02235 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
02236 if (ast_test_flag64(peerflags, OPT_GO_ON))
02237 ast_set_flag(&(config.features_caller), AST_FEATURE_NO_H_EXTEN);
02238
02239 config.end_bridge_callback = end_bridge_callback;
02240 config.end_bridge_callback_data = chan;
02241 config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
02242
02243 if (moh) {
02244 moh = 0;
02245 ast_moh_stop(chan);
02246 } else if (sentringing) {
02247 sentringing = 0;
02248 ast_indicate(chan, -1);
02249 }
02250
02251 ast_deactivate_generator(chan);
02252 chan->visible_indication = 0;
02253
02254 res = ast_channel_make_compatible(chan, peer);
02255 if (res < 0) {
02256 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
02257 ast_hangup(peer);
02258 res = -1;
02259 goto done;
02260 }
02261 if (opermode) {
02262 struct oprmode oprmode;
02263
02264 oprmode.peer = peer;
02265 oprmode.mode = opermode;
02266
02267 ast_channel_setoption(chan, AST_OPTION_OPRMODE, &oprmode, sizeof(oprmode), 0);
02268 }
02269 res = ast_bridge_call(chan, peer, &config);
02270 }
02271
02272 strcpy(peer->context, chan->context);
02273
02274 if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
02275 int autoloopflag;
02276 int found;
02277 int res9;
02278
02279 strcpy(peer->exten, "h");
02280 peer->priority = 1;
02281 autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP);
02282 ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
02283
02284 while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
02285 peer->priority++;
02286
02287 if (found && res9) {
02288
02289 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02290 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02291 }
02292 ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);
02293 }
02294 if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
02295 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
02296 ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
02297 ast_pbx_start(peer);
02298 } else {
02299 if (!ast_check_hangup(chan))
02300 chan->hangupcause = peer->hangupcause;
02301 ast_hangup(peer);
02302 }
02303 }
02304 out:
02305 if (moh) {
02306 moh = 0;
02307 ast_moh_stop(chan);
02308 } else if (sentringing) {
02309 sentringing = 0;
02310 ast_indicate(chan, -1);
02311 }
02312
02313 if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02314 ast_filedelete(pa.privintro, NULL);
02315 if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02316 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
02317 } else {
02318 ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
02319 }
02320 }
02321
02322 ast_channel_early_bridge(chan, NULL);
02323 hanguptree(outgoing, NULL, 0);
02324 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
02325 senddialendevent(chan, pa.status);
02326 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
02327
02328 if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
02329 if (!ast_tvzero(calldurationlimit))
02330 memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
02331 res = 0;
02332 }
02333
02334 done:
02335 if (config.warning_sound) {
02336 ast_free((char *)config.warning_sound);
02337 }
02338 if (config.end_sound) {
02339 ast_free((char *)config.end_sound);
02340 }
02341 if (config.start_sound) {
02342 ast_free((char *)config.start_sound);
02343 }
02344 return res;
02345 }
02346
02347 static int dial_exec(struct ast_channel *chan, void *data)
02348 {
02349 struct ast_flags64 peerflags;
02350
02351 memset(&peerflags, 0, sizeof(peerflags));
02352
02353 return dial_exec_full(chan, data, &peerflags, NULL);
02354 }
02355
02356 static int retrydial_exec(struct ast_channel *chan, void *data)
02357 {
02358 char *parse;
02359 const char *context = NULL;
02360 int sleepms = 0, loops = 0, res = -1;
02361 struct ast_flags64 peerflags = { 0, };
02362 AST_DECLARE_APP_ARGS(args,
02363 AST_APP_ARG(announce);
02364 AST_APP_ARG(sleep);
02365 AST_APP_ARG(retries);
02366 AST_APP_ARG(dialdata);
02367 );
02368
02369 if (ast_strlen_zero(data)) {
02370 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
02371 return -1;
02372 }
02373
02374 parse = ast_strdupa(data);
02375 AST_STANDARD_APP_ARGS(args, parse);
02376
02377 if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
02378 sleepms *= 1000;
02379
02380 if (!ast_strlen_zero(args.retries)) {
02381 loops = atoi(args.retries);
02382 }
02383
02384 if (!args.dialdata) {
02385 ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
02386 goto done;
02387 }
02388
02389 if (sleepms < 1000)
02390 sleepms = 10000;
02391
02392 if (!loops)
02393 loops = -1;
02394
02395 ast_channel_lock(chan);
02396 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
02397 context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
02398 ast_channel_unlock(chan);
02399
02400 res = 0;
02401 while (loops) {
02402 int continue_exec;
02403
02404 chan->data = "Retrying";
02405 if (ast_test_flag(chan, AST_FLAG_MOH))
02406 ast_moh_stop(chan);
02407
02408 res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
02409 if (continue_exec)
02410 break;
02411
02412 if (res == 0) {
02413 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
02414 if (!ast_strlen_zero(args.announce)) {
02415 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02416 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02417 ast_waitstream(chan, AST_DIGIT_ANY);
02418 } else
02419 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02420 }
02421 if (!res && sleepms) {
02422 if (!ast_test_flag(chan, AST_FLAG_MOH))
02423 ast_moh_start(chan, NULL, NULL);
02424 res = ast_waitfordigit(chan, sleepms);
02425 }
02426 } else {
02427 if (!ast_strlen_zero(args.announce)) {
02428 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02429 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02430 res = ast_waitstream(chan, "");
02431 } else
02432 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02433 }
02434 if (sleepms) {
02435 if (!ast_test_flag(chan, AST_FLAG_MOH))
02436 ast_moh_start(chan, NULL, NULL);
02437 if (!res)
02438 res = ast_waitfordigit(chan, sleepms);
02439 }
02440 }
02441 }
02442
02443 if (res < 0 || res == AST_PBX_INCOMPLETE) {
02444 break;
02445 } else if (res > 0) {
02446 if (onedigit_goto(chan, context, (char) res, 1)) {
02447 res = 0;
02448 break;
02449 }
02450 }
02451 loops--;
02452 }
02453 if (loops == 0)
02454 res = 0;
02455 else if (res == 1)
02456 res = 0;
02457
02458 if (ast_test_flag(chan, AST_FLAG_MOH))
02459 ast_moh_stop(chan);
02460 done:
02461 return res;
02462 }
02463
02464 static int unload_module(void)
02465 {
02466 int res;
02467 struct ast_context *con;
02468
02469 res = ast_unregister_application(app);
02470 res |= ast_unregister_application(rapp);
02471
02472 if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
02473 ast_context_remove_extension2(con, "s", 1, NULL, 0);
02474 ast_context_destroy(con, "app_dial");
02475 }
02476
02477 return res;
02478 }
02479
02480 static int load_module(void)
02481 {
02482 int res;
02483 struct ast_context *con;
02484
02485 con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
02486 if (!con)
02487 ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
02488 else
02489 ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial");
02490
02491 res = ast_register_application_xml(app, dial_exec);
02492 res |= ast_register_application_xml(rapp, retrydial_exec);
02493
02494 return res;
02495 }
02496
02497 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");