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 #include "asterisk.h"
00032
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 411314 $")
00034
00035 #include "asterisk/module.h"
00036 #include "asterisk/channel.h"
00037 #include "asterisk/pbx.h"
00038 #include "asterisk/utils.h"
00039 #include "asterisk/app.h"
00040 #include "asterisk/callerid.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 enum ID_FIELD_STATUS {
00404 ID_FIELD_VALID,
00405 ID_FIELD_INVALID,
00406 ID_FIELD_UNKNOWN
00407 };
00408
00409 AST_DEFINE_APP_ARGS_TYPE(ast_party_func_args,
00410 AST_APP_ARG(member);
00411 AST_APP_ARG(opts);
00412 AST_APP_ARG(other);
00413 );
00414
00415 AST_DEFINE_APP_ARGS_TYPE(ast_party_members,
00416 AST_APP_ARG(subnames[10]);
00417 );
00418
00419 enum CONNECTED_LINE_OPT_FLAGS {
00420 CONNECTED_LINE_OPT_INHIBIT = (1 << 0),
00421 };
00422 enum CONNECTED_LINE_OPT_ARGS {
00423 CONNECTED_LINE_OPT_DUMMY,
00424
00425
00426 CONNECTED_LINE_OPT_ARG_ARRAY_SIZE
00427 };
00428
00429 AST_APP_OPTIONS(connectedline_opts, BEGIN_OPTIONS
00430 AST_APP_OPTION('i', CONNECTED_LINE_OPT_INHIBIT),
00431 END_OPTIONS);
00432
00433 enum REDIRECTING_OPT_FLAGS {
00434 REDIRECTING_OPT_INHIBIT = (1 << 0),
00435 };
00436 enum REDIRECTING_OPT_ARGS {
00437 REDIRECTING_OPT_DUMMY,
00438
00439
00440 REDIRECTING_OPT_ARG_ARRAY_SIZE
00441 };
00442
00443 AST_APP_OPTIONS(redirecting_opts, BEGIN_OPTIONS
00444 AST_APP_OPTION('i', REDIRECTING_OPT_INHIBIT),
00445 END_OPTIONS);
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 static enum ID_FIELD_STATUS party_name_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_name *name)
00462 {
00463 enum ID_FIELD_STATUS status;
00464
00465 status = ID_FIELD_VALID;
00466
00467 if (argc == 0) {
00468
00469 if (name->valid && name->str) {
00470 ast_copy_string(buf, name->str, len);
00471 }
00472 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
00473 snprintf(buf, len, "%d", name->valid);
00474 } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
00475 ast_copy_string(buf, ast_party_name_charset_str(name->char_set), len);
00476 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
00477
00478 ast_copy_string(buf, ast_named_caller_presentation(name->presentation), len);
00479 } else {
00480 status = ID_FIELD_UNKNOWN;
00481 }
00482
00483 return status;
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 static enum ID_FIELD_STATUS party_number_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_number *number)
00501 {
00502 enum ID_FIELD_STATUS status;
00503
00504 status = ID_FIELD_VALID;
00505
00506 if (argc == 0) {
00507
00508 if (number->valid && number->str) {
00509 ast_copy_string(buf, number->str, len);
00510 }
00511 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
00512 snprintf(buf, len, "%d", number->valid);
00513 } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
00514 snprintf(buf, len, "%d", number->plan);
00515 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
00516
00517 ast_copy_string(buf, ast_named_caller_presentation(number->presentation), len);
00518 } else {
00519 status = ID_FIELD_UNKNOWN;
00520 }
00521
00522 return status;
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 static enum ID_FIELD_STATUS party_subaddress_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_subaddress *subaddress)
00540 {
00541 enum ID_FIELD_STATUS status;
00542
00543 status = ID_FIELD_VALID;
00544
00545 if (argc == 0) {
00546
00547 if (subaddress->str) {
00548 ast_copy_string(buf, subaddress->str, len);
00549 }
00550 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
00551 snprintf(buf, len, "%d", subaddress->valid);
00552 } else if (argc == 1 && !strcasecmp("type", argv[0])) {
00553 snprintf(buf, len, "%d", subaddress->type);
00554 } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
00555 snprintf(buf, len, "%d", subaddress->odd_even_indicator);
00556 } else {
00557 status = ID_FIELD_UNKNOWN;
00558 }
00559
00560 return status;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 static enum ID_FIELD_STATUS party_id_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
00578 {
00579 enum ID_FIELD_STATUS status;
00580
00581 if (argc == 0) {
00582
00583 return ID_FIELD_UNKNOWN;
00584 }
00585
00586 status = ID_FIELD_VALID;
00587
00588 if (argc == 1 && !strcasecmp("all", argv[0])) {
00589 snprintf(buf, len, "\"%s\" <%s>",
00590 S_COR(id->name.valid, id->name.str, ""),
00591 S_COR(id->number.valid, id->number.str, ""));
00592 } else if (!strcasecmp("name", argv[0])) {
00593 status = party_name_read(buf, len, argc - 1, argv + 1, &id->name);
00594 } else if (!strncasecmp("num", argv[0], 3)) {
00595
00596 status = party_number_read(buf, len, argc - 1, argv + 1, &id->number);
00597 } else if (!strncasecmp("subaddr", argv[0], 7)) {
00598
00599 status = party_subaddress_read(buf, len, argc - 1, argv + 1, &id->subaddress);
00600 } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
00601 if (id->tag) {
00602 ast_copy_string(buf, id->tag, len);
00603 }
00604 } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
00605
00606 snprintf(buf, len, "%d", id->number.plan);
00607 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
00608
00609
00610
00611
00612 ast_copy_string(buf,
00613 ast_named_caller_presentation(ast_party_id_presentation(id)), len);
00614 } else {
00615 status = ID_FIELD_UNKNOWN;
00616 }
00617
00618 return status;
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 static enum ID_FIELD_STATUS party_name_write(struct ast_party_name *name, int argc, char *argv[], const char *value)
00636 {
00637 char *val;
00638 enum ID_FIELD_STATUS status;
00639
00640 status = ID_FIELD_VALID;
00641
00642 if (argc == 0) {
00643
00644 name->valid = 1;
00645 name->str = ast_strdup(value);
00646 ast_trim_blanks(name->str);
00647 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
00648 name->valid = atoi(value) ? 1 : 0;
00649 } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
00650 int char_set;
00651
00652 val = ast_strdupa(value);
00653 ast_trim_blanks(val);
00654
00655 if (('0' <= val[0]) && (val[0] <= '9')) {
00656 char_set = atoi(val);
00657 } else {
00658 char_set = ast_party_name_charset_parse(val);
00659 }
00660
00661 if (char_set < 0) {
00662 ast_log(LOG_ERROR,
00663 "Unknown name char-set '%s', value unchanged\n", val);
00664 status = ID_FIELD_INVALID;
00665 } else {
00666 name->char_set = char_set;
00667 }
00668 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
00669 int pres;
00670
00671
00672 val = ast_strdupa(value);
00673 ast_trim_blanks(val);
00674
00675 if (('0' <= val[0]) && (val[0] <= '9')) {
00676 pres = atoi(val);
00677 } else {
00678 pres = ast_parse_caller_presentation(val);
00679 }
00680
00681 if (pres < 0) {
00682 ast_log(LOG_ERROR,
00683 "Unknown name presentation '%s', value unchanged\n", val);
00684 status = ID_FIELD_INVALID;
00685 } else {
00686 name->presentation = pres;
00687 }
00688 } else {
00689 status = ID_FIELD_UNKNOWN;
00690 }
00691
00692 return status;
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 static enum ID_FIELD_STATUS party_number_write(struct ast_party_number *number, int argc, char *argv[], const char *value)
00710 {
00711 char *val;
00712 enum ID_FIELD_STATUS status;
00713
00714 status = ID_FIELD_VALID;
00715
00716 if (argc == 0) {
00717
00718 number->valid = 1;
00719 number->str = ast_strdup(value);
00720 ast_trim_blanks(number->str);
00721 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
00722 number->valid = atoi(value) ? 1 : 0;
00723 } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
00724 val = ast_strdupa(value);
00725 ast_trim_blanks(val);
00726
00727 if (('0' <= val[0]) && (val[0] <= '9')) {
00728 number->plan = atoi(val);
00729 } else {
00730 ast_log(LOG_ERROR,
00731 "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
00732 status = ID_FIELD_INVALID;
00733 }
00734 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
00735 int pres;
00736
00737
00738 val = ast_strdupa(value);
00739 ast_trim_blanks(val);
00740
00741 if (('0' <= val[0]) && (val[0] <= '9')) {
00742 pres = atoi(val);
00743 } else {
00744 pres = ast_parse_caller_presentation(val);
00745 }
00746
00747 if (pres < 0) {
00748 ast_log(LOG_ERROR,
00749 "Unknown number presentation '%s', value unchanged\n", val);
00750 status = ID_FIELD_INVALID;
00751 } else {
00752 number->presentation = pres;
00753 }
00754 } else {
00755 status = ID_FIELD_UNKNOWN;
00756 }
00757
00758 return status;
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 static enum ID_FIELD_STATUS party_subaddress_write(struct ast_party_subaddress *subaddress, int argc, char *argv[], const char *value)
00776 {
00777 enum ID_FIELD_STATUS status;
00778
00779 status = ID_FIELD_VALID;
00780
00781 if (argc == 0) {
00782
00783 subaddress->str = ast_strdup(value);
00784 ast_trim_blanks(subaddress->str);
00785 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
00786 subaddress->valid = atoi(value) ? 1 : 0;
00787 } else if (argc == 1 && !strcasecmp("type", argv[0])) {
00788 subaddress->type = atoi(value) ? 2 : 0;
00789 } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
00790 subaddress->odd_even_indicator = atoi(value) ? 1 : 0;
00791 } else {
00792 status = ID_FIELD_UNKNOWN;
00793 }
00794
00795 return status;
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 static enum ID_FIELD_STATUS party_id_write(struct ast_party_id *id, int argc, char *argv[], const char *value)
00813 {
00814 char *val;
00815 enum ID_FIELD_STATUS status;
00816
00817 if (argc == 0) {
00818
00819 return ID_FIELD_UNKNOWN;
00820 }
00821
00822 status = ID_FIELD_VALID;
00823
00824 if (argc == 1 && !strcasecmp("all", argv[0])) {
00825 char name[256];
00826 char num[256];
00827
00828 ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
00829 id->name.valid = 1;
00830 id->name.str = ast_strdup(name);
00831 if (!id->name.str) {
00832 return ID_FIELD_INVALID;
00833 }
00834 id->number.valid = 1;
00835 id->number.str = ast_strdup(num);
00836 if (!id->number.str) {
00837 return ID_FIELD_INVALID;
00838 }
00839 } else if (!strcasecmp("name", argv[0])) {
00840 status = party_name_write(&id->name, argc - 1, argv + 1, value);
00841 } else if (!strncasecmp("num", argv[0], 3)) {
00842
00843 status = party_number_write(&id->number, argc - 1, argv + 1, value);
00844 } else if (!strncasecmp("subaddr", argv[0], 7)) {
00845
00846 status = party_subaddress_write(&id->subaddress, argc - 1, argv + 1, value);
00847 } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
00848 id->tag = ast_strdup(value);
00849 ast_trim_blanks(id->tag);
00850 } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
00851
00852 argv[0] = "plan";
00853 status = party_number_write(&id->number, argc, argv, value);
00854 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
00855 int pres;
00856
00857
00858
00859
00860
00861 val = ast_strdupa(value);
00862 ast_trim_blanks(val);
00863
00864 if (('0' <= val[0]) && (val[0] <= '9')) {
00865 pres = atoi(val);
00866 } else {
00867 pres = ast_parse_caller_presentation(val);
00868 }
00869
00870 if (pres < 0) {
00871 ast_log(LOG_ERROR,
00872 "Unknown combined presentation '%s', value unchanged\n", val);
00873 status = ID_FIELD_INVALID;
00874 } else {
00875 id->name.presentation = pres;
00876 id->number.presentation = pres;
00877 }
00878 } else {
00879 status = ID_FIELD_UNKNOWN;
00880 }
00881
00882 return status;
00883 }
00884
00885
00886 static int callerpres_deprecate_notify;
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 static int callerpres_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
00902 {
00903 if (!chan) {
00904 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00905 return -1;
00906 }
00907
00908 if (!callerpres_deprecate_notify) {
00909 callerpres_deprecate_notify = 1;
00910 ast_log(LOG_WARNING, "CALLERPRES is deprecated."
00911 " Use CALLERID(name-pres) or CALLERID(num-pres) instead.\n");
00912 }
00913 ast_copy_string(buf,
00914 ast_named_caller_presentation(ast_party_id_presentation(&ast_channel_caller(chan)->id)), len);
00915 return 0;
00916 }
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 static int callerpres_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
00931 {
00932 int pres;
00933
00934 if (!chan) {
00935 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00936 return -1;
00937 }
00938
00939 if (!callerpres_deprecate_notify) {
00940 callerpres_deprecate_notify = 1;
00941 ast_log(LOG_WARNING, "CALLERPRES is deprecated."
00942 " Use CALLERID(name-pres) or CALLERID(num-pres) instead.\n");
00943 }
00944
00945 pres = ast_parse_caller_presentation(value);
00946 if (pres < 0) {
00947 ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show function CALLERPRES')\n", value);
00948 } else {
00949 ast_channel_caller(chan)->id.name.presentation = pres;
00950 ast_channel_caller(chan)->id.number.presentation = pres;
00951 }
00952 return 0;
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 static int callerid_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
00969 {
00970 char *parms;
00971 struct ast_party_members member;
00972 AST_DECLARE_APP_ARGS(args,
00973 AST_APP_ARG(member);
00974 AST_APP_ARG(cid);
00975 );
00976
00977
00978 *buf = 0;
00979
00980 if (!chan) {
00981 return -1;
00982 }
00983
00984 parms = ast_strdupa(data);
00985 AST_STANDARD_APP_ARGS(args, parms);
00986 if (args.argc == 0) {
00987
00988 return -1;
00989 }
00990
00991 AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
00992 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
00993
00994 return -1;
00995 }
00996
00997 if (args.argc == 2) {
00998 char name[80];
00999 char num[80];
01000
01001 ast_callerid_split(args.cid, name, sizeof(name), num, sizeof(num));
01002
01003 if (member.argc == 1 && !strcasecmp("all", member.argv[0])) {
01004 snprintf(buf, len, "\"%s\" <%s>", name, num);
01005 } else if (member.argc == 1 && !strcasecmp("name", member.argv[0])) {
01006 ast_copy_string(buf, name, len);
01007 } else if (member.argc == 1 && !strncasecmp("num", member.argv[0], 3)) {
01008
01009 ast_copy_string(buf, num, len);
01010 } else {
01011 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01012 }
01013 } else {
01014 enum ID_FIELD_STATUS status;
01015 ast_channel_lock(chan);
01016
01017 if (member.argc == 1 && !strcasecmp("rdnis", member.argv[0])) {
01018 if (ast_channel_redirecting(chan)->from.number.valid
01019 && ast_channel_redirecting(chan)->from.number.str) {
01020 ast_copy_string(buf, ast_channel_redirecting(chan)->from.number.str, len);
01021 }
01022 } else if (!strcasecmp("dnid", member.argv[0])) {
01023 if (member.argc == 1) {
01024
01025 member.argc = 2;
01026 member.argv[1] = "num";
01027 }
01028 if (!strncasecmp("num", member.argv[1], 3)) {
01029
01030
01031
01032
01033 if (member.argc == 2) {
01034
01035 if (ast_channel_dialed(chan)->number.str) {
01036 ast_copy_string(buf, ast_channel_dialed(chan)->number.str, len);
01037 }
01038 } else if (member.argc == 3 && !strcasecmp("plan", member.argv[2])) {
01039
01040 snprintf(buf, len, "%d", ast_channel_dialed(chan)->number.plan);
01041 } else {
01042 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01043 }
01044 } else if (!strncasecmp("subaddr", member.argv[1], 7)) {
01045
01046
01047
01048
01049 status = party_subaddress_read(buf, len, member.argc - 2, member.argv + 2,
01050 &ast_channel_dialed(chan)->subaddress);
01051 switch (status) {
01052 case ID_FIELD_VALID:
01053 case ID_FIELD_INVALID:
01054 break;
01055 default:
01056 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01057 break;
01058 }
01059 } else {
01060 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01061 }
01062 } else if (member.argc == 1 && !strcasecmp("ani2", member.argv[0])) {
01063 snprintf(buf, len, "%d", ast_channel_caller(chan)->ani2);
01064 } else if (!strcasecmp("ani", member.argv[0])) {
01065 if (member.argc == 1) {
01066
01067 member.argc = 2;
01068 member.argv[1] = "num";
01069 }
01070 status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
01071 &ast_channel_caller(chan)->ani);
01072 switch (status) {
01073 case ID_FIELD_VALID:
01074 case ID_FIELD_INVALID:
01075 break;
01076 default:
01077 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01078 break;
01079 }
01080 } else if (!strcasecmp("priv", member.argv[0])) {
01081 status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
01082 &ast_channel_caller(chan)->priv);
01083 switch (status) {
01084 case ID_FIELD_VALID:
01085 case ID_FIELD_INVALID:
01086 break;
01087 default:
01088 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01089 break;
01090 }
01091 } else {
01092 status = party_id_read(buf, len, member.argc, member.argv, &ast_channel_caller(chan)->id);
01093 switch (status) {
01094 case ID_FIELD_VALID:
01095 case ID_FIELD_INVALID:
01096 break;
01097 default:
01098 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01099 break;
01100 }
01101 }
01102
01103 ast_channel_unlock(chan);
01104 }
01105
01106 return 0;
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121 static int callerid_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
01122 {
01123 struct ast_party_caller caller;
01124 struct ast_party_dialed dialed;
01125 enum ID_FIELD_STATUS status;
01126 char *val;
01127 char *parms;
01128 struct ast_party_func_args args;
01129 struct ast_party_members member;
01130
01131 if (!value || !chan) {
01132 return -1;
01133 }
01134
01135 parms = ast_strdupa(data);
01136 AST_STANDARD_APP_ARGS(args, parms);
01137 if (args.argc == 0) {
01138
01139 return -1;
01140 }
01141
01142 AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
01143 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
01144
01145 return -1;
01146 }
01147
01148 value = ast_skip_blanks(value);
01149
01150 ast_channel_lock(chan);
01151 if (member.argc == 1 && !strcasecmp("rdnis", member.argv[0])) {
01152 ast_channel_redirecting(chan)->from.number.valid = 1;
01153 ast_free(ast_channel_redirecting(chan)->from.number.str);
01154 ast_channel_redirecting(chan)->from.number.str = ast_strdup(value);
01155 if (ast_channel_cdr(chan)) {
01156 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01157 }
01158 } else if (!strcasecmp("dnid", member.argv[0])) {
01159 ast_party_dialed_set_init(&dialed, ast_channel_dialed(chan));
01160 if (member.argc == 1) {
01161
01162 member.argc = 2;
01163 member.argv[1] = "num";
01164 }
01165 if (!strncasecmp("num", member.argv[1], 3)) {
01166
01167
01168
01169
01170 if (member.argc == 2) {
01171
01172 dialed.number.str = ast_strdup(value);
01173 ast_trim_blanks(dialed.number.str);
01174 ast_party_dialed_set(ast_channel_dialed(chan), &dialed);
01175 if (ast_channel_cdr(chan)) {
01176 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01177 }
01178 } else if (member.argc == 3 && !strcasecmp("plan", member.argv[2])) {
01179
01180 val = ast_strdupa(value);
01181 ast_trim_blanks(val);
01182
01183 if (('0' <= val[0]) && (val[0] <= '9')) {
01184 ast_channel_dialed(chan)->number.plan = atoi(val);
01185 if (ast_channel_cdr(chan)) {
01186 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01187 }
01188 } else {
01189 ast_log(LOG_ERROR,
01190 "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
01191 }
01192 } else {
01193 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01194 }
01195 } else if (!strncasecmp("subaddr", member.argv[1], 7)) {
01196
01197
01198
01199
01200 status = party_subaddress_write(&dialed.subaddress, member.argc - 2,
01201 member.argv + 2, value);
01202 switch (status) {
01203 case ID_FIELD_VALID:
01204 ast_party_dialed_set(ast_channel_dialed(chan), &dialed);
01205 if (ast_channel_cdr(chan)) {
01206 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01207 }
01208 break;
01209 case ID_FIELD_INVALID:
01210 break;
01211 default:
01212 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01213 break;
01214 }
01215 } else {
01216 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01217 }
01218 ast_party_dialed_free(&dialed);
01219 } else if (member.argc == 1 && !strcasecmp("ani2", member.argv[0])) {
01220 val = ast_strdupa(value);
01221 ast_trim_blanks(val);
01222
01223 if (('0' <= val[0]) && (val[0] <= '9')) {
01224 ast_channel_caller(chan)->ani2 = atoi(val);
01225 if (ast_channel_cdr(chan)) {
01226 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01227 }
01228 } else {
01229 ast_log(LOG_ERROR, "Unknown callerid ani2 '%s', value unchanged\n", val);
01230 }
01231 } else if (!strcasecmp("ani", member.argv[0])) {
01232 ast_party_caller_set_init(&caller, ast_channel_caller(chan));
01233 if (member.argc == 1) {
01234
01235 member.argc = 2;
01236 member.argv[1] = "num";
01237 }
01238 status = party_id_write(&caller.ani, member.argc - 1, member.argv + 1, value);
01239 switch (status) {
01240 case ID_FIELD_VALID:
01241 ast_party_caller_set(ast_channel_caller(chan), &caller, NULL);
01242 if (ast_channel_cdr(chan)) {
01243 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01244 }
01245 break;
01246 case ID_FIELD_INVALID:
01247 break;
01248 default:
01249 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01250 break;
01251 }
01252 ast_party_caller_free(&caller);
01253 } else if (!strcasecmp("priv", member.argv[0])) {
01254 ast_party_caller_set_init(&caller, ast_channel_caller(chan));
01255 status = party_id_write(&caller.priv, member.argc - 1, member.argv + 1, value);
01256 switch (status) {
01257 case ID_FIELD_VALID:
01258 ast_party_caller_set(ast_channel_caller(chan), &caller, NULL);
01259 if (ast_channel_cdr(chan)) {
01260 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01261 }
01262 break;
01263 case ID_FIELD_INVALID:
01264 break;
01265 default:
01266 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01267 break;
01268 }
01269 ast_party_caller_free(&caller);
01270 } else {
01271 ast_party_caller_set_init(&caller, ast_channel_caller(chan));
01272 status = party_id_write(&caller.id, member.argc, member.argv, value);
01273 switch (status) {
01274 case ID_FIELD_VALID:
01275 ast_channel_set_caller_event(chan, &caller, NULL);
01276 if (ast_channel_cdr(chan)) {
01277 ast_cdr_setcid(ast_channel_cdr(chan), chan);
01278 }
01279 break;
01280 case ID_FIELD_INVALID:
01281 break;
01282 default:
01283 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
01284 break;
01285 }
01286 ast_party_caller_free(&caller);
01287 }
01288 ast_channel_unlock(chan);
01289
01290 return 0;
01291 }
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306 static int connectedline_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
01307 {
01308 struct ast_party_members member;
01309 char *read_what;
01310 enum ID_FIELD_STATUS status;
01311
01312
01313 *buf = 0;
01314
01315 if (!chan) {
01316 return -1;
01317 }
01318
01319 read_what = ast_strdupa(data);
01320 AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
01321 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
01322
01323 return -1;
01324 }
01325
01326 ast_channel_lock(chan);
01327
01328 if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
01329 ast_copy_string(buf, ast_connected_line_source_name(ast_channel_connected(chan)->source), len);
01330 } else if (!strcasecmp("priv", member.argv[0])) {
01331 status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
01332 &ast_channel_connected(chan)->priv);
01333 switch (status) {
01334 case ID_FIELD_VALID:
01335 case ID_FIELD_INVALID:
01336 break;
01337 default:
01338 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
01339 break;
01340 }
01341 } else {
01342 status = party_id_read(buf, len, member.argc, member.argv, &ast_channel_connected(chan)->id);
01343 switch (status) {
01344 case ID_FIELD_VALID:
01345 case ID_FIELD_INVALID:
01346 break;
01347 default:
01348 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
01349 break;
01350 }
01351 }
01352
01353 ast_channel_unlock(chan);
01354
01355 return 0;
01356 }
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370 static int connectedline_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
01371 {
01372 struct ast_party_connected_line connected;
01373 char *val;
01374 char *parms;
01375 void (*set_it)(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
01376 struct ast_party_func_args args;
01377 struct ast_party_members member;
01378 struct ast_flags opts;
01379 char *opt_args[CONNECTED_LINE_OPT_ARG_ARRAY_SIZE];
01380 enum ID_FIELD_STATUS status;
01381
01382 if (!value || !chan) {
01383 return -1;
01384 }
01385
01386 parms = ast_strdupa(data);
01387 AST_STANDARD_APP_ARGS(args, parms);
01388 if (args.argc == 0) {
01389
01390 return -1;
01391 }
01392
01393 AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
01394 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
01395
01396 return -1;
01397 }
01398
01399 if (ast_app_parse_options(connectedline_opts, &opts, opt_args, args.opts)) {
01400
01401 return -1;
01402 }
01403
01404
01405 if (ast_test_flag(&opts, CONNECTED_LINE_OPT_INHIBIT)) {
01406 set_it = ast_channel_set_connected_line;
01407 } else {
01408 set_it = ast_channel_update_connected_line;
01409 }
01410
01411 ast_channel_lock(chan);
01412 ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
01413 ast_channel_unlock(chan);
01414
01415 value = ast_skip_blanks(value);
01416
01417 if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
01418 int source;
01419
01420 val = ast_strdupa(value);
01421 ast_trim_blanks(val);
01422
01423 if (('0' <= val[0]) && (val[0] <= '9')) {
01424 source = atoi(val);
01425 } else {
01426 source = ast_connected_line_source_parse(val);
01427 }
01428
01429 if (source < 0) {
01430 ast_log(LOG_ERROR, "Unknown connectedline source '%s', value unchanged\n", val);
01431 } else {
01432 connected.source = source;
01433 set_it(chan, &connected, NULL);
01434 }
01435 } else if (!strcasecmp("priv", member.argv[0])) {
01436 status = party_id_write(&connected.priv, member.argc - 1, member.argv + 1, value);
01437 switch (status) {
01438 case ID_FIELD_VALID:
01439 set_it(chan, &connected, NULL);
01440 break;
01441 case ID_FIELD_INVALID:
01442 break;
01443 default:
01444 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
01445 break;
01446 }
01447 ast_party_connected_line_free(&connected);
01448 } else {
01449 status = party_id_write(&connected.id, member.argc, member.argv, value);
01450 switch (status) {
01451 case ID_FIELD_VALID:
01452 set_it(chan, &connected, NULL);
01453 break;
01454 case ID_FIELD_INVALID:
01455 break;
01456 default:
01457 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
01458 break;
01459 }
01460 ast_party_connected_line_free(&connected);
01461 }
01462
01463 return 0;
01464 }
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479 static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
01480 {
01481 struct ast_party_members member;
01482 char *read_what;
01483 const struct ast_party_redirecting *ast_redirecting;
01484 enum ID_FIELD_STATUS status;
01485
01486
01487 *buf = 0;
01488
01489 if (!chan) {
01490 return -1;
01491 }
01492
01493 read_what = ast_strdupa(data);
01494 AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
01495 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
01496
01497 return -1;
01498 }
01499
01500 ast_channel_lock(chan);
01501
01502 ast_redirecting = ast_channel_redirecting(chan);
01503 if (!strcasecmp("orig", member.argv[0])) {
01504 if (member.argc == 2 && !strcasecmp("reason", member.argv[1])) {
01505 ast_copy_string(buf,
01506 ast_redirecting_reason_name(ast_redirecting->orig_reason), len);
01507 } else {
01508 status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
01509 &ast_redirecting->orig);
01510 switch (status) {
01511 case ID_FIELD_VALID:
01512 case ID_FIELD_INVALID:
01513 break;
01514 default:
01515 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01516 break;
01517 }
01518 }
01519 } else if (!strcasecmp("from", member.argv[0])) {
01520 status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
01521 &ast_redirecting->from);
01522 switch (status) {
01523 case ID_FIELD_VALID:
01524 case ID_FIELD_INVALID:
01525 break;
01526 default:
01527 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01528 break;
01529 }
01530 } else if (!strcasecmp("to", member.argv[0])) {
01531 status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
01532 &ast_redirecting->to);
01533 switch (status) {
01534 case ID_FIELD_VALID:
01535 case ID_FIELD_INVALID:
01536 break;
01537 default:
01538 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01539 break;
01540 }
01541 } else if (member.argc == 1 && !strncasecmp("pres", member.argv[0], 4)) {
01542
01543
01544
01545
01546 ast_copy_string(buf,
01547 ast_named_caller_presentation(
01548 ast_party_id_presentation(&ast_redirecting->from)), len);
01549 } else if (member.argc == 1 && !strcasecmp("reason", member.argv[0])) {
01550 ast_copy_string(buf, ast_redirecting_reason_name(ast_redirecting->reason), len);
01551 } else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
01552 snprintf(buf, len, "%d", ast_redirecting->count);
01553 } else if (1 < member.argc && !strcasecmp("priv", member.argv[0])) {
01554 if (!strcasecmp("orig", member.argv[1])) {
01555 status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
01556 &ast_redirecting->priv_orig);
01557 switch (status) {
01558 case ID_FIELD_VALID:
01559 case ID_FIELD_INVALID:
01560 break;
01561 default:
01562 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01563 break;
01564 }
01565 } else if (!strcasecmp("from", member.argv[1])) {
01566 status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
01567 &ast_redirecting->priv_from);
01568 switch (status) {
01569 case ID_FIELD_VALID:
01570 case ID_FIELD_INVALID:
01571 break;
01572 default:
01573 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01574 break;
01575 }
01576 } else if (!strcasecmp("to", member.argv[1])) {
01577 status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
01578 &ast_redirecting->priv_to);
01579 switch (status) {
01580 case ID_FIELD_VALID:
01581 case ID_FIELD_INVALID:
01582 break;
01583 default:
01584 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01585 break;
01586 }
01587 } else {
01588 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01589 }
01590 } else {
01591 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01592 }
01593
01594 ast_channel_unlock(chan);
01595
01596 return 0;
01597 }
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611 static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
01612 {
01613 struct ast_party_redirecting redirecting;
01614 enum ID_FIELD_STATUS status;
01615 char *val;
01616 char *parms;
01617 void (*set_it)(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
01618 struct ast_party_func_args args;
01619 struct ast_party_members member;
01620 struct ast_flags opts;
01621 char *opt_args[REDIRECTING_OPT_ARG_ARRAY_SIZE];
01622
01623 if (!value || !chan) {
01624 return -1;
01625 }
01626
01627 parms = ast_strdupa(data);
01628 AST_STANDARD_APP_ARGS(args, parms);
01629 if (args.argc == 0) {
01630
01631 return -1;
01632 }
01633
01634 AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
01635 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
01636
01637 return -1;
01638 }
01639
01640 if (ast_app_parse_options(redirecting_opts, &opts, opt_args, args.opts)) {
01641
01642 return -1;
01643 }
01644
01645
01646 if (ast_test_flag(&opts, REDIRECTING_OPT_INHIBIT)) {
01647 set_it = ast_channel_set_redirecting;
01648 } else {
01649 set_it = ast_channel_update_redirecting;
01650 }
01651
01652 ast_channel_lock(chan);
01653 ast_party_redirecting_set_init(&redirecting, ast_channel_redirecting(chan));
01654 ast_channel_unlock(chan);
01655
01656 value = ast_skip_blanks(value);
01657
01658 if (!strcasecmp("orig", member.argv[0])) {
01659 if (member.argc == 2 && !strcasecmp("reason", member.argv[1])) {
01660 int reason;
01661
01662 val = ast_strdupa(value);
01663 ast_trim_blanks(val);
01664
01665 if (('0' <= val[0]) && (val[0] <= '9')) {
01666 reason = atoi(val);
01667 } else {
01668 reason = ast_redirecting_reason_parse(val);
01669 }
01670
01671 if (reason < 0) {
01672 ast_log(LOG_ERROR,
01673 "Unknown redirecting orig reason '%s', value unchanged\n", val);
01674 } else {
01675 redirecting.orig_reason = reason;
01676 set_it(chan, &redirecting, NULL);
01677 }
01678 } else {
01679 status = party_id_write(&redirecting.orig, member.argc - 1, member.argv + 1,
01680 value);
01681 switch (status) {
01682 case ID_FIELD_VALID:
01683 set_it(chan, &redirecting, NULL);
01684 break;
01685 case ID_FIELD_INVALID:
01686 break;
01687 default:
01688 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01689 break;
01690 }
01691 ast_party_redirecting_free(&redirecting);
01692 }
01693 } else if (!strcasecmp("from", member.argv[0])) {
01694 status = party_id_write(&redirecting.from, member.argc - 1, member.argv + 1,
01695 value);
01696 switch (status) {
01697 case ID_FIELD_VALID:
01698 set_it(chan, &redirecting, NULL);
01699 break;
01700 case ID_FIELD_INVALID:
01701 break;
01702 default:
01703 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01704 break;
01705 }
01706 ast_party_redirecting_free(&redirecting);
01707 } else if (!strcasecmp("to", member.argv[0])) {
01708 status = party_id_write(&redirecting.to, member.argc - 1, member.argv + 1, value);
01709 switch (status) {
01710 case ID_FIELD_VALID:
01711 set_it(chan, &redirecting, NULL);
01712 break;
01713 case ID_FIELD_INVALID:
01714 break;
01715 default:
01716 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01717 break;
01718 }
01719 ast_party_redirecting_free(&redirecting);
01720 } else if (member.argc == 1 && !strncasecmp("pres", member.argv[0], 4)) {
01721 int pres;
01722
01723 val = ast_strdupa(value);
01724 ast_trim_blanks(val);
01725
01726 if (('0' <= val[0]) && (val[0] <= '9')) {
01727 pres = atoi(val);
01728 } else {
01729 pres = ast_parse_caller_presentation(val);
01730 }
01731
01732 if (pres < 0) {
01733 ast_log(LOG_ERROR,
01734 "Unknown redirecting combined presentation '%s', value unchanged\n", val);
01735 } else {
01736 redirecting.from.name.presentation = pres;
01737 redirecting.from.number.presentation = pres;
01738 redirecting.to.name.presentation = pres;
01739 redirecting.to.number.presentation = pres;
01740 set_it(chan, &redirecting, NULL);
01741 }
01742 } else if (member.argc == 1 && !strcasecmp("reason", member.argv[0])) {
01743 int reason;
01744
01745 val = ast_strdupa(value);
01746 ast_trim_blanks(val);
01747
01748 if (('0' <= val[0]) && (val[0] <= '9')) {
01749 reason = atoi(val);
01750 } else {
01751 reason = ast_redirecting_reason_parse(val);
01752 }
01753
01754 if (reason < 0) {
01755 ast_log(LOG_ERROR, "Unknown redirecting reason '%s', value unchanged\n", val);
01756 } else {
01757 redirecting.reason = reason;
01758 set_it(chan, &redirecting, NULL);
01759 }
01760 } else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
01761 val = ast_strdupa(value);
01762 ast_trim_blanks(val);
01763
01764 if (('0' <= val[0]) && (val[0] <= '9')) {
01765 redirecting.count = atoi(val);
01766 set_it(chan, &redirecting, NULL);
01767 } else {
01768 ast_log(LOG_ERROR, "Unknown redirecting count '%s', value unchanged\n", val);
01769 }
01770 } else if (1 < member.argc && !strcasecmp("priv", member.argv[0])) {
01771 if (!strcasecmp("orig", member.argv[1])) {
01772 status = party_id_write(&redirecting.priv_orig, member.argc - 2, member.argv + 2,
01773 value);
01774 switch (status) {
01775 case ID_FIELD_VALID:
01776 set_it(chan, &redirecting, NULL);
01777 break;
01778 case ID_FIELD_INVALID:
01779 break;
01780 default:
01781 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01782 break;
01783 }
01784 ast_party_redirecting_free(&redirecting);
01785 } else if (!strcasecmp("from", member.argv[1])) {
01786 status = party_id_write(&redirecting.priv_from, member.argc - 2, member.argv + 2,
01787 value);
01788 switch (status) {
01789 case ID_FIELD_VALID:
01790 set_it(chan, &redirecting, NULL);
01791 break;
01792 case ID_FIELD_INVALID:
01793 break;
01794 default:
01795 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01796 break;
01797 }
01798 ast_party_redirecting_free(&redirecting);
01799 } else if (!strcasecmp("to", member.argv[1])) {
01800 status = party_id_write(&redirecting.priv_to, member.argc - 2, member.argv + 2, value);
01801 switch (status) {
01802 case ID_FIELD_VALID:
01803 set_it(chan, &redirecting, NULL);
01804 break;
01805 case ID_FIELD_INVALID:
01806 break;
01807 default:
01808 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01809 break;
01810 }
01811 ast_party_redirecting_free(&redirecting);
01812 } else {
01813 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01814 }
01815 } else {
01816 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
01817 }
01818
01819 return 0;
01820 }
01821
01822 static struct ast_custom_function callerid_function = {
01823 .name = "CALLERID",
01824 .read = callerid_read,
01825 .read_max = 256,
01826 .write = callerid_write,
01827 };
01828
01829 static struct ast_custom_function callerpres_function = {
01830 .name = "CALLERPRES",
01831 .read = callerpres_read,
01832 .read_max = 50,
01833 .write = callerpres_write,
01834 };
01835
01836 static struct ast_custom_function connectedline_function = {
01837 .name = "CONNECTEDLINE",
01838 .read = connectedline_read,
01839 .write = connectedline_write,
01840 };
01841
01842 static struct ast_custom_function redirecting_function = {
01843 .name = "REDIRECTING",
01844 .read = redirecting_read,
01845 .write = redirecting_write,
01846 };
01847
01848
01849
01850
01851
01852
01853
01854
01855 static int unload_module(void)
01856 {
01857 int res;
01858
01859 res = ast_custom_function_unregister(&callerpres_function);
01860 res |= ast_custom_function_unregister(&callerid_function);
01861 res |= ast_custom_function_unregister(&connectedline_function);
01862 res |= ast_custom_function_unregister(&redirecting_function);
01863 return res;
01864 }
01865
01866
01867
01868
01869
01870
01871
01872
01873 static int load_module(void)
01874 {
01875 int res;
01876
01877 res = ast_custom_function_register(&callerpres_function);
01878 res |= ast_custom_function_register(&callerid_function);
01879 res |= ast_custom_function_register(&connectedline_function);
01880 res |= ast_custom_function_register(&redirecting_function);
01881 return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
01882 }
01883
01884
01885 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)");