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