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