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: 296002 $")
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 {
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 frame\n");
01329 }
01330 break;
01331 case AST_FRAME_HTML:
01332 if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
01333 ast_log(LOG_WARNING, "Unable to send URL\n");
01334 }
01335 break;
01336 default:
01337 break;
01338 }
01339 }
01340 ast_frfree(f);
01341 }
01342 if (winner == in) {
01343 struct ast_frame *f = ast_read(in);
01344 #if 0
01345 if (f && (f->frametype != AST_FRAME_VOICE))
01346 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
01347 else if (!f || (f->frametype != AST_FRAME_VOICE))
01348 printf("Hangup received on %s\n", in->name);
01349 #endif
01350 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
01351
01352 *to = -1;
01353 strcpy(pa->status, "CANCEL");
01354 ast_cdr_noanswer(in->cdr);
01355 if (f) {
01356 if (f->data.uint32) {
01357 in->hangupcause = f->data.uint32;
01358 }
01359 ast_frfree(f);
01360 }
01361 if (is_cc_recall) {
01362 ast_cc_completed(in, "CC completed, although the caller hung up (cancelled)");
01363 }
01364 return NULL;
01365 }
01366
01367
01368 if (f->frametype == AST_FRAME_DTMF) {
01369 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
01370 const char *context;
01371 ast_channel_lock(in);
01372 context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
01373 if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
01374 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
01375 *to = 0;
01376 ast_cdr_noanswer(in->cdr);
01377 *result = f->subclass.integer;
01378 strcpy(pa->status, "CANCEL");
01379 ast_frfree(f);
01380 ast_channel_unlock(in);
01381 if (is_cc_recall) {
01382 ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
01383 }
01384 return NULL;
01385 }
01386 ast_channel_unlock(in);
01387 }
01388
01389 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
01390 detect_disconnect(in, f->subclass.integer, featurecode)) {
01391 ast_verb(3, "User requested call disconnect.\n");
01392 *to = 0;
01393 strcpy(pa->status, "CANCEL");
01394 ast_cdr_noanswer(in->cdr);
01395 ast_frfree(f);
01396 if (is_cc_recall) {
01397 ast_cc_completed(in, "CC completed, but the caller hung up with DTMF");
01398 }
01399 return NULL;
01400 }
01401 }
01402
01403
01404 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
01405 if (ast_channel_sendhtml(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1)
01406 ast_log(LOG_WARNING, "Unable to send URL\n");
01407
01408 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
01409 if (ast_write(outgoing->chan, f))
01410 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
01411 }
01412 if (single && (f->frametype == AST_FRAME_CONTROL)) {
01413 if ((f->subclass.integer == AST_CONTROL_HOLD) ||
01414 (f->subclass.integer == AST_CONTROL_UNHOLD) ||
01415 (f->subclass.integer == AST_CONTROL_VIDUPDATE) ||
01416 (f->subclass.integer == AST_CONTROL_SRCUPDATE)) {
01417 ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass.integer, outgoing->chan->name);
01418 ast_indicate_data(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen);
01419 } else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
01420 if (ast_channel_connected_line_macro(in, outgoing->chan, f, 0, 1)) {
01421 ast_indicate_data(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen);
01422 }
01423 } else if (f->subclass.integer == AST_CONTROL_REDIRECTING) {
01424 if (ast_channel_redirecting_macro(in, outgoing->chan, f, 0, 1)) {
01425 ast_indicate_data(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen);
01426 }
01427 }
01428 }
01429 ast_frfree(f);
01430 }
01431 if (!*to)
01432 ast_verb(3, "Nobody picked up in %d ms\n", orig);
01433 if (!*to || ast_check_hangup(in))
01434 ast_cdr_noanswer(in->cdr);
01435 }
01436
01437 #ifdef HAVE_EPOLL
01438 for (epollo = outgoing; epollo; epollo = epollo->next) {
01439 if (epollo->chan)
01440 ast_poll_channel_del(in, epollo->chan);
01441 }
01442 #endif
01443
01444 if (is_cc_recall) {
01445 ast_cc_completed(in, "Recall completed!");
01446 }
01447 return peer;
01448 }
01449
01450 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode)
01451 {
01452 struct ast_flags features = { AST_FEATURE_DISCONNECT };
01453 struct ast_call_feature feature = { 0, };
01454 int res;
01455
01456 ast_str_append(&featurecode, 1, "%c", code);
01457
01458 res = ast_feature_detect(chan, &features, ast_str_buffer(featurecode), &feature);
01459
01460 if (res != AST_FEATURE_RETURN_STOREDIGITS) {
01461 ast_str_reset(featurecode);
01462 }
01463 if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
01464 return 1;
01465 }
01466
01467 return 0;
01468 }
01469
01470 static void replace_macro_delimiter(char *s)
01471 {
01472 for (; *s; s++)
01473 if (*s == '^')
01474 *s = ',';
01475 }
01476
01477
01478 static int valid_priv_reply(struct ast_flags64 *opts, int res)
01479 {
01480 if (res < '1')
01481 return 0;
01482 if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
01483 return 1;
01484 if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
01485 return 1;
01486 return 0;
01487 }
01488
01489 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
01490 struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
01491 {
01492
01493 int res2;
01494 int loopcount = 0;
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504 if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01505 char *original_moh = ast_strdupa(chan->musicclass);
01506 ast_indicate(chan, -1);
01507 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01508 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01509 ast_string_field_set(chan, musicclass, original_moh);
01510 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01511 ast_indicate(chan, AST_CONTROL_RINGING);
01512 pa->sentringing++;
01513 }
01514
01515
01516 res2 = ast_autoservice_start(chan);
01517
01518 for (loopcount = 0; loopcount < 3; loopcount++) {
01519 if (res2 && loopcount == 0)
01520 break;
01521 if (!res2)
01522 res2 = ast_play_and_wait(peer, "priv-callpending");
01523 if (!valid_priv_reply(opts, res2))
01524 res2 = 0;
01525
01526
01527
01528 if (!res2)
01529 res2 = ast_play_and_wait(peer, pa->privintro);
01530 if (!valid_priv_reply(opts, res2))
01531 res2 = 0;
01532
01533 if (!res2) {
01534
01535 if (ast_test_flag64(opts, OPT_PRIVACY))
01536 res2 = ast_play_and_wait(peer, "priv-callee-options");
01537 if (ast_test_flag64(opts, OPT_SCREENING))
01538 res2 = ast_play_and_wait(peer, "screen-callee-options");
01539 }
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 if (valid_priv_reply(opts, res2))
01557 break;
01558
01559 res2 = ast_play_and_wait(peer, "vm-sorry");
01560 }
01561
01562 if (ast_test_flag64(opts, OPT_MUSICBACK)) {
01563 ast_moh_stop(chan);
01564 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01565 ast_indicate(chan, -1);
01566 pa->sentringing = 0;
01567 }
01568 ast_autoservice_stop(chan);
01569 if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
01570
01571 static const char * const _val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
01572 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
01573 int i = res2 - '1';
01574 ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
01575 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
01576 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
01577 }
01578 switch (res2) {
01579 case '1':
01580 break;
01581 case '2':
01582 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01583 break;
01584 case '3':
01585 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01586 break;
01587 case '4':
01588 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01589 break;
01590 case '5':
01591
01592 if (ast_test_flag64(opts, OPT_PRIVACY))
01593 break;
01594
01595 default:
01596
01597
01598
01599
01600 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
01601
01602
01603 break;
01604 }
01605
01606 if (res2 == '1') {
01607
01608
01609 if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
01610 ast_filedelete(pa->privintro, NULL);
01611 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01612 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01613 else
01614 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01615 }
01616 return 0;
01617 } else {
01618 ast_hangup(peer);
01619 return -1;
01620 }
01621 }
01622
01623
01624 static int setup_privacy_args(struct privacy_args *pa,
01625 struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
01626 {
01627 char callerid[60];
01628 int res;
01629 char *l;
01630 int silencethreshold;
01631
01632 if (chan->caller.id.number.valid
01633 && !ast_strlen_zero(chan->caller.id.number.str)) {
01634 l = ast_strdupa(chan->caller.id.number.str);
01635 ast_shrink_phone_number(l);
01636 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
01637 ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
01638 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
01639 } else {
01640 ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
01641 pa->privdb_val = AST_PRIVACY_UNKNOWN;
01642 }
01643 } else {
01644 char *tnam, *tn2;
01645
01646 tnam = ast_strdupa(chan->name);
01647
01648 for (tn2 = tnam; *tn2; tn2++) {
01649 if (*tn2 == '/')
01650 *tn2 = '=';
01651 }
01652 ast_verb(3, "Privacy-- callerid is empty\n");
01653
01654 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
01655 l = callerid;
01656 pa->privdb_val = AST_PRIVACY_UNKNOWN;
01657 }
01658
01659 ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
01660
01661 if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
01662
01663 ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
01664 pa->privdb_val = AST_PRIVACY_ALLOW;
01665 } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
01666 ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
01667 }
01668
01669 if (pa->privdb_val == AST_PRIVACY_DENY) {
01670 ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
01671 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01672 return 0;
01673 } else if (pa->privdb_val == AST_PRIVACY_KILL) {
01674 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01675 return 0;
01676 } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
01677 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01678 return 0;
01679 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
01680
01681
01682
01683
01684
01685 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
01686 if ((res = ast_mkdir(pa->privintro, 0755))) {
01687 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
01688 return -1;
01689 }
01690
01691 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
01692 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
01693
01694
01695
01696 } else {
01697 int duration;
01698
01699
01700
01701
01702
01703
01704
01705 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
01706 ast_answer(chan);
01707 res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "sln", &duration, silencethreshold, 2000, 0);
01708
01709
01710 if (res == -1) {
01711
01712 ast_filedelete(pa->privintro, NULL);
01713 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01714 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01715 else
01716 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01717 return -1;
01718 }
01719 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
01720 ast_waitstream(chan, "");
01721 }
01722 }
01723 return 1;
01724 }
01725
01726 static void end_bridge_callback(void *data)
01727 {
01728 char buf[80];
01729 time_t end;
01730 struct ast_channel *chan = data;
01731
01732 if (!chan->cdr) {
01733 return;
01734 }
01735
01736 time(&end);
01737
01738 ast_channel_lock(chan);
01739 if (chan->cdr->answer.tv_sec) {
01740 snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->answer.tv_sec);
01741 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
01742 }
01743
01744 if (chan->cdr->start.tv_sec) {
01745 snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->start.tv_sec);
01746 pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
01747 }
01748 ast_channel_unlock(chan);
01749 }
01750
01751 static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) {
01752 bconfig->end_bridge_callback_data = originator;
01753 }
01754
01755 static int dial_handle_playtones(struct ast_channel *chan, const char *data)
01756 {
01757 struct ast_tone_zone_sound *ts = NULL;
01758 int res;
01759 const char *str = data;
01760
01761 if (ast_strlen_zero(str)) {
01762 ast_debug(1,"Nothing to play\n");
01763 return -1;
01764 }
01765
01766 ts = ast_get_indication_tone(chan->zone, str);
01767
01768 if (ts && ts->data[0]) {
01769 res = ast_playtones_start(chan, 0, ts->data, 0);
01770 } else {
01771 res = -1;
01772 }
01773
01774 if (ts) {
01775 ts = ast_tone_zone_sound_unref(ts);
01776 }
01777
01778 if (res) {
01779 ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);
01780 }
01781
01782 return res;
01783 }
01784
01785 static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
01786 {
01787 int res = -1;
01788 char *rest, *cur;
01789 struct chanlist *outgoing = NULL;
01790 struct ast_channel *peer;
01791 int to;
01792 struct cause_args num = { chan, 0, 0, 0 };
01793 int cause;
01794 char numsubst[256];
01795 char *cid_num = NULL, *cid_name = NULL, *cid_tag = NULL, *cid_pres = NULL;
01796
01797 struct ast_bridge_config config = { { 0, } };
01798 struct timeval calldurationlimit = { 0, };
01799 char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
01800 struct privacy_args pa = {
01801 .sentringing = 0,
01802 .privdb_val = 0,
01803 .status = "INVALIDARGS",
01804 };
01805 int sentringing = 0, moh = 0;
01806 const char *outbound_group = NULL;
01807 int result = 0;
01808 char *parse;
01809 int opermode = 0;
01810 int delprivintro = 0;
01811 AST_DECLARE_APP_ARGS(args,
01812 AST_APP_ARG(peers);
01813 AST_APP_ARG(timeout);
01814 AST_APP_ARG(options);
01815 AST_APP_ARG(url);
01816 );
01817 struct ast_flags64 opts = { 0, };
01818 char *opt_args[OPT_ARG_ARRAY_SIZE];
01819 struct ast_datastore *datastore = NULL;
01820 int fulldial = 0, num_dialed = 0;
01821 int ignore_cc = 0;
01822 char device_name[AST_CHANNEL_NAME];
01823
01824
01825 pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
01826 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
01827 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
01828 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
01829 pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
01830
01831 if (ast_strlen_zero(data)) {
01832 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01833 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01834 return -1;
01835 }
01836
01837 parse = ast_strdupa(data);
01838
01839 AST_STANDARD_APP_ARGS(args, parse);
01840
01841 if (!ast_strlen_zero(args.options) &&
01842 ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
01843 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01844 goto done;
01845 }
01846
01847 if (ast_strlen_zero(args.peers)) {
01848 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01849 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01850 goto done;
01851 }
01852
01853 if (ast_cc_call_init(chan, &ignore_cc)) {
01854 goto done;
01855 }
01856
01857 if (ast_test_flag64(&opts, OPT_SCREEN_NOINTRO) && !ast_strlen_zero(opt_args[OPT_ARG_SCREEN_NOINTRO])) {
01858 delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
01859
01860 if (delprivintro < 0 || delprivintro > 1) {
01861 ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
01862 delprivintro = 0;
01863 }
01864 }
01865
01866 if (!ast_test_flag64(&opts, OPT_RINGBACK)) {
01867 opt_args[OPT_ARG_RINGBACK] = NULL;
01868 }
01869
01870 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
01871 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
01872 ast_verb(3, "Setting operator services mode to %d.\n", opermode);
01873 }
01874
01875 if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
01876 calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
01877 if (!calldurationlimit.tv_sec) {
01878 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
01879 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01880 goto done;
01881 }
01882 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
01883 }
01884
01885 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
01886 dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
01887 dtmfcalled = strsep(&dtmf_progress, ":");
01888 dtmfcalling = strsep(&dtmf_progress, ":");
01889 }
01890
01891 if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
01892 if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
01893 goto done;
01894 }
01895
01896 if (ast_test_flag64(&opts, OPT_FORCECLID) && !ast_strlen_zero(opt_args[OPT_ARG_FORCECLID]))
01897 ast_callerid_parse(opt_args[OPT_ARG_FORCECLID], &cid_name, &cid_num);
01898 if (ast_test_flag64(&opts, OPT_FORCE_CID_TAG) && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_TAG]))
01899 cid_tag = ast_strdupa(opt_args[OPT_ARG_FORCE_CID_TAG]);
01900 if (ast_test_flag64(&opts, OPT_FORCE_CID_PRES) && !ast_strlen_zero(opt_args[OPT_ARG_FORCE_CID_PRES]))
01901 cid_pres = ast_strdupa(opt_args[OPT_ARG_FORCE_CID_PRES]);
01902 if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
01903 ast_cdr_reset(chan->cdr, NULL);
01904 if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
01905 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
01906
01907 if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
01908 res = setup_privacy_args(&pa, &opts, opt_args, chan);
01909 if (res <= 0)
01910 goto out;
01911 res = -1;
01912 }
01913
01914 if (ast_test_flag64(&opts, OPT_DTMF_EXIT) || ast_test_flag64(&opts, OPT_CALLER_HANGUP)) {
01915 __ast_answer(chan, 0, 0);
01916 }
01917
01918 if (continue_exec)
01919 *continue_exec = 0;
01920
01921
01922
01923 ast_channel_lock(chan);
01924 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
01925 outbound_group = ast_strdupa(outbound_group);
01926 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
01927 } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
01928 outbound_group = ast_strdupa(outbound_group);
01929 }
01930 ast_channel_unlock(chan);
01931 ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_IGNORE_CONNECTEDLINE |
01932 OPT_CANCEL_TIMEOUT | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB | OPT_FORCECLID);
01933
01934
01935 rest = args.peers;
01936 while ((cur = strsep(&rest, "&")) ) {
01937 struct chanlist *tmp;
01938 struct ast_channel *tc;
01939
01940 char *number = cur;
01941 char *interface = ast_strdupa(number);
01942 char *tech = strsep(&number, "/");
01943
01944 struct ast_dialed_interface *di;
01945 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
01946 num_dialed++;
01947 if (!number) {
01948 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
01949 goto out;
01950 }
01951 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01952 goto out;
01953 if (opts.flags) {
01954 ast_copy_flags64(tmp, &opts,
01955 OPT_CANCEL_ELSEWHERE |
01956 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
01957 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
01958 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
01959 OPT_CALLEE_PARK | OPT_CALLER_PARK |
01960 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
01961 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
01962 ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
01963 }
01964 ast_copy_string(numsubst, number, sizeof(numsubst));
01965
01966
01967 ast_channel_lock(chan);
01968 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
01969
01970
01971
01972
01973
01974
01975 ast_party_connected_line_copy(&tmp->connected, &chan->connected);
01976 ast_channel_unlock(chan);
01977
01978 if (datastore)
01979 dialed_interfaces = datastore->data;
01980 else {
01981 if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
01982 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
01983 chanlist_free(tmp);
01984 goto out;
01985 }
01986
01987 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
01988
01989 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
01990 ast_datastore_free(datastore);
01991 chanlist_free(tmp);
01992 goto out;
01993 }
01994
01995 datastore->data = dialed_interfaces;
01996 AST_LIST_HEAD_INIT(dialed_interfaces);
01997
01998 ast_channel_lock(chan);
01999 ast_channel_datastore_add(chan, datastore);
02000 ast_channel_unlock(chan);
02001 }
02002
02003 AST_LIST_LOCK(dialed_interfaces);
02004 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
02005 if (!strcasecmp(di->interface, interface)) {
02006 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
02007 di->interface);
02008 break;
02009 }
02010 }
02011 AST_LIST_UNLOCK(dialed_interfaces);
02012
02013 if (di) {
02014 fulldial++;
02015 chanlist_free(tmp);
02016 continue;
02017 }
02018
02019
02020
02021
02022
02023 if (strcasecmp(tech, "Local")) {
02024 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
02025 AST_LIST_UNLOCK(dialed_interfaces);
02026 chanlist_free(tmp);
02027 goto out;
02028 }
02029 strcpy(di->interface, interface);
02030
02031 AST_LIST_LOCK(dialed_interfaces);
02032 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
02033 AST_LIST_UNLOCK(dialed_interfaces);
02034 }
02035
02036 tc = ast_request(tech, chan->nativeformats, chan, numsubst, &cause);
02037 if (!tc) {
02038
02039 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
02040 tech, cause, ast_cause2str(cause));
02041 handle_cause(cause, &num);
02042 if (!rest)
02043 chan->hangupcause = cause;
02044 chanlist_free(tmp);
02045 if (!ignore_cc && (cause == AST_CAUSE_BUSY || cause == AST_CAUSE_CONGESTION)) {
02046 if (!ast_cc_callback(chan, tech, numsubst, ast_cc_busy_interface)) {
02047 ast_cc_extension_monitor_add_dialstring(chan, interface, "");
02048 }
02049 }
02050 continue;
02051 }
02052 ast_channel_get_device_name(tc, device_name, sizeof(device_name));
02053 if (!ignore_cc) {
02054 ast_cc_extension_monitor_add_dialstring(chan, interface, device_name);
02055 }
02056 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
02057
02058 ast_channel_lock(tc);
02059 while (ast_channel_trylock(chan)) {
02060 CHANNEL_DEADLOCK_AVOIDANCE(tc);
02061 }
02062
02063 if (!outgoing && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
02064 ast_rtp_instance_early_bridge_make_compatible(tc, chan);
02065 }
02066
02067
02068 ast_channel_inherit_variables(chan, tc);
02069 ast_channel_datastore_inherit(chan, tc);
02070
02071 tc->appl = "AppDial";
02072 tc->data = "(Outgoing Line)";
02073 memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
02074
02075
02076 if (!tc->caller.id.number.valid) {
02077 if (chan->connected.id.number.valid) {
02078 struct ast_party_caller caller;
02079
02080 ast_party_caller_set_init(&caller, &tc->caller);
02081 caller.id = chan->connected.id;
02082 caller.ani = chan->connected.ani;
02083 ast_channel_set_caller_event(tc, &caller, NULL);
02084 } else if (!ast_strlen_zero(chan->dialed.number.str)) {
02085 ast_set_callerid(tc, chan->dialed.number.str, NULL, NULL);
02086 } else if (!ast_strlen_zero(S_OR(chan->macroexten, chan->exten))) {
02087 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), NULL, NULL);
02088 }
02089 ast_set_flag64(tmp, DIAL_CALLERID_ABSENT);
02090 }
02091
02092 if (ast_test_flag64(peerflags, OPT_FORCECLID) && !ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
02093 struct ast_party_connected_line connected;
02094 int pres;
02095
02096 ast_party_connected_line_set_init(&connected, &tmp->chan->connected);
02097 if (cid_pres) {
02098 pres = ast_parse_caller_presentation(cid_pres);
02099 if (pres < 0) {
02100 pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
02101 }
02102 } else {
02103 pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
02104 }
02105 if (cid_num) {
02106 connected.id.number.valid = 1;
02107 connected.id.number.str = cid_num;
02108 connected.id.number.presentation = pres;
02109 }
02110 if (cid_name) {
02111 connected.id.name.valid = 1;
02112 connected.id.name.str = cid_name;
02113 connected.id.name.presentation = pres;
02114 }
02115 connected.id.tag = cid_tag;
02116 ast_channel_set_connected_line(tmp->chan, &connected, NULL);
02117 } else {
02118 ast_connected_line_copy_from_caller(&tc->connected, &chan->caller);
02119 }
02120
02121 ast_party_redirecting_copy(&tc->redirecting, &chan->redirecting);
02122
02123 tc->dialed.transit_network_select = chan->dialed.transit_network_select;
02124
02125 if (!ast_strlen_zero(chan->accountcode)) {
02126 ast_string_field_set(tc, peeraccount, chan->accountcode);
02127 }
02128 if (ast_strlen_zero(tc->musicclass))
02129 ast_string_field_set(tc, musicclass, chan->musicclass);
02130
02131
02132 tc->adsicpe = chan->adsicpe;
02133 tc->transfercapability = chan->transfercapability;
02134
02135
02136 if (outbound_group)
02137 ast_app_group_set_channel(tc, outbound_group);
02138
02139 if (ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE))
02140 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
02141
02142
02143 if (ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE))
02144 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
02145
02146
02147
02148 ast_string_field_set(tc, dialcontext, ast_strlen_zero(chan->macrocontext) ? chan->context : chan->macrocontext);
02149 if (!ast_strlen_zero(chan->macroexten))
02150 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
02151 else
02152 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
02153
02154 ast_channel_unlock(tc);
02155 res = ast_call(tc, numsubst, 0);
02156
02157
02158 if (chan->cdr)
02159 ast_cdr_setdestchan(chan->cdr, tc->name);
02160
02161
02162 if (res) {
02163
02164 ast_debug(1, "ast call on peer returned %d\n", res);
02165 ast_verb(3, "Couldn't call %s\n", numsubst);
02166 if (tc->hangupcause) {
02167 chan->hangupcause = tc->hangupcause;
02168 }
02169 ast_channel_unlock(chan);
02170 ast_cc_call_failed(chan, tc, interface);
02171 ast_hangup(tc);
02172 tc = NULL;
02173 chanlist_free(tmp);
02174 continue;
02175 } else {
02176 const char *tmpexten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
02177 senddialevent(chan, tc, numsubst);
02178 ast_verb(3, "Called %s\n", numsubst);
02179 ast_channel_unlock(chan);
02180 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
02181 char cidname[AST_MAX_EXTENSION];
02182 ast_set_callerid(tc, tmpexten, get_cid_name(cidname, sizeof(cidname), chan), NULL);
02183 }
02184 }
02185
02186
02187
02188 ast_set_flag64(tmp, DIAL_STILLGOING);
02189 tmp->chan = tc;
02190 tmp->next = outgoing;
02191 outgoing = tmp;
02192
02193 if (outgoing->chan->_state == AST_STATE_UP)
02194 break;
02195 }
02196
02197 if (ast_strlen_zero(args.timeout)) {
02198 to = -1;
02199 } else {
02200 to = atoi(args.timeout);
02201 if (to > 0)
02202 to *= 1000;
02203 else {
02204 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
02205 to = -1;
02206 }
02207 }
02208
02209 if (!outgoing) {
02210 strcpy(pa.status, "CHANUNAVAIL");
02211 if (fulldial == num_dialed) {
02212 res = -1;
02213 goto out;
02214 }
02215 } else {
02216
02217 strcpy(pa.status, "NOANSWER");
02218 if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
02219 moh = 1;
02220 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
02221 char *original_moh = ast_strdupa(chan->musicclass);
02222 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
02223 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
02224 ast_string_field_set(chan, musicclass, original_moh);
02225 } else {
02226 ast_moh_start(chan, NULL, NULL);
02227 }
02228 ast_indicate(chan, AST_CONTROL_PROGRESS);
02229 } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
02230 if (!ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
02231 if (dial_handle_playtones(chan, opt_args[OPT_ARG_RINGBACK])){
02232 ast_indicate(chan, AST_CONTROL_RINGING);
02233 sentringing++;
02234 } else {
02235 ast_indicate(chan, AST_CONTROL_PROGRESS);
02236 }
02237 } else {
02238 ast_indicate(chan, AST_CONTROL_RINGING);
02239 sentringing++;
02240 }
02241 }
02242 }
02243
02244 peer = wait_for_answer(chan, outgoing, &to, peerflags, opt_args, &pa, &num, &result, dtmf_progress, ignore_cc);
02245
02246
02247
02248
02249
02250
02251
02252 if (!ast_channel_datastore_remove(chan, datastore))
02253 ast_datastore_free(datastore);
02254 if (!peer) {
02255 if (result) {
02256 res = result;
02257 } else if (to) {
02258 res = -1;
02259 } else {
02260 res = 0;
02261 }
02262
02263
02264
02265 if (chan->hangupcause == AST_CAUSE_INVALID_NUMBER_FORMAT) {
02266 res = AST_PBX_INCOMPLETE;
02267 }
02268
02269
02270 } else {
02271 const char *number;
02272
02273 if (ast_test_flag64(&opts, OPT_CALLER_ANSWER))
02274 ast_answer(chan);
02275
02276 strcpy(pa.status, "ANSWER");
02277 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
02278
02279
02280
02281 hanguptree(outgoing, peer, 1);
02282 outgoing = NULL;
02283
02284 if (chan->cdr) {
02285 ast_cdr_setdestchan(chan->cdr, peer->name);
02286 ast_cdr_setanswer(chan->cdr, peer->cdr->answer);
02287 }
02288 if (peer->name)
02289 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
02290
02291 ast_channel_lock(peer);
02292 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
02293 if (!number)
02294 number = numsubst;
02295 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
02296 ast_channel_unlock(peer);
02297
02298 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
02299 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
02300 ast_channel_sendurl( peer, args.url );
02301 }
02302 if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
02303 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
02304 res = 0;
02305 goto out;
02306 }
02307 }
02308 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
02309 res = 0;
02310 } else {
02311 int digit = 0;
02312 struct ast_channel *chans[2];
02313 struct ast_channel *active_chan;
02314
02315 chans[0] = chan;
02316 chans[1] = peer;
02317
02318
02319
02320
02321 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
02322 if (res) {
02323 res = 0;
02324 ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
02325 }
02326
02327 ast_set_flag(peer, AST_FLAG_END_DTMF_ONLY);
02328 while (peer->stream) {
02329 int ms;
02330
02331 ms = ast_sched_wait(peer->sched);
02332
02333 if (ms < 0 && !peer->timingfunc) {
02334 ast_stopstream(peer);
02335 break;
02336 }
02337 if (ms < 0)
02338 ms = 1000;
02339
02340 active_chan = ast_waitfor_n(chans, 2, &ms);
02341 if (active_chan) {
02342 struct ast_frame *fr = ast_read(active_chan);
02343 if (!fr) {
02344 ast_hangup(peer);
02345 res = -1;
02346 goto done;
02347 }
02348 switch(fr->frametype) {
02349 case AST_FRAME_DTMF_END:
02350 digit = fr->subclass.integer;
02351 if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
02352 ast_stopstream(peer);
02353 res = ast_senddigit(chan, digit, 0);
02354 }
02355 break;
02356 case AST_FRAME_CONTROL:
02357 switch (fr->subclass.integer) {
02358 case AST_CONTROL_HANGUP:
02359 ast_frfree(fr);
02360 ast_hangup(peer);
02361 res = -1;
02362 goto done;
02363 default:
02364 break;
02365 }
02366 break;
02367 default:
02368
02369 break;
02370 }
02371 ast_frfree(fr);
02372 }
02373 ast_sched_runq(peer->sched);
02374 }
02375 ast_clear_flag(peer, AST_FLAG_END_DTMF_ONLY);
02376 }
02377
02378 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
02379
02380
02381 ast_clear_flag(chan->cdr, AST_CDR_FLAG_DIALED);
02382 ast_clear_flag(peer->cdr, AST_CDR_FLAG_DIALED);
02383
02384 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
02385 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
02386
02387 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02388 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02389 peer->priority = chan->priority + 2;
02390 ast_pbx_start(peer);
02391 hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
02392 if (continue_exec)
02393 *continue_exec = 1;
02394 res = 0;
02395 goto done;
02396 }
02397
02398 if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
02399 struct ast_app *theapp;
02400 const char *macro_result;
02401
02402 res = ast_autoservice_start(chan);
02403 if (res) {
02404 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02405 res = -1;
02406 }
02407
02408 theapp = pbx_findapp("Macro");
02409
02410 if (theapp && !res) {
02411
02412 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02413 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02414
02415 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
02416 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
02417 ast_debug(1, "Macro exited with status %d\n", res);
02418 res = 0;
02419 } else {
02420 ast_log(LOG_ERROR, "Could not find application Macro\n");
02421 res = -1;
02422 }
02423
02424 if (ast_autoservice_stop(chan) < 0) {
02425 res = -1;
02426 }
02427
02428 ast_channel_lock(peer);
02429
02430 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
02431 char *macro_transfer_dest;
02432
02433 if (!strcasecmp(macro_result, "BUSY")) {
02434 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02435 ast_set_flag64(peerflags, OPT_GO_ON);
02436 res = -1;
02437 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
02438 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02439 ast_set_flag64(peerflags, OPT_GO_ON);
02440 res = -1;
02441 } else if (!strcasecmp(macro_result, "CONTINUE")) {
02442
02443
02444
02445
02446 ast_set_flag64(peerflags, OPT_GO_ON);
02447 res = -1;
02448 } else if (!strcasecmp(macro_result, "ABORT")) {
02449
02450 res = -1;
02451 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
02452 res = -1;
02453
02454 if (strchr(macro_transfer_dest, '^')) {
02455 replace_macro_delimiter(macro_transfer_dest);
02456 if (!ast_parseable_goto(chan, macro_transfer_dest))
02457 ast_set_flag64(peerflags, OPT_GO_ON);
02458 }
02459 }
02460 }
02461
02462 ast_channel_unlock(peer);
02463 }
02464
02465 if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
02466 struct ast_app *theapp;
02467 const char *gosub_result;
02468 char *gosub_args, *gosub_argstart;
02469 int res9 = -1;
02470
02471 res9 = ast_autoservice_start(chan);
02472 if (res9) {
02473 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02474 res9 = -1;
02475 }
02476
02477 theapp = pbx_findapp("Gosub");
02478
02479 if (theapp && !res9) {
02480 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
02481
02482
02483 ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
02484 ast_copy_string(peer->exten, "s", sizeof(peer->exten));
02485 peer->priority = 0;
02486
02487 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
02488 if (gosub_argstart) {
02489 *gosub_argstart = 0;
02490 if (asprintf(&gosub_args, "%s,s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1) < 0) {
02491 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02492 gosub_args = NULL;
02493 }
02494 *gosub_argstart = ',';
02495 } else {
02496 if (asprintf(&gosub_args, "%s,s,1", opt_args[OPT_ARG_CALLEE_GOSUB]) < 0) {
02497 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02498 gosub_args = NULL;
02499 }
02500 }
02501
02502 if (gosub_args) {
02503 res9 = pbx_exec(peer, theapp, gosub_args);
02504 if (!res9) {
02505 struct ast_pbx_args args;
02506
02507 memset(&args, 0, sizeof(args));
02508 args.no_hangup_chan = 1;
02509 ast_pbx_run_args(peer, &args);
02510 }
02511 ast_free(gosub_args);
02512 ast_debug(1, "Gosub exited with status %d\n", res9);
02513 } else {
02514 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
02515 }
02516
02517 } else if (!res9) {
02518 ast_log(LOG_ERROR, "Could not find application Gosub\n");
02519 res9 = -1;
02520 }
02521
02522 if (ast_autoservice_stop(chan) < 0) {
02523 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
02524 res9 = -1;
02525 }
02526
02527 ast_channel_lock(peer);
02528
02529 if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
02530 char *gosub_transfer_dest;
02531 const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
02532
02533
02534 if (gosub_retval) {
02535 pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
02536 }
02537
02538 if (!strcasecmp(gosub_result, "BUSY")) {
02539 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02540 ast_set_flag64(peerflags, OPT_GO_ON);
02541 res = -1;
02542 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
02543 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02544 ast_set_flag64(peerflags, OPT_GO_ON);
02545 res = -1;
02546 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
02547
02548
02549
02550
02551 ast_set_flag64(peerflags, OPT_GO_ON);
02552 res = -1;
02553 } else if (!strcasecmp(gosub_result, "ABORT")) {
02554
02555 res = -1;
02556 } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
02557 res = -1;
02558
02559 if (strchr(gosub_transfer_dest, '^')) {
02560 replace_macro_delimiter(gosub_transfer_dest);
02561 if (!ast_parseable_goto(chan, gosub_transfer_dest))
02562 ast_set_flag64(peerflags, OPT_GO_ON);
02563 }
02564 }
02565 }
02566
02567 ast_channel_unlock(peer);
02568 }
02569
02570 if (!res) {
02571 if (!ast_tvzero(calldurationlimit)) {
02572 struct timeval whentohangup = calldurationlimit;
02573 peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
02574 }
02575 if (!ast_strlen_zero(dtmfcalled)) {
02576 ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
02577 res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
02578 }
02579 if (!ast_strlen_zero(dtmfcalling)) {
02580 ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
02581 res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
02582 }
02583 }
02584
02585 if (res) {
02586 res = -1;
02587 } else {
02588 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
02589 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
02590 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
02591 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
02592 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
02593 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
02594 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
02595 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
02596 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
02597 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
02598 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
02599 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
02600 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
02601 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
02602 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
02603 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
02604 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
02605 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
02606 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
02607 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
02608 if (ast_test_flag64(peerflags, OPT_GO_ON))
02609 ast_set_flag(&(config.features_caller), AST_FEATURE_NO_H_EXTEN);
02610
02611 config.end_bridge_callback = end_bridge_callback;
02612 config.end_bridge_callback_data = chan;
02613 config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
02614
02615 if (moh) {
02616 moh = 0;
02617 ast_moh_stop(chan);
02618 } else if (sentringing) {
02619 sentringing = 0;
02620 ast_indicate(chan, -1);
02621 }
02622
02623 ast_deactivate_generator(chan);
02624 chan->visible_indication = 0;
02625
02626 res = ast_channel_make_compatible(chan, peer);
02627 if (res < 0) {
02628 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
02629 ast_hangup(peer);
02630 res = -1;
02631 goto done;
02632 }
02633 if (opermode) {
02634 struct oprmode oprmode;
02635
02636 oprmode.peer = peer;
02637 oprmode.mode = opermode;
02638
02639 ast_channel_setoption(chan, AST_OPTION_OPRMODE, &oprmode, sizeof(oprmode), 0);
02640 }
02641 res = ast_bridge_call(chan, peer, &config);
02642 }
02643
02644 strcpy(peer->context, chan->context);
02645
02646 if (ast_test_flag64(&opts, OPT_PEER_H)
02647 && ast_exists_extension(peer, peer->context, "h", 1,
02648 S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL))) {
02649 int autoloopflag;
02650 int found;
02651 int res9;
02652
02653 strcpy(peer->exten, "h");
02654 peer->priority = 1;
02655 autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP);
02656 ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
02657
02658 while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten,
02659 peer->priority,
02660 S_COR(peer->caller.id.number.valid, peer->caller.id.number.str, NULL),
02661 &found, 1)) == 0) {
02662 peer->priority++;
02663 }
02664
02665 if (found && res9) {
02666
02667 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02668 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02669 }
02670 ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);
02671 }
02672 if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON)) {
02673 if(!ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
02674 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
02675 ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
02676 } else {
02677 int res;
02678 res = ast_goto_if_exists(peer, chan->context, chan->exten, (chan->priority) + 1);
02679 if (res == AST_PBX_GOTO_FAILED) {
02680 ast_hangup(peer);
02681 goto out;
02682 }
02683 }
02684 ast_pbx_start(peer);
02685 } else {
02686 if (!ast_check_hangup(chan))
02687 chan->hangupcause = peer->hangupcause;
02688 ast_hangup(peer);
02689 }
02690 }
02691 out:
02692 if (moh) {
02693 moh = 0;
02694 ast_moh_stop(chan);
02695 } else if (sentringing) {
02696 sentringing = 0;
02697 ast_indicate(chan, -1);
02698 }
02699
02700 if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02701 ast_filedelete(pa.privintro, NULL);
02702 if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02703 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
02704 } else {
02705 ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
02706 }
02707 }
02708
02709 ast_channel_early_bridge(chan, NULL);
02710 hanguptree(outgoing, NULL, 0);
02711 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
02712 senddialendevent(chan, pa.status);
02713 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
02714
02715 if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
02716 if (!ast_tvzero(calldurationlimit))
02717 memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
02718 res = 0;
02719 }
02720
02721 done:
02722 if (config.warning_sound) {
02723 ast_free((char *)config.warning_sound);
02724 }
02725 if (config.end_sound) {
02726 ast_free((char *)config.end_sound);
02727 }
02728 if (config.start_sound) {
02729 ast_free((char *)config.start_sound);
02730 }
02731 ast_ignore_cc(chan);
02732 return res;
02733 }
02734
02735 static int dial_exec(struct ast_channel *chan, const char *data)
02736 {
02737 struct ast_flags64 peerflags;
02738
02739 memset(&peerflags, 0, sizeof(peerflags));
02740
02741 return dial_exec_full(chan, data, &peerflags, NULL);
02742 }
02743
02744 static int retrydial_exec(struct ast_channel *chan, const char *data)
02745 {
02746 char *parse;
02747 const char *context = NULL;
02748 int sleepms = 0, loops = 0, res = -1;
02749 struct ast_flags64 peerflags = { 0, };
02750 AST_DECLARE_APP_ARGS(args,
02751 AST_APP_ARG(announce);
02752 AST_APP_ARG(sleep);
02753 AST_APP_ARG(retries);
02754 AST_APP_ARG(dialdata);
02755 );
02756
02757 if (ast_strlen_zero(data)) {
02758 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
02759 return -1;
02760 }
02761
02762 parse = ast_strdupa(data);
02763 AST_STANDARD_APP_ARGS(args, parse);
02764
02765 if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
02766 sleepms *= 1000;
02767
02768 if (!ast_strlen_zero(args.retries)) {
02769 loops = atoi(args.retries);
02770 }
02771
02772 if (!args.dialdata) {
02773 ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
02774 goto done;
02775 }
02776
02777 if (sleepms < 1000)
02778 sleepms = 10000;
02779
02780 if (!loops)
02781 loops = -1;
02782
02783 ast_channel_lock(chan);
02784 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
02785 context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
02786 ast_channel_unlock(chan);
02787
02788 res = 0;
02789 while (loops) {
02790 int continue_exec;
02791
02792 chan->data = "Retrying";
02793 if (ast_test_flag(chan, AST_FLAG_MOH))
02794 ast_moh_stop(chan);
02795
02796 res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
02797 if (continue_exec)
02798 break;
02799
02800 if (res == 0) {
02801 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
02802 if (!ast_strlen_zero(args.announce)) {
02803 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02804 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02805 ast_waitstream(chan, AST_DIGIT_ANY);
02806 } else
02807 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02808 }
02809 if (!res && sleepms) {
02810 if (!ast_test_flag(chan, AST_FLAG_MOH))
02811 ast_moh_start(chan, NULL, NULL);
02812 res = ast_waitfordigit(chan, sleepms);
02813 }
02814 } else {
02815 if (!ast_strlen_zero(args.announce)) {
02816 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02817 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02818 res = ast_waitstream(chan, "");
02819 } else
02820 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02821 }
02822 if (sleepms) {
02823 if (!ast_test_flag(chan, AST_FLAG_MOH))
02824 ast_moh_start(chan, NULL, NULL);
02825 if (!res)
02826 res = ast_waitfordigit(chan, sleepms);
02827 }
02828 }
02829 }
02830
02831 if (res < 0 || res == AST_PBX_INCOMPLETE) {
02832 break;
02833 } else if (res > 0) {
02834 if (onedigit_goto(chan, context, (char) res, 1)) {
02835 res = 0;
02836 break;
02837 }
02838 }
02839 loops--;
02840 }
02841 if (loops == 0)
02842 res = 0;
02843 else if (res == 1)
02844 res = 0;
02845
02846 if (ast_test_flag(chan, AST_FLAG_MOH))
02847 ast_moh_stop(chan);
02848 done:
02849 return res;
02850 }
02851
02852 static int unload_module(void)
02853 {
02854 int res;
02855 struct ast_context *con;
02856
02857 res = ast_unregister_application(app);
02858 res |= ast_unregister_application(rapp);
02859
02860 if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
02861 ast_context_remove_extension2(con, "s", 1, NULL, 0);
02862 ast_context_destroy(con, "app_dial");
02863 }
02864
02865 return res;
02866 }
02867
02868 static int load_module(void)
02869 {
02870 int res;
02871 struct ast_context *con;
02872
02873 con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
02874 if (!con)
02875 ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
02876 else
02877 ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial");
02878
02879 res = ast_register_application_xml(app, dial_exec);
02880 res |= ast_register_application_xml(rapp, retrydial_exec);
02881
02882 return res;
02883 }
02884
02885 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");