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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include "asterisk.h"
00058
00059 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 409053 $")
00060
00061 #include "asterisk/io.h"
00062 #include "asterisk/file.h"
00063 #include "asterisk/logger.h"
00064 #include "asterisk/module.h"
00065 #include "asterisk/app.h"
00066 #include "asterisk/lock.h"
00067 #include "asterisk/options.h"
00068 #include "asterisk/strings.h"
00069 #include "asterisk/cli.h"
00070 #include "asterisk/utils.h"
00071 #include "asterisk/config.h"
00072 #include "asterisk/astobj2.h"
00073 #include "asterisk/res_fax.h"
00074 #include "asterisk/file.h"
00075 #include "asterisk/channel.h"
00076 #include "asterisk/pbx.h"
00077 #include "asterisk/manager.h"
00078 #include "asterisk/dsp.h"
00079 #include "asterisk/indications.h"
00080 #include "asterisk/ast_version.h"
00081 #include "asterisk/translate.h"
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 static const char app_receivefax[] = "ReceiveFAX";
00231 static const char app_sendfax[] = "SendFAX";
00232
00233 struct debug_info_history {
00234 unsigned int consec_frames;
00235 unsigned int consec_ms;
00236 unsigned char silence;
00237 };
00238
00239 struct ast_fax_debug_info {
00240 struct timeval base_tv;
00241 struct debug_info_history c2s, s2c;
00242 struct ast_dsp *dsp;
00243 };
00244
00245
00246 struct fax_gateway {
00247
00248 struct ast_fax_session *s;
00249 struct ast_fax_session *peer_v21_session;
00250 struct ast_fax_session *chan_v21_session;
00251
00252 struct ast_fax_tech_token *token;
00253
00254 struct timeval timeout_start;
00255
00256 int framehook;
00257
00258 int bridged:1;
00259
00260 int detected_v21:1;
00261
00262 enum ast_t38_state t38_state;
00263
00264 struct ast_format chan_read_format;
00265 struct ast_format chan_write_format;
00266 struct ast_format peer_read_format;
00267 struct ast_format peer_write_format;
00268 };
00269
00270
00271 struct fax_detect {
00272
00273 struct timeval timeout_start;
00274
00275 int timeout;
00276
00277 struct ast_dsp *dsp;
00278
00279 struct ast_format orig_format;
00280
00281 struct ast_fax_session_details *details;
00282
00283 int flags;
00284 };
00285
00286
00287 #define FAX_DETECT_MODE_CNG (1 << 0)
00288 #define FAX_DETECT_MODE_T38 (1 << 1)
00289 #define FAX_DETECT_MODE_BOTH (FAX_DETECT_MODE_CNG | FAX_DETECT_MODE_T38)
00290
00291 static int fax_logger_level = -1;
00292
00293
00294 #define FAX_MAXBUCKETS 10
00295
00296 #define RES_FAX_TIMEOUT 10000
00297 #define FAX_GATEWAY_TIMEOUT RES_FAX_TIMEOUT
00298
00299
00300 static struct {
00301
00302 int active_sessions;
00303
00304 int reserved_sessions;
00305
00306 struct ao2_container *container;
00307
00308 int fax_tx_attempts;
00309
00310 int fax_rx_attempts;
00311
00312 int fax_complete;
00313
00314 int fax_failures;
00315
00316 int nextsessionname;
00317 } faxregistry;
00318
00319
00320 struct fax_module {
00321 const struct ast_fax_tech *tech;
00322 AST_RWLIST_ENTRY(fax_module) list;
00323 };
00324 static AST_RWLIST_HEAD_STATIC(faxmodules, fax_module);
00325
00326 #define RES_FAX_MINRATE 4800
00327 #define RES_FAX_MAXRATE 14400
00328 #define RES_FAX_STATUSEVENTS 0
00329 #define RES_FAX_MODEM (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29)
00330
00331 struct fax_options {
00332 enum ast_fax_modems modems;
00333 uint32_t statusevents:1;
00334 uint32_t ecm:1;
00335 unsigned int minrate;
00336 unsigned int maxrate;
00337 };
00338
00339 static struct fax_options general_options;
00340
00341 static const struct fax_options default_options = {
00342 .minrate = RES_FAX_MINRATE,
00343 .maxrate = RES_FAX_MAXRATE,
00344 .statusevents = RES_FAX_STATUSEVENTS,
00345 .modems = RES_FAX_MODEM,
00346 .ecm = AST_FAX_OPTFLAG_TRUE,
00347 };
00348
00349 AST_RWLOCK_DEFINE_STATIC(options_lock);
00350
00351 static void get_general_options(struct fax_options* options);
00352 static void set_general_options(const struct fax_options* options);
00353
00354 static const char *config = "res_fax.conf";
00355
00356 static int global_fax_debug = 0;
00357
00358 enum {
00359 OPT_CALLEDMODE = (1 << 0),
00360 OPT_CALLERMODE = (1 << 1),
00361 OPT_DEBUG = (1 << 2),
00362 OPT_STATUS = (1 << 3),
00363 OPT_ALLOWAUDIO = (1 << 5),
00364 OPT_REQUEST_T38 = (1 << 6),
00365 OPT_FORCE_AUDIO = (1 << 7),
00366 };
00367
00368 AST_APP_OPTIONS(fax_exec_options, BEGIN_OPTIONS
00369 AST_APP_OPTION('a', OPT_CALLEDMODE),
00370 AST_APP_OPTION('c', OPT_CALLERMODE),
00371 AST_APP_OPTION('d', OPT_DEBUG),
00372 AST_APP_OPTION('f', OPT_ALLOWAUDIO),
00373 AST_APP_OPTION('F', OPT_FORCE_AUDIO),
00374 AST_APP_OPTION('s', OPT_STATUS),
00375 AST_APP_OPTION('z', OPT_REQUEST_T38),
00376 END_OPTIONS);
00377
00378 struct manager_event_info {
00379 char context[AST_MAX_CONTEXT];
00380 char exten[AST_MAX_EXTENSION];
00381 char cid[128];
00382 };
00383
00384 static void debug_check_frame_for_silence(struct ast_fax_session *s, unsigned int c2s, struct ast_frame *frame)
00385 {
00386 struct debug_info_history *history = c2s ? &s->debug_info->c2s : &s->debug_info->s2c;
00387 int dspsilence;
00388 unsigned int last_consec_frames, last_consec_ms;
00389 unsigned char wassil;
00390 struct timeval diff;
00391
00392 diff = ast_tvsub(ast_tvnow(), s->debug_info->base_tv);
00393
00394 ast_dsp_reset(s->debug_info->dsp);
00395 ast_dsp_silence(s->debug_info->dsp, frame, &dspsilence);
00396
00397 wassil = history->silence;
00398 history->silence = (dspsilence != 0) ? 1 : 0;
00399 if (history->silence != wassil) {
00400 last_consec_frames = history->consec_frames;
00401 last_consec_ms = history->consec_ms;
00402 history->consec_frames = 0;
00403 history->consec_ms = 0;
00404
00405 if ((last_consec_frames != 0)) {
00406 ast_verb(6, "Channel '%s' fax session '%d', [ %.3ld.%.6ld ], %s sent %d frames (%d ms) of %s.\n",
00407 s->channame, s->id, (long) diff.tv_sec, (long int) diff.tv_usec,
00408 (c2s) ? "channel" : "stack", last_consec_frames, last_consec_ms,
00409 (wassil) ? "silence" : "energy");
00410 }
00411 }
00412
00413 history->consec_frames++;
00414 history->consec_ms += (frame->samples / 8);
00415 }
00416
00417 static void destroy_callback(void *data)
00418 {
00419 if (data) {
00420 ao2_ref(data, -1);
00421 }
00422 }
00423
00424 static const struct ast_datastore_info fax_datastore = {
00425 .type = "res_fax",
00426 .destroy = destroy_callback,
00427 };
00428
00429
00430 static struct ast_fax_session_details *find_details(struct ast_channel *chan)
00431 {
00432 struct ast_fax_session_details *details;
00433 struct ast_datastore *datastore;
00434
00435 ast_channel_lock(chan);
00436 if (!(datastore = ast_channel_datastore_find(chan, &fax_datastore, NULL))) {
00437 ast_channel_unlock(chan);
00438 return NULL;
00439 }
00440 if (!(details = datastore->data)) {
00441 ast_log(LOG_WARNING, "Huh? channel '%s' has a FAX datastore without data!\n", ast_channel_name(chan));
00442 ast_channel_unlock(chan);
00443 return NULL;
00444 }
00445 ao2_ref(details, 1);
00446 ast_channel_unlock(chan);
00447
00448 return details;
00449 }
00450
00451
00452 static void destroy_session_details(void *details)
00453 {
00454 struct ast_fax_session_details *d = details;
00455 struct ast_fax_document *doc;
00456
00457 while ((doc = AST_LIST_REMOVE_HEAD(&d->documents, next))) {
00458 ast_free(doc);
00459 }
00460 ast_string_field_free_memory(d);
00461 }
00462
00463
00464 static struct ast_fax_session_details *session_details_new(void)
00465 {
00466 struct ast_fax_session_details *d;
00467 struct fax_options options;
00468
00469 if (!(d = ao2_alloc(sizeof(*d), destroy_session_details))) {
00470 return NULL;
00471 }
00472
00473 if (ast_string_field_init(d, 512)) {
00474 ao2_ref(d, -1);
00475 return NULL;
00476 }
00477
00478 get_general_options(&options);
00479
00480 AST_LIST_HEAD_INIT_NOLOCK(&d->documents);
00481
00482
00483
00484 d->option.request_t38 = AST_FAX_OPTFLAG_FALSE;
00485 d->option.send_cng = AST_FAX_OPTFLAG_FALSE;
00486 d->option.send_ced = AST_FAX_OPTFLAG_FALSE;
00487 d->option.ecm = options.ecm;
00488 d->option.statusevents = options.statusevents;
00489 d->modems = options.modems;
00490 d->minrate = options.minrate;
00491 d->maxrate = options.maxrate;
00492 d->gateway_id = -1;
00493 d->faxdetect_id = -1;
00494 d->gateway_timeout = 0;
00495
00496 return d;
00497 }
00498
00499 static struct ast_control_t38_parameters our_t38_parameters = {
00500 .version = 0,
00501 .max_ifp = 400,
00502 .rate = AST_T38_RATE_14400,
00503 .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
00504 };
00505
00506 static void t38_parameters_ast_to_fax(struct ast_fax_t38_parameters *dst, const struct ast_control_t38_parameters *src)
00507 {
00508 dst->version = src->version;
00509 dst->max_ifp = src->max_ifp;
00510 dst->rate = src->rate;
00511 dst->rate_management = src->rate_management;
00512 dst->fill_bit_removal = src->fill_bit_removal;
00513 dst->transcoding_mmr = src->transcoding_mmr;
00514 dst->transcoding_jbig = src->transcoding_jbig;
00515 }
00516
00517 static void t38_parameters_fax_to_ast(struct ast_control_t38_parameters *dst, const struct ast_fax_t38_parameters *src)
00518 {
00519 dst->version = src->version;
00520 dst->max_ifp = src->max_ifp;
00521 dst->rate = src->rate;
00522 dst->rate_management = src->rate_management;
00523 dst->fill_bit_removal = src->fill_bit_removal;
00524 dst->transcoding_mmr = src->transcoding_mmr;
00525 dst->transcoding_jbig = src->transcoding_jbig;
00526 }
00527
00528
00529
00530 static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan)
00531 {
00532 struct ast_fax_session_details *details;
00533 struct ast_datastore *datastore;
00534
00535 if ((details = find_details(chan))) {
00536 return details;
00537 }
00538
00539 if (!(details = session_details_new())) {
00540 ast_log(LOG_WARNING, "channel '%s' can't get a FAX details structure for the datastore!\n", ast_channel_name(chan));
00541 return NULL;
00542 }
00543 if (!(datastore = ast_datastore_alloc(&fax_datastore, NULL))) {
00544 ao2_ref(details, -1);
00545 ast_log(LOG_WARNING, "channel '%s' can't get a datastore!\n", ast_channel_name(chan));
00546 return NULL;
00547 }
00548
00549 datastore->data = details;
00550
00551
00552 t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
00553 t38_parameters_ast_to_fax(&details->their_t38_parameters, &our_t38_parameters);
00554
00555 ao2_ref(details, 1);
00556 ast_channel_lock(chan);
00557 ast_channel_datastore_add(chan, datastore);
00558 ast_channel_unlock(chan);
00559 return details;
00560 }
00561
00562 unsigned int ast_fax_maxrate(void)
00563 {
00564 struct fax_options options;
00565 get_general_options(&options);
00566
00567 return options.maxrate;
00568 }
00569
00570 unsigned int ast_fax_minrate(void)
00571 {
00572 struct fax_options options;
00573 get_general_options(&options);
00574
00575 return options.minrate;
00576 }
00577
00578 static int update_modem_bits(enum ast_fax_modems *bits, const char *value)
00579 {
00580 char *m[5], *tok, *v = (char *)value;
00581 int i = 0, j;
00582
00583 if (!strchr(v, ',')) {
00584 m[i++] = v;
00585 m[i] = NULL;
00586 } else {
00587 tok = strtok(v, ", ");
00588 while (tok && (i < 5)) {
00589 m[i++] = tok;
00590 tok = strtok(NULL, ", ");
00591 }
00592 m[i] = NULL;
00593 }
00594
00595 *bits = 0;
00596 for (j = 0; j < i; j++) {
00597 if (!strcasecmp(m[j], "v17")) {
00598 *bits |= AST_FAX_MODEM_V17;
00599 } else if (!strcasecmp(m[j], "v27")) {
00600 *bits |= AST_FAX_MODEM_V27;
00601 } else if (!strcasecmp(m[j], "v29")) {
00602 *bits |= AST_FAX_MODEM_V29;
00603 } else if (!strcasecmp(m[j], "v34")) {
00604 *bits |= AST_FAX_MODEM_V34;
00605 } else {
00606 ast_log(LOG_WARNING, "ignoring invalid modem setting: '%s', valid options {v17 | v27 | v29 | v34}\n", m[j]);
00607 }
00608 }
00609 return 0;
00610 }
00611 static char *ast_fax_caps_to_str(enum ast_fax_capabilities caps, char *buf, size_t bufsize)
00612 {
00613 char *out = buf;
00614 size_t size = bufsize;
00615 int first = 1;
00616
00617 if (caps & AST_FAX_TECH_SEND) {
00618 if (!first) {
00619 ast_build_string(&buf, &size, ",");
00620 }
00621 ast_build_string(&buf, &size, "SEND");
00622 first = 0;
00623 }
00624 if (caps & AST_FAX_TECH_RECEIVE) {
00625 if (!first) {
00626 ast_build_string(&buf, &size, ",");
00627 }
00628 ast_build_string(&buf, &size, "RECEIVE");
00629 first = 0;
00630 }
00631 if (caps & AST_FAX_TECH_AUDIO) {
00632 if (!first) {
00633 ast_build_string(&buf, &size, ",");
00634 }
00635 ast_build_string(&buf, &size, "AUDIO");
00636 first = 0;
00637 }
00638 if (caps & AST_FAX_TECH_T38) {
00639 if (!first) {
00640 ast_build_string(&buf, &size, ",");
00641 }
00642 ast_build_string(&buf, &size, "T38");
00643 first = 0;
00644 }
00645 if (caps & AST_FAX_TECH_MULTI_DOC) {
00646 if (!first) {
00647 ast_build_string(&buf, &size, ",");
00648 }
00649 ast_build_string(&buf, &size, "MULTI_DOC");
00650 first = 0;
00651 }
00652 if (caps & AST_FAX_TECH_GATEWAY) {
00653 if (!first) {
00654 ast_build_string(&buf, &size, ",");
00655 }
00656 ast_build_string(&buf, &size, "GATEWAY");
00657 first = 0;
00658 }
00659 if (caps & AST_FAX_TECH_V21_DETECT) {
00660 if (!first) {
00661 ast_build_string(&buf, &size, ",");
00662 }
00663 ast_build_string(&buf, &size, "V21");
00664 first = 0;
00665 }
00666
00667 return out;
00668 }
00669
00670 static int ast_fax_modem_to_str(enum ast_fax_modems bits, char *tbuf, size_t bufsize)
00671 {
00672 int count = 0;
00673
00674 if (bits & AST_FAX_MODEM_V17) {
00675 strcat(tbuf, "V17");
00676 count++;
00677 }
00678 if (bits & AST_FAX_MODEM_V27) {
00679 if (count) {
00680 strcat(tbuf, ",");
00681 }
00682 strcat(tbuf, "V27");
00683 count++;
00684 }
00685 if (bits & AST_FAX_MODEM_V29) {
00686 if (count) {
00687 strcat(tbuf, ",");
00688 }
00689 strcat(tbuf, "V29");
00690 count++;
00691 }
00692 if (bits & AST_FAX_MODEM_V34) {
00693 if (count) {
00694 strcat(tbuf, ",");
00695 }
00696 strcat(tbuf, "V34");
00697 count++;
00698 }
00699
00700 return 0;
00701 }
00702
00703 static int check_modem_rate(enum ast_fax_modems modems, unsigned int rate)
00704 {
00705 switch (rate) {
00706 case 2400:
00707 if (!(modems & (AST_FAX_MODEM_V34))) {
00708 return 1;
00709 }
00710 break;
00711 case 4800:
00712 if (!(modems & (AST_FAX_MODEM_V27 | AST_FAX_MODEM_V34))) {
00713 return 1;
00714 }
00715 break;
00716 case 7200:
00717 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
00718 return 1;
00719 }
00720 break;
00721 case 9600:
00722 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
00723 return 1;
00724 }
00725 break;
00726 case 12000:
00727 case 14400:
00728 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V34))) {
00729 return 1;
00730 }
00731 break;
00732 case 28800:
00733 case 33600:
00734 if (!(modems & AST_FAX_MODEM_V34)) {
00735 return 1;
00736 }
00737 break;
00738 default:
00739
00740 return 1;
00741 }
00742
00743 return 0;
00744 }
00745
00746
00747 int ast_fax_tech_register(struct ast_fax_tech *tech)
00748 {
00749 struct fax_module *fax;
00750
00751 if (!(fax = ast_calloc(1, sizeof(*fax)))) {
00752 return -1;
00753 }
00754 fax->tech = tech;
00755 AST_RWLIST_WRLOCK(&faxmodules);
00756 AST_RWLIST_INSERT_TAIL(&faxmodules, fax, list);
00757 AST_RWLIST_UNLOCK(&faxmodules);
00758 ast_module_ref(ast_module_info->self);
00759
00760 ast_verb(3, "Registered handler for '%s' (%s)\n", fax->tech->type, fax->tech->description);
00761
00762 return 0;
00763 }
00764
00765
00766 void ast_fax_tech_unregister(struct ast_fax_tech *tech)
00767 {
00768 struct fax_module *fax;
00769
00770 ast_verb(3, "Unregistering FAX module type '%s'\n", tech->type);
00771
00772 AST_RWLIST_WRLOCK(&faxmodules);
00773 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&faxmodules, fax, list) {
00774 if (fax->tech != tech) {
00775 continue;
00776 }
00777 AST_RWLIST_REMOVE_CURRENT(list);
00778 ast_module_unref(ast_module_info->self);
00779 ast_free(fax);
00780 ast_verb(4, "Unregistered FAX module type '%s'\n", tech->type);
00781 break;
00782 }
00783 AST_RWLIST_TRAVERSE_SAFE_END;
00784 AST_RWLIST_UNLOCK(&faxmodules);
00785 }
00786
00787
00788 const char *ast_fax_state_to_str(enum ast_fax_state state)
00789 {
00790 switch (state) {
00791 case AST_FAX_STATE_UNINITIALIZED:
00792 return "Uninitialized";
00793 case AST_FAX_STATE_INITIALIZED:
00794 return "Initialized";
00795 case AST_FAX_STATE_OPEN:
00796 return "Open";
00797 case AST_FAX_STATE_ACTIVE:
00798 return "Active";
00799 case AST_FAX_STATE_COMPLETE:
00800 return "Complete";
00801 case AST_FAX_STATE_RESERVED:
00802 return "Reserved";
00803 case AST_FAX_STATE_INACTIVE:
00804 return "Inactive";
00805 default:
00806 ast_log(LOG_WARNING, "unhandled FAX state: %d\n", state);
00807 return "Unknown";
00808 }
00809 }
00810
00811 void ast_fax_log(int level, const char *file, const int line, const char *function, const char *msg)
00812 {
00813 if (fax_logger_level != -1) {
00814 ast_log_dynamic_level(fax_logger_level, "%s", msg);
00815 } else {
00816 ast_log(level, file, line, function, "%s", msg);
00817 }
00818 }
00819
00820
00821 static unsigned int fax_rate_str_to_int(const char *ratestr)
00822 {
00823 int rate;
00824
00825 if (sscanf(ratestr, "%d", &rate) != 1) {
00826 ast_log(LOG_ERROR, "failed to sscanf '%s' to rate\n", ratestr);
00827 return 0;
00828 }
00829 switch (rate) {
00830 case 2400:
00831 case 4800:
00832 case 7200:
00833 case 9600:
00834 case 12000:
00835 case 14400:
00836 case 28800:
00837 case 33600:
00838 return rate;
00839 default:
00840 ast_log(LOG_WARNING, "ignoring invalid rate '%s'. Valid options are {2400 | 4800 | 7200 | 9600 | 12000 | 14400 | 28800 | 33600}\n", ratestr);
00841 return 0;
00842 }
00843 }
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 static void fax_session_release(struct ast_fax_session *s, struct ast_fax_tech_token *token)
00859 {
00860 if (token) {
00861 s->tech->release_token(token);
00862 }
00863
00864 if (s->state == AST_FAX_STATE_RESERVED) {
00865 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
00866 s->state = AST_FAX_STATE_INACTIVE;
00867 }
00868 }
00869
00870
00871 static void destroy_session(void *session)
00872 {
00873 struct ast_fax_session *s = session;
00874
00875 if (s->tech) {
00876 fax_session_release(s, NULL);
00877 if (s->tech_pvt) {
00878 s->tech->destroy_session(s);
00879 }
00880 ast_module_unref(s->tech->module);
00881 }
00882
00883 if (s->details) {
00884 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00885 s->details->caps &= ~AST_FAX_TECH_GATEWAY;
00886 }
00887 ao2_ref(s->details, -1);
00888 }
00889
00890 if (s->debug_info) {
00891 ast_dsp_free(s->debug_info->dsp);
00892 ast_free(s->debug_info);
00893 }
00894
00895 if (s->smoother) {
00896 ast_smoother_free(s->smoother);
00897 }
00898
00899 if (s->state != AST_FAX_STATE_INACTIVE) {
00900 ast_atomic_fetchadd_int(&faxregistry.active_sessions, -1);
00901 }
00902
00903 ast_free(s->channame);
00904 ast_free(s->chan_uniqueid);
00905 }
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 static struct ast_fax_session *fax_session_reserve(struct ast_fax_session_details *details, struct ast_fax_tech_token **token)
00921 {
00922 struct ast_fax_session *s;
00923 struct fax_module *faxmod;
00924
00925 if (!(s = ao2_alloc(sizeof(*s), destroy_session))) {
00926 return NULL;
00927 }
00928
00929 s->state = AST_FAX_STATE_INACTIVE;
00930 s->details = details;
00931 ao2_ref(s->details, 1);
00932
00933
00934
00935
00936 AST_RWLIST_RDLOCK(&faxmodules);
00937 AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
00938 if ((faxmod->tech->caps & details->caps) != details->caps) {
00939 continue;
00940 }
00941 ast_debug(4, "Reserving a FAX session from '%s'.\n", faxmod->tech->description);
00942 ast_module_ref(faxmod->tech->module);
00943 s->tech = faxmod->tech;
00944 break;
00945 }
00946 AST_RWLIST_UNLOCK(&faxmodules);
00947
00948 if (!faxmod) {
00949 char caps[128] = "";
00950 ast_log(LOG_ERROR, "Could not locate a FAX technology module with capabilities (%s)\n", ast_fax_caps_to_str(details->caps, caps, sizeof(caps)));
00951 ao2_ref(s, -1);
00952 return NULL;
00953 }
00954
00955 if (!s->tech->reserve_session) {
00956 ast_debug(1, "Selected FAX technology module (%s) does not support reserving sessions.\n", s->tech->description);
00957 return s;
00958 }
00959
00960 if (!(*token = s->tech->reserve_session(s))) {
00961 ao2_ref(s, -1);
00962 return NULL;
00963 }
00964
00965 s->state = AST_FAX_STATE_RESERVED;
00966 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, 1);
00967
00968 return s;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 static struct ast_fax_session *fax_session_new(struct ast_fax_session_details *details, struct ast_channel *chan, struct ast_fax_session *reserved, struct ast_fax_tech_token *token)
00988 {
00989 struct ast_fax_session *s = NULL;
00990 struct fax_module *faxmod;
00991
00992 if (reserved) {
00993 s = reserved;
00994 ao2_ref(reserved, +1);
00995
00996
00997
00998
00999
01000
01001
01002 if (s->state == AST_FAX_STATE_RESERVED) {
01003 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
01004 s->state = AST_FAX_STATE_UNINITIALIZED;
01005 }
01006 }
01007
01008 if (!s && !(s = ao2_alloc(sizeof(*s), destroy_session))) {
01009 return NULL;
01010 }
01011
01012 ast_atomic_fetchadd_int(&faxregistry.active_sessions, 1);
01013 s->state = AST_FAX_STATE_UNINITIALIZED;
01014
01015 if (details->option.debug && (details->caps & AST_FAX_TECH_AUDIO)) {
01016 if (!(s->debug_info = ast_calloc(1, sizeof(*(s->debug_info))))) {
01017 fax_session_release(s, token);
01018 ao2_ref(s, -1);
01019 return NULL;
01020 }
01021 if (!(s->debug_info->dsp = ast_dsp_new())) {
01022 ast_free(s->debug_info);
01023 s->debug_info = NULL;
01024 fax_session_release(s, token);
01025 ao2_ref(s, -1);
01026 return NULL;
01027 }
01028 ast_dsp_set_threshold(s->debug_info->dsp, 128);
01029 }
01030
01031 if (!(s->channame = ast_strdup(ast_channel_name(chan)))) {
01032 fax_session_release(s, token);
01033 ao2_ref(s, -1);
01034 return NULL;
01035 }
01036
01037 if (!(s->chan_uniqueid = ast_strdup(ast_channel_uniqueid(chan)))) {
01038 fax_session_release(s, token);
01039 ao2_ref(s, -1);
01040 return NULL;
01041 }
01042
01043 s->chan = chan;
01044 if (!s->details) {
01045 s->details = details;
01046 ao2_ref(s->details, 1);
01047 }
01048
01049 details->id = s->id = ast_atomic_fetchadd_int(&faxregistry.nextsessionname, 1);
01050
01051 if (!token) {
01052
01053 AST_RWLIST_RDLOCK(&faxmodules);
01054 AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
01055 if ((faxmod->tech->caps & details->caps) != details->caps) {
01056 continue;
01057 }
01058 ast_debug(4, "Requesting a new FAX session from '%s'.\n", faxmod->tech->description);
01059 ast_module_ref(faxmod->tech->module);
01060 s->tech = faxmod->tech;
01061 break;
01062 }
01063 AST_RWLIST_UNLOCK(&faxmodules);
01064
01065 if (!faxmod) {
01066 char caps[128] = "";
01067 ast_log(LOG_ERROR, "Could not locate a FAX technology module with capabilities (%s)\n", ast_fax_caps_to_str(details->caps, caps, sizeof(caps)));
01068 ao2_ref(s, -1);
01069 return NULL;
01070 }
01071 }
01072
01073 if (!(s->tech_pvt = s->tech->new_session(s, token))) {
01074 ast_log(LOG_ERROR, "FAX session failed to initialize.\n");
01075 ao2_ref(s, -1);
01076 return NULL;
01077 }
01078
01079 if (!(ao2_link(faxregistry.container, s))) {
01080 ast_log(LOG_ERROR, "failed to add FAX session '%d' to container.\n", s->id);
01081 ao2_ref(s, -1);
01082 return NULL;
01083 }
01084 ast_debug(4, "channel '%s' using FAX session '%d'\n", s->channame, s->id);
01085
01086 return s;
01087 }
01088
01089 static void get_manager_event_info(struct ast_channel *chan, struct manager_event_info *info)
01090 {
01091 pbx_substitute_variables_helper(chan, "${CONTEXT}", info->context, sizeof(info->context));
01092 pbx_substitute_variables_helper(chan, "${EXTEN}", info->exten, sizeof(info->exten));
01093 pbx_substitute_variables_helper(chan, "${CALLERID(num)}", info->cid, sizeof(info->cid));
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108 static char *generate_filenames_string(struct ast_fax_session_details *details, char *prefix, char *separator)
01109 {
01110 char *filenames, *c;
01111 size_t size = 0;
01112 int first = 1;
01113 struct ast_fax_document *doc;
01114
01115
01116 if (AST_LIST_EMPTY(&details->documents)) {
01117 return NULL;
01118 }
01119
01120
01121 AST_LIST_TRAVERSE(&details->documents, doc, next) {
01122 size += strlen(separator) + strlen(prefix) + strlen(doc->filename);
01123 }
01124 size += 1;
01125
01126 if (!(filenames = ast_malloc(size))) {
01127 return NULL;
01128 }
01129 c = filenames;
01130
01131 ast_build_string(&c, &size, "%s%s", prefix, AST_LIST_FIRST(&details->documents)->filename);
01132 AST_LIST_TRAVERSE(&details->documents, doc, next) {
01133 if (first) {
01134 first = 0;
01135 continue;
01136 }
01137
01138 ast_build_string(&c, &size, "%s%s%s", separator, prefix, doc->filename);
01139 }
01140
01141 return filenames;
01142 }
01143
01144
01145 static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details, const char *status)
01146 {
01147 char *filenames = generate_filenames_string(details, "FileName: ", "\r\n");
01148
01149 ast_channel_lock(chan);
01150 if (details->option.statusevents) {
01151 struct manager_event_info info;
01152
01153 get_manager_event_info(chan, &info);
01154 manager_event(EVENT_FLAG_CALL,
01155 "FAXStatus",
01156 "Operation: %s\r\n"
01157 "Status: %s\r\n"
01158 "Channel: %s\r\n"
01159 "Context: %s\r\n"
01160 "Exten: %s\r\n"
01161 "CallerID: %s\r\n"
01162 "LocalStationID: %s\r\n"
01163 "%s%s",
01164 (details->caps & AST_FAX_TECH_GATEWAY) ? "gateway" : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
01165 status,
01166 ast_channel_name(chan),
01167 info.context,
01168 info.exten,
01169 info.cid,
01170 details->localstationid,
01171 S_OR(filenames, ""),
01172 filenames ? "\r\n" : "");
01173 }
01174 ast_channel_unlock(chan);
01175
01176 if (filenames) {
01177 ast_free(filenames);
01178 }
01179
01180 return 0;
01181 }
01182
01183
01184 static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
01185 {
01186 char buf[10];
01187 pbx_builtin_setvar_helper(chan, "FAXSTATUS", S_OR(details->result, NULL));
01188 pbx_builtin_setvar_helper(chan, "FAXERROR", S_OR(details->error, NULL));
01189 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", S_OR(details->resultstr, NULL));
01190 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", S_OR(details->remotestationid, NULL));
01191 pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", S_OR(details->localstationid, NULL));
01192 pbx_builtin_setvar_helper(chan, "FAXBITRATE", S_OR(details->transfer_rate, NULL));
01193 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", S_OR(details->resolution, NULL));
01194
01195 snprintf(buf, sizeof(buf), "%d", details->pages_transferred);
01196 pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
01197 }
01198
01199 #define GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason) \
01200 do { \
01201 if (ast_strlen_zero(fax->details->result)) \
01202 ast_string_field_set(fax->details, result, "FAILED"); \
01203 if (ast_strlen_zero(fax->details->resultstr)) \
01204 ast_string_field_set(fax->details, resultstr, reason); \
01205 if (ast_strlen_zero(fax->details->error)) \
01206 ast_string_field_set(fax->details, error, errorstr); \
01207 set_channel_variables(chan, fax->details); \
01208 } while (0)
01209
01210 #define GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason) \
01211 do { \
01212 GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason); \
01213 } while (0)
01214
01215 #define GENERIC_FAX_EXEC_ERROR(fax, chan, errorstr, reason) \
01216 do { \
01217 ast_log(LOG_ERROR, "channel '%s' FAX session '%d' failure, reason: '%s' (%s)\n", ast_channel_name(chan), fax->id, reason, errorstr); \
01218 GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason); \
01219 } while (0)
01220
01221 static int set_fax_t38_caps(struct ast_channel *chan, struct ast_fax_session_details *details)
01222 {
01223 switch (ast_channel_get_t38_state(chan)) {
01224 case T38_STATE_UNKNOWN:
01225 details->caps |= AST_FAX_TECH_T38;
01226 break;
01227 case T38_STATE_REJECTED:
01228 case T38_STATE_UNAVAILABLE:
01229 details->caps |= AST_FAX_TECH_AUDIO;
01230 break;
01231 case T38_STATE_NEGOTIATED:
01232
01233 case T38_STATE_NEGOTIATING: {
01234
01235
01236
01237
01238
01239
01240
01241 struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_PARMS, };
01242 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)) != AST_T38_REQUEST_PARMS) {
01243 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", ast_channel_name(chan));
01244 return -1;
01245 }
01246 details->caps |= AST_FAX_TECH_T38;
01247 break;
01248 }
01249 default:
01250 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", ast_channel_name(chan));
01251 return -1;
01252 }
01253
01254 return 0;
01255 }
01256
01257 static int disable_t38(struct ast_channel *chan)
01258 {
01259 int timeout_ms;
01260 struct ast_frame *frame = NULL;
01261 struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
01262 struct timeval start;
01263 int ms;
01264
01265 ast_debug(1, "Shutting down T.38 on %s\n", ast_channel_name(chan));
01266 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0) {
01267 ast_debug(1, "error while disabling T.38 on channel '%s'\n", ast_channel_name(chan));
01268 return -1;
01269 }
01270
01271
01272 timeout_ms = 5000;
01273 start = ast_tvnow();
01274 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01275 ms = ast_waitfor(chan, ms);
01276
01277 if (ms == 0) {
01278 break;
01279 }
01280 if (ms < 0) {
01281 ast_debug(1, "error while disabling T.38 on channel '%s'\n", ast_channel_name(chan));
01282 return -1;
01283 }
01284
01285 if (!(frame = ast_read(chan))) {
01286 return -1;
01287 }
01288 if ((frame->frametype == AST_FRAME_CONTROL) &&
01289 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01290 (frame->datalen == sizeof(t38_parameters))) {
01291 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01292
01293 switch (parameters->request_response) {
01294 case AST_T38_TERMINATED:
01295 ast_debug(1, "Shut down T.38 on %s\n", ast_channel_name(chan));
01296 break;
01297 case AST_T38_REFUSED:
01298 ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", ast_channel_name(chan));
01299 ast_frfree(frame);
01300 return -1;
01301 default:
01302 ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", ast_channel_name(chan));
01303 ast_frfree(frame);
01304 return -1;
01305 }
01306 ast_frfree(frame);
01307 break;
01308 }
01309 ast_frfree(frame);
01310 }
01311
01312 if (ms == 0) {
01313 ast_debug(1, "channel '%s' timed-out during T.38 shutdown\n", ast_channel_name(chan));
01314 }
01315
01316 return 0;
01317 }
01318
01319
01320 static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_details *details, struct ast_fax_session *reserved, struct ast_fax_tech_token *token)
01321 {
01322 int ms;
01323 int timeout = RES_FAX_TIMEOUT;
01324 int chancount;
01325 unsigned int expected_frametype = -1;
01326 union ast_frame_subclass expected_framesubclass = { .integer = -1 };
01327 unsigned int t38negotiated = (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED);
01328 struct ast_control_t38_parameters t38_parameters;
01329 const char *tempvar;
01330 struct ast_fax_session *fax = NULL;
01331 struct ast_frame *frame = NULL;
01332 struct ast_channel *c = chan;
01333 struct ast_format orig_write_format;
01334 struct ast_format orig_read_format;
01335 int remaining_time;
01336 struct timeval start;
01337
01338 ast_format_clear(&orig_write_format);
01339 ast_format_clear(&orig_read_format);
01340 chancount = 1;
01341
01342
01343 if (!(fax = fax_session_new(details, chan, reserved, token))) {
01344 ast_log(LOG_ERROR, "Can't create a FAX session, FAX attempt failed.\n");
01345 report_fax_status(chan, details, "No Available Resource");
01346 return -1;
01347 }
01348
01349 ast_channel_lock(chan);
01350
01351 if (ast_strlen_zero(details->headerinfo) && (tempvar = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO"))) {
01352 ast_string_field_set(details, headerinfo, tempvar);
01353 }
01354 if (ast_strlen_zero(details->localstationid)) {
01355 tempvar = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
01356 ast_string_field_set(details, localstationid, tempvar ? tempvar : "unknown");
01357 }
01358 ast_channel_unlock(chan);
01359
01360 report_fax_status(chan, details, "Allocating Resources");
01361
01362 if (details->caps & AST_FAX_TECH_AUDIO) {
01363 expected_frametype = AST_FRAME_VOICE;;
01364 ast_format_set(&expected_framesubclass.format, AST_FORMAT_SLINEAR, 0);
01365 ast_format_copy(&orig_write_format, ast_channel_writeformat(chan));
01366 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
01367 ast_log(LOG_ERROR, "channel '%s' failed to set write format to signed linear'.\n", ast_channel_name(chan));
01368 ao2_lock(faxregistry.container);
01369 ao2_unlink(faxregistry.container, fax);
01370 ao2_unlock(faxregistry.container);
01371 ao2_ref(fax, -1);
01372 ast_channel_unlock(chan);
01373 return -1;
01374 }
01375 ast_format_copy(&orig_read_format, ast_channel_readformat(chan));
01376 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
01377 ast_log(LOG_ERROR, "channel '%s' failed to set read format to signed linear.\n", ast_channel_name(chan));
01378 ao2_lock(faxregistry.container);
01379 ao2_unlink(faxregistry.container, fax);
01380 ao2_unlock(faxregistry.container);
01381 ao2_ref(fax, -1);
01382 ast_channel_unlock(chan);
01383 return -1;
01384 }
01385 if (fax->smoother) {
01386 ast_smoother_free(fax->smoother);
01387 fax->smoother = NULL;
01388 }
01389 if (!(fax->smoother = ast_smoother_new(320))) {
01390 ast_log(LOG_WARNING, "Channel '%s' FAX session '%d' failed to obtain a smoother.\n", ast_channel_name(chan), fax->id);
01391 }
01392 } else {
01393 expected_frametype = AST_FRAME_MODEM;
01394 expected_framesubclass.integer = AST_MODEM_T38;
01395 }
01396
01397 if (fax->debug_info) {
01398 fax->debug_info->base_tv = ast_tvnow();
01399 }
01400
01401
01402
01403 ast_string_field_set(details, result, "");
01404 ast_string_field_set(details, resultstr, "");
01405 ast_string_field_set(details, error, "");
01406 set_channel_variables(chan, details);
01407
01408 if (fax->tech->start_session(fax) < 0) {
01409 GENERIC_FAX_EXEC_ERROR(fax, chan, "INIT_ERROR", "failed to start FAX session");
01410 }
01411
01412 report_fax_status(chan, details, "FAX Transmission In Progress");
01413
01414 ast_debug(5, "channel %s will wait on FAX fd %d\n", ast_channel_name(chan), fax->fd);
01415
01416
01417 remaining_time = timeout;
01418 start = ast_tvnow();
01419 while (remaining_time > 0) {
01420 struct ast_channel *ready_chan;
01421 int ofd, exception;
01422
01423 ms = 1000;
01424 errno = 0;
01425 ready_chan = ast_waitfor_nandfds(&c, chancount, &fax->fd, 1, &exception, &ofd, &ms);
01426 if (ready_chan) {
01427 if (!(frame = ast_read(chan))) {
01428
01429
01430
01431
01432 ast_debug(1, "Channel '%s' did not return a frame; probably hung up.\n", ast_channel_name(chan));
01433 GENERIC_FAX_EXEC_SET_VARS(fax, chan, "HANGUP", "remote channel hungup");
01434 c = NULL;
01435 chancount = 0;
01436 remaining_time = ast_remaining_ms(start, timeout);
01437 fax->tech->cancel_session(fax);
01438 if (fax->tech->generate_silence) {
01439 fax->tech->generate_silence(fax);
01440 }
01441 continue;
01442 }
01443
01444 if ((frame->frametype == AST_FRAME_CONTROL) &&
01445 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01446 (frame->datalen == sizeof(t38_parameters))) {
01447 unsigned int was_t38 = t38negotiated;
01448 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01449
01450 switch (parameters->request_response) {
01451 case AST_T38_REQUEST_NEGOTIATE:
01452
01453
01454
01455 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01456 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01457 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01458 break;
01459 case AST_T38_NEGOTIATED:
01460 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01461 t38negotiated = 1;
01462 break;
01463 default:
01464 break;
01465 }
01466 if (t38negotiated && !was_t38) {
01467 fax->tech->switch_to_t38(fax);
01468 details->caps &= ~AST_FAX_TECH_AUDIO;
01469 expected_frametype = AST_FRAME_MODEM;
01470 expected_framesubclass.integer = AST_MODEM_T38;
01471 if (fax->smoother) {
01472 ast_smoother_free(fax->smoother);
01473 fax->smoother = NULL;
01474 }
01475
01476 report_fax_status(chan, details, "T.38 Negotiated");
01477
01478 ast_verb(3, "Channel '%s' switched to T.38 FAX session '%d'.\n", ast_channel_name(chan), fax->id);
01479 }
01480 } else if ((frame->frametype == expected_frametype) &&
01481 (!memcmp(&frame->subclass, &expected_framesubclass, sizeof(frame->subclass)))) {
01482 struct ast_frame *f;
01483
01484 if (fax->smoother) {
01485
01486 if (ast_smoother_feed(fax->smoother, frame) < 0) {
01487 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "Failed to feed the smoother");
01488 }
01489 while ((f = ast_smoother_read(fax->smoother)) && (f->data.ptr)) {
01490 if (fax->debug_info) {
01491 debug_check_frame_for_silence(fax, 1, f);
01492 }
01493
01494 fax->tech->write(fax, f);
01495 fax->frames_received++;
01496 if (f != frame) {
01497 ast_frfree(f);
01498 }
01499 }
01500 } else {
01501
01502 fax->tech->write(fax, frame);
01503 fax->frames_received++;
01504 }
01505 start = ast_tvnow();
01506 }
01507 ast_frfree(frame);
01508 } else if (ofd == fax->fd) {
01509
01510
01511 if (!(frame = fax->tech->read(fax))) {
01512 break;
01513 }
01514
01515 if (fax->debug_info && (frame->frametype == AST_FRAME_VOICE)) {
01516 debug_check_frame_for_silence(fax, 0, frame);
01517 }
01518
01519 ast_write(chan, frame);
01520 fax->frames_sent++;
01521 ast_frfree(frame);
01522 start = ast_tvnow();
01523 } else {
01524 if (ms && (ofd < 0)) {
01525 if ((errno == 0) || (errno == EINTR)) {
01526 remaining_time = ast_remaining_ms(start, timeout);
01527 if (remaining_time <= 0)
01528 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
01529 continue;
01530 } else {
01531 ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(chan));
01532 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "error polling data");
01533 break;
01534 }
01535 } else {
01536
01537 remaining_time = ast_remaining_ms(start, timeout);
01538 if (remaining_time <= 0) {
01539 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
01540 break;
01541 }
01542 }
01543 }
01544 }
01545 ast_debug(3, "channel '%s' - event loop stopped { timeout: %d, remaining_time: %d }\n", ast_channel_name(chan), timeout, remaining_time);
01546
01547 set_channel_variables(chan, details);
01548
01549 ast_atomic_fetchadd_int(&faxregistry.fax_complete, 1);
01550 if (!strcasecmp(details->result, "FAILED")) {
01551 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01552 }
01553
01554 if (fax) {
01555 ao2_lock(faxregistry.container);
01556 ao2_unlink(faxregistry.container, fax);
01557 ao2_unlock(faxregistry.container);
01558 ao2_ref(fax, -1);
01559 }
01560
01561
01562
01563
01564 if (chancount) {
01565 if (orig_read_format.id) {
01566 ast_set_read_format(chan, &orig_read_format);
01567 }
01568 if (orig_write_format.id) {
01569 ast_set_write_format(chan, &orig_write_format);
01570 }
01571 }
01572
01573
01574 return chancount;
01575 }
01576
01577 static int receivefax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
01578 {
01579 int timeout_ms;
01580 struct ast_frame *frame = NULL;
01581 struct ast_control_t38_parameters t38_parameters;
01582 struct timeval start;
01583 int ms;
01584
01585
01586 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
01587
01588 if (ast_playtones_start(chan, 1024, "!2100/3000", 1)) {
01589 ast_log(LOG_ERROR, "error generating CED tone on %s\n", ast_channel_name(chan));
01590 return -1;
01591 }
01592
01593 timeout_ms = 3000;
01594 start = ast_tvnow();
01595 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01596 ms = ast_waitfor(chan, ms);
01597
01598 if (ms < 0) {
01599 ast_log(LOG_ERROR, "error while generating CED tone on %s\n", ast_channel_name(chan));
01600 ast_playtones_stop(chan);
01601 return -1;
01602 }
01603
01604 if (ms == 0) {
01605 break;
01606 }
01607
01608 if (!(frame = ast_read(chan))) {
01609 ast_log(LOG_ERROR, "error reading frame while generating CED tone on %s\n", ast_channel_name(chan));
01610 ast_playtones_stop(chan);
01611 return -1;
01612 }
01613
01614 if ((frame->frametype == AST_FRAME_CONTROL) &&
01615 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01616 (frame->datalen == sizeof(t38_parameters))) {
01617 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01618
01619 switch (parameters->request_response) {
01620 case AST_T38_REQUEST_NEGOTIATE:
01621
01622
01623
01624 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01625 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01626 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01627 ast_playtones_stop(chan);
01628 break;
01629 case AST_T38_NEGOTIATED:
01630 ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
01631 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01632 details->caps &= ~AST_FAX_TECH_AUDIO;
01633 report_fax_status(chan, details, "T.38 Negotiated");
01634 break;
01635 default:
01636 break;
01637 }
01638 }
01639 ast_frfree(frame);
01640 }
01641
01642 ast_playtones_stop(chan);
01643 }
01644
01645
01646 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01647 return 0;
01648 }
01649
01650
01651 ast_debug(1, "Negotiating T.38 for receive on %s\n", ast_channel_name(chan));
01652
01653
01654 timeout_ms = 5000;
01655
01656
01657 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01658 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
01659 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
01660 return -1;
01661 }
01662
01663 start = ast_tvnow();
01664 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01665 int break_loop = 0;
01666
01667 ms = ast_waitfor(chan, ms);
01668 if (ms < 0) {
01669 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
01670 return -1;
01671 }
01672 if (ms == 0) {
01673 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(chan));
01674 details->caps &= ~AST_FAX_TECH_T38;
01675 break;
01676 }
01677
01678 if (!(frame = ast_read(chan))) {
01679 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
01680 return -1;
01681 }
01682
01683 if ((frame->frametype == AST_FRAME_CONTROL) &&
01684 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01685 (frame->datalen == sizeof(t38_parameters))) {
01686 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01687
01688 switch (parameters->request_response) {
01689 case AST_T38_REQUEST_NEGOTIATE:
01690 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01691 t38_parameters.request_response = AST_T38_NEGOTIATED;
01692 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01693 break;
01694 case AST_T38_NEGOTIATED:
01695 ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
01696 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01697 details->caps &= ~AST_FAX_TECH_AUDIO;
01698 report_fax_status(chan, details, "T.38 Negotiated");
01699 break_loop = 1;
01700 break;
01701 case AST_T38_REFUSED:
01702 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(chan));
01703 details->caps &= ~AST_FAX_TECH_T38;
01704 break_loop = 1;
01705 break;
01706 default:
01707 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(chan));
01708 details->caps &= ~AST_FAX_TECH_T38;
01709 break_loop = 1;
01710 break;
01711 }
01712 }
01713 ast_frfree(frame);
01714 if (break_loop) {
01715 break;
01716 }
01717 }
01718
01719
01720 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01721 return 0;
01722 }
01723
01724
01725 if (details->option.allow_audio != AST_FAX_OPTFLAG_TRUE) {
01726 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", ast_channel_name(chan));
01727 return -1;
01728 }
01729
01730
01731 details->caps |= AST_FAX_TECH_AUDIO;
01732
01733 return 0;
01734 }
01735
01736
01737 static int receivefax_exec(struct ast_channel *chan, const char *data)
01738 {
01739 char *parse, modems[128] = "";
01740 int channel_alive;
01741 struct ast_fax_session_details *details;
01742 struct ast_fax_session *s;
01743 struct ast_fax_tech_token *token = NULL;
01744 struct ast_fax_document *doc;
01745 AST_DECLARE_APP_ARGS(args,
01746 AST_APP_ARG(filename);
01747 AST_APP_ARG(options);
01748 );
01749 struct ast_flags opts = { 0, };
01750 struct manager_event_info info;
01751 enum ast_t38_state t38state;
01752
01753
01754 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
01755 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
01756 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
01757 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
01758 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
01759
01760
01761
01762 if (!(details = find_or_create_details(chan))) {
01763 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
01764 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
01765 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
01766 return -1;
01767 }
01768
01769 ast_string_field_set(details, result, "FAILED");
01770 ast_string_field_set(details, resultstr, "error starting fax session");
01771 ast_string_field_set(details, error, "INIT_ERROR");
01772 set_channel_variables(chan, details);
01773
01774 if (details->gateway_id > 0) {
01775 ast_string_field_set(details, resultstr, "can't receive a fax on a channel with a T.38 gateway");
01776 set_channel_variables(chan, details);
01777 ast_log(LOG_ERROR, "executing ReceiveFAX on a channel with a T.38 Gateway is not supported\n");
01778 ao2_ref(details, -1);
01779 return -1;
01780 }
01781
01782 if (details->maxrate < details->minrate) {
01783 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01784 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
01785 set_channel_variables(chan, details);
01786 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
01787 ao2_ref(details, -1);
01788 return -1;
01789 }
01790
01791 if (check_modem_rate(details->modems, details->minrate)) {
01792 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
01793 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
01794 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01795 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
01796 set_channel_variables(chan, details);
01797 ao2_ref(details, -1);
01798 return -1;
01799 }
01800
01801 if (check_modem_rate(details->modems, details->maxrate)) {
01802 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
01803 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
01804 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01805 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
01806 set_channel_variables(chan, details);
01807 ao2_ref(details, -1);
01808 return -1;
01809 }
01810
01811 if (ast_strlen_zero(data)) {
01812 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01813 ast_string_field_set(details, resultstr, "invalid arguments");
01814 set_channel_variables(chan, details);
01815 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
01816 ao2_ref(details, -1);
01817 return -1;
01818 }
01819 parse = ast_strdupa(data);
01820 AST_STANDARD_APP_ARGS(args, parse);
01821
01822 if (!ast_strlen_zero(args.options) &&
01823 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
01824 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01825 ast_string_field_set(details, resultstr, "invalid arguments");
01826 set_channel_variables(chan, details);
01827 ao2_ref(details, -1);
01828 return -1;
01829 }
01830 if (ast_strlen_zero(args.filename)) {
01831 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01832 ast_string_field_set(details, resultstr, "invalid arguments");
01833 set_channel_variables(chan, details);
01834 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
01835 ao2_ref(details, -1);
01836 return -1;
01837 }
01838
01839
01840 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
01841 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01842 ast_string_field_set(details, resultstr, "invalid arguments");
01843 set_channel_variables(chan, details);
01844 ast_log(LOG_WARNING, "%s does not support polling\n", app_receivefax);
01845 ao2_ref(details, -1);
01846 return -1;
01847 }
01848
01849 ast_atomic_fetchadd_int(&faxregistry.fax_rx_attempts, 1);
01850
01851 pbx_builtin_setvar_helper(chan, "FAXERROR", "Channel Problems");
01852 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "Error before FAX transmission started.");
01853
01854 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(args.filename) + 1))) {
01855 ast_string_field_set(details, error, "MEMORY_ERROR");
01856 ast_string_field_set(details, resultstr, "error allocating memory");
01857 set_channel_variables(chan, details);
01858 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
01859 ao2_ref(details, -1);
01860 return -1;
01861 }
01862
01863 strcpy(doc->filename, args.filename);
01864 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
01865
01866 ast_verb(3, "Channel '%s' receiving FAX '%s'\n", ast_channel_name(chan), args.filename);
01867
01868 details->caps = AST_FAX_TECH_RECEIVE;
01869 details->option.send_ced = AST_FAX_OPTFLAG_TRUE;
01870
01871
01872 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
01873 details->option.debug = AST_FAX_OPTFLAG_TRUE;
01874 }
01875
01876
01877 if (ast_test_flag(&opts, OPT_STATUS)) {
01878 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
01879 }
01880
01881 t38state = ast_channel_get_t38_state(chan);
01882 if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
01883 ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
01884 ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
01885 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
01886 }
01887
01888 if (!(s = fax_session_reserve(details, &token))) {
01889 ast_string_field_set(details, resultstr, "error reserving fax session");
01890 set_channel_variables(chan, details);
01891 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
01892 ao2_ref(details, -1);
01893 return -1;
01894 }
01895
01896
01897 if (ast_channel_state(chan) != AST_STATE_UP) {
01898 if (ast_answer(chan)) {
01899 ast_string_field_set(details, resultstr, "error answering channel");
01900 set_channel_variables(chan, details);
01901 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", ast_channel_name(chan));
01902 fax_session_release(s, token);
01903 ao2_ref(s, -1);
01904 ao2_ref(details, -1);
01905 return -1;
01906 }
01907 }
01908
01909 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
01910 if (set_fax_t38_caps(chan, details)) {
01911 ast_string_field_set(details, error, "T38_NEG_ERROR");
01912 ast_string_field_set(details, resultstr, "error negotiating T.38");
01913 set_channel_variables(chan, details);
01914 fax_session_release(s, token);
01915 ao2_ref(s, -1);
01916 ao2_ref(details, -1);
01917 return -1;
01918 }
01919 } else {
01920 details->caps |= AST_FAX_TECH_AUDIO;
01921 }
01922
01923 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
01924 if (receivefax_t38_init(chan, details)) {
01925 ast_string_field_set(details, error, "T38_NEG_ERROR");
01926 ast_string_field_set(details, resultstr, "error negotiating T.38");
01927 set_channel_variables(chan, details);
01928 fax_session_release(s, token);
01929 ao2_ref(s, -1);
01930 ao2_ref(details, -1);
01931 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", ast_channel_name(chan));
01932 return -1;
01933 }
01934 }
01935
01936 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
01937 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01938 }
01939
01940 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01941 if (disable_t38(chan)) {
01942 ast_debug(1, "error disabling T.38 mode on %s\n", ast_channel_name(chan));
01943 }
01944 }
01945
01946
01947 ast_channel_lock(chan);
01948
01949 get_manager_event_info(chan, &info);
01950 manager_event(EVENT_FLAG_CALL,
01951 "ReceiveFAX",
01952 "Channel: %s\r\n"
01953 "Context: %s\r\n"
01954 "Exten: %s\r\n"
01955 "CallerID: %s\r\n"
01956 "RemoteStationID: %s\r\n"
01957 "LocalStationID: %s\r\n"
01958 "PagesTransferred: %s\r\n"
01959 "Resolution: %s\r\n"
01960 "TransferRate: %s\r\n"
01961 "FileName: %s\r\n",
01962 ast_channel_name(chan),
01963 info.context,
01964 info.exten,
01965 info.cid,
01966 S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
01967 S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
01968 S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
01969 S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
01970 S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
01971 args.filename);
01972 ast_channel_unlock(chan);
01973
01974 ao2_ref(s, -1);
01975 ao2_ref(details, -1);
01976
01977
01978 return (!channel_alive) ? -1 : 0;
01979 }
01980
01981 static int sendfax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
01982 {
01983 int timeout_ms;
01984 struct ast_frame *frame = NULL;
01985 struct ast_control_t38_parameters t38_parameters;
01986 struct timeval start;
01987 int ms;
01988
01989
01990
01991
01992
01993
01994
01995 timeout_ms = 10500;
01996
01997
01998 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
01999 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000", 1)) {
02000 ast_log(LOG_ERROR, "error generating CNG tone on %s\n", ast_channel_name(chan));
02001 return -1;
02002 }
02003 }
02004
02005 start = ast_tvnow();
02006 while ((ms = ast_remaining_ms(start, timeout_ms))) {
02007 int break_loop = 0;
02008 ms = ast_waitfor(chan, ms);
02009
02010 if (ms < 0) {
02011 ast_log(LOG_ERROR, "error while generating CNG tone on %s\n", ast_channel_name(chan));
02012 ast_playtones_stop(chan);
02013 return -1;
02014 }
02015
02016 if (ms == 0) {
02017 break;
02018 }
02019
02020 if (!(frame = ast_read(chan))) {
02021 ast_log(LOG_ERROR, "error reading frame while generating CNG tone on %s\n", ast_channel_name(chan));
02022 ast_playtones_stop(chan);
02023 return -1;
02024 }
02025
02026 if ((frame->frametype == AST_FRAME_CONTROL) &&
02027 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
02028 (frame->datalen == sizeof(t38_parameters))) {
02029 struct ast_control_t38_parameters *parameters = frame->data.ptr;
02030
02031 switch (parameters->request_response) {
02032 case AST_T38_REQUEST_NEGOTIATE:
02033
02034
02035
02036 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
02037 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
02038 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
02039 ast_playtones_stop(chan);
02040 break;
02041 case AST_T38_NEGOTIATED:
02042 ast_debug(1, "Negotiated T.38 for send on %s\n", ast_channel_name(chan));
02043 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
02044 details->caps &= ~AST_FAX_TECH_AUDIO;
02045 report_fax_status(chan, details, "T.38 Negotiated");
02046 break_loop = 1;
02047 break;
02048 default:
02049 break;
02050 }
02051 }
02052 ast_frfree(frame);
02053 if (break_loop) {
02054 break;
02055 }
02056 }
02057
02058 ast_playtones_stop(chan);
02059
02060 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02061 return 0;
02062 }
02063
02064
02065 if (details->option.request_t38 == AST_FAX_OPTFLAG_TRUE) {
02066 ast_debug(1, "Negotiating T.38 for send on %s\n", ast_channel_name(chan));
02067
02068
02069 timeout_ms = 5000;
02070
02071
02072 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
02073 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
02074 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
02075 return -1;
02076 }
02077
02078 start = ast_tvnow();
02079 while ((ms = ast_remaining_ms(start, timeout_ms))) {
02080 int break_loop = 0;
02081
02082 ms = ast_waitfor(chan, ms);
02083 if (ms < 0) {
02084 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
02085 return -1;
02086 }
02087 if (ms == 0) {
02088 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(chan));
02089 details->caps &= ~AST_FAX_TECH_T38;
02090 break;
02091 }
02092
02093 if (!(frame = ast_read(chan))) {
02094 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
02095 return -1;
02096 }
02097
02098 if ((frame->frametype == AST_FRAME_CONTROL) &&
02099 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
02100 (frame->datalen == sizeof(t38_parameters))) {
02101 struct ast_control_t38_parameters *parameters = frame->data.ptr;
02102
02103 switch (parameters->request_response) {
02104 case AST_T38_REQUEST_NEGOTIATE:
02105 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
02106 t38_parameters.request_response = AST_T38_NEGOTIATED;
02107 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
02108 break;
02109 case AST_T38_NEGOTIATED:
02110 ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
02111 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
02112 details->caps &= ~AST_FAX_TECH_AUDIO;
02113 report_fax_status(chan, details, "T.38 Negotiated");
02114 break_loop = 1;
02115 break;
02116 case AST_T38_REFUSED:
02117 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(chan));
02118 details->caps &= ~AST_FAX_TECH_T38;
02119 break_loop = 1;
02120 break;
02121 default:
02122 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(chan));
02123 details->caps &= ~AST_FAX_TECH_T38;
02124 break_loop = 1;
02125 break;
02126 }
02127 }
02128 ast_frfree(frame);
02129 if (break_loop) {
02130 break;
02131 }
02132 }
02133
02134
02135 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02136 return 0;
02137 }
02138
02139
02140
02141 if (details->option.allow_audio == AST_FAX_OPTFLAG_TRUE) {
02142 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000", 1)) {
02143 ast_log(LOG_ERROR, "error generating second CNG tone on %s\n", ast_channel_name(chan));
02144 return -1;
02145 }
02146
02147 timeout_ms = 3500;
02148 start = ast_tvnow();
02149 while ((ms = ast_remaining_ms(start, timeout_ms))) {
02150 int break_loop = 0;
02151
02152 ms = ast_waitfor(chan, ms);
02153 if (ms < 0) {
02154 ast_log(LOG_ERROR, "error while generating second CNG tone on %s\n", ast_channel_name(chan));
02155 ast_playtones_stop(chan);
02156 return -1;
02157 }
02158 if (ms == 0) {
02159 break;
02160 }
02161
02162 if (!(frame = ast_read(chan))) {
02163 ast_log(LOG_ERROR, "error reading frame while generating second CNG tone on %s\n", ast_channel_name(chan));
02164 ast_playtones_stop(chan);
02165 return -1;
02166 }
02167
02168 if ((frame->frametype == AST_FRAME_CONTROL) &&
02169 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
02170 (frame->datalen == sizeof(t38_parameters))) {
02171 struct ast_control_t38_parameters *parameters = frame->data.ptr;
02172
02173 switch (parameters->request_response) {
02174 case AST_T38_REQUEST_NEGOTIATE:
02175
02176
02177
02178 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
02179 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
02180 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
02181 ast_playtones_stop(chan);
02182 break;
02183 case AST_T38_NEGOTIATED:
02184 ast_debug(1, "Negotiated T.38 for send on %s\n", ast_channel_name(chan));
02185 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
02186 details->caps &= ~AST_FAX_TECH_AUDIO;
02187 report_fax_status(chan, details, "T.38 Negotiated");
02188 break_loop = 1;
02189 break;
02190 default:
02191 break;
02192 }
02193 }
02194 ast_frfree(frame);
02195 if (break_loop) {
02196 break;
02197 }
02198 }
02199
02200 ast_playtones_stop(chan);
02201
02202
02203 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02204 return 0;
02205 }
02206 }
02207 }
02208
02209
02210 if (details->option.allow_audio == AST_FAX_OPTFLAG_FALSE) {
02211 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", ast_channel_name(chan));
02212 return -1;
02213 }
02214
02215
02216 details->caps |= AST_FAX_TECH_AUDIO;
02217
02218 return 0;
02219 }
02220
02221
02222
02223 static int sendfax_exec(struct ast_channel *chan, const char *data)
02224 {
02225 char *parse, *filenames, *c, modems[128] = "";
02226 int channel_alive, file_count;
02227 struct ast_fax_session_details *details;
02228 struct ast_fax_session *s;
02229 struct ast_fax_tech_token *token = NULL;
02230 struct ast_fax_document *doc;
02231 AST_DECLARE_APP_ARGS(args,
02232 AST_APP_ARG(filenames);
02233 AST_APP_ARG(options);
02234 );
02235 struct ast_flags opts = { 0, };
02236 struct manager_event_info info;
02237 enum ast_t38_state t38state;
02238
02239
02240 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
02241 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
02242 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
02243 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
02244 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
02245
02246
02247
02248 if (!(details = find_or_create_details(chan))) {
02249 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
02250 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
02251 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
02252 return -1;
02253 }
02254
02255 ast_string_field_set(details, result, "FAILED");
02256 ast_string_field_set(details, resultstr, "error starting fax session");
02257 ast_string_field_set(details, error, "INIT_ERROR");
02258 set_channel_variables(chan, details);
02259
02260 if (details->gateway_id > 0) {
02261 ast_string_field_set(details, resultstr, "can't send a fax on a channel with a T.38 gateway");
02262 set_channel_variables(chan, details);
02263 ast_log(LOG_ERROR, "executing SendFAX on a channel with a T.38 Gateway is not supported\n");
02264 ao2_ref(details, -1);
02265 return -1;
02266 }
02267
02268 if (details->maxrate < details->minrate) {
02269 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02270 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
02271 set_channel_variables(chan, details);
02272 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
02273 ao2_ref(details, -1);
02274 return -1;
02275 }
02276
02277 if (check_modem_rate(details->modems, details->minrate)) {
02278 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
02279 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
02280 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02281 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
02282 set_channel_variables(chan, details);
02283 ao2_ref(details, -1);
02284 return -1;
02285 }
02286
02287 if (check_modem_rate(details->modems, details->maxrate)) {
02288 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
02289 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
02290 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02291 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
02292 set_channel_variables(chan, details);
02293 ao2_ref(details, -1);
02294 return -1;
02295 }
02296
02297 if (ast_strlen_zero(data)) {
02298 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02299 ast_string_field_set(details, resultstr, "invalid arguments");
02300 set_channel_variables(chan, details);
02301 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]][,options])\n", app_sendfax);
02302 ao2_ref(details, -1);
02303 return -1;
02304 }
02305 parse = ast_strdupa(data);
02306 AST_STANDARD_APP_ARGS(args, parse);
02307
02308
02309 if (!ast_strlen_zero(args.options) &&
02310 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
02311 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02312 ast_string_field_set(details, resultstr, "invalid arguments");
02313 set_channel_variables(chan, details);
02314 ao2_ref(details, -1);
02315 return -1;
02316 }
02317 if (ast_strlen_zero(args.filenames)) {
02318 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02319 ast_string_field_set(details, resultstr, "invalid arguments");
02320 set_channel_variables(chan, details);
02321 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]],options])\n", app_sendfax);
02322 ao2_ref(details, -1);
02323 return -1;
02324 }
02325
02326
02327 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
02328 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02329 ast_string_field_set(details, resultstr, "invalid arguments");
02330 set_channel_variables(chan, details);
02331 ast_log(LOG_WARNING, "%s does not support polling\n", app_sendfax);
02332 ao2_ref(details, -1);
02333 return -1;
02334 }
02335
02336 ast_atomic_fetchadd_int(&faxregistry.fax_tx_attempts, 1);
02337
02338 file_count = 0;
02339 filenames = args.filenames;
02340 while ((c = strsep(&filenames, "&"))) {
02341 if (access(c, (F_OK | R_OK)) < 0) {
02342 ast_string_field_set(details, error, "FILE_ERROR");
02343 ast_string_field_set(details, resultstr, "error reading file");
02344 set_channel_variables(chan, details);
02345 ast_log(LOG_ERROR, "access failure. Verify '%s' exists and check permissions.\n", args.filenames);
02346 ao2_ref(details, -1);
02347 return -1;
02348 }
02349
02350 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(c) + 1))) {
02351 ast_string_field_set(details, error, "MEMORY_ERROR");
02352 ast_string_field_set(details, resultstr, "error allocating memory");
02353 set_channel_variables(chan, details);
02354 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
02355 ao2_ref(details, -1);
02356 return -1;
02357 }
02358
02359 strcpy(doc->filename, c);
02360 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
02361 file_count++;
02362 }
02363
02364 ast_verb(3, "Channel '%s' sending FAX:\n", ast_channel_name(chan));
02365 AST_LIST_TRAVERSE(&details->documents, doc, next) {
02366 ast_verb(3, " %s\n", doc->filename);
02367 }
02368
02369 details->caps = AST_FAX_TECH_SEND;
02370
02371 if (file_count > 1) {
02372 details->caps |= AST_FAX_TECH_MULTI_DOC;
02373 }
02374
02375
02376 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
02377 details->option.debug = AST_FAX_OPTFLAG_TRUE;
02378 }
02379
02380
02381 if (ast_test_flag(&opts, OPT_STATUS)) {
02382 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
02383 }
02384
02385 t38state = ast_channel_get_t38_state(chan);
02386 if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
02387 ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
02388 ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
02389 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
02390 }
02391
02392 if (ast_test_flag(&opts, OPT_REQUEST_T38)) {
02393 details->option.request_t38 = AST_FAX_OPTFLAG_TRUE;
02394 }
02395
02396 if (!(s = fax_session_reserve(details, &token))) {
02397 ast_string_field_set(details, resultstr, "error reserving fax session");
02398 set_channel_variables(chan, details);
02399 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
02400 ao2_ref(details, -1);
02401 return -1;
02402 }
02403
02404
02405 if (ast_channel_state(chan) != AST_STATE_UP) {
02406 if (ast_answer(chan)) {
02407 ast_string_field_set(details, resultstr, "error answering channel");
02408 set_channel_variables(chan, details);
02409 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", ast_channel_name(chan));
02410 fax_session_release(s, token);
02411 ao2_ref(s, -1);
02412 ao2_ref(details, -1);
02413 return -1;
02414 }
02415 }
02416
02417 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
02418 if (set_fax_t38_caps(chan, details)) {
02419 ast_string_field_set(details, error, "T38_NEG_ERROR");
02420 ast_string_field_set(details, resultstr, "error negotiating T.38");
02421 set_channel_variables(chan, details);
02422 fax_session_release(s, token);
02423 ao2_ref(s, -1);
02424 ao2_ref(details, -1);
02425 return -1;
02426 }
02427 } else {
02428 details->caps |= AST_FAX_TECH_AUDIO;
02429 }
02430
02431 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
02432 if (sendfax_t38_init(chan, details)) {
02433 ast_string_field_set(details, error, "T38_NEG_ERROR");
02434 ast_string_field_set(details, resultstr, "error negotiating T.38");
02435 set_channel_variables(chan, details);
02436 fax_session_release(s, token);
02437 ao2_ref(s, -1);
02438 ao2_ref(details, -1);
02439 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", ast_channel_name(chan));
02440 return -1;
02441 }
02442 } else {
02443 details->option.send_cng = 1;
02444 }
02445
02446 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
02447 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02448 }
02449
02450 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02451 if (disable_t38(chan)) {
02452 ast_debug(1, "error disabling T.38 mode on %s\n", ast_channel_name(chan));
02453 }
02454 }
02455
02456 if (!(filenames = generate_filenames_string(details, "FileName: ", "\r\n"))) {
02457 ast_log(LOG_ERROR, "Error generating SendFAX manager event\n");
02458 ao2_ref(s, -1);
02459 ao2_ref(details, -1);
02460 return (!channel_alive) ? -1 : 0;
02461 }
02462
02463
02464 ast_channel_lock(chan);
02465 get_manager_event_info(chan, &info);
02466 manager_event(EVENT_FLAG_CALL,
02467 "SendFAX",
02468 "Channel: %s\r\n"
02469 "Context: %s\r\n"
02470 "Exten: %s\r\n"
02471 "CallerID: %s\r\n"
02472 "RemoteStationID: %s\r\n"
02473 "LocalStationID: %s\r\n"
02474 "PagesTransferred: %s\r\n"
02475 "Resolution: %s\r\n"
02476 "TransferRate: %s\r\n"
02477 "%s\r\n",
02478 ast_channel_name(chan),
02479 info.context,
02480 info.exten,
02481 info.cid,
02482 S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
02483 S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
02484 S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
02485 S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
02486 S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
02487 filenames);
02488 ast_channel_unlock(chan);
02489
02490 ast_free(filenames);
02491
02492 ao2_ref(s, -1);
02493 ao2_ref(details, -1);
02494
02495
02496 return (!channel_alive) ? -1 : 0;
02497 }
02498
02499
02500 static void destroy_v21_sessions(struct fax_gateway *gateway)
02501 {
02502 if (gateway->chan_v21_session) {
02503 ao2_lock(faxregistry.container);
02504 ao2_unlink(faxregistry.container, gateway->chan_v21_session);
02505 ao2_unlock(faxregistry.container);
02506
02507 ao2_ref(gateway->chan_v21_session, -1);
02508 gateway->chan_v21_session = NULL;
02509 }
02510
02511 if (gateway->peer_v21_session) {
02512 ao2_lock(faxregistry.container);
02513 ao2_unlink(faxregistry.container, gateway->peer_v21_session);
02514 ao2_unlock(faxregistry.container);
02515
02516 ao2_ref(gateway->peer_v21_session, -1);
02517 gateway->peer_v21_session = NULL;
02518 }
02519 }
02520
02521
02522 static void destroy_gateway(void *data)
02523 {
02524 struct fax_gateway *gateway = data;
02525
02526 destroy_v21_sessions(gateway);
02527
02528 if (gateway->s) {
02529 fax_session_release(gateway->s, gateway->token);
02530 gateway->token = NULL;
02531
02532 ao2_lock(faxregistry.container);
02533 ao2_unlink(faxregistry.container, gateway->s);
02534 ao2_unlock(faxregistry.container);
02535
02536 ao2_ref(gateway->s, -1);
02537 gateway->s = NULL;
02538 }
02539 }
02540
02541
02542
02543
02544
02545
02546 static struct fax_gateway *fax_gateway_new(struct ast_channel *chan, struct ast_fax_session_details *details)
02547 {
02548 struct fax_gateway *gateway = ao2_alloc(sizeof(*gateway), destroy_gateway);
02549 struct ast_fax_session_details *v21_details;
02550 if (!gateway) {
02551 return NULL;
02552 }
02553
02554 if (!(v21_details = session_details_new())) {
02555 ao2_ref(gateway, -1);
02556 return NULL;
02557 }
02558
02559 v21_details->caps = AST_FAX_TECH_V21_DETECT;
02560 if (!(gateway->chan_v21_session = fax_session_new(v21_details, chan, NULL, NULL))) {
02561 ao2_ref(v21_details, -1);
02562 ao2_ref(gateway, -1);
02563 return NULL;
02564 }
02565
02566 if (!(gateway->peer_v21_session = fax_session_new(v21_details, chan, NULL, NULL))) {
02567 ao2_ref(v21_details, -1);
02568 ao2_ref(gateway, -1);
02569 return NULL;
02570 }
02571 ao2_ref(v21_details, -1);
02572
02573 gateway->framehook = -1;
02574
02575 details->caps = AST_FAX_TECH_GATEWAY;
02576 if (details->gateway_timeout && !(gateway->s = fax_session_reserve(details, &gateway->token))) {
02577 details->caps &= ~AST_FAX_TECH_GATEWAY;
02578 ast_log(LOG_ERROR, "Can't reserve a FAX session, gateway attempt failed.\n");
02579 ao2_ref(gateway, -1);
02580 return NULL;
02581 }
02582
02583 return gateway;
02584 }
02585
02586
02587
02588
02589
02590
02591 static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session_details *details, struct ast_channel *chan)
02592 {
02593 struct ast_fax_session *s;
02594
02595
02596 if (!(s = fax_session_new(details, chan, gateway->s, gateway->token))) {
02597 gateway->token = NULL;
02598 ast_string_field_set(details, result, "FAILED");
02599 ast_string_field_set(details, resultstr, "error starting gateway session");
02600 ast_string_field_set(details, error, "INIT_ERROR");
02601 set_channel_variables(chan, details);
02602 report_fax_status(chan, details, "No Available Resource");
02603 ast_log(LOG_ERROR, "Can't create a FAX session, gateway attempt failed.\n");
02604 return -1;
02605 }
02606
02607
02608 if (gateway->s) {
02609 ao2_ref(gateway->s, -1);
02610 }
02611 gateway->s = s;
02612 gateway->token = NULL;
02613
02614 if (gateway->s->tech->start_session(gateway->s) < 0) {
02615 ast_string_field_set(details, result, "FAILED");
02616 ast_string_field_set(details, resultstr, "error starting gateway session");
02617 ast_string_field_set(details, error, "INIT_ERROR");
02618 set_channel_variables(chan, details);
02619 return -1;
02620 }
02621
02622 gateway->timeout_start.tv_sec = 0;
02623 gateway->timeout_start.tv_usec = 0;
02624
02625 report_fax_status(chan, details, "FAX Transmission In Progress");
02626
02627 return 0;
02628 }
02629
02630 static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_frame *f)
02631 {
02632 struct ast_frame *fp;
02633 struct ast_control_t38_parameters t38_parameters = {
02634 .request_response = AST_T38_REQUEST_NEGOTIATE,
02635 };
02636 struct ast_frame control_frame = {
02637 .src = "res_fax",
02638 .frametype = AST_FRAME_CONTROL,
02639 .datalen = sizeof(t38_parameters),
02640 .subclass.integer = AST_CONTROL_T38_PARAMETERS,
02641 .data.ptr = &t38_parameters,
02642 };
02643
02644 struct ast_fax_session_details *details = find_details(chan);
02645
02646 if (!details) {
02647 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
02648 ast_framehook_detach(chan, gateway->framehook);
02649 return f;
02650 }
02651
02652 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
02653 ao2_ref(details, -1);
02654
02655 if (!(fp = ast_frisolate(&control_frame))) {
02656 ast_log(LOG_ERROR, "error generating T.38 request control frame on chan %s for T.38 gateway session\n", ast_channel_name(chan));
02657 return f;
02658 }
02659
02660 gateway->t38_state = T38_STATE_NEGOTIATING;
02661 gateway->timeout_start = ast_tvnow();
02662 details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
02663
02664 ast_debug(1, "requesting T.38 for gateway session for %s\n", ast_channel_name(chan));
02665 return fp;
02666 }
02667
02668 static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f)
02669 {
02670 struct ast_channel *other = (active == chan) ? peer : chan;
02671 struct ast_fax_session *active_v21_session = (active == chan) ? gateway->chan_v21_session : gateway->peer_v21_session;
02672
02673 if (!active_v21_session || gateway->detected_v21) {
02674 return f;
02675 }
02676
02677 if (active_v21_session->tech->write(active_v21_session, f) == 0 &&
02678 active_v21_session->details->option.v21_detected) {
02679 gateway->detected_v21 = 1;
02680 }
02681
02682 if (gateway->detected_v21) {
02683 destroy_v21_sessions(gateway);
02684 if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
02685 ast_debug(1, "detected v21 preamble from %s\n", ast_channel_name(active));
02686 return fax_gateway_request_t38(gateway, chan, f);
02687 } else {
02688 ast_debug(1, "detected v21 preamble on %s, but %s does not support T.38 for T.38 gateway session\n", ast_channel_name(active), ast_channel_name(other));
02689 }
02690 }
02691
02692 return f;
02693 }
02694
02695 static int fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
02696 {
02697 if (active == chan) {
02698 return ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
02699 } else {
02700 return ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
02701 }
02702 }
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712 static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f)
02713 {
02714 struct ast_control_t38_parameters *control_params = f->data.ptr;
02715 struct ast_channel *other = (active == chan) ? peer : chan;
02716 struct ast_fax_session_details *details;
02717
02718 if (f->datalen != sizeof(struct ast_control_t38_parameters)) {
02719
02720
02721 return f;
02722 }
02723
02724
02725 if ((gateway->t38_state == T38_STATE_NEGOTIATED && control_params->request_response == AST_T38_NEGOTIATED)
02726 || (gateway->t38_state == T38_STATE_REJECTED && control_params->request_response == AST_T38_REFUSED)
02727 || (gateway->t38_state == T38_STATE_NEGOTIATING && control_params->request_response == AST_T38_REQUEST_TERMINATE)) {
02728
02729 return f;
02730 }
02731
02732 if (!(details = find_details(chan))) {
02733 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
02734 ast_framehook_detach(chan, gateway->framehook);
02735 return f;
02736 }
02737
02738 if (control_params->request_response == AST_T38_REQUEST_NEGOTIATE) {
02739 enum ast_t38_state state = ast_channel_get_t38_state(other);
02740
02741 if (state == T38_STATE_UNKNOWN) {
02742
02743
02744
02745
02746 ast_debug(1, "%s is attempting to negotiate T.38 with %s, we'll see what happens\n", ast_channel_name(active), ast_channel_name(other));
02747 t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
02748 gateway->t38_state = T38_STATE_UNKNOWN;
02749 gateway->timeout_start = ast_tvnow();
02750 details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
02751 ao2_ref(details, -1);
02752 return f;
02753 } else if (state == T38_STATE_UNAVAILABLE || state == T38_STATE_REJECTED) {
02754
02755
02756 ast_debug(1, "%s is attempting to negotiate T.38 but %s does not support it\n", ast_channel_name(active), ast_channel_name(other));
02757 ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
02758
02759 t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
02760 t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
02761
02762 if (fax_gateway_start(gateway, details, chan)) {
02763 ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
02764 gateway->t38_state = T38_STATE_REJECTED;
02765 control_params->request_response = AST_T38_REFUSED;
02766
02767 ast_framehook_detach(chan, details->gateway_id);
02768 details->gateway_id = -1;
02769 } else {
02770 gateway->t38_state = T38_STATE_NEGOTIATED;
02771 control_params->request_response = AST_T38_NEGOTIATED;
02772 report_fax_status(chan, details, "T.38 Negotiated");
02773 }
02774
02775 fax_gateway_indicate_t38(chan, active, control_params);
02776
02777 ao2_ref(details, -1);
02778 return &ast_null_frame;
02779 } else if (gateway->t38_state == T38_STATE_NEGOTIATING) {
02780
02781
02782
02783
02784
02785 t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
02786 gateway->t38_state = T38_STATE_UNKNOWN;
02787 gateway->timeout_start = ast_tvnow();
02788 details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
02789
02790 ast_debug(1, "%s is attempting to negotiate T.38 after we already sent a negotiation request based on v21 preamble detection\n", ast_channel_name(active));
02791 ao2_ref(details, -1);
02792 return &ast_null_frame;
02793 } else if (gateway->t38_state == T38_STATE_NEGOTIATED) {
02794
02795
02796
02797
02798
02799 t38_parameters_fax_to_ast(control_params, &details->their_t38_parameters);
02800 ast_framehook_detach(chan, details->gateway_id);
02801 details->gateway_id = -1;
02802
02803 control_params->request_response = AST_T38_NEGOTIATED;
02804
02805 fax_gateway_indicate_t38(chan, active, control_params);
02806
02807 ast_string_field_set(details, result, "SUCCESS");
02808 ast_string_field_set(details, resultstr, "no gateway necessary");
02809 ast_string_field_set(details, error, "NATIVE_T38");
02810 set_channel_variables(chan, details);
02811
02812 ast_debug(1, "%s is attempting to negotiate T.38 after we already negotiated T.38 with %s, disabling the gateway\n", ast_channel_name(active), ast_channel_name(other));
02813 ao2_ref(details, -1);
02814 return &ast_null_frame;
02815 } else {
02816 ast_log(LOG_WARNING, "%s is attempting to negotiate T.38 while %s is in an unsupported state\n", ast_channel_name(active), ast_channel_name(other));
02817 ao2_ref(details, -1);
02818 return f;
02819 }
02820 } else if (gateway->t38_state == T38_STATE_NEGOTIATING
02821 && control_params->request_response == AST_T38_REFUSED) {
02822
02823 ast_debug(1, "unable to negotiate T.38 on %s for fax gateway\n", ast_channel_name(active));
02824
02825
02826
02827
02828 if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
02829 gateway->t38_state = T38_STATE_UNAVAILABLE;
02830 } else {
02831 ast_framehook_detach(chan, details->gateway_id);
02832 details->gateway_id = -1;
02833
02834 ast_string_field_set(details, result, "FAILED");
02835 ast_string_field_set(details, resultstr, "unable to negotiate T.38");
02836 ast_string_field_set(details, error, "T38_NEG_ERROR");
02837 set_channel_variables(chan, details);
02838 }
02839
02840 ao2_ref(details, -1);
02841 return &ast_null_frame;
02842 } else if (gateway->t38_state == T38_STATE_NEGOTIATING
02843 && control_params->request_response == AST_T38_NEGOTIATED) {
02844
02845 ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
02846
02847 t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
02848
02849 if (fax_gateway_start(gateway, details, chan)) {
02850 ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
02851 gateway->t38_state = T38_STATE_NEGOTIATING;
02852 control_params->request_response = AST_T38_REQUEST_TERMINATE;
02853
02854 fax_gateway_indicate_t38(chan, active, control_params);
02855 } else {
02856 gateway->t38_state = T38_STATE_NEGOTIATED;
02857 report_fax_status(chan, details, "T.38 Negotiated");
02858 }
02859
02860 ao2_ref(details, -1);
02861 return &ast_null_frame;
02862 } else if (control_params->request_response == AST_T38_REFUSED) {
02863
02864
02865
02866 ast_debug(1, "%s attempted to negotiate T.38 but %s refused the request\n", ast_channel_name(other), ast_channel_name(active));
02867 ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(other), ast_channel_name(active));
02868
02869 t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
02870
02871 if (fax_gateway_start(gateway, details, chan)) {
02872 ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
02873 gateway->t38_state = T38_STATE_REJECTED;
02874 control_params->request_response = AST_T38_REFUSED;
02875
02876 ast_framehook_detach(chan, details->gateway_id);
02877 details->gateway_id = -1;
02878 } else {
02879 gateway->t38_state = T38_STATE_NEGOTIATED;
02880 control_params->request_response = AST_T38_NEGOTIATED;
02881 }
02882
02883 ao2_ref(details, -1);
02884 return f;
02885 } else if (control_params->request_response == AST_T38_REQUEST_TERMINATE) {
02886
02887
02888
02889 ast_debug(1, "T.38 channel %s is requesting a shutdown of T.38, disabling the gateway\n", ast_channel_name(active));
02890
02891 ast_framehook_detach(chan, details->gateway_id);
02892 details->gateway_id = -1;
02893
02894 gateway->t38_state = T38_STATE_REJECTED;
02895 control_params->request_response = AST_T38_TERMINATED;
02896
02897 fax_gateway_indicate_t38(chan, active, control_params);
02898
02899 ao2_ref(details, -1);
02900 return &ast_null_frame;
02901 } else if (control_params->request_response == AST_T38_NEGOTIATED) {
02902 ast_debug(1, "T.38 successfully negotiated between %s and %s, no gateway necessary\n", ast_channel_name(active), ast_channel_name(other));
02903
02904 ast_framehook_detach(chan, details->gateway_id);
02905 details->gateway_id = -1;
02906
02907 ast_string_field_set(details, result, "SUCCESS");
02908 ast_string_field_set(details, resultstr, "no gateway necessary");
02909 ast_string_field_set(details, error, "NATIVE_T38");
02910 set_channel_variables(chan, details);
02911
02912 ao2_ref(details, -1);
02913 return f;
02914 } else if (control_params->request_response == AST_T38_TERMINATED) {
02915 ast_debug(1, "T.38 disabled on channel %s\n", ast_channel_name(active));
02916
02917 ast_framehook_detach(chan, details->gateway_id);
02918 details->gateway_id = -1;
02919
02920 ao2_ref(details, -1);
02921 return &ast_null_frame;
02922 }
02923
02924 ao2_ref(details, -1);
02925 return f;
02926 }
02927
02928
02929
02930 static void fax_gateway_framehook_destroy(void *data) {
02931 struct fax_gateway *gateway = data;
02932
02933 if (gateway->s) {
02934 switch (gateway->s->state) {
02935 case AST_FAX_STATE_INITIALIZED:
02936 case AST_FAX_STATE_OPEN:
02937 case AST_FAX_STATE_ACTIVE:
02938 case AST_FAX_STATE_COMPLETE:
02939 if (gateway->s->tech->cancel_session) {
02940 gateway->s->tech->cancel_session(gateway->s);
02941 }
02942
02943 default:
02944 break;
02945 }
02946 }
02947
02948 ao2_ref(gateway, -1);
02949 }
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964 static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data) {
02965 struct fax_gateway *gateway = data;
02966 struct ast_channel *peer, *active;
02967 struct ast_fax_session_details *details;
02968
02969 if (gateway->s) {
02970 details = gateway->s->details;
02971 ao2_ref(details, 1);
02972 } else {
02973 if (!(details = find_details(chan))) {
02974 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
02975 ast_framehook_detach(chan, gateway->framehook);
02976 return f;
02977 }
02978 }
02979
02980
02981 if (event == AST_FRAMEHOOK_EVENT_DETACHED) {
02982 set_channel_variables(chan, details);
02983
02984 if (gateway->bridged) {
02985 ast_set_read_format(chan, &gateway->chan_read_format);
02986 ast_set_read_format(chan, &gateway->chan_write_format);
02987
02988 if ((peer = ast_bridged_channel(chan))) {
02989 ast_set_read_format(peer, &gateway->peer_read_format);
02990 ast_set_read_format(peer, &gateway->peer_write_format);
02991 ast_channel_make_compatible(chan, peer);
02992 }
02993 }
02994
02995 ao2_ref(details, -1);
02996 return NULL;
02997 }
02998
02999 if (!f || (event == AST_FRAMEHOOK_EVENT_ATTACHED)) {
03000 ao2_ref(details, -1);
03001 return NULL;
03002 };
03003
03004
03005 if (ast_test_flag(f, AST_FAX_FRFLAG_GATEWAY)) {
03006 ao2_ref(details, -1);
03007 return f;
03008 }
03009
03010 if (!(peer = ast_bridged_channel(chan))) {
03011
03012 ao2_ref(details, -1);
03013 return f;
03014 }
03015
03016 if (!gateway->bridged && peer) {
03017
03018 if (ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE && ast_channel_get_t38_state(peer) == T38_STATE_UNAVAILABLE) {
03019 ast_debug(1, "not starting gateway for %s and %s; neither channel supports T.38\n", ast_channel_name(chan), ast_channel_name(peer));
03020 ast_framehook_detach(chan, gateway->framehook);
03021 details->gateway_id = -1;
03022
03023 ast_string_field_set(details, result, "FAILED");
03024 ast_string_field_set(details, resultstr, "neither channel supports T.38");
03025 ast_string_field_set(details, error, "T38_NEG_ERROR");
03026 set_channel_variables(chan, details);
03027 ao2_ref(details, -1);
03028 return f;
03029 }
03030
03031 if (details->gateway_timeout) {
03032 gateway->timeout_start = ast_tvnow();
03033 }
03034
03035
03036
03037 ast_format_copy(&gateway->chan_read_format, ast_channel_readformat(chan));
03038 ast_format_copy(&gateway->chan_write_format, ast_channel_readformat(chan));
03039
03040 ast_format_copy(&gateway->peer_read_format, ast_channel_readformat(peer));
03041 ast_format_copy(&gateway->peer_write_format, ast_channel_readformat(peer));
03042
03043 ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
03044 ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
03045
03046 ast_set_read_format_by_id(peer, AST_FORMAT_SLINEAR);
03047 ast_set_write_format_by_id(peer, AST_FORMAT_SLINEAR);
03048
03049 ast_channel_make_compatible(chan, peer);
03050 gateway->bridged = 1;
03051 }
03052
03053 if (gateway->bridged && !ast_tvzero(gateway->timeout_start)) {
03054 if (ast_tvdiff_ms(ast_tvnow(), gateway->timeout_start) > details->gateway_timeout) {
03055 ast_debug(1, "no fax activity between %s and %s after %d ms, disabling gateway\n", ast_channel_name(chan), ast_channel_name(peer), details->gateway_timeout);
03056 ast_framehook_detach(chan, gateway->framehook);
03057 details->gateway_id = -1;
03058
03059 ast_string_field_set(details, result, "FAILED");
03060 ast_string_field_build(details, resultstr, "no fax activity after %d ms", details->gateway_timeout);
03061 ast_string_field_set(details, error, "TIMEOUT");
03062 set_channel_variables(chan, details);
03063 ao2_ref(details, -1);
03064 return f;
03065 }
03066 }
03067
03068
03069 switch (f->frametype) {
03070 case AST_FRAME_VOICE:
03071 switch (f->subclass.format.id) {
03072 case AST_FORMAT_SLINEAR:
03073 case AST_FORMAT_ALAW:
03074 case AST_FORMAT_ULAW:
03075 break;
03076 default:
03077 ao2_ref(details, -1);
03078 return f;
03079 }
03080 break;
03081 case AST_FRAME_MODEM:
03082 if (f->subclass.integer == AST_MODEM_T38) {
03083 break;
03084 }
03085 ao2_ref(details, -1);
03086 return f;
03087 case AST_FRAME_CONTROL:
03088 if (f->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
03089 break;
03090 }
03091 ao2_ref(details, -1);
03092 return f;
03093 default:
03094 ao2_ref(details, -1);
03095 return f;
03096 }
03097
03098
03099 switch (event) {
03100 case AST_FRAMEHOOK_EVENT_WRITE:
03101 active = peer;
03102 break;
03103 case AST_FRAMEHOOK_EVENT_READ:
03104 active = chan;
03105 break;
03106 default:
03107 ast_log(LOG_WARNING, "unhandled framehook event %i\n", event);
03108 ao2_ref(details, -1);
03109 return f;
03110 }
03111
03112
03113 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
03114 ao2_ref(details, -1);
03115 return fax_gateway_detect_t38(gateway, chan, peer, active, f);
03116 }
03117
03118 if (!gateway->detected_v21 && gateway->t38_state == T38_STATE_UNAVAILABLE && f->frametype == AST_FRAME_VOICE) {
03119
03120
03121 ao2_ref(details, -1);
03122 return fax_gateway_detect_v21(gateway, chan, peer, active, f);
03123 }
03124
03125
03126 if (gateway->t38_state == T38_STATE_NEGOTIATED) {
03127
03128
03129 if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id != AST_FORMAT_SLINEAR)) {
03130 if (ast_channel_readtrans(active) && (f = ast_translate(ast_channel_readtrans(active), f, 1)) == NULL) {
03131 f = &ast_null_frame;
03132 ao2_ref(details, -1);
03133 return f;
03134 }
03135 }
03136
03137
03138
03139
03140
03141 gateway->s->tech->write(gateway->s, f);
03142 if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id != AST_FORMAT_SLINEAR) && ast_channel_readtrans(active)) {
03143
03144
03145 ast_frfree(f);
03146 }
03147 f = &ast_null_frame;
03148 ao2_ref(details, -1);
03149 return f;
03150 }
03151
03152
03153 if (gateway->t38_state != T38_STATE_UNAVAILABLE && gateway->t38_state != T38_STATE_REJECTED) {
03154 if (f->frametype == AST_FRAME_VOICE && f->subclass.format.id == AST_FORMAT_SLINEAR) {
03155 short silence_buf[f->samples];
03156 struct ast_frame silence_frame = {
03157 .frametype = AST_FRAME_VOICE,
03158 .data.ptr = silence_buf,
03159 .samples = f->samples,
03160 .datalen = sizeof(silence_buf),
03161 };
03162 ast_format_set(&silence_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
03163 memset(silence_buf, 0, sizeof(silence_buf));
03164
03165 ao2_ref(details, -1);
03166 return ast_frisolate(&silence_frame);
03167 } else {
03168 ao2_ref(details, -1);
03169 return &ast_null_frame;
03170 }
03171 }
03172
03173 ao2_ref(details, -1);
03174 return f;
03175 }
03176
03177
03178
03179
03180
03181
03182
03183 static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details)
03184 {
03185 struct fax_gateway *gateway;
03186 struct ast_framehook_interface fr_hook = {
03187 .version = AST_FRAMEHOOK_INTERFACE_VERSION,
03188 .event_cb = fax_gateway_framehook,
03189 .destroy_cb = fax_gateway_framehook_destroy,
03190 };
03191
03192 ast_string_field_set(details, result, "SUCCESS");
03193 ast_string_field_set(details, resultstr, "gateway operation started successfully");
03194 ast_string_field_set(details, error, "NO_ERROR");
03195 set_channel_variables(chan, details);
03196
03197
03198 gateway = fax_gateway_new(chan, details);
03199 if (!gateway) {
03200 ast_string_field_set(details, result, "FAILED");
03201 ast_string_field_set(details, resultstr, "error initializing gateway session");
03202 ast_string_field_set(details, error, "INIT_ERROR");
03203 set_channel_variables(chan, details);
03204 report_fax_status(chan, details, "No Available Resource");
03205 return -1;
03206 }
03207
03208 fr_hook.data = gateway;
03209 ast_channel_lock(chan);
03210 gateway->framehook = ast_framehook_attach(chan, &fr_hook);
03211 ast_channel_unlock(chan);
03212
03213 if (gateway->framehook < 0) {
03214 ao2_ref(gateway, -1);
03215 ast_string_field_set(details, result, "FAILED");
03216 ast_string_field_set(details, resultstr, "error attaching gateway to channel");
03217 ast_string_field_set(details, error, "INIT_ERROR");
03218 set_channel_variables(chan, details);
03219 return -1;
03220 }
03221
03222 return gateway->framehook;
03223 }
03224
03225
03226 static void destroy_faxdetect(void *data)
03227 {
03228 struct fax_detect *faxdetect = data;
03229
03230 if (faxdetect->dsp) {
03231 ast_dsp_free(faxdetect->dsp);
03232 faxdetect->dsp = NULL;
03233 }
03234 ao2_ref(faxdetect->details, -1);
03235 }
03236
03237
03238
03239
03240
03241
03242
03243 static struct fax_detect *fax_detect_new(struct ast_channel *chan, int timeout, int flags)
03244 {
03245 struct fax_detect *faxdetect = ao2_alloc(sizeof(*faxdetect), destroy_faxdetect);
03246 if (!faxdetect) {
03247 return NULL;
03248 }
03249
03250 faxdetect->flags = flags;
03251
03252 if (timeout) {
03253 faxdetect->timeout_start = ast_tvnow();
03254 } else {
03255 faxdetect->timeout_start.tv_sec = 0;
03256 faxdetect->timeout_start.tv_usec = 0;
03257 }
03258
03259 if (faxdetect->flags & FAX_DETECT_MODE_CNG) {
03260 faxdetect->dsp = ast_dsp_new();
03261 if (!faxdetect->dsp) {
03262 ao2_ref(faxdetect, -1);
03263 return NULL;
03264 }
03265 ast_dsp_set_features(faxdetect->dsp, DSP_FEATURE_FAX_DETECT);
03266 ast_dsp_set_faxmode(faxdetect->dsp, DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_SQUELCH);
03267 } else {
03268 faxdetect->dsp = NULL;
03269 }
03270
03271 return faxdetect;
03272 }
03273
03274
03275
03276 static void fax_detect_framehook_destroy(void *data) {
03277 struct fax_detect *faxdetect = data;
03278
03279 ao2_ref(faxdetect, -1);
03280 }
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293 static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data) {
03294 struct fax_detect *faxdetect = data;
03295 struct ast_fax_session_details *details;
03296 struct ast_control_t38_parameters *control_params;
03297 struct ast_channel *peer;
03298 int result = 0;
03299
03300 details = faxdetect->details;
03301
03302 switch (event) {
03303 case AST_FRAMEHOOK_EVENT_ATTACHED:
03304
03305 ast_format_copy(&faxdetect->orig_format, ast_channel_readformat(chan));
03306 switch (ast_channel_readformat(chan)->id) {
03307 case AST_FORMAT_SLINEAR:
03308 case AST_FORMAT_ALAW:
03309 case AST_FORMAT_ULAW:
03310 break;
03311 default:
03312 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
03313 ast_framehook_detach(chan, details->faxdetect_id);
03314 details->faxdetect_id = -1;
03315 return f;
03316 }
03317 }
03318 return NULL;
03319 case AST_FRAMEHOOK_EVENT_DETACHED:
03320
03321 ast_set_read_format(chan, &faxdetect->orig_format);
03322 if ((peer = ast_bridged_channel(chan))) {
03323 ast_channel_make_compatible(chan, peer);
03324 }
03325 return NULL;
03326 case AST_FRAMEHOOK_EVENT_READ:
03327 if (f) {
03328 break;
03329 }
03330 default:
03331 return f;
03332 };
03333
03334 if (details->faxdetect_id < 0) {
03335 return f;
03336 }
03337
03338 if ((!ast_tvzero(faxdetect->timeout_start) &&
03339 (ast_tvdiff_ms(ast_tvnow(), faxdetect->timeout_start) > faxdetect->timeout))) {
03340 ast_framehook_detach(chan, details->faxdetect_id);
03341 details->faxdetect_id = -1;
03342 return f;
03343 }
03344
03345
03346 switch (f->frametype) {
03347 case AST_FRAME_VOICE:
03348
03349 if (!faxdetect->dsp) {
03350 return f;
03351 }
03352
03353 switch (f->subclass.format.id) {
03354 case AST_FORMAT_SLINEAR:
03355 case AST_FORMAT_ALAW:
03356 case AST_FORMAT_ULAW:
03357 break;
03358 default:
03359 return f;
03360 }
03361 break;
03362 case AST_FRAME_CONTROL:
03363 if ((f->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
03364 (faxdetect->flags & FAX_DETECT_MODE_T38)) {
03365 break;
03366 }
03367 return f;
03368 default:
03369 return f;
03370 }
03371
03372 if (f->frametype == AST_FRAME_VOICE) {
03373 f = ast_dsp_process(chan, faxdetect->dsp, f);
03374 if (f->frametype == AST_FRAME_DTMF) {
03375 result = f->subclass.integer;
03376 }
03377 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->datalen == sizeof(struct ast_control_t38_parameters))) {
03378 control_params = f->data.ptr;
03379 switch (control_params->request_response) {
03380 case AST_T38_NEGOTIATED:
03381 case AST_T38_REQUEST_NEGOTIATE:
03382 result = 't';
03383 break;
03384 default:
03385 break;
03386 }
03387 }
03388
03389 if (result) {
03390 const char *target_context = S_OR(ast_channel_macrocontext(chan), ast_channel_context(chan));
03391 switch (result) {
03392 case 'f':
03393 case 't':
03394 ast_channel_unlock(chan);
03395 if (ast_exists_extension(chan, target_context, "fax", 1,
03396 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
03397 ast_channel_lock(chan);
03398 ast_verb(2, "Redirecting '%s' to fax extension due to %s detection\n",
03399 ast_channel_name(chan), (result == 'f') ? "CNG" : "T38");
03400 pbx_builtin_setvar_helper(chan, "FAXEXTEN", ast_channel_exten(chan));
03401 if (ast_async_goto(chan, target_context, "fax", 1)) {
03402 ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(chan), target_context);
03403 }
03404 ast_frfree(f);
03405 f = &ast_null_frame;
03406 } else {
03407 ast_channel_lock(chan);
03408 ast_log(LOG_NOTICE, "FAX %s detected but no fax extension in context (%s)\n",
03409 (result == 'f') ? "CNG" : "T38", target_context);
03410 }
03411 }
03412 ast_framehook_detach(chan, details->faxdetect_id);
03413 details->faxdetect_id = -1;
03414 }
03415
03416 return f;
03417 }
03418
03419
03420
03421
03422
03423
03424
03425
03426 static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags)
03427 {
03428 struct fax_detect *faxdetect;
03429 struct ast_fax_session_details *details;
03430 struct ast_framehook_interface fr_hook = {
03431 .version = AST_FRAMEHOOK_INTERFACE_VERSION,
03432 .event_cb = fax_detect_framehook,
03433 .destroy_cb = fax_detect_framehook_destroy,
03434 };
03435
03436 if (!(details = find_or_create_details(chan))) {
03437 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
03438 return -1;
03439 }
03440
03441
03442 faxdetect = fax_detect_new(chan, timeout, flags);
03443 if (!faxdetect) {
03444 ao2_ref(details, -1);
03445 return -1;
03446 }
03447
03448 fr_hook.data = faxdetect;
03449 faxdetect->details = details;
03450 ast_channel_lock(chan);
03451 details->faxdetect_id = ast_framehook_attach(chan, &fr_hook);
03452 ast_channel_unlock(chan);
03453
03454 if (details->faxdetect_id < 0) {
03455 ao2_ref(faxdetect, -1);
03456 }
03457
03458 return details->faxdetect_id;
03459 }
03460
03461
03462 static int session_hash_cb(const void *obj, const int flags)
03463 {
03464 const struct ast_fax_session *s = obj;
03465
03466 return s->id;
03467 }
03468
03469
03470 static int session_cmp_cb(void *obj, void *arg, int flags)
03471 {
03472 struct ast_fax_session *lhs = obj, *rhs = arg;
03473
03474 return (lhs->id == rhs->id) ? CMP_MATCH | CMP_STOP : 0;
03475 }
03476
03477
03478 static char *fax_session_tab_complete(struct ast_cli_args *a)
03479 {
03480 int tklen;
03481 int wordnum = 0;
03482 char *name = NULL;
03483 struct ao2_iterator i;
03484 struct ast_fax_session *s;
03485 char tbuf[5];
03486
03487 if (a->pos != 3) {
03488 return NULL;
03489 }
03490
03491 tklen = strlen(a->word);
03492 i = ao2_iterator_init(faxregistry.container, 0);
03493 while ((s = ao2_iterator_next(&i))) {
03494 snprintf(tbuf, sizeof(tbuf), "%d", s->id);
03495 if (!strncasecmp(a->word, tbuf, tklen) && ++wordnum > a->n) {
03496 name = ast_strdup(tbuf);
03497 ao2_ref(s, -1);
03498 break;
03499 }
03500 ao2_ref(s, -1);
03501 }
03502 ao2_iterator_destroy(&i);
03503 return name;
03504 }
03505
03506 static char *cli_fax_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03507 {
03508 struct fax_module *fax;
03509
03510 switch(cmd) {
03511 case CLI_INIT:
03512 e->command = "fax show version";
03513 e->usage =
03514 "Usage: fax show version\n"
03515 " Show versions of FAX For Asterisk components.\n";
03516 return NULL;
03517 case CLI_GENERATE:
03518 return NULL;
03519 }
03520
03521 if (a->argc != 3) {
03522 return CLI_SHOWUSAGE;
03523 }
03524
03525 ast_cli(a->fd, "FAX For Asterisk Components:\n");
03526 ast_cli(a->fd, "\tApplications: %s\n", ast_get_version());
03527 AST_RWLIST_RDLOCK(&faxmodules);
03528 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
03529 ast_cli(a->fd, "\t%s: %s\n", fax->tech->description, fax->tech->version);
03530 }
03531 AST_RWLIST_UNLOCK(&faxmodules);
03532 ast_cli(a->fd, "\n");
03533
03534 return CLI_SUCCESS;
03535 }
03536
03537
03538 static char *cli_fax_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03539 {
03540 int flag;
03541 const char *what;
03542
03543 switch (cmd) {
03544 case CLI_INIT:
03545 e->command = "fax set debug {on|off}";
03546 e->usage =
03547 "Usage: fax set debug { on | off }\n"
03548 " Enable/Disable FAX debugging on new FAX sessions. The basic FAX debugging will result in\n"
03549 " additional events sent to manager sessions with 'call' class permissions. When\n"
03550 " verbosity is greater than '5' events will be displayed to the console and audio versus\n"
03551 " energy analysis will be performed and displayed to the console.\n";
03552 return NULL;
03553 case CLI_GENERATE:
03554 return NULL;
03555 }
03556
03557 what = a->argv[e->args-1];
03558 if (!strcasecmp(what, "on")) {
03559 flag = 1;
03560 } else if (!strcasecmp(what, "off")) {
03561 flag = 0;
03562 } else {
03563 return CLI_SHOWUSAGE;
03564 }
03565
03566 global_fax_debug = flag;
03567 ast_cli(a->fd, "\n\nFAX Debug %s\n\n", (flag) ? "Enabled" : "Disabled");
03568
03569 return CLI_SUCCESS;
03570 }
03571
03572
03573 static char *cli_fax_show_capabilities(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03574 {
03575 struct fax_module *fax;
03576 unsigned int num_modules = 0;
03577
03578 switch (cmd) {
03579 case CLI_INIT:
03580 e->command = "fax show capabilities";
03581 e->usage =
03582 "Usage: fax show capabilities\n"
03583 " Shows the capabilities of the registered FAX technology modules\n";
03584 return NULL;
03585 case CLI_GENERATE:
03586 return NULL;
03587 }
03588
03589 ast_cli(a->fd, "\n\nRegistered FAX Technology Modules:\n\n");
03590 AST_RWLIST_RDLOCK(&faxmodules);
03591 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
03592 ast_cli(a->fd, "%-15s : %s\n%-15s : %s\n%-15s : ", "Type", fax->tech->type, "Description", fax->tech->description, "Capabilities");
03593 fax->tech->cli_show_capabilities(a->fd);
03594 num_modules++;
03595 }
03596 AST_RWLIST_UNLOCK(&faxmodules);
03597 ast_cli(a->fd, "%d registered modules\n\n", num_modules);
03598
03599 return CLI_SUCCESS;
03600 }
03601
03602
03603 static char *cli_fax_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03604 {
03605 struct fax_module *fax;
03606 char modems[128] = "";
03607 struct fax_options options;
03608
03609 switch (cmd) {
03610 case CLI_INIT:
03611 e->command = "fax show settings";
03612 e->usage =
03613 "Usage: fax show settings\n"
03614 " Show the global settings and defaults of both the FAX core and technology modules\n";
03615 return NULL;
03616 case CLI_GENERATE:
03617 return NULL;
03618 }
03619
03620 get_general_options(&options);
03621
03622 ast_cli(a->fd, "FAX For Asterisk Settings:\n");
03623 ast_cli(a->fd, "\tECM: %s\n", options.ecm ? "Enabled" : "Disabled");
03624 ast_cli(a->fd, "\tStatus Events: %s\n", options.statusevents ? "On" : "Off");
03625 ast_cli(a->fd, "\tMinimum Bit Rate: %d\n", options.minrate);
03626 ast_cli(a->fd, "\tMaximum Bit Rate: %d\n", options.maxrate);
03627 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
03628 ast_cli(a->fd, "\tModem Modulations Allowed: %s\n", modems);
03629 ast_cli(a->fd, "\n\nFAX Technology Modules:\n\n");
03630 AST_RWLIST_RDLOCK(&faxmodules);
03631 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
03632 ast_cli(a->fd, "%s (%s) Settings:\n", fax->tech->type, fax->tech->description);
03633 fax->tech->cli_show_settings(a->fd);
03634 }
03635 AST_RWLIST_UNLOCK(&faxmodules);
03636
03637 return CLI_SUCCESS;
03638 }
03639
03640
03641 static char *cli_fax_show_session(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03642 {
03643 struct ast_fax_session *s, tmp;
03644
03645 switch (cmd) {
03646 case CLI_INIT:
03647 e->command = "fax show session";
03648 e->usage =
03649 "Usage: fax show session <session number>\n"
03650 " Shows status of the named FAX session\n";
03651 return NULL;
03652 case CLI_GENERATE:
03653 return fax_session_tab_complete(a);
03654 }
03655
03656 if (a->argc != 4) {
03657 return CLI_SHOWUSAGE;
03658 }
03659
03660 if (sscanf(a->argv[3], "%d", &tmp.id) != 1) {
03661 ast_log(LOG_ERROR, "invalid session id: '%s'\n", a->argv[3]);
03662 return RESULT_SUCCESS;
03663 }
03664
03665 ast_cli(a->fd, "\nFAX Session Details:\n--------------------\n\n");
03666 s = ao2_find(faxregistry.container, &tmp, OBJ_POINTER);
03667 if (s) {
03668 s->tech->cli_show_session(s, a->fd);
03669 ao2_ref(s, -1);
03670 }
03671 ast_cli(a->fd, "\n\n");
03672
03673 return CLI_SUCCESS;
03674 }
03675
03676
03677 static char *cli_fax_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03678 {
03679 struct fax_module *fax;
03680
03681 switch (cmd) {
03682 case CLI_INIT:
03683 e->command = "fax show stats";
03684 e->usage =
03685 "Usage: fax show stats\n"
03686 " Shows a statistical summary of FAX transmissions\n";
03687 return NULL;
03688 case CLI_GENERATE:
03689 return NULL;
03690 }
03691
03692 ast_cli(a->fd, "\nFAX Statistics:\n---------------\n\n");
03693 ast_cli(a->fd, "%-20.20s : %d\n", "Current Sessions", faxregistry.active_sessions);
03694 ast_cli(a->fd, "%-20.20s : %d\n", "Reserved Sessions", faxregistry.reserved_sessions);
03695 ast_cli(a->fd, "%-20.20s : %d\n", "Transmit Attempts", faxregistry.fax_tx_attempts);
03696 ast_cli(a->fd, "%-20.20s : %d\n", "Receive Attempts", faxregistry.fax_rx_attempts);
03697 ast_cli(a->fd, "%-20.20s : %d\n", "Completed FAXes", faxregistry.fax_complete);
03698 ast_cli(a->fd, "%-20.20s : %d\n", "Failed FAXes", faxregistry.fax_failures);
03699 AST_RWLIST_RDLOCK(&faxmodules);
03700 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
03701 fax->tech->cli_show_stats(a->fd);
03702 }
03703 AST_RWLIST_UNLOCK(&faxmodules);
03704 ast_cli(a->fd, "\n\n");
03705
03706 return CLI_SUCCESS;
03707 }
03708
03709 static const char *cli_session_type(struct ast_fax_session *s)
03710 {
03711 if (s->details->caps & AST_FAX_TECH_AUDIO) {
03712 return "G.711";
03713 }
03714 if (s->details->caps & AST_FAX_TECH_T38) {
03715 return "T.38";
03716 }
03717
03718 return "none";
03719 }
03720
03721 static const char *cli_session_operation(struct ast_fax_session *s)
03722 {
03723 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
03724 return "gateway";
03725 }
03726 if (s->details->caps & AST_FAX_TECH_SEND) {
03727 return "send";
03728 }
03729 if (s->details->caps & AST_FAX_TECH_RECEIVE) {
03730 return "receive";
03731 }
03732 if (s->details->caps & AST_FAX_TECH_V21_DETECT) {
03733 return "V.21";
03734 }
03735
03736 return "none";
03737 }
03738
03739
03740 static char *cli_fax_show_sessions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03741 {
03742 struct ast_fax_session *s;
03743 struct ao2_iterator i;
03744 int session_count;
03745 char *filenames;
03746
03747 switch (cmd) {
03748 case CLI_INIT:
03749 e->command = "fax show sessions";
03750 e->usage =
03751 "Usage: fax show sessions\n"
03752 " Shows the current FAX sessions\n";
03753 return NULL;
03754 case CLI_GENERATE:
03755 return NULL;
03756 }
03757
03758 ast_cli(a->fd, "\nCurrent FAX Sessions:\n\n");
03759 ast_cli(a->fd, "%-20.20s %-10.10s %-10.10s %-5.5s %-10.10s %-15.15s %-30.30s\n",
03760 "Channel", "Tech", "FAXID", "Type", "Operation", "State", "File(s)");
03761 i = ao2_iterator_init(faxregistry.container, 0);
03762 while ((s = ao2_iterator_next(&i))) {
03763 ao2_lock(s);
03764
03765 filenames = generate_filenames_string(s->details, "", ", ");
03766
03767 ast_cli(a->fd, "%-20.20s %-10.10s %-10d %-5.5s %-10.10s %-15.15s %-30s\n",
03768 s->channame, s->tech->type, s->id,
03769 cli_session_type(s),
03770 cli_session_operation(s),
03771 ast_fax_state_to_str(s->state), S_OR(filenames, ""));
03772
03773 ast_free(filenames);
03774 ao2_unlock(s);
03775 ao2_ref(s, -1);
03776 }
03777 ao2_iterator_destroy(&i);
03778 session_count = ao2_container_count(faxregistry.container);
03779 ast_cli(a->fd, "\n%d FAX sessions\n\n", session_count);
03780
03781 return CLI_SUCCESS;
03782 }
03783
03784 static struct ast_cli_entry fax_cli[] = {
03785 AST_CLI_DEFINE(cli_fax_show_version, "Show versions of FAX For Asterisk components"),
03786 AST_CLI_DEFINE(cli_fax_set_debug, "Enable/Disable FAX debugging on new FAX sessions"),
03787 AST_CLI_DEFINE(cli_fax_show_capabilities, "Show the capabilities of the registered FAX technology modules"),
03788 AST_CLI_DEFINE(cli_fax_show_settings, "Show the global settings and defaults of both the FAX core and technology modules"),
03789 AST_CLI_DEFINE(cli_fax_show_session, "Show the status of the named FAX sessions"),
03790 AST_CLI_DEFINE(cli_fax_show_sessions, "Show the current FAX sessions"),
03791 AST_CLI_DEFINE(cli_fax_show_stats, "Summarize FAX session history"),
03792 };
03793
03794 static void set_general_options(const struct fax_options *options)
03795 {
03796 ast_rwlock_wrlock(&options_lock);
03797 general_options = *options;
03798 ast_rwlock_unlock(&options_lock);
03799 }
03800
03801 static void get_general_options(struct fax_options *options)
03802 {
03803 ast_rwlock_rdlock(&options_lock);
03804 *options = general_options;
03805 ast_rwlock_unlock(&options_lock);
03806 }
03807
03808
03809 static int set_config(int reload)
03810 {
03811 struct ast_config *cfg;
03812 struct ast_variable *v;
03813 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
03814 char modems[128] = "";
03815 struct fax_options options;
03816 int res = 0;
03817
03818 options = default_options;
03819
03820
03821
03822
03823
03824
03825 if (!reload) {
03826 set_general_options(&options);
03827 }
03828
03829
03830 if (!(cfg = ast_config_load2(config, "res_fax", config_flags))) {
03831 ast_log(LOG_NOTICE, "Configuration file '%s' not found, %s options.\n",
03832 config, reload ? "not changing" : "using default");
03833 return 0;
03834 }
03835
03836 if (cfg == CONFIG_STATUS_FILEINVALID) {
03837 ast_log(LOG_NOTICE, "Configuration file '%s' is invalid, %s options.\n",
03838 config, reload ? "not changing" : "using default");
03839 return 0;
03840 }
03841
03842 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
03843 return 0;
03844 }
03845
03846 if (reload) {
03847 options = default_options;
03848 }
03849
03850
03851 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
03852 int rate;
03853
03854 if (!strcasecmp(v->name, "minrate")) {
03855 ast_debug(3, "reading minrate '%s' from configuration file\n", v->value);
03856 if ((rate = fax_rate_str_to_int(v->value)) == 0) {
03857 res = -1;
03858 goto end;
03859 }
03860 options.minrate = rate;
03861 } else if (!strcasecmp(v->name, "maxrate")) {
03862 ast_debug(3, "reading maxrate '%s' from configuration file\n", v->value);
03863 if ((rate = fax_rate_str_to_int(v->value)) == 0) {
03864 res = -1;
03865 goto end;
03866 }
03867 options.maxrate = rate;
03868 } else if (!strcasecmp(v->name, "statusevents")) {
03869 ast_debug(3, "reading statusevents '%s' from configuration file\n", v->value);
03870 options.statusevents = ast_true(v->value);
03871 } else if (!strcasecmp(v->name, "ecm")) {
03872 ast_debug(3, "reading ecm '%s' from configuration file\n", v->value);
03873 options.ecm = ast_true(v->value);
03874 } else if ((!strcasecmp(v->name, "modem")) || (!strcasecmp(v->name, "modems"))) {
03875 options.modems = 0;
03876 update_modem_bits(&options.modems, v->value);
03877 }
03878 }
03879
03880 if (options.maxrate < options.minrate) {
03881 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", options.maxrate, options.minrate);
03882 res = -1;
03883 goto end;
03884 }
03885
03886 if (options.minrate == 2400 && (options.modems & AST_FAX_MODEM_V27) && !(options.modems & (AST_FAX_MODEM_V34))) {
03887 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
03888 ast_log(LOG_WARNING, "'modems' setting '%s' is no longer accepted with 'minrate' setting %d\n", modems, options.minrate);
03889 ast_log(LOG_WARNING, "'minrate' has been reset to 4800, please update res_fax.conf.\n");
03890 options.minrate = 4800;
03891 }
03892
03893 if (check_modem_rate(options.modems, options.minrate)) {
03894 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
03895 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, options.minrate);
03896 res = -1;
03897 goto end;
03898 }
03899
03900 if (check_modem_rate(options.modems, options.maxrate)) {
03901 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
03902 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, options.maxrate);
03903 res = -1;
03904 goto end;
03905 }
03906
03907 set_general_options(&options);
03908
03909 end:
03910 ast_config_destroy(cfg);
03911 return res;
03912 }
03913
03914
03915 static int acf_faxopt_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
03916 {
03917 struct ast_fax_session_details *details = find_details(chan);
03918 int res = 0;
03919 char *filenames;
03920
03921 if (!details) {
03922 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", ast_channel_name(chan), data);
03923 return -1;
03924 }
03925 if (!strcasecmp(data, "ecm")) {
03926 ast_copy_string(buf, details->option.ecm ? "yes" : "no", len);
03927 } else if (!strcasecmp(data, "t38gateway") || !strcasecmp(data, "gateway") ||
03928 !strcasecmp(data, "t38_gateway") || !strcasecmp(data, "faxgateway")) {
03929 ast_copy_string(buf, details->gateway_id != -1 ? "yes" : "no", len);
03930 } else if (!strcasecmp(data, "faxdetect")) {
03931 ast_copy_string(buf, details->faxdetect_id != -1 ? "yes" : "no", len);
03932 } else if (!strcasecmp(data, "error")) {
03933 ast_copy_string(buf, details->error, len);
03934 } else if (!strcasecmp(data, "filename")) {
03935 if (AST_LIST_EMPTY(&details->documents)) {
03936 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", ast_channel_name(chan), data);
03937 res = -1;
03938 } else {
03939 ast_copy_string(buf, AST_LIST_FIRST(&details->documents)->filename, len);
03940 }
03941 } else if (!strcasecmp(data, "filenames")) {
03942 if (AST_LIST_EMPTY(&details->documents)) {
03943 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", ast_channel_name(chan), data);
03944 res = -1;
03945 } else if ((filenames = generate_filenames_string(details, "", ","))) {
03946 ast_copy_string(buf, filenames, len);
03947 ast_free(filenames);
03948 } else {
03949 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s), there was an error generating the filenames list.\n", ast_channel_name(chan), data);
03950 res = -1;
03951 }
03952 } else if (!strcasecmp(data, "headerinfo")) {
03953 ast_copy_string(buf, details->headerinfo, len);
03954 } else if (!strcasecmp(data, "localstationid")) {
03955 ast_copy_string(buf, details->localstationid, len);
03956 } else if (!strcasecmp(data, "maxrate")) {
03957 snprintf(buf, len, "%d", details->maxrate);
03958 } else if (!strcasecmp(data, "minrate")) {
03959 snprintf(buf, len, "%d", details->minrate);
03960 } else if (!strcasecmp(data, "pages")) {
03961 snprintf(buf, len, "%d", details->pages_transferred);
03962 } else if (!strcasecmp(data, "rate")) {
03963 ast_copy_string(buf, details->transfer_rate, len);
03964 } else if (!strcasecmp(data, "remotestationid")) {
03965 ast_copy_string(buf, details->remotestationid, len);
03966 } else if (!strcasecmp(data, "resolution")) {
03967 ast_copy_string(buf, details->resolution, len);
03968 } else if (!strcasecmp(data, "sessionid")) {
03969 snprintf(buf, len, "%d", details->id);
03970 } else if (!strcasecmp(data, "status")) {
03971 ast_copy_string(buf, details->result, len);
03972 } else if (!strcasecmp(data, "statusstr")) {
03973 ast_copy_string(buf, details->resultstr, len);
03974 } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
03975 ast_fax_modem_to_str(details->modems, buf, len);
03976 } else {
03977 ast_log(LOG_WARNING, "channel '%s' can't read FAXOPT(%s) because it is unhandled!\n", ast_channel_name(chan), data);
03978 res = -1;
03979 }
03980 ao2_ref(details, -1);
03981
03982 return res;
03983 }
03984
03985
03986 static int acf_faxopt_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
03987 {
03988 int res = 0;
03989 struct ast_fax_session_details *details;
03990
03991 if (!(details = find_or_create_details(chan))) {
03992 ast_log(LOG_WARNING, "channel '%s' can't set FAXOPT(%s) to '%s' because it failed to create a datastore.\n", ast_channel_name(chan), data, value);
03993 return -1;
03994 }
03995 ast_debug(3, "channel '%s' setting FAXOPT(%s) to '%s'\n", ast_channel_name(chan), data, value);
03996
03997 if (!strcasecmp(data, "ecm")) {
03998 const char *val = ast_skip_blanks(value);
03999 if (ast_true(val)) {
04000 details->option.ecm = AST_FAX_OPTFLAG_TRUE;
04001 } else if (ast_false(val)) {
04002 details->option.ecm = AST_FAX_OPTFLAG_FALSE;
04003 } else {
04004 ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(ecm).\n", value);
04005 }
04006 } else if (!strcasecmp(data, "t38gateway") || !strcasecmp(data, "gateway") ||
04007 !strcasecmp(data, "t38_gateway") || !strcasecmp(data, "faxgateway")) {
04008 const char *val = ast_skip_blanks(value);
04009 char *timeout = strchr(val, ',');
04010
04011 if (timeout) {
04012 *timeout++ = '\0';
04013 }
04014
04015 if (ast_true(val)) {
04016 if (details->gateway_id < 0) {
04017 details->gateway_timeout = 0;
04018 if (timeout) {
04019 unsigned int gwtimeout;
04020 if (sscanf(timeout, "%u", &gwtimeout) == 1) {
04021 details->gateway_timeout = gwtimeout * 1000;
04022 } else {
04023 ast_log(LOG_WARNING, "Unsupported timeout '%s' passed to FAXOPT(%s).\n", timeout, data);
04024 }
04025 }
04026
04027 details->gateway_id = fax_gateway_attach(chan, details);
04028 if (details->gateway_id < 0) {
04029 ast_log(LOG_ERROR, "Error attaching T.38 gateway to channel %s.\n", ast_channel_name(chan));
04030 res = -1;
04031 } else {
04032 ast_debug(1, "Attached T.38 gateway to channel %s.\n", ast_channel_name(chan));
04033 }
04034 } else {
04035 ast_log(LOG_WARNING, "Attempt to attach a T.38 gateway on channel (%s) with gateway already running.\n", ast_channel_name(chan));
04036 }
04037 } else if (ast_false(val)) {
04038 ast_framehook_detach(chan, details->gateway_id);
04039 details->gateway_id = -1;
04040 } else {
04041 ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(%s).\n", value, data);
04042 }
04043 } else if (!strcasecmp(data, "faxdetect")) {
04044 const char *val = ast_skip_blanks(value);
04045 char *timeout = strchr(val, ',');
04046 unsigned int fdtimeout = 0;
04047 int flags;
04048 int faxdetect;
04049
04050 if (timeout) {
04051 *timeout++ = '\0';
04052 }
04053
04054 if (ast_true(val) || !strcasecmp(val, "t38") || !strcasecmp(val, "cng")) {
04055 if (details->faxdetect_id < 0) {
04056 if (timeout && (sscanf(timeout, "%u", &fdtimeout) == 1)) {
04057 if (fdtimeout > 0) {
04058 fdtimeout = fdtimeout * 1000;
04059 } else {
04060 ast_log(LOG_WARNING, "Timeout cannot be negative ignoring timeout\n");
04061 }
04062 }
04063
04064 if (!strcasecmp(val, "t38")) {
04065 flags = FAX_DETECT_MODE_T38;
04066 } else if (!strcasecmp(val, "cng")) {
04067 flags = FAX_DETECT_MODE_CNG;
04068 } else {
04069 flags = FAX_DETECT_MODE_BOTH;
04070 }
04071
04072 faxdetect = fax_detect_attach(chan, fdtimeout, flags);
04073 if (faxdetect < 0) {
04074 ast_log(LOG_ERROR, "Error attaching FAX detect to channel %s.\n", ast_channel_name(chan));
04075 res = -1;
04076 } else {
04077 ast_debug(1, "Attached FAX detect to channel %s.\n", ast_channel_name(chan));
04078 }
04079 } else {
04080 ast_log(LOG_WARNING, "Attempt to attach a FAX detect on channel (%s) with FAX detect already running.\n", ast_channel_name(chan));
04081 }
04082 } else if (ast_false(val)) {
04083 ast_framehook_detach(chan, details->faxdetect_id);
04084 details->faxdetect_id = -1;
04085 } else {
04086 ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(%s).\n", value, data);
04087 }
04088 } else if (!strcasecmp(data, "headerinfo")) {
04089 ast_string_field_set(details, headerinfo, value);
04090 } else if (!strcasecmp(data, "localstationid")) {
04091 ast_string_field_set(details, localstationid, value);
04092 } else if (!strcasecmp(data, "maxrate")) {
04093 details->maxrate = fax_rate_str_to_int(value);
04094 if (!details->maxrate) {
04095 details->maxrate = ast_fax_maxrate();
04096 }
04097 } else if (!strcasecmp(data, "minrate")) {
04098 details->minrate = fax_rate_str_to_int(value);
04099 if (!details->minrate) {
04100 details->minrate = ast_fax_minrate();
04101 }
04102 } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
04103 update_modem_bits(&details->modems, value);
04104 } else {
04105 ast_log(LOG_WARNING, "channel '%s' set FAXOPT(%s) to '%s' is unhandled!\n", ast_channel_name(chan), data, value);
04106 res = -1;
04107 }
04108
04109 ao2_ref(details, -1);
04110
04111 return res;
04112 }
04113
04114
04115 struct ast_custom_function acf_faxopt = {
04116 .name = "FAXOPT",
04117 .read = acf_faxopt_read,
04118 .write = acf_faxopt_write,
04119 };
04120
04121
04122 static int unload_module(void)
04123 {
04124 ast_cli_unregister_multiple(fax_cli, ARRAY_LEN(fax_cli));
04125
04126 if (ast_custom_function_unregister(&acf_faxopt) < 0) {
04127 ast_log(LOG_WARNING, "failed to unregister function '%s'\n", acf_faxopt.name);
04128 }
04129
04130 if (ast_unregister_application(app_sendfax) < 0) {
04131 ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_sendfax);
04132 }
04133
04134 if (ast_unregister_application(app_receivefax) < 0) {
04135 ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_receivefax);
04136 }
04137
04138 if (fax_logger_level != -1) {
04139 ast_logger_unregister_level("FAX");
04140 }
04141
04142 ao2_ref(faxregistry.container, -1);
04143
04144 return 0;
04145 }
04146
04147
04148 static int load_module(void)
04149 {
04150 int res;
04151
04152
04153 faxregistry.active_sessions = 0;
04154 faxregistry.reserved_sessions = 0;
04155 if (!(faxregistry.container = ao2_container_alloc(FAX_MAXBUCKETS, session_hash_cb, session_cmp_cb))) {
04156 return AST_MODULE_LOAD_DECLINE;
04157 }
04158
04159 if (set_config(0) < 0) {
04160 ast_log(LOG_ERROR, "failed to load configuration file '%s'\n", config);
04161 ao2_ref(faxregistry.container, -1);
04162 return AST_MODULE_LOAD_DECLINE;
04163 }
04164
04165
04166 if (ast_register_application_xml(app_sendfax, sendfax_exec) < 0) {
04167 ast_log(LOG_WARNING, "failed to register '%s'.\n", app_sendfax);
04168 ao2_ref(faxregistry.container, -1);
04169 return AST_MODULE_LOAD_DECLINE;
04170 }
04171 if (ast_register_application_xml(app_receivefax, receivefax_exec) < 0) {
04172 ast_log(LOG_WARNING, "failed to register '%s'.\n", app_receivefax);
04173 ast_unregister_application(app_sendfax);
04174 ao2_ref(faxregistry.container, -1);
04175 return AST_MODULE_LOAD_DECLINE;
04176 }
04177
04178 ast_cli_register_multiple(fax_cli, ARRAY_LEN(fax_cli));
04179 res = ast_custom_function_register(&acf_faxopt);
04180 fax_logger_level = ast_logger_register_level("FAX");
04181
04182 return res;
04183 }
04184
04185 static int reload_module(void)
04186 {
04187 set_config(1);
04188 return 0;
04189 }
04190
04191
04192 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Generic FAX Applications",
04193 .load = load_module,
04194 .unload = unload_module,
04195 .reload = reload_module,
04196 .load_pri = AST_MODPRI_APP_DEPEND,
04197 );