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 #include "asterisk.h"
00039
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 425405 $")
00041
00042 #include "asterisk/io.h"
00043 #include "asterisk/file.h"
00044 #include "asterisk/logger.h"
00045 #include "asterisk/module.h"
00046 #include "asterisk/app.h"
00047 #include "asterisk/lock.h"
00048 #include "asterisk/options.h"
00049 #include "asterisk/strings.h"
00050 #include "asterisk/cli.h"
00051 #include "asterisk/utils.h"
00052 #include "asterisk/config.h"
00053 #include "asterisk/astobj2.h"
00054 #include "asterisk/res_fax.h"
00055 #include "asterisk/file.h"
00056 #include "asterisk/channel.h"
00057 #include "asterisk/pbx.h"
00058 #include "asterisk/manager.h"
00059 #include "asterisk/dsp.h"
00060 #include "asterisk/indications.h"
00061 #include "asterisk/ast_version.h"
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 static const char app_receivefax[] = "ReceiveFAX";
00199 static const char app_sendfax[] = "SendFAX";
00200
00201 struct debug_info_history {
00202 unsigned int consec_frames;
00203 unsigned int consec_ms;
00204 unsigned char silence;
00205 };
00206
00207 struct ast_fax_debug_info {
00208 struct timeval base_tv;
00209 struct debug_info_history c2s, s2c;
00210 struct ast_dsp *dsp;
00211 };
00212
00213 static int fax_logger_level = -1;
00214
00215
00216 #define FAX_MAXBUCKETS 10
00217
00218 #define RES_FAX_TIMEOUT 10000
00219
00220
00221 static struct {
00222
00223 int active_sessions;
00224
00225 int reserved_sessions;
00226
00227 struct ao2_container *container;
00228
00229 int fax_tx_attempts;
00230
00231 int fax_rx_attempts;
00232
00233 int fax_complete;
00234
00235 int fax_failures;
00236
00237 int nextsessionname;
00238 } faxregistry;
00239
00240
00241 struct fax_module {
00242 const struct ast_fax_tech *tech;
00243 AST_RWLIST_ENTRY(fax_module) list;
00244 };
00245 static AST_RWLIST_HEAD_STATIC(faxmodules, fax_module);
00246
00247 #define RES_FAX_MINRATE 4800
00248 #define RES_FAX_MAXRATE 14400
00249 #define RES_FAX_STATUSEVENTS 0
00250 #define RES_FAX_MODEM (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29)
00251
00252 struct fax_options {
00253 enum ast_fax_modems modems;
00254 uint32_t statusevents:1;
00255 uint32_t ecm:1;
00256 unsigned int minrate;
00257 unsigned int maxrate;
00258 };
00259
00260 static struct fax_options general_options;
00261
00262 static const struct fax_options default_options = {
00263 .minrate = RES_FAX_MINRATE,
00264 .maxrate = RES_FAX_MAXRATE,
00265 .statusevents = RES_FAX_STATUSEVENTS,
00266 .modems = RES_FAX_MODEM,
00267 .ecm = AST_FAX_OPTFLAG_TRUE,
00268 };
00269
00270 AST_RWLOCK_DEFINE_STATIC(options_lock);
00271
00272 static void get_general_options(struct fax_options* options);
00273 static void set_general_options(const struct fax_options* options);
00274
00275 static const char *config = "res_fax.conf";
00276
00277 static int global_fax_debug = 0;
00278
00279 enum {
00280 OPT_CALLEDMODE = (1 << 0),
00281 OPT_CALLERMODE = (1 << 1),
00282 OPT_DEBUG = (1 << 2),
00283 OPT_STATUS = (1 << 3),
00284 OPT_ALLOWAUDIO = (1 << 5),
00285 OPT_REQUEST_T38 = (1 << 6),
00286 };
00287
00288 AST_APP_OPTIONS(fax_exec_options, BEGIN_OPTIONS
00289 AST_APP_OPTION('a', OPT_CALLEDMODE),
00290 AST_APP_OPTION('c', OPT_CALLERMODE),
00291 AST_APP_OPTION('d', OPT_DEBUG),
00292 AST_APP_OPTION('f', OPT_ALLOWAUDIO),
00293 AST_APP_OPTION('s', OPT_STATUS),
00294 AST_APP_OPTION('z', OPT_REQUEST_T38),
00295 END_OPTIONS);
00296
00297 struct manager_event_info {
00298 char context[AST_MAX_CONTEXT];
00299 char exten[AST_MAX_EXTENSION];
00300 char cid[128];
00301 };
00302
00303 static void debug_check_frame_for_silence(struct ast_fax_session *s, unsigned int c2s, struct ast_frame *frame)
00304 {
00305 struct debug_info_history *history = c2s ? &s->debug_info->c2s : &s->debug_info->s2c;
00306 int dspsilence;
00307 unsigned int last_consec_frames, last_consec_ms;
00308 unsigned char wassil;
00309 struct timeval diff;
00310
00311 diff = ast_tvsub(ast_tvnow(), s->debug_info->base_tv);
00312
00313 ast_dsp_reset(s->debug_info->dsp);
00314 ast_dsp_silence(s->debug_info->dsp, frame, &dspsilence);
00315
00316 wassil = history->silence;
00317 history->silence = (dspsilence != 0) ? 1 : 0;
00318 if (history->silence != wassil) {
00319 last_consec_frames = history->consec_frames;
00320 last_consec_ms = history->consec_ms;
00321 history->consec_frames = 0;
00322 history->consec_ms = 0;
00323
00324 if ((last_consec_frames != 0)) {
00325 ast_verb(6, "Channel '%s' fax session '%u', [ %.3ld.%.6ld ], %s sent %u frames (%u ms) of %s.\n",
00326 s->channame, s->id, (long) diff.tv_sec, (long int) diff.tv_usec,
00327 (c2s) ? "channel" : "stack", last_consec_frames, last_consec_ms,
00328 (wassil) ? "silence" : "energy");
00329 }
00330 }
00331
00332 history->consec_frames++;
00333 history->consec_ms += (frame->samples / 8);
00334 }
00335
00336 static void destroy_callback(void *data)
00337 {
00338 if (data) {
00339 ao2_ref(data, -1);
00340 }
00341 }
00342
00343 static const struct ast_datastore_info fax_datastore = {
00344 .type = "res_fax",
00345 .destroy = destroy_callback,
00346 };
00347
00348
00349 static struct ast_fax_session_details *find_details(struct ast_channel *chan)
00350 {
00351 struct ast_fax_session_details *details;
00352 struct ast_datastore *datastore;
00353
00354 ast_channel_lock(chan);
00355 if (!(datastore = ast_channel_datastore_find(chan, &fax_datastore, NULL))) {
00356 ast_channel_unlock(chan);
00357 return NULL;
00358 }
00359 if (!(details = datastore->data)) {
00360 ast_log(LOG_WARNING, "Huh? channel '%s' has a FAX datastore without data!\n", chan->name);
00361 ast_channel_unlock(chan);
00362 return NULL;
00363 }
00364 ao2_ref(details, 1);
00365 ast_channel_unlock(chan);
00366
00367 return details;
00368 }
00369
00370
00371 static void destroy_session_details(void *details)
00372 {
00373 struct ast_fax_session_details *d = details;
00374 struct ast_fax_document *doc;
00375
00376 while ((doc = AST_LIST_REMOVE_HEAD(&d->documents, next))) {
00377 ast_free(doc);
00378 }
00379 ast_string_field_free_memory(d);
00380 }
00381
00382
00383 static struct ast_fax_session_details *session_details_new(void)
00384 {
00385 struct ast_fax_session_details *d;
00386 struct fax_options options;
00387
00388 if (!(d = ao2_alloc(sizeof(*d), destroy_session_details))) {
00389 return NULL;
00390 }
00391
00392 if (ast_string_field_init(d, 512)) {
00393 ao2_ref(d, -1);
00394 return NULL;
00395 }
00396
00397 get_general_options(&options);
00398
00399 AST_LIST_HEAD_INIT_NOLOCK(&d->documents);
00400
00401
00402
00403 d->option.request_t38 = AST_FAX_OPTFLAG_FALSE;
00404 d->option.send_cng = AST_FAX_OPTFLAG_FALSE;
00405 d->option.send_ced = AST_FAX_OPTFLAG_FALSE;
00406 d->option.ecm = options.ecm;
00407 d->option.statusevents = options.statusevents;
00408 d->modems = options.modems;
00409 d->minrate = options.minrate;
00410 d->maxrate = options.maxrate;
00411
00412 return d;
00413 }
00414
00415
00416
00417 static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan)
00418 {
00419 struct ast_fax_session_details *details;
00420 struct ast_datastore *datastore;
00421
00422 if ((details = find_details(chan))) {
00423 return details;
00424 }
00425
00426 if (!(details = session_details_new())) {
00427 ast_log(LOG_WARNING, "channel '%s' can't get a FAX details structure for the datastore!\n", chan->name);
00428 return NULL;
00429 }
00430 if (!(datastore = ast_datastore_alloc(&fax_datastore, NULL))) {
00431 ao2_ref(details, -1);
00432 ast_log(LOG_WARNING, "channel '%s' can't get a datastore!\n", chan->name);
00433 return NULL;
00434 }
00435
00436 datastore->data = details;
00437 ao2_ref(details, 1);
00438 ast_channel_lock(chan);
00439 ast_channel_datastore_add(chan, datastore);
00440 ast_channel_unlock(chan);
00441 return details;
00442 }
00443
00444 unsigned int ast_fax_maxrate(void)
00445 {
00446 struct fax_options options;
00447 get_general_options(&options);
00448
00449 return options.maxrate;
00450 }
00451
00452 unsigned int ast_fax_minrate(void)
00453 {
00454 struct fax_options options;
00455 get_general_options(&options);
00456
00457 return options.minrate;
00458 }
00459
00460 static int update_modem_bits(enum ast_fax_modems *bits, const char *value)
00461 {
00462 char *m[5], *tok, *v = (char *)value;
00463 int i = 0, j;
00464
00465 if (!strchr(v, ',')) {
00466 m[i++] = v;
00467 m[i] = NULL;
00468 } else {
00469 tok = strtok(v, ", ");
00470 while (tok && i < ARRAY_LEN(m) - 1) {
00471 m[i++] = tok;
00472 tok = strtok(NULL, ", ");
00473 }
00474 m[i] = NULL;
00475 }
00476
00477 *bits = 0;
00478 for (j = 0; j < i; j++) {
00479 if (!strcasecmp(m[j], "v17")) {
00480 *bits |= AST_FAX_MODEM_V17;
00481 } else if (!strcasecmp(m[j], "v27")) {
00482 *bits |= AST_FAX_MODEM_V27;
00483 } else if (!strcasecmp(m[j], "v29")) {
00484 *bits |= AST_FAX_MODEM_V29;
00485 } else if (!strcasecmp(m[j], "v34")) {
00486 *bits |= AST_FAX_MODEM_V34;
00487 } else {
00488 ast_log(LOG_WARNING, "ignoring invalid modem setting: '%s', valid options {v17 | v27 | v29 | v34}\n", m[j]);
00489 }
00490 }
00491 return 0;
00492 }
00493
00494 static char *ast_fax_caps_to_str(enum ast_fax_capabilities caps, char *buf, size_t bufsize)
00495 {
00496 char *out = buf;
00497 size_t size = bufsize;
00498 int first = 1;
00499
00500 if (caps & AST_FAX_TECH_SEND) {
00501 if (!first) {
00502 ast_build_string(&buf, &size, ",");
00503 }
00504 ast_build_string(&buf, &size, "SEND");
00505 first = 0;
00506 }
00507 if (caps & AST_FAX_TECH_RECEIVE) {
00508 if (!first) {
00509 ast_build_string(&buf, &size, ",");
00510 }
00511 ast_build_string(&buf, &size, "RECEIVE");
00512 first = 0;
00513 }
00514 if (caps & AST_FAX_TECH_AUDIO) {
00515 if (!first) {
00516 ast_build_string(&buf, &size, ",");
00517 }
00518 ast_build_string(&buf, &size, "AUDIO");
00519 first = 0;
00520 }
00521 if (caps & AST_FAX_TECH_T38) {
00522 if (!first) {
00523 ast_build_string(&buf, &size, ",");
00524 }
00525 ast_build_string(&buf, &size, "T38");
00526 first = 0;
00527 }
00528 if (caps & AST_FAX_TECH_MULTI_DOC) {
00529 if (!first) {
00530 ast_build_string(&buf, &size, ",");
00531 }
00532 ast_build_string(&buf, &size, "MULTI_DOC");
00533 first = 0;
00534 }
00535
00536 return out;
00537 }
00538
00539 static int ast_fax_modem_to_str(enum ast_fax_modems bits, char *tbuf, size_t bufsize)
00540 {
00541 int count = 0;
00542
00543 if (bits & AST_FAX_MODEM_V17) {
00544 strcat(tbuf, "V17");
00545 count++;
00546 }
00547 if (bits & AST_FAX_MODEM_V27) {
00548 if (count) {
00549 strcat(tbuf, ",");
00550 }
00551 strcat(tbuf, "V27");
00552 count++;
00553 }
00554 if (bits & AST_FAX_MODEM_V29) {
00555 if (count) {
00556 strcat(tbuf, ",");
00557 }
00558 strcat(tbuf, "V29");
00559 count++;
00560 }
00561 if (bits & AST_FAX_MODEM_V34) {
00562 if (count) {
00563 strcat(tbuf, ",");
00564 }
00565 strcat(tbuf, "V34");
00566 count++;
00567 }
00568
00569 return 0;
00570 }
00571
00572 static int check_modem_rate(enum ast_fax_modems modems, unsigned int rate)
00573 {
00574 switch (rate) {
00575 case 2400:
00576 if (!(modems & (AST_FAX_MODEM_V34))) {
00577 return 1;
00578 }
00579 break;
00580 case 4800:
00581 if (!(modems & (AST_FAX_MODEM_V27 | AST_FAX_MODEM_V34))) {
00582 return 1;
00583 }
00584 break;
00585 case 7200:
00586 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
00587 return 1;
00588 }
00589 break;
00590 case 9600:
00591 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
00592 return 1;
00593 }
00594 break;
00595 case 12000:
00596 case 14400:
00597 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V34))) {
00598 return 1;
00599 }
00600 break;
00601 case 28800:
00602 case 33600:
00603 if (!(modems & AST_FAX_MODEM_V34)) {
00604 return 1;
00605 }
00606 break;
00607 default:
00608
00609 return 1;
00610 }
00611
00612 return 0;
00613 }
00614
00615
00616 int ast_fax_tech_register(struct ast_fax_tech *tech)
00617 {
00618 struct fax_module *fax;
00619
00620 if (!(fax = ast_calloc(1, sizeof(*fax)))) {
00621 return -1;
00622 }
00623 fax->tech = tech;
00624 AST_RWLIST_WRLOCK(&faxmodules);
00625 AST_RWLIST_INSERT_TAIL(&faxmodules, fax, list);
00626 AST_RWLIST_UNLOCK(&faxmodules);
00627 ast_module_ref(ast_module_info->self);
00628
00629 ast_verb(3, "Registered handler for '%s' (%s)\n", fax->tech->type, fax->tech->description);
00630
00631 return 0;
00632 }
00633
00634
00635 void ast_fax_tech_unregister(struct ast_fax_tech *tech)
00636 {
00637 struct fax_module *fax;
00638
00639 ast_verb(3, "Unregistering FAX module type '%s'\n", tech->type);
00640
00641 AST_RWLIST_WRLOCK(&faxmodules);
00642 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&faxmodules, fax, list) {
00643 if (fax->tech != tech) {
00644 continue;
00645 }
00646 AST_RWLIST_REMOVE_CURRENT(list);
00647 ast_module_unref(ast_module_info->self);
00648 ast_free(fax);
00649 ast_verb(4, "Unregistered FAX module type '%s'\n", tech->type);
00650 break;
00651 }
00652 AST_RWLIST_TRAVERSE_SAFE_END;
00653 AST_RWLIST_UNLOCK(&faxmodules);
00654 }
00655
00656
00657 const char *ast_fax_state_to_str(enum ast_fax_state state)
00658 {
00659 switch (state) {
00660 case AST_FAX_STATE_UNINITIALIZED:
00661 return "Uninitialized";
00662 case AST_FAX_STATE_INITIALIZED:
00663 return "Initialized";
00664 case AST_FAX_STATE_OPEN:
00665 return "Open";
00666 case AST_FAX_STATE_ACTIVE:
00667 return "Active";
00668 case AST_FAX_STATE_COMPLETE:
00669 return "Complete";
00670 case AST_FAX_STATE_RESERVED:
00671 return "Reserved";
00672 case AST_FAX_STATE_INACTIVE:
00673 return "Inactive";
00674 default:
00675 ast_log(LOG_WARNING, "unhandled FAX state: %u\n", state);
00676 return "Unknown";
00677 }
00678 }
00679
00680 void ast_fax_log(int level, const char *file, const int line, const char *function, const char *msg)
00681 {
00682 if (fax_logger_level != -1) {
00683 ast_log_dynamic_level(fax_logger_level, "%s", msg);
00684 } else {
00685 ast_log(level, file, line, function, "%s", msg);
00686 }
00687 }
00688
00689
00690 static unsigned int fax_rate_str_to_int(const char *ratestr)
00691 {
00692 int rate;
00693
00694 if (sscanf(ratestr, "%d", &rate) != 1) {
00695 ast_log(LOG_ERROR, "failed to sscanf '%s' to rate\n", ratestr);
00696 return 0;
00697 }
00698 switch (rate) {
00699 case 2400:
00700 case 4800:
00701 case 7200:
00702 case 9600:
00703 case 12000:
00704 case 14400:
00705 case 28800:
00706 case 33600:
00707 return rate;
00708 default:
00709 ast_log(LOG_WARNING, "ignoring invalid rate '%s'. Valid options are {2400 | 4800 | 7200 | 9600 | 12000 | 14400 | 28800 | 33600}\n", ratestr);
00710 return 0;
00711 }
00712 }
00713
00714 static void fax_session_release(struct ast_fax_session *s, struct ast_fax_tech_token *token)
00715 {
00716 if (token) {
00717 s->tech->release_token(token);
00718 }
00719
00720 if (s->state == AST_FAX_STATE_RESERVED) {
00721 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
00722 s->state = AST_FAX_STATE_INACTIVE;
00723 }
00724 }
00725
00726
00727 static void destroy_session(void *session)
00728 {
00729 struct ast_fax_session *s = session;
00730
00731 if (s->tech) {
00732 fax_session_release(s, NULL);
00733 if (s->tech_pvt) {
00734 s->tech->destroy_session(s);
00735 }
00736 ast_module_unref(s->tech->module);
00737 }
00738
00739 if (s->details) {
00740 ao2_ref(s->details, -1);
00741 }
00742
00743 if (s->debug_info) {
00744 ast_dsp_free(s->debug_info->dsp);
00745 ast_free(s->debug_info);
00746 }
00747
00748 if (s->smoother) {
00749 ast_smoother_free(s->smoother);
00750 }
00751
00752 if (s->state != AST_FAX_STATE_INACTIVE) {
00753 ast_atomic_fetchadd_int(&faxregistry.active_sessions, -1);
00754 }
00755
00756 ast_free(s->channame);
00757 ast_free(s->chan_uniqueid);
00758 }
00759
00760 static struct ast_fax_session *fax_session_reserve(struct ast_fax_session_details *details, struct ast_fax_tech_token **token)
00761 {
00762 struct ast_fax_session *s;
00763 struct fax_module *faxmod;
00764 char caps[128] = "";
00765
00766 if (!(s = ao2_alloc(sizeof(*s), destroy_session))) {
00767 return NULL;
00768 }
00769
00770 s->state = AST_FAX_STATE_INACTIVE;
00771
00772
00773
00774
00775 AST_RWLIST_RDLOCK(&faxmodules);
00776 AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
00777 if ((faxmod->tech->caps & details->caps) != details->caps) {
00778 continue;
00779 }
00780 ast_debug(4, "Reserving a FAX session from '%s'.\n", faxmod->tech->description);
00781 ast_module_ref(faxmod->tech->module);
00782 s->tech = faxmod->tech;
00783 break;
00784 }
00785 AST_RWLIST_UNLOCK(&faxmodules);
00786
00787 if (!faxmod) {
00788 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)));
00789 ao2_ref(s, -1);
00790 return NULL;
00791 }
00792
00793 if (!s->tech->reserve_session) {
00794 ast_debug(1, "Selected FAX technology module (%s) does not support reserving sessions.\n", s->tech->description);
00795 return s;
00796 }
00797
00798 if (!(*token = s->tech->reserve_session(s))) {
00799 ao2_ref(s, -1);
00800 return NULL;
00801 }
00802
00803 s->state = AST_FAX_STATE_RESERVED;
00804 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, 1);
00805
00806 return s;
00807 }
00808
00809
00810 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)
00811 {
00812 struct ast_fax_session *s = NULL;
00813 struct fax_module *faxmod;
00814 char caps[128] = "";
00815
00816 if (reserved) {
00817 s = reserved;
00818 ao2_ref(reserved, +1);
00819
00820 if (s->state == AST_FAX_STATE_RESERVED) {
00821 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
00822 s->state = AST_FAX_STATE_UNINITIALIZED;
00823 }
00824 }
00825
00826 if (!s && !(s = ao2_alloc(sizeof(*s), destroy_session))) {
00827 return NULL;
00828 }
00829
00830 ast_atomic_fetchadd_int(&faxregistry.active_sessions, 1);
00831 s->state = AST_FAX_STATE_UNINITIALIZED;
00832
00833 if (details->option.debug && (details->caps & AST_FAX_TECH_AUDIO)) {
00834 if (!(s->debug_info = ast_calloc(1, sizeof(*(s->debug_info))))) {
00835 fax_session_release(s, token);
00836 ao2_ref(s, -1);
00837 return NULL;
00838 }
00839 if (!(s->debug_info->dsp = ast_dsp_new())) {
00840 ast_free(s->debug_info);
00841 s->debug_info = NULL;
00842 fax_session_release(s, token);
00843 ao2_ref(s, -1);
00844 return NULL;
00845 }
00846 ast_dsp_set_threshold(s->debug_info->dsp, 128);
00847 }
00848
00849 if (!(s->channame = ast_strdup(chan->name))) {
00850 fax_session_release(s, token);
00851 ao2_ref(s, -1);
00852 return NULL;
00853 }
00854
00855 if (!(s->chan_uniqueid = ast_strdup(chan->uniqueid))) {
00856 fax_session_release(s, token);
00857 ao2_ref(s, -1);
00858 return NULL;
00859 }
00860
00861 s->chan = chan;
00862 s->details = details;
00863 ao2_ref(s->details, 1);
00864
00865 details->id = s->id = ast_atomic_fetchadd_int(&faxregistry.nextsessionname, 1);
00866
00867 if (!token) {
00868
00869 AST_RWLIST_RDLOCK(&faxmodules);
00870 AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
00871 if ((faxmod->tech->caps & details->caps) != details->caps) {
00872 continue;
00873 }
00874 ast_debug(4, "Requesting a new FAX session from '%s'.\n", faxmod->tech->description);
00875 ast_module_ref(faxmod->tech->module);
00876 if (reserved) {
00877
00878 ast_module_unref(reserved->tech->module);
00879 }
00880 s->tech = faxmod->tech;
00881 break;
00882 }
00883 AST_RWLIST_UNLOCK(&faxmodules);
00884
00885 if (!faxmod) {
00886 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)));
00887 ao2_ref(s, -1);
00888 return NULL;
00889 }
00890 }
00891
00892 if (!(s->tech_pvt = s->tech->new_session(s, token))) {
00893 ast_log(LOG_ERROR, "FAX session failed to initialize.\n");
00894 ao2_ref(s, -1);
00895 return NULL;
00896 }
00897
00898 if (!(ao2_link(faxregistry.container, s))) {
00899 ast_log(LOG_ERROR, "failed to add FAX session '%u' to container.\n", s->id);
00900 ao2_ref(s, -1);
00901 return NULL;
00902 }
00903 ast_debug(4, "channel '%s' using FAX session '%u'\n", s->channame, s->id);
00904
00905 return s;
00906 }
00907
00908 static void get_manager_event_info(struct ast_channel *chan, struct manager_event_info *info)
00909 {
00910 pbx_substitute_variables_helper(chan, "${CONTEXT}", info->context, sizeof(info->context));
00911 pbx_substitute_variables_helper(chan, "${EXTEN}", info->exten, sizeof(info->exten));
00912 pbx_substitute_variables_helper(chan, "${CALLERID(num)}", info->cid, sizeof(info->cid));
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 static char *generate_filenames_string(struct ast_fax_session_details *details, char *prefix, char *separator)
00928 {
00929 char *filenames, *c;
00930 size_t size = 0;
00931 int first = 1;
00932 struct ast_fax_document *doc;
00933
00934
00935 if (AST_LIST_EMPTY(&details->documents)) {
00936 return NULL;
00937 }
00938
00939
00940 AST_LIST_TRAVERSE(&details->documents, doc, next) {
00941 size += strlen(separator) + strlen(prefix) + strlen(doc->filename);
00942 }
00943 size += 1;
00944
00945 if (!(filenames = ast_malloc(size))) {
00946 return NULL;
00947 }
00948 c = filenames;
00949
00950 ast_build_string(&c, &size, "%s%s", prefix, AST_LIST_FIRST(&details->documents)->filename);
00951 AST_LIST_TRAVERSE(&details->documents, doc, next) {
00952 if (first) {
00953 first = 0;
00954 continue;
00955 }
00956
00957 ast_build_string(&c, &size, "%s%s%s", separator, prefix, doc->filename);
00958 }
00959
00960 return filenames;
00961 }
00962
00963
00964 static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details, const char *status)
00965 {
00966 char *filenames = generate_filenames_string(details, "FileName: ", "\r\n");
00967 if (!filenames) {
00968 return 1;
00969 }
00970
00971 ast_channel_lock(chan);
00972 if (details->option.statusevents) {
00973 struct manager_event_info info;
00974
00975 get_manager_event_info(chan, &info);
00976 manager_event(EVENT_FLAG_CALL,
00977 (details->caps & AST_FAX_TECH_RECEIVE) ? "ReceiveFAXStatus" : "SendFAXStatus",
00978 "Status: %s\r\n"
00979 "Channel: %s\r\n"
00980 "Context: %s\r\n"
00981 "Exten: %s\r\n"
00982 "CallerID: %s\r\n"
00983 "LocalStationID: %s\r\n"
00984 "%s\r\n",
00985 status,
00986 chan->name,
00987 info.context,
00988 info.exten,
00989 info.cid,
00990 details->localstationid,
00991 filenames);
00992 }
00993 ast_channel_unlock(chan);
00994 ast_free(filenames);
00995
00996 return 0;
00997 }
00998
00999
01000 static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
01001 {
01002 char buf[10];
01003 pbx_builtin_setvar_helper(chan, "FAXSTATUS", S_OR(details->result, NULL));
01004 pbx_builtin_setvar_helper(chan, "FAXERROR", S_OR(details->error, NULL));
01005 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", S_OR(details->resultstr, NULL));
01006 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", S_OR(details->remotestationid, NULL));
01007 pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", S_OR(details->localstationid, NULL));
01008 pbx_builtin_setvar_helper(chan, "FAXBITRATE", S_OR(details->transfer_rate, NULL));
01009 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", S_OR(details->resolution, NULL));
01010
01011 snprintf(buf, sizeof(buf), "%u", details->pages_transferred);
01012 pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
01013 }
01014
01015 #define GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason) \
01016 do { \
01017 if (ast_strlen_zero(fax->details->result)) \
01018 ast_string_field_set(fax->details, result, "FAILED"); \
01019 if (ast_strlen_zero(fax->details->resultstr)) \
01020 ast_string_field_set(fax->details, resultstr, reason); \
01021 if (ast_strlen_zero(fax->details->error)) \
01022 ast_string_field_set(fax->details, error, errorstr); \
01023 set_channel_variables(chan, fax->details); \
01024 } while (0)
01025
01026 #define GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason) \
01027 do { \
01028 GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason); \
01029 } while (0)
01030
01031 #define GENERIC_FAX_EXEC_ERROR(fax, chan, errorstr, reason) \
01032 do { \
01033 ast_log(LOG_ERROR, "channel '%s' FAX session '%u' failure, reason: '%s' (%s)\n", chan->name, fax->id, reason, errorstr); \
01034 GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason); \
01035 } while (0)
01036
01037 static void t38_parameters_ast_to_fax(struct ast_fax_t38_parameters *dst, const struct ast_control_t38_parameters *src)
01038 {
01039 dst->version = src->version;
01040 dst->max_ifp = src->max_ifp;
01041 dst->rate = src->rate;
01042 dst->rate_management = src->rate_management;
01043 dst->fill_bit_removal = src->fill_bit_removal;
01044 dst->transcoding_mmr = src->transcoding_mmr;
01045 dst->transcoding_jbig = src->transcoding_jbig;
01046 }
01047
01048 static void t38_parameters_fax_to_ast(struct ast_control_t38_parameters *dst, const struct ast_fax_t38_parameters *src)
01049 {
01050 dst->version = src->version;
01051 dst->max_ifp = src->max_ifp;
01052 dst->rate = src->rate;
01053 dst->rate_management = src->rate_management;
01054 dst->fill_bit_removal = src->fill_bit_removal;
01055 dst->transcoding_mmr = src->transcoding_mmr;
01056 dst->transcoding_jbig = src->transcoding_jbig;
01057 }
01058
01059 static int set_fax_t38_caps(struct ast_channel *chan, struct ast_fax_session_details *details)
01060 {
01061 switch (ast_channel_get_t38_state(chan)) {
01062 case T38_STATE_UNKNOWN:
01063 details->caps |= AST_FAX_TECH_T38;
01064 break;
01065 case T38_STATE_UNAVAILABLE:
01066 details->caps |= AST_FAX_TECH_AUDIO;
01067 break;
01068 case T38_STATE_NEGOTIATING: {
01069
01070
01071
01072
01073
01074
01075
01076 struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_PARMS, };
01077 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)) != AST_T38_REQUEST_PARMS) {
01078 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", chan->name);
01079 return -1;
01080 }
01081 details->caps |= AST_FAX_TECH_T38;
01082 break;
01083 }
01084 default:
01085 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", chan->name);
01086 return -1;
01087 }
01088
01089 return 0;
01090 }
01091
01092 static int disable_t38(struct ast_channel *chan)
01093 {
01094 int timeout_ms;
01095 struct ast_frame *frame = NULL;
01096 struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
01097 struct timeval start;
01098 int ms;
01099
01100 ast_debug(1, "Shutting down T.38 on %s\n", chan->name);
01101 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0) {
01102 ast_debug(1, "error while disabling T.38 on channel '%s'\n", chan->name);
01103 return -1;
01104 }
01105
01106
01107 timeout_ms = 5000;
01108 start = ast_tvnow();
01109 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01110 ms = ast_waitfor(chan, ms);
01111
01112 if (ms == 0) {
01113 break;
01114 }
01115 if (ms < 0) {
01116 ast_debug(1, "error while disabling T.38 on channel '%s'\n", chan->name);
01117 return -1;
01118 }
01119
01120 if (!(frame = ast_read(chan))) {
01121 return -1;
01122 }
01123 if ((frame->frametype == AST_FRAME_CONTROL) &&
01124 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01125 (frame->datalen == sizeof(t38_parameters))) {
01126 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01127
01128 switch (parameters->request_response) {
01129 case AST_T38_TERMINATED:
01130 ast_debug(1, "Shut down T.38 on %s\n", chan->name);
01131 break;
01132 case AST_T38_REFUSED:
01133 ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", chan->name);
01134 ast_frfree(frame);
01135 return -1;
01136 default:
01137 ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", chan->name);
01138 ast_frfree(frame);
01139 return -1;
01140 }
01141 ast_frfree(frame);
01142 break;
01143 }
01144 ast_frfree(frame);
01145 }
01146
01147 if (ms == 0) {
01148 ast_debug(1, "channel '%s' timed-out during T.38 shutdown\n", chan->name);
01149 }
01150
01151 return 0;
01152 }
01153
01154 static struct ast_control_t38_parameters our_t38_parameters = {
01155 .version = 0,
01156 .max_ifp = 400,
01157 .rate = AST_T38_RATE_14400,
01158 .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
01159 };
01160
01161
01162 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)
01163 {
01164 int ms;
01165 int timeout = RES_FAX_TIMEOUT;
01166 int chancount;
01167 unsigned int expected_frametype = -1;
01168 union ast_frame_subclass expected_framesubclass = { .integer = -1 };
01169 unsigned int t38negotiated = (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED);
01170 struct ast_control_t38_parameters t38_parameters;
01171 const char *tempvar;
01172 struct ast_fax_session *fax = NULL;
01173 struct ast_frame *frame = NULL;
01174 struct ast_channel *c = chan;
01175 unsigned int orig_write_format = 0, orig_read_format = 0;
01176 int remaining_time;
01177 struct timeval start;
01178
01179 chancount = 1;
01180
01181
01182 if (!(fax = fax_session_new(details, chan, reserved, token))) {
01183 ast_log(LOG_ERROR, "Can't create a FAX session, FAX attempt failed.\n");
01184 report_fax_status(chan, details, "No Available Resource");
01185 return -1;
01186 }
01187
01188 ast_channel_lock(chan);
01189
01190 if (ast_strlen_zero(details->headerinfo) && (tempvar = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO"))) {
01191 ast_string_field_set(details, headerinfo, tempvar);
01192 }
01193 if (ast_strlen_zero(details->localstationid)) {
01194 tempvar = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
01195 ast_string_field_set(details, localstationid, tempvar ? tempvar : "unknown");
01196 }
01197 ast_channel_unlock(chan);
01198
01199 report_fax_status(chan, details, "Allocating Resources");
01200
01201 if (details->caps & AST_FAX_TECH_AUDIO) {
01202 expected_frametype = AST_FRAME_VOICE;;
01203 expected_framesubclass.codec = AST_FORMAT_SLINEAR;
01204 orig_write_format = chan->writeformat;
01205 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
01206 ast_log(LOG_ERROR, "channel '%s' failed to set write format to signed linear'.\n", chan->name);
01207 ao2_lock(faxregistry.container);
01208 ao2_unlink(faxregistry.container, fax);
01209 ao2_unlock(faxregistry.container);
01210 ao2_ref(fax, -1);
01211 ast_channel_unlock(chan);
01212 return -1;
01213 }
01214 orig_read_format = chan->readformat;
01215 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
01216 ast_log(LOG_ERROR, "channel '%s' failed to set read format to signed linear.\n", chan->name);
01217 ao2_lock(faxregistry.container);
01218 ao2_unlink(faxregistry.container, fax);
01219 ao2_unlock(faxregistry.container);
01220 ao2_ref(fax, -1);
01221 ast_channel_unlock(chan);
01222 return -1;
01223 }
01224 if (fax->smoother) {
01225 ast_smoother_free(fax->smoother);
01226 fax->smoother = NULL;
01227 }
01228 if (!(fax->smoother = ast_smoother_new(320))) {
01229 ast_log(LOG_WARNING, "Channel '%s' FAX session '%u' failed to obtain a smoother.\n", chan->name, fax->id);
01230 }
01231 } else {
01232 expected_frametype = AST_FRAME_MODEM;
01233 expected_framesubclass.codec = AST_MODEM_T38;
01234 }
01235
01236 if (fax->debug_info) {
01237 fax->debug_info->base_tv = ast_tvnow();
01238 }
01239
01240
01241
01242 ast_string_field_set(details, result, "");
01243 ast_string_field_set(details, resultstr, "");
01244 ast_string_field_set(details, error, "");
01245 set_channel_variables(chan, details);
01246
01247 if (fax->tech->start_session(fax) < 0) {
01248 GENERIC_FAX_EXEC_ERROR(fax, chan, "INIT_ERROR", "failed to start FAX session");
01249 }
01250
01251 report_fax_status(chan, details, "FAX Transmission In Progress");
01252
01253 ast_debug(5, "channel %s will wait on FAX fd %d\n", chan->name, fax->fd);
01254
01255
01256 remaining_time = timeout;
01257 start = ast_tvnow();
01258 while (remaining_time > 0) {
01259 struct ast_channel *ready_chan;
01260 int ofd, exception;
01261
01262 ms = 1000;
01263 errno = 0;
01264 ready_chan = ast_waitfor_nandfds(&c, chancount, &fax->fd, 1, &exception, &ofd, &ms);
01265 if (ready_chan) {
01266 if (!(frame = ast_read(chan))) {
01267
01268
01269
01270
01271 ast_debug(1, "Channel '%s' did not return a frame; probably hung up.\n", chan->name);
01272 GENERIC_FAX_EXEC_SET_VARS(fax, chan, "HANGUP", "remote channel hungup");
01273 c = NULL;
01274 chancount = 0;
01275 remaining_time = ast_remaining_ms(start, timeout);
01276 fax->tech->cancel_session(fax);
01277 if (fax->tech->generate_silence) {
01278 fax->tech->generate_silence(fax);
01279 }
01280 continue;
01281 }
01282
01283 if ((frame->frametype == AST_FRAME_CONTROL) &&
01284 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01285 (frame->datalen == sizeof(t38_parameters))) {
01286 unsigned int was_t38 = t38negotiated;
01287 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01288
01289 switch (parameters->request_response) {
01290 case AST_T38_REQUEST_NEGOTIATE:
01291
01292
01293
01294 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01295 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01296 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01297 break;
01298 case AST_T38_NEGOTIATED:
01299 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01300 t38negotiated = 1;
01301 break;
01302 default:
01303 break;
01304 }
01305 if (t38negotiated && !was_t38) {
01306 fax->tech->switch_to_t38(fax);
01307 details->caps &= ~AST_FAX_TECH_AUDIO;
01308 expected_frametype = AST_FRAME_MODEM;
01309 expected_framesubclass.codec = AST_MODEM_T38;
01310 if (fax->smoother) {
01311 ast_smoother_free(fax->smoother);
01312 fax->smoother = NULL;
01313 }
01314
01315 report_fax_status(chan, details, "T.38 Negotiated");
01316
01317 ast_verb(3, "Channel '%s' switched to T.38 FAX session '%u'.\n", chan->name, fax->id);
01318 }
01319 } else if ((frame->frametype == expected_frametype) &&
01320 (!memcmp(&frame->subclass, &expected_framesubclass, sizeof(frame->subclass)))) {
01321 struct ast_frame *f;
01322
01323 if (fax->smoother) {
01324
01325 if (ast_smoother_feed(fax->smoother, frame) < 0) {
01326 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "Failed to feed the smoother");
01327 }
01328 while ((f = ast_smoother_read(fax->smoother)) && (f->data.ptr)) {
01329 if (fax->debug_info) {
01330 debug_check_frame_for_silence(fax, 1, f);
01331 }
01332
01333 fax->tech->write(fax, f);
01334 fax->frames_received++;
01335 if (f != frame) {
01336 ast_frfree(f);
01337 }
01338 }
01339 } else {
01340
01341 fax->tech->write(fax, frame);
01342 fax->frames_received++;
01343 }
01344 start = ast_tvnow();
01345 }
01346 ast_frfree(frame);
01347 } else if (ofd == fax->fd) {
01348
01349
01350 if (!(frame = fax->tech->read(fax))) {
01351 break;
01352 }
01353
01354 if (fax->debug_info && (frame->frametype == AST_FRAME_VOICE)) {
01355 debug_check_frame_for_silence(fax, 0, frame);
01356 }
01357
01358 ast_write(chan, frame);
01359 fax->frames_sent++;
01360 ast_frfree(frame);
01361 start = ast_tvnow();
01362 } else {
01363 if (ms && (ofd < 0)) {
01364 if ((errno == 0) || (errno == EINTR)) {
01365 remaining_time = ast_remaining_ms(start, timeout);
01366 if (remaining_time <= 0)
01367 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
01368 continue;
01369 } else {
01370 ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", chan->name);
01371 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "error polling data");
01372 break;
01373 }
01374 } else {
01375
01376 remaining_time = ast_remaining_ms(start, timeout);
01377 if (remaining_time <= 0) {
01378 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
01379 break;
01380 }
01381 }
01382 }
01383 }
01384 ast_debug(3, "channel '%s' - event loop stopped { timeout: %d, remaining_time: %d }\n", chan->name, timeout, remaining_time);
01385
01386 set_channel_variables(chan, details);
01387
01388 if (!strcasecmp(details->result, "FAILED")) {
01389 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01390 } else {
01391 ast_atomic_fetchadd_int(&faxregistry.fax_complete, 1);
01392 }
01393
01394 if (fax) {
01395 ao2_lock(faxregistry.container);
01396 ao2_unlink(faxregistry.container, fax);
01397 ao2_unlock(faxregistry.container);
01398 ao2_ref(fax, -1);
01399 }
01400
01401
01402
01403
01404 if (chancount) {
01405 if (orig_read_format) {
01406 ast_set_read_format(chan, orig_read_format);
01407 }
01408 if (orig_write_format) {
01409 ast_set_write_format(chan, orig_write_format);
01410 }
01411 }
01412
01413
01414 return chancount;
01415 }
01416
01417 static int receivefax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
01418 {
01419 int timeout_ms;
01420 struct ast_frame *frame = NULL;
01421 struct ast_control_t38_parameters t38_parameters;
01422 struct timeval start;
01423 int ms;
01424
01425 t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
01426
01427
01428 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
01429
01430 if (ast_playtones_start(chan, 1024, "!2100/3000", 1)) {
01431 ast_log(LOG_ERROR, "error generating CED tone on %s\n", chan->name);
01432 return -1;
01433 }
01434
01435 timeout_ms = 3000;
01436 start = ast_tvnow();
01437 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01438 ms = ast_waitfor(chan, ms);
01439
01440 if (ms < 0) {
01441 ast_log(LOG_ERROR, "error while generating CED tone on %s\n", chan->name);
01442 ast_playtones_stop(chan);
01443 return -1;
01444 }
01445
01446 if (ms == 0) {
01447 break;
01448 }
01449
01450 if (!(frame = ast_read(chan))) {
01451 ast_log(LOG_ERROR, "error reading frame while generating CED tone on %s\n", chan->name);
01452 ast_playtones_stop(chan);
01453 return -1;
01454 }
01455
01456 if ((frame->frametype == AST_FRAME_CONTROL) &&
01457 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01458 (frame->datalen == sizeof(t38_parameters))) {
01459 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01460
01461 switch (parameters->request_response) {
01462 case AST_T38_REQUEST_NEGOTIATE:
01463
01464
01465
01466 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01467 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01468 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01469 ast_playtones_stop(chan);
01470 break;
01471 case AST_T38_NEGOTIATED:
01472 ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
01473 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01474 details->caps &= ~AST_FAX_TECH_AUDIO;
01475 report_fax_status(chan, details, "T.38 Negotiated");
01476 break;
01477 default:
01478 break;
01479 }
01480 }
01481 ast_frfree(frame);
01482 }
01483
01484 ast_playtones_stop(chan);
01485 }
01486
01487
01488 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01489 return 0;
01490 }
01491
01492
01493 ast_debug(1, "Negotiating T.38 for receive on %s\n", chan->name);
01494
01495
01496 timeout_ms = 5000;
01497
01498
01499 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01500 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
01501 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
01502 return -1;
01503 }
01504
01505 start = ast_tvnow();
01506 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01507 int break_loop = 0;
01508
01509 ms = ast_waitfor(chan, ms);
01510 if (ms < 0) {
01511 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01512 return -1;
01513 }
01514 if (ms == 0) {
01515 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", chan->name);
01516 details->caps &= ~AST_FAX_TECH_T38;
01517 break;
01518 }
01519
01520 if (!(frame = ast_read(chan))) {
01521 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01522 return -1;
01523 }
01524
01525 if ((frame->frametype == AST_FRAME_CONTROL) &&
01526 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01527 (frame->datalen == sizeof(t38_parameters))) {
01528 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01529
01530 switch (parameters->request_response) {
01531 case AST_T38_REQUEST_NEGOTIATE:
01532 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01533 t38_parameters.request_response = AST_T38_NEGOTIATED;
01534 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01535 break;
01536 case AST_T38_NEGOTIATED:
01537 ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
01538 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01539 details->caps &= ~AST_FAX_TECH_AUDIO;
01540 report_fax_status(chan, details, "T.38 Negotiated");
01541 break_loop = 1;
01542 break;
01543 case AST_T38_REFUSED:
01544 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", chan->name);
01545 details->caps &= ~AST_FAX_TECH_T38;
01546 break_loop = 1;
01547 break;
01548 default:
01549 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", chan->name);
01550 details->caps &= ~AST_FAX_TECH_T38;
01551 break_loop = 1;
01552 break;
01553 }
01554 }
01555 ast_frfree(frame);
01556 if (break_loop) {
01557 break;
01558 }
01559 }
01560
01561
01562 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01563 return 0;
01564 }
01565
01566
01567 if (details->option.allow_audio != AST_FAX_OPTFLAG_TRUE) {
01568 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", chan->name);
01569 return -1;
01570 }
01571
01572
01573 details->caps |= AST_FAX_TECH_AUDIO;
01574
01575 return 0;
01576 }
01577
01578
01579 static int receivefax_exec(struct ast_channel *chan, const char *data)
01580 {
01581 char *parse, modems[128] = "";
01582 int channel_alive;
01583 struct ast_fax_session_details *details;
01584 struct ast_fax_session *s;
01585 struct ast_fax_tech_token *token = NULL;
01586 struct ast_fax_document *doc;
01587 AST_DECLARE_APP_ARGS(args,
01588 AST_APP_ARG(filename);
01589 AST_APP_ARG(options);
01590 );
01591 struct ast_flags opts = { 0, };
01592 struct manager_event_info info;
01593
01594
01595 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
01596 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
01597 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
01598 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
01599 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
01600
01601
01602
01603 ast_atomic_fetchadd_int(&faxregistry.fax_rx_attempts, 1);
01604
01605
01606
01607 if (!(details = find_or_create_details(chan))) {
01608 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01609 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
01610 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
01611 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
01612 return -1;
01613 }
01614
01615 ast_string_field_set(details, result, "FAILED");
01616 ast_string_field_set(details, resultstr, "error starting fax session");
01617 ast_string_field_set(details, error, "INIT_ERROR");
01618 set_channel_variables(chan, details);
01619
01620 if (details->maxrate < details->minrate) {
01621 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01622 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01623 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
01624 set_channel_variables(chan, details);
01625 ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", details->maxrate, details->minrate);
01626 ao2_ref(details, -1);
01627 return -1;
01628 }
01629
01630 if (check_modem_rate(details->modems, details->minrate)) {
01631 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01632 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
01633 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, details->minrate);
01634 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01635 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
01636 set_channel_variables(chan, details);
01637 ao2_ref(details, -1);
01638 return -1;
01639 }
01640
01641 if (check_modem_rate(details->modems, details->maxrate)) {
01642 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01643 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
01644 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, details->maxrate);
01645 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01646 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
01647 set_channel_variables(chan, details);
01648 ao2_ref(details, -1);
01649 return -1;
01650 }
01651
01652 if (ast_strlen_zero(data)) {
01653 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01654 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01655 ast_string_field_set(details, resultstr, "invalid arguments");
01656 set_channel_variables(chan, details);
01657 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
01658 ao2_ref(details, -1);
01659 return -1;
01660 }
01661 parse = ast_strdupa(data);
01662 AST_STANDARD_APP_ARGS(args, parse);
01663
01664 if (!ast_strlen_zero(args.options) &&
01665 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
01666 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01667 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01668 ast_string_field_set(details, resultstr, "invalid arguments");
01669 set_channel_variables(chan, details);
01670 ao2_ref(details, -1);
01671 return -1;
01672 }
01673 if (ast_strlen_zero(args.filename)) {
01674 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01675 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01676 ast_string_field_set(details, resultstr, "invalid arguments");
01677 set_channel_variables(chan, details);
01678 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
01679 ao2_ref(details, -1);
01680 return -1;
01681 }
01682
01683
01684 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
01685 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01686 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01687 ast_string_field_set(details, resultstr, "invalid arguments");
01688 set_channel_variables(chan, details);
01689 ast_log(LOG_WARNING, "%s does not support polling\n", app_receivefax);
01690 ao2_ref(details, -1);
01691 return -1;
01692 }
01693
01694 pbx_builtin_setvar_helper(chan, "FAXERROR", "Channel Problems");
01695 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "Error before FAX transmission started.");
01696
01697 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(args.filename) + 1))) {
01698 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01699 ast_string_field_set(details, error, "MEMORY_ERROR");
01700 ast_string_field_set(details, resultstr, "error allocating memory");
01701 set_channel_variables(chan, details);
01702 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
01703 ao2_ref(details, -1);
01704 return -1;
01705 }
01706
01707 strcpy(doc->filename, args.filename);
01708 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
01709
01710 ast_verb(3, "Channel '%s' receiving FAX '%s'\n", chan->name, args.filename);
01711
01712 details->caps = AST_FAX_TECH_RECEIVE;
01713 details->option.send_ced = AST_FAX_OPTFLAG_TRUE;
01714
01715
01716 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
01717 details->option.debug = AST_FAX_OPTFLAG_TRUE;
01718 }
01719
01720
01721 if (ast_test_flag(&opts, OPT_STATUS)) {
01722 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
01723 }
01724
01725 if ((ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE) ||
01726 ast_test_flag(&opts, OPT_ALLOWAUDIO)) {
01727 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
01728 }
01729
01730 if (!(s = fax_session_reserve(details, &token))) {
01731 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01732 ast_string_field_set(details, resultstr, "error reserving fax session");
01733 set_channel_variables(chan, details);
01734 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
01735 ao2_ref(details, -1);
01736 return -1;
01737 }
01738
01739
01740 if (chan->_state != AST_STATE_UP) {
01741 if (ast_answer(chan)) {
01742 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01743 ast_string_field_set(details, resultstr, "error answering channel");
01744 set_channel_variables(chan, details);
01745 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
01746 fax_session_release(s, token);
01747 ao2_ref(s, -1);
01748 ao2_ref(details, -1);
01749 return -1;
01750 }
01751 }
01752
01753 if (set_fax_t38_caps(chan, details)) {
01754 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01755 ast_string_field_set(details, error, "T38_NEG_ERROR");
01756 ast_string_field_set(details, resultstr, "error negotiating T.38");
01757 set_channel_variables(chan, details);
01758 fax_session_release(s, token);
01759 ao2_ref(s, -1);
01760 ao2_ref(details, -1);
01761 return -1;
01762 }
01763
01764 if (details->caps & AST_FAX_TECH_T38) {
01765 if (receivefax_t38_init(chan, details)) {
01766 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01767 ast_string_field_set(details, error, "T38_NEG_ERROR");
01768 ast_string_field_set(details, resultstr, "error negotiating T.38");
01769 set_channel_variables(chan, details);
01770 fax_session_release(s, token);
01771 ao2_ref(s, -1);
01772 ao2_ref(details, -1);
01773 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
01774 return -1;
01775 }
01776 }
01777
01778 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
01779 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01780 }
01781
01782 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01783 if (disable_t38(chan)) {
01784 ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
01785 }
01786 }
01787
01788
01789 ast_channel_lock(chan);
01790
01791 get_manager_event_info(chan, &info);
01792 manager_event(EVENT_FLAG_CALL,
01793 "ReceiveFAX",
01794 "Channel: %s\r\n"
01795 "Context: %s\r\n"
01796 "Exten: %s\r\n"
01797 "CallerID: %s\r\n"
01798 "RemoteStationID: %s\r\n"
01799 "LocalStationID: %s\r\n"
01800 "PagesTransferred: %s\r\n"
01801 "Resolution: %s\r\n"
01802 "TransferRate: %s\r\n"
01803 "FileName: %s\r\n",
01804 chan->name,
01805 info.context,
01806 info.exten,
01807 info.cid,
01808 S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
01809 S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
01810 S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
01811 S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
01812 S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
01813 args.filename);
01814 ast_channel_unlock(chan);
01815
01816 ao2_ref(s, -1);
01817 ao2_ref(details, -1);
01818
01819
01820 return (!channel_alive) ? -1 : 0;
01821 }
01822
01823 static int sendfax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
01824 {
01825 int timeout_ms;
01826 struct ast_frame *frame = NULL;
01827 struct ast_control_t38_parameters t38_parameters;
01828 struct timeval start;
01829 int ms;
01830
01831 t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
01832
01833
01834
01835
01836
01837
01838
01839 timeout_ms = 10500;
01840
01841
01842 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
01843 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000", 1)) {
01844 ast_log(LOG_ERROR, "error generating CNG tone on %s\n", chan->name);
01845 return -1;
01846 }
01847 }
01848
01849 start = ast_tvnow();
01850 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01851 int break_loop = 0;
01852 ms = ast_waitfor(chan, ms);
01853
01854 if (ms < 0) {
01855 ast_log(LOG_ERROR, "error while generating CNG tone on %s\n", chan->name);
01856 ast_playtones_stop(chan);
01857 return -1;
01858 }
01859
01860 if (ms == 0) {
01861 break;
01862 }
01863
01864 if (!(frame = ast_read(chan))) {
01865 ast_log(LOG_ERROR, "error reading frame while generating CNG tone on %s\n", chan->name);
01866 ast_playtones_stop(chan);
01867 return -1;
01868 }
01869
01870 if ((frame->frametype == AST_FRAME_CONTROL) &&
01871 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01872 (frame->datalen == sizeof(t38_parameters))) {
01873 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01874
01875 switch (parameters->request_response) {
01876 case AST_T38_REQUEST_NEGOTIATE:
01877
01878
01879
01880 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01881 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01882 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01883 ast_playtones_stop(chan);
01884 break;
01885 case AST_T38_NEGOTIATED:
01886 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
01887 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01888 details->caps &= ~AST_FAX_TECH_AUDIO;
01889 report_fax_status(chan, details, "T.38 Negotiated");
01890 break_loop = 1;
01891 break;
01892 default:
01893 break;
01894 }
01895 }
01896 ast_frfree(frame);
01897 if (break_loop) {
01898 break;
01899 }
01900 }
01901
01902 ast_playtones_stop(chan);
01903
01904 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01905 return 0;
01906 }
01907
01908
01909 if (details->option.request_t38 == AST_FAX_OPTFLAG_TRUE) {
01910 ast_debug(1, "Negotiating T.38 for send on %s\n", chan->name);
01911
01912
01913 timeout_ms = 5000;
01914
01915
01916 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01917 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
01918 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
01919 return -1;
01920 }
01921
01922 start = ast_tvnow();
01923 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01924 int break_loop = 0;
01925
01926 ms = ast_waitfor(chan, ms);
01927 if (ms < 0) {
01928 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01929 return -1;
01930 }
01931 if (ms == 0) {
01932 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", chan->name);
01933 details->caps &= ~AST_FAX_TECH_T38;
01934 break;
01935 }
01936
01937 if (!(frame = ast_read(chan))) {
01938 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01939 return -1;
01940 }
01941
01942 if ((frame->frametype == AST_FRAME_CONTROL) &&
01943 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01944 (frame->datalen == sizeof(t38_parameters))) {
01945 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01946
01947 switch (parameters->request_response) {
01948 case AST_T38_REQUEST_NEGOTIATE:
01949 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01950 t38_parameters.request_response = AST_T38_NEGOTIATED;
01951 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01952 break;
01953 case AST_T38_NEGOTIATED:
01954 ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
01955 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01956 details->caps &= ~AST_FAX_TECH_AUDIO;
01957 report_fax_status(chan, details, "T.38 Negotiated");
01958 break_loop = 1;
01959 break;
01960 case AST_T38_REFUSED:
01961 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", chan->name);
01962 details->caps &= ~AST_FAX_TECH_T38;
01963 break_loop = 1;
01964 break;
01965 default:
01966 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", chan->name);
01967 details->caps &= ~AST_FAX_TECH_T38;
01968 break_loop = 1;
01969 break;
01970 }
01971 }
01972 ast_frfree(frame);
01973 if (break_loop) {
01974 break;
01975 }
01976 }
01977
01978
01979 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01980 return 0;
01981 }
01982
01983
01984
01985 if (details->option.allow_audio == AST_FAX_OPTFLAG_TRUE) {
01986 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000", 1)) {
01987 ast_log(LOG_ERROR, "error generating second CNG tone on %s\n", chan->name);
01988 return -1;
01989 }
01990
01991 timeout_ms = 3500;
01992 start = ast_tvnow();
01993 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01994 int break_loop = 0;
01995
01996 ms = ast_waitfor(chan, ms);
01997 if (ms < 0) {
01998 ast_log(LOG_ERROR, "error while generating second CNG tone on %s\n", chan->name);
01999 ast_playtones_stop(chan);
02000 return -1;
02001 }
02002 if (ms == 0) {
02003 break;
02004 }
02005
02006 if (!(frame = ast_read(chan))) {
02007 ast_log(LOG_ERROR, "error reading frame while generating second CNG tone on %s\n", chan->name);
02008 ast_playtones_stop(chan);
02009 return -1;
02010 }
02011
02012 if ((frame->frametype == AST_FRAME_CONTROL) &&
02013 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
02014 (frame->datalen == sizeof(t38_parameters))) {
02015 struct ast_control_t38_parameters *parameters = frame->data.ptr;
02016
02017 switch (parameters->request_response) {
02018 case AST_T38_REQUEST_NEGOTIATE:
02019
02020
02021
02022 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
02023 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
02024 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
02025 ast_playtones_stop(chan);
02026 break;
02027 case AST_T38_NEGOTIATED:
02028 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
02029 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
02030 details->caps &= ~AST_FAX_TECH_AUDIO;
02031 report_fax_status(chan, details, "T.38 Negotiated");
02032 break_loop = 1;
02033 break;
02034 default:
02035 break;
02036 }
02037 }
02038 ast_frfree(frame);
02039 if (break_loop) {
02040 break;
02041 }
02042 }
02043
02044 ast_playtones_stop(chan);
02045
02046
02047 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02048 return 0;
02049 }
02050 }
02051 }
02052
02053
02054 if (details->option.allow_audio == AST_FAX_OPTFLAG_FALSE) {
02055 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", chan->name);
02056 return -1;
02057 }
02058
02059
02060 details->caps |= AST_FAX_TECH_AUDIO;
02061
02062 return 0;
02063 }
02064
02065
02066
02067 static int sendfax_exec(struct ast_channel *chan, const char *data)
02068 {
02069 char *parse, *filenames, *c, modems[128] = "";
02070 int channel_alive, file_count;
02071 struct ast_fax_session_details *details;
02072 struct ast_fax_session *s;
02073 struct ast_fax_tech_token *token = NULL;
02074 struct ast_fax_document *doc;
02075 AST_DECLARE_APP_ARGS(args,
02076 AST_APP_ARG(filenames);
02077 AST_APP_ARG(options);
02078 );
02079 struct ast_flags opts = { 0, };
02080 struct manager_event_info info;
02081
02082
02083 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
02084 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
02085 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
02086 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
02087 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
02088
02089
02090
02091 ast_atomic_fetchadd_int(&faxregistry.fax_tx_attempts, 1);
02092
02093
02094
02095 if (!(details = find_or_create_details(chan))) {
02096 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02097 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
02098 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
02099 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
02100 return -1;
02101 }
02102
02103 ast_string_field_set(details, result, "FAILED");
02104 ast_string_field_set(details, resultstr, "error starting fax session");
02105 ast_string_field_set(details, error, "INIT_ERROR");
02106 set_channel_variables(chan, details);
02107
02108 if (details->maxrate < details->minrate) {
02109 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02110 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02111 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
02112 set_channel_variables(chan, details);
02113 ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", details->maxrate, details->minrate);
02114 ao2_ref(details, -1);
02115 return -1;
02116 }
02117
02118 if (check_modem_rate(details->modems, details->minrate)) {
02119 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02120 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
02121 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, details->minrate);
02122 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02123 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
02124 set_channel_variables(chan, details);
02125 ao2_ref(details, -1);
02126 return -1;
02127 }
02128
02129 if (check_modem_rate(details->modems, details->maxrate)) {
02130 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02131 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
02132 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, details->maxrate);
02133 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02134 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
02135 set_channel_variables(chan, details);
02136 ao2_ref(details, -1);
02137 return -1;
02138 }
02139
02140 if (ast_strlen_zero(data)) {
02141 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02142 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02143 ast_string_field_set(details, resultstr, "invalid arguments");
02144 set_channel_variables(chan, details);
02145 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]][,options])\n", app_sendfax);
02146 ao2_ref(details, -1);
02147 return -1;
02148 }
02149 parse = ast_strdupa(data);
02150 AST_STANDARD_APP_ARGS(args, parse);
02151
02152
02153 if (!ast_strlen_zero(args.options) &&
02154 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
02155 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02156 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02157 ast_string_field_set(details, resultstr, "invalid arguments");
02158 set_channel_variables(chan, details);
02159 ao2_ref(details, -1);
02160 return -1;
02161 }
02162 if (ast_strlen_zero(args.filenames)) {
02163 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02164 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02165 ast_string_field_set(details, resultstr, "invalid arguments");
02166 set_channel_variables(chan, details);
02167 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]],options])\n", app_sendfax);
02168 ao2_ref(details, -1);
02169 return -1;
02170 }
02171
02172
02173 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
02174 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02175 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02176 ast_string_field_set(details, resultstr, "invalid arguments");
02177 set_channel_variables(chan, details);
02178 ast_log(LOG_WARNING, "%s does not support polling\n", app_sendfax);
02179 ao2_ref(details, -1);
02180 return -1;
02181 }
02182
02183 file_count = 0;
02184 filenames = args.filenames;
02185 while ((c = strsep(&filenames, "&"))) {
02186 if (access(c, (F_OK | R_OK)) < 0) {
02187 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02188 ast_string_field_set(details, error, "FILE_ERROR");
02189 ast_string_field_set(details, resultstr, "error reading file");
02190 set_channel_variables(chan, details);
02191 ast_log(LOG_ERROR, "access failure. Verify '%s' exists and check permissions.\n", args.filenames);
02192 ao2_ref(details, -1);
02193 return -1;
02194 }
02195
02196 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(c) + 1))) {
02197 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02198 ast_string_field_set(details, error, "MEMORY_ERROR");
02199 ast_string_field_set(details, resultstr, "error allocating memory");
02200 set_channel_variables(chan, details);
02201 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
02202 ao2_ref(details, -1);
02203 return -1;
02204 }
02205
02206 strcpy(doc->filename, c);
02207 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
02208 file_count++;
02209 }
02210
02211 if (file_count > 1) {
02212 details->caps |= AST_FAX_TECH_MULTI_DOC;
02213 }
02214
02215 ast_verb(3, "Channel '%s' sending FAX:\n", chan->name);
02216 AST_LIST_TRAVERSE(&details->documents, doc, next) {
02217 ast_verb(3, " %s\n", doc->filename);
02218 }
02219
02220 details->caps = AST_FAX_TECH_SEND;
02221
02222
02223 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
02224 details->option.debug = AST_FAX_OPTFLAG_TRUE;
02225 }
02226
02227
02228 if (ast_test_flag(&opts, OPT_STATUS)) {
02229 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
02230 }
02231
02232 if ((ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE) ||
02233 ast_test_flag(&opts, OPT_ALLOWAUDIO)) {
02234 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
02235 }
02236
02237 if (ast_test_flag(&opts, OPT_REQUEST_T38)) {
02238 details->option.request_t38 = AST_FAX_OPTFLAG_TRUE;
02239 }
02240
02241 if (!(s = fax_session_reserve(details, &token))) {
02242 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02243 ast_string_field_set(details, resultstr, "error reserving fax session");
02244 set_channel_variables(chan, details);
02245 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
02246 ao2_ref(details, -1);
02247 return -1;
02248 }
02249
02250
02251 if (chan->_state != AST_STATE_UP) {
02252 if (ast_answer(chan)) {
02253 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02254 ast_string_field_set(details, resultstr, "error answering channel");
02255 set_channel_variables(chan, details);
02256 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
02257 fax_session_release(s, token);
02258 ao2_ref(s, -1);
02259 ao2_ref(details, -1);
02260 return -1;
02261 }
02262 }
02263
02264 if (set_fax_t38_caps(chan, details)) {
02265 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02266 ast_string_field_set(details, error, "T38_NEG_ERROR");
02267 ast_string_field_set(details, resultstr, "error negotiating T.38");
02268 set_channel_variables(chan, details);
02269 fax_session_release(s, token);
02270 ao2_ref(s, -1);
02271 ao2_ref(details, -1);
02272 return -1;
02273 }
02274
02275 if (details->caps & AST_FAX_TECH_T38) {
02276 if (sendfax_t38_init(chan, details)) {
02277 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02278 ast_string_field_set(details, error, "T38_NEG_ERROR");
02279 ast_string_field_set(details, resultstr, "error negotiating T.38");
02280 set_channel_variables(chan, details);
02281 fax_session_release(s, token);
02282 ao2_ref(s, -1);
02283 ao2_ref(details, -1);
02284 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
02285 return -1;
02286 }
02287 } else {
02288 details->option.send_cng = 1;
02289 }
02290
02291 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
02292 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02293 }
02294
02295 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02296 if (disable_t38(chan)) {
02297 ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
02298 }
02299 }
02300
02301 if (!(filenames = generate_filenames_string(details, "FileName: ", "\r\n"))) {
02302 ast_log(LOG_ERROR, "Error generating SendFAX manager event\n");
02303 ao2_ref(s, -1);
02304 ao2_ref(details, -1);
02305 return (!channel_alive) ? -1 : 0;
02306 }
02307
02308
02309 ast_channel_lock(chan);
02310 get_manager_event_info(chan, &info);
02311 manager_event(EVENT_FLAG_CALL,
02312 "SendFAX",
02313 "Channel: %s\r\n"
02314 "Context: %s\r\n"
02315 "Exten: %s\r\n"
02316 "CallerID: %s\r\n"
02317 "RemoteStationID: %s\r\n"
02318 "LocalStationID: %s\r\n"
02319 "PagesTransferred: %s\r\n"
02320 "Resolution: %s\r\n"
02321 "TransferRate: %s\r\n"
02322 "%s\r\n",
02323 chan->name,
02324 info.context,
02325 info.exten,
02326 info.cid,
02327 S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
02328 S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
02329 S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
02330 S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
02331 S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
02332 filenames);
02333 ast_channel_unlock(chan);
02334
02335 ast_free(filenames);
02336
02337 ao2_ref(s, -1);
02338 ao2_ref(details, -1);
02339
02340
02341 return (!channel_alive) ? -1 : 0;
02342 }
02343
02344
02345 static int session_hash_cb(const void *obj, const int flags)
02346 {
02347 const struct ast_fax_session *s = obj;
02348
02349 return s->id;
02350 }
02351
02352
02353 static int session_cmp_cb(void *obj, void *arg, int flags)
02354 {
02355 struct ast_fax_session *lhs = obj, *rhs = arg;
02356
02357 return (lhs->id == rhs->id) ? CMP_MATCH | CMP_STOP : 0;
02358 }
02359
02360
02361 static char *fax_session_tab_complete(struct ast_cli_args *a)
02362 {
02363 int tklen;
02364 int wordnum = 0;
02365 char *name = NULL;
02366 struct ao2_iterator i;
02367 struct ast_fax_session *s;
02368 char tbuf[5];
02369
02370 if (a->pos != 3) {
02371 return NULL;
02372 }
02373
02374 tklen = strlen(a->word);
02375 i = ao2_iterator_init(faxregistry.container, 0);
02376 while ((s = ao2_iterator_next(&i))) {
02377 snprintf(tbuf, sizeof(tbuf), "%u", s->id);
02378 if (!strncasecmp(a->word, tbuf, tklen) && ++wordnum > a->n) {
02379 name = ast_strdup(tbuf);
02380 ao2_ref(s, -1);
02381 break;
02382 }
02383 ao2_ref(s, -1);
02384 }
02385 ao2_iterator_destroy(&i);
02386 return name;
02387 }
02388
02389 static char *cli_fax_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02390 {
02391 struct fax_module *fax;
02392
02393 switch(cmd) {
02394 case CLI_INIT:
02395 e->command = "fax show version";
02396 e->usage =
02397 "Usage: fax show version\n"
02398 " Show versions of FAX For Asterisk components.\n";
02399 return NULL;
02400 case CLI_GENERATE:
02401 return NULL;
02402 }
02403
02404 if (a->argc != 3) {
02405 return CLI_SHOWUSAGE;
02406 }
02407
02408 ast_cli(a->fd, "FAX For Asterisk Components:\n");
02409 ast_cli(a->fd, "\tApplications: %s\n", ast_get_version());
02410 AST_RWLIST_RDLOCK(&faxmodules);
02411 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02412 ast_cli(a->fd, "\t%s: %s\n", fax->tech->description, fax->tech->version);
02413 }
02414 AST_RWLIST_UNLOCK(&faxmodules);
02415 ast_cli(a->fd, "\n");
02416
02417 return CLI_SUCCESS;
02418 }
02419
02420
02421 static char *cli_fax_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02422 {
02423 int flag;
02424 const char *what;
02425
02426 switch (cmd) {
02427 case CLI_INIT:
02428 e->command = "fax set debug {on|off}";
02429 e->usage =
02430 "Usage: fax set debug { on | off }\n"
02431 " Enable/Disable FAX debugging on new FAX sessions. The basic FAX debugging will result in\n"
02432 " additional events sent to manager sessions with 'call' class permissions. When\n"
02433 " verbosity is greater than '5' events will be displayed to the console and audio versus\n"
02434 " energy analysis will be performed and displayed to the console.\n";
02435 return NULL;
02436 case CLI_GENERATE:
02437 return NULL;
02438 }
02439
02440 what = a->argv[e->args-1];
02441 if (!strcasecmp(what, "on")) {
02442 flag = 1;
02443 } else if (!strcasecmp(what, "off")) {
02444 flag = 0;
02445 } else {
02446 return CLI_SHOWUSAGE;
02447 }
02448
02449 global_fax_debug = flag;
02450 ast_cli(a->fd, "\n\nFAX Debug %s\n\n", (flag) ? "Enabled" : "Disabled");
02451
02452 return CLI_SUCCESS;
02453 }
02454
02455
02456 static char *cli_fax_show_capabilities(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02457 {
02458 struct fax_module *fax;
02459 unsigned int num_modules = 0;
02460
02461 switch (cmd) {
02462 case CLI_INIT:
02463 e->command = "fax show capabilities";
02464 e->usage =
02465 "Usage: fax show capabilities\n"
02466 " Shows the capabilities of the registered FAX technology modules\n";
02467 return NULL;
02468 case CLI_GENERATE:
02469 return NULL;
02470 }
02471
02472 ast_cli(a->fd, "\n\nRegistered FAX Technology Modules:\n\n");
02473 AST_RWLIST_RDLOCK(&faxmodules);
02474 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02475 ast_cli(a->fd, "%-15s : %s\n%-15s : %s\n%-15s : ", "Type", fax->tech->type, "Description", fax->tech->description, "Capabilities");
02476 fax->tech->cli_show_capabilities(a->fd);
02477 num_modules++;
02478 }
02479 AST_RWLIST_UNLOCK(&faxmodules);
02480 ast_cli(a->fd, "%u registered modules\n\n", num_modules);
02481
02482 return CLI_SUCCESS;
02483 }
02484
02485
02486 static char *cli_fax_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02487 {
02488 struct fax_module *fax;
02489 char modems[128] = "";
02490 struct fax_options options;
02491
02492 switch (cmd) {
02493 case CLI_INIT:
02494 e->command = "fax show settings";
02495 e->usage =
02496 "Usage: fax show settings\n"
02497 " Show the global settings and defaults of both the FAX core and technology modules\n";
02498 return NULL;
02499 case CLI_GENERATE:
02500 return NULL;
02501 }
02502
02503 get_general_options(&options);
02504
02505 ast_cli(a->fd, "FAX For Asterisk Settings:\n");
02506 ast_cli(a->fd, "\tECM: %s\n", options.ecm ? "Enabled" : "Disabled");
02507 ast_cli(a->fd, "\tStatus Events: %s\n", options.statusevents ? "On" : "Off");
02508 ast_cli(a->fd, "\tMinimum Bit Rate: %u\n", options.minrate);
02509 ast_cli(a->fd, "\tMaximum Bit Rate: %u\n", options.maxrate);
02510 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02511 ast_cli(a->fd, "\tModem Modulations Allowed: %s\n", modems);
02512 ast_cli(a->fd, "\n\nFAX Technology Modules:\n\n");
02513 AST_RWLIST_RDLOCK(&faxmodules);
02514 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02515 ast_cli(a->fd, "%s (%s) Settings:\n", fax->tech->type, fax->tech->description);
02516 fax->tech->cli_show_settings(a->fd);
02517 }
02518 AST_RWLIST_UNLOCK(&faxmodules);
02519
02520 return CLI_SUCCESS;
02521 }
02522
02523
02524 static char *cli_fax_show_session(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02525 {
02526 struct ast_fax_session *s, tmp;
02527
02528 switch (cmd) {
02529 case CLI_INIT:
02530 e->command = "fax show session";
02531 e->usage =
02532 "Usage: fax show session <session number>\n"
02533 " Shows status of the named FAX session\n";
02534 return NULL;
02535 case CLI_GENERATE:
02536 return fax_session_tab_complete(a);
02537 }
02538
02539 if (a->argc != 4) {
02540 return CLI_SHOWUSAGE;
02541 }
02542
02543 if (sscanf(a->argv[3], "%u", &tmp.id) != 1) {
02544 ast_log(LOG_ERROR, "invalid session id: '%s'\n", a->argv[3]);
02545 return RESULT_SUCCESS;
02546 }
02547
02548 ast_cli(a->fd, "\nFAX Session Details:\n--------------------\n\n");
02549 s = ao2_find(faxregistry.container, &tmp, OBJ_POINTER);
02550 if (s) {
02551 s->tech->cli_show_session(s, a->fd);
02552 ao2_ref(s, -1);
02553 }
02554 ast_cli(a->fd, "\n\n");
02555
02556 return CLI_SUCCESS;
02557 }
02558
02559
02560 static char *cli_fax_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02561 {
02562 struct fax_module *fax;
02563
02564 switch (cmd) {
02565 case CLI_INIT:
02566 e->command = "fax show stats";
02567 e->usage =
02568 "Usage: fax show stats\n"
02569 " Shows a statistical summary of FAX transmissions\n";
02570 return NULL;
02571 case CLI_GENERATE:
02572 return NULL;
02573 }
02574
02575 ast_cli(a->fd, "\nFAX Statistics:\n---------------\n\n");
02576 ast_cli(a->fd, "%-20.20s : %d\n", "Current Sessions", faxregistry.active_sessions);
02577 ast_cli(a->fd, "%-20.20s : %d\n", "Reserved Sessions", faxregistry.reserved_sessions);
02578 ast_cli(a->fd, "%-20.20s : %d\n", "Transmit Attempts", faxregistry.fax_tx_attempts);
02579 ast_cli(a->fd, "%-20.20s : %d\n", "Receive Attempts", faxregistry.fax_rx_attempts);
02580 ast_cli(a->fd, "%-20.20s : %d\n", "Completed FAXes", faxregistry.fax_complete);
02581 ast_cli(a->fd, "%-20.20s : %d\n", "Failed FAXes", faxregistry.fax_failures);
02582 AST_RWLIST_RDLOCK(&faxmodules);
02583 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02584 fax->tech->cli_show_stats(a->fd);
02585 }
02586 AST_RWLIST_UNLOCK(&faxmodules);
02587 ast_cli(a->fd, "\n\n");
02588
02589 return CLI_SUCCESS;
02590 }
02591
02592
02593 static char *cli_fax_show_sessions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02594 {
02595 struct ast_fax_session *s;
02596 struct ao2_iterator i;
02597 int session_count;
02598 char *filenames;
02599
02600 switch (cmd) {
02601 case CLI_INIT:
02602 e->command = "fax show sessions";
02603 e->usage =
02604 "Usage: fax show sessions\n"
02605 " Shows the current FAX sessions\n";
02606 return NULL;
02607 case CLI_GENERATE:
02608 return NULL;
02609 }
02610
02611 ast_cli(a->fd, "\nCurrent FAX Sessions:\n\n");
02612 ast_cli(a->fd, "%-20.20s %-10.10s %-10.10s %-5.5s %-10.10s %-15.15s %-30.30s\n",
02613 "Channel", "Tech", "FAXID", "Type", "Operation", "State", "File(s)");
02614 i = ao2_iterator_init(faxregistry.container, 0);
02615 while ((s = ao2_iterator_next(&i))) {
02616 ao2_lock(s);
02617
02618 if (!(filenames = generate_filenames_string(s->details, "", ", "))) {
02619 ast_log(LOG_ERROR, "Error printing filenames for 'fax show sessions' command\n");
02620 ao2_unlock(s);
02621 ao2_ref(s, -1);
02622 ao2_iterator_destroy(&i);
02623 return CLI_FAILURE;
02624 }
02625
02626 ast_cli(a->fd, "%-20.20s %-10.10s %-10u %-5.5s %-10.10s %-15.15s %-30s\n",
02627 s->channame, s->tech->type, s->id,
02628 (s->details->caps & AST_FAX_TECH_AUDIO) ? "G.711" : "T.38",
02629 (s->details->caps & AST_FAX_TECH_SEND) ? "send" : "receive",
02630 ast_fax_state_to_str(s->state), filenames);
02631
02632 ast_free(filenames);
02633 ao2_unlock(s);
02634 ao2_ref(s, -1);
02635 }
02636 ao2_iterator_destroy(&i);
02637 session_count = ao2_container_count(faxregistry.container);
02638 ast_cli(a->fd, "\n%d FAX sessions\n\n", session_count);
02639
02640 return CLI_SUCCESS;
02641 }
02642
02643 static struct ast_cli_entry fax_cli[] = {
02644 AST_CLI_DEFINE(cli_fax_show_version, "Show versions of FAX For Asterisk components"),
02645 AST_CLI_DEFINE(cli_fax_set_debug, "Enable/Disable FAX debugging on new FAX sessions"),
02646 AST_CLI_DEFINE(cli_fax_show_capabilities, "Show the capabilities of the registered FAX technology modules"),
02647 AST_CLI_DEFINE(cli_fax_show_settings, "Show the global settings and defaults of both the FAX core and technology modules"),
02648 AST_CLI_DEFINE(cli_fax_show_session, "Show the status of the named FAX sessions"),
02649 AST_CLI_DEFINE(cli_fax_show_sessions, "Show the current FAX sessions"),
02650 AST_CLI_DEFINE(cli_fax_show_stats, "Summarize FAX session history"),
02651 };
02652
02653 static void set_general_options(const struct fax_options *options)
02654 {
02655 ast_rwlock_wrlock(&options_lock);
02656 general_options = *options;
02657 ast_rwlock_unlock(&options_lock);
02658 }
02659
02660 static void get_general_options(struct fax_options *options)
02661 {
02662 ast_rwlock_rdlock(&options_lock);
02663 *options = general_options;
02664 ast_rwlock_unlock(&options_lock);
02665 }
02666
02667
02668 static int set_config(int reload)
02669 {
02670 struct ast_config *cfg;
02671 struct ast_variable *v;
02672 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
02673 char modems[128] = "";
02674 struct fax_options options;
02675 int res = 0;
02676
02677 options = default_options;
02678
02679
02680
02681
02682
02683
02684 if (!reload) {
02685 set_general_options(&options);
02686 }
02687
02688
02689 if (!(cfg = ast_config_load2(config, "res_fax", config_flags))) {
02690 ast_log(LOG_NOTICE, "Configuration file '%s' not found, %s options.\n",
02691 config, reload ? "not changing" : "using default");
02692 return 0;
02693 }
02694
02695 if (cfg == CONFIG_STATUS_FILEINVALID) {
02696 ast_log(LOG_NOTICE, "Configuration file '%s' is invalid, %s options.\n",
02697 config, reload ? "not changing" : "using default");
02698 return 0;
02699 }
02700
02701 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
02702 return 0;
02703 }
02704
02705 if (reload) {
02706 options = default_options;
02707 }
02708
02709
02710 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
02711 int rate;
02712
02713 if (!strcasecmp(v->name, "minrate")) {
02714 ast_debug(3, "reading minrate '%s' from configuration file\n", v->value);
02715 if ((rate = fax_rate_str_to_int(v->value)) == 0) {
02716 res = -1;
02717 goto end;
02718 }
02719 options.minrate = rate;
02720 } else if (!strcasecmp(v->name, "maxrate")) {
02721 ast_debug(3, "reading maxrate '%s' from configuration file\n", v->value);
02722 if ((rate = fax_rate_str_to_int(v->value)) == 0) {
02723 res = -1;
02724 goto end;
02725 }
02726 options.maxrate = rate;
02727 } else if (!strcasecmp(v->name, "statusevents")) {
02728 ast_debug(3, "reading statusevents '%s' from configuration file\n", v->value);
02729 options.statusevents = ast_true(v->value);
02730 } else if (!strcasecmp(v->name, "ecm")) {
02731 ast_debug(3, "reading ecm '%s' from configuration file\n", v->value);
02732 options.ecm = ast_true(v->value);
02733 } else if ((!strcasecmp(v->name, "modem")) || (!strcasecmp(v->name, "modems"))) {
02734 options.modems = 0;
02735 update_modem_bits(&options.modems, v->value);
02736 }
02737 }
02738
02739 if (options.maxrate < options.minrate) {
02740 ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", options.maxrate, options.minrate);
02741 res = -1;
02742 goto end;
02743 }
02744
02745 if (options.minrate == 2400 && (options.modems & AST_FAX_MODEM_V27) && !(options.modems & (AST_FAX_MODEM_V34))) {
02746 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02747 ast_log(LOG_WARNING, "'modems' setting '%s' is no longer accepted with 'minrate' setting %u\n", modems, options.minrate);
02748 ast_log(LOG_WARNING, "'minrate' has been reset to 4800, please update res_fax.conf.\n");
02749 options.minrate = 4800;
02750 }
02751
02752 if (check_modem_rate(options.modems, options.minrate)) {
02753 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02754 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, options.minrate);
02755 res = -1;
02756 goto end;
02757 }
02758
02759 if (check_modem_rate(options.modems, options.maxrate)) {
02760 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02761 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, options.maxrate);
02762 res = -1;
02763 goto end;
02764 }
02765
02766 set_general_options(&options);
02767
02768 end:
02769 ast_config_destroy(cfg);
02770 return res;
02771 }
02772
02773
02774 static int acf_faxopt_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
02775 {
02776 struct ast_fax_session_details *details = find_details(chan);
02777 int res = 0;
02778 char *filenames;
02779
02780 if (!details) {
02781 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", chan->name, data);
02782 return -1;
02783 }
02784 if (!strcasecmp(data, "ecm")) {
02785 ast_copy_string(buf, details->option.ecm ? "yes" : "no", len);
02786 } else if (!strcasecmp(data, "error")) {
02787 ast_copy_string(buf, details->error, len);
02788 } else if (!strcasecmp(data, "filename")) {
02789 if (AST_LIST_EMPTY(&details->documents)) {
02790 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", chan->name, data);
02791 res = -1;
02792 } else {
02793 ast_copy_string(buf, AST_LIST_FIRST(&details->documents)->filename, len);
02794 }
02795 } else if (!strcasecmp(data, "filenames")) {
02796 if (AST_LIST_EMPTY(&details->documents)) {
02797 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", chan->name, data);
02798 res = -1;
02799 } else if ((filenames = generate_filenames_string(details, "", ","))) {
02800 ast_copy_string(buf, filenames, len);
02801 ast_free(filenames);
02802 } else {
02803 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s), there was an error generating the filenames list.\n", chan->name, data);
02804 res = -1;
02805 }
02806 } else if (!strcasecmp(data, "headerinfo")) {
02807 ast_copy_string(buf, details->headerinfo, len);
02808 } else if (!strcasecmp(data, "localstationid")) {
02809 ast_copy_string(buf, details->localstationid, len);
02810 } else if (!strcasecmp(data, "maxrate")) {
02811 snprintf(buf, len, "%u", details->maxrate);
02812 } else if (!strcasecmp(data, "minrate")) {
02813 snprintf(buf, len, "%u", details->minrate);
02814 } else if (!strcasecmp(data, "pages")) {
02815 snprintf(buf, len, "%u", details->pages_transferred);
02816 } else if (!strcasecmp(data, "rate")) {
02817 ast_copy_string(buf, details->transfer_rate, len);
02818 } else if (!strcasecmp(data, "remotestationid")) {
02819 ast_copy_string(buf, details->remotestationid, len);
02820 } else if (!strcasecmp(data, "resolution")) {
02821 ast_copy_string(buf, details->resolution, len);
02822 } else if (!strcasecmp(data, "sessionid")) {
02823 snprintf(buf, len, "%u", details->id);
02824 } else if (!strcasecmp(data, "status")) {
02825 ast_copy_string(buf, details->result, len);
02826 } else if (!strcasecmp(data, "statusstr")) {
02827 ast_copy_string(buf, details->resultstr, len);
02828 } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
02829 ast_fax_modem_to_str(details->modems, buf, len);
02830 } else {
02831 ast_log(LOG_WARNING, "channel '%s' can't read FAXOPT(%s) because it is unhandled!\n", chan->name, data);
02832 res = -1;
02833 }
02834 ao2_ref(details, -1);
02835
02836 return res;
02837 }
02838
02839
02840 static int acf_faxopt_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
02841 {
02842 int res = 0;
02843 struct ast_fax_session_details *details;
02844
02845 if (!(details = find_or_create_details(chan))) {
02846 ast_log(LOG_WARNING, "channel '%s' can't set FAXOPT(%s) to '%s' because it failed to create a datastore.\n", chan->name, data, value);
02847 return -1;
02848 }
02849 ast_debug(3, "channel '%s' setting FAXOPT(%s) to '%s'\n", chan->name, data, value);
02850
02851 if (!strcasecmp(data, "ecm")) {
02852 const char *val = ast_skip_blanks(value);
02853 if (ast_true(val)) {
02854 details->option.ecm = AST_FAX_OPTFLAG_TRUE;
02855 } else if (ast_false(val)) {
02856 details->option.ecm = AST_FAX_OPTFLAG_FALSE;
02857 } else {
02858 ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(ecm).\n", value);
02859 }
02860 } else if (!strcasecmp(data, "headerinfo")) {
02861 ast_string_field_set(details, headerinfo, value);
02862 } else if (!strcasecmp(data, "localstationid")) {
02863 ast_string_field_set(details, localstationid, value);
02864 } else if (!strcasecmp(data, "maxrate")) {
02865 details->maxrate = fax_rate_str_to_int(value);
02866 if (!details->maxrate) {
02867 details->maxrate = ast_fax_maxrate();
02868 }
02869 } else if (!strcasecmp(data, "minrate")) {
02870 details->minrate = fax_rate_str_to_int(value);
02871 if (!details->minrate) {
02872 details->minrate = ast_fax_minrate();
02873 }
02874 } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
02875 update_modem_bits(&details->modems, value);
02876 } else {
02877 ast_log(LOG_WARNING, "channel '%s' set FAXOPT(%s) to '%s' is unhandled!\n", chan->name, data, value);
02878 res = -1;
02879 }
02880
02881 ao2_ref(details, -1);
02882
02883 return res;
02884 }
02885
02886
02887 struct ast_custom_function acf_faxopt = {
02888 .name = "FAXOPT",
02889 .read = acf_faxopt_read,
02890 .write = acf_faxopt_write,
02891 };
02892
02893
02894 static int unload_module(void)
02895 {
02896 ast_cli_unregister_multiple(fax_cli, ARRAY_LEN(fax_cli));
02897
02898 if (ast_custom_function_unregister(&acf_faxopt) < 0) {
02899 ast_log(LOG_WARNING, "failed to unregister function '%s'\n", acf_faxopt.name);
02900 }
02901
02902 if (ast_unregister_application(app_sendfax) < 0) {
02903 ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_sendfax);
02904 }
02905
02906 if (ast_unregister_application(app_receivefax) < 0) {
02907 ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_receivefax);
02908 }
02909
02910 if (fax_logger_level != -1) {
02911 ast_logger_unregister_level("FAX");
02912 }
02913
02914 ao2_ref(faxregistry.container, -1);
02915
02916 return 0;
02917 }
02918
02919
02920 static int load_module(void)
02921 {
02922 int res;
02923
02924
02925 faxregistry.active_sessions = 0;
02926 faxregistry.reserved_sessions = 0;
02927 if (!(faxregistry.container = ao2_container_alloc(FAX_MAXBUCKETS, session_hash_cb, session_cmp_cb))) {
02928 return AST_MODULE_LOAD_DECLINE;
02929 }
02930
02931 if (set_config(0) < 0) {
02932 ast_log(LOG_ERROR, "failed to load configuration file '%s'\n", config);
02933 ao2_ref(faxregistry.container, -1);
02934 return AST_MODULE_LOAD_DECLINE;
02935 }
02936
02937
02938 if (ast_register_application_xml(app_sendfax, sendfax_exec) < 0) {
02939 ast_log(LOG_WARNING, "failed to register '%s'.\n", app_sendfax);
02940 ao2_ref(faxregistry.container, -1);
02941 return AST_MODULE_LOAD_DECLINE;
02942 }
02943 if (ast_register_application_xml(app_receivefax, receivefax_exec) < 0) {
02944 ast_log(LOG_WARNING, "failed to register '%s'.\n", app_receivefax);
02945 ast_unregister_application(app_sendfax);
02946 ao2_ref(faxregistry.container, -1);
02947 return AST_MODULE_LOAD_DECLINE;
02948 }
02949 ast_cli_register_multiple(fax_cli, ARRAY_LEN(fax_cli));
02950 res = ast_custom_function_register(&acf_faxopt);
02951 fax_logger_level = ast_logger_register_level("FAX");
02952
02953 return res;
02954 }
02955
02956 static int reload_module(void)
02957 {
02958 set_config(1);
02959 return 0;
02960 }
02961
02962
02963 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Generic FAX Applications",
02964 .load = load_module,
02965 .unload = unload_module,
02966 .reload = reload_module,
02967 .load_pri = AST_MODPRI_APP_DEPEND,
02968 );