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: 409052 $")
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 '%d', [ %.3ld.%.6ld ], %s sent %d frames (%d 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 < 5)) {
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: %d\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 s->tech = faxmod->tech;
00877 break;
00878 }
00879 AST_RWLIST_UNLOCK(&faxmodules);
00880
00881 if (!faxmod) {
00882 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)));
00883 ao2_ref(s, -1);
00884 return NULL;
00885 }
00886 }
00887
00888 if (!(s->tech_pvt = s->tech->new_session(s, token))) {
00889 ast_log(LOG_ERROR, "FAX session failed to initialize.\n");
00890 ao2_ref(s, -1);
00891 return NULL;
00892 }
00893
00894 if (!(ao2_link(faxregistry.container, s))) {
00895 ast_log(LOG_ERROR, "failed to add FAX session '%d' to container.\n", s->id);
00896 ao2_ref(s, -1);
00897 return NULL;
00898 }
00899 ast_debug(4, "channel '%s' using FAX session '%d'\n", s->channame, s->id);
00900
00901 return s;
00902 }
00903
00904 static void get_manager_event_info(struct ast_channel *chan, struct manager_event_info *info)
00905 {
00906 pbx_substitute_variables_helper(chan, "${CONTEXT}", info->context, sizeof(info->context));
00907 pbx_substitute_variables_helper(chan, "${EXTEN}", info->exten, sizeof(info->exten));
00908 pbx_substitute_variables_helper(chan, "${CALLERID(num)}", info->cid, sizeof(info->cid));
00909 }
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923 static char *generate_filenames_string(struct ast_fax_session_details *details, char *prefix, char *separator)
00924 {
00925 char *filenames, *c;
00926 size_t size = 0;
00927 int first = 1;
00928 struct ast_fax_document *doc;
00929
00930
00931 if (AST_LIST_EMPTY(&details->documents)) {
00932 return NULL;
00933 }
00934
00935
00936 AST_LIST_TRAVERSE(&details->documents, doc, next) {
00937 size += strlen(separator) + strlen(prefix) + strlen(doc->filename);
00938 }
00939 size += 1;
00940
00941 if (!(filenames = ast_malloc(size))) {
00942 return NULL;
00943 }
00944 c = filenames;
00945
00946 ast_build_string(&c, &size, "%s%s", prefix, AST_LIST_FIRST(&details->documents)->filename);
00947 AST_LIST_TRAVERSE(&details->documents, doc, next) {
00948 if (first) {
00949 first = 0;
00950 continue;
00951 }
00952
00953 ast_build_string(&c, &size, "%s%s%s", separator, prefix, doc->filename);
00954 }
00955
00956 return filenames;
00957 }
00958
00959
00960 static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details, const char *status)
00961 {
00962 char *filenames = generate_filenames_string(details, "FileName: ", "\r\n");
00963 if (!filenames) {
00964 return 1;
00965 }
00966
00967 ast_channel_lock(chan);
00968 if (details->option.statusevents) {
00969 struct manager_event_info info;
00970
00971 get_manager_event_info(chan, &info);
00972 manager_event(EVENT_FLAG_CALL,
00973 (details->caps & AST_FAX_TECH_RECEIVE) ? "ReceiveFAXStatus" : "SendFAXStatus",
00974 "Status: %s\r\n"
00975 "Channel: %s\r\n"
00976 "Context: %s\r\n"
00977 "Exten: %s\r\n"
00978 "CallerID: %s\r\n"
00979 "LocalStationID: %s\r\n"
00980 "%s\r\n",
00981 status,
00982 chan->name,
00983 info.context,
00984 info.exten,
00985 info.cid,
00986 details->localstationid,
00987 filenames);
00988 }
00989 ast_channel_unlock(chan);
00990 ast_free(filenames);
00991
00992 return 0;
00993 }
00994
00995
00996 static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
00997 {
00998 char buf[10];
00999 pbx_builtin_setvar_helper(chan, "FAXSTATUS", S_OR(details->result, NULL));
01000 pbx_builtin_setvar_helper(chan, "FAXERROR", S_OR(details->error, NULL));
01001 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", S_OR(details->resultstr, NULL));
01002 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", S_OR(details->remotestationid, NULL));
01003 pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", S_OR(details->localstationid, NULL));
01004 pbx_builtin_setvar_helper(chan, "FAXBITRATE", S_OR(details->transfer_rate, NULL));
01005 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", S_OR(details->resolution, NULL));
01006
01007 snprintf(buf, sizeof(buf), "%d", details->pages_transferred);
01008 pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
01009 }
01010
01011 #define GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason) \
01012 do { \
01013 if (ast_strlen_zero(fax->details->result)) \
01014 ast_string_field_set(fax->details, result, "FAILED"); \
01015 if (ast_strlen_zero(fax->details->resultstr)) \
01016 ast_string_field_set(fax->details, resultstr, reason); \
01017 if (ast_strlen_zero(fax->details->error)) \
01018 ast_string_field_set(fax->details, error, errorstr); \
01019 set_channel_variables(chan, fax->details); \
01020 } while (0)
01021
01022 #define GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason) \
01023 do { \
01024 GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason); \
01025 } while (0)
01026
01027 #define GENERIC_FAX_EXEC_ERROR(fax, chan, errorstr, reason) \
01028 do { \
01029 ast_log(LOG_ERROR, "channel '%s' FAX session '%d' failure, reason: '%s' (%s)\n", chan->name, fax->id, reason, errorstr); \
01030 GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason); \
01031 } while (0)
01032
01033 static void t38_parameters_ast_to_fax(struct ast_fax_t38_parameters *dst, const struct ast_control_t38_parameters *src)
01034 {
01035 dst->version = src->version;
01036 dst->max_ifp = src->max_ifp;
01037 dst->rate = src->rate;
01038 dst->rate_management = src->rate_management;
01039 dst->fill_bit_removal = src->fill_bit_removal;
01040 dst->transcoding_mmr = src->transcoding_mmr;
01041 dst->transcoding_jbig = src->transcoding_jbig;
01042 }
01043
01044 static void t38_parameters_fax_to_ast(struct ast_control_t38_parameters *dst, const struct ast_fax_t38_parameters *src)
01045 {
01046 dst->version = src->version;
01047 dst->max_ifp = src->max_ifp;
01048 dst->rate = src->rate;
01049 dst->rate_management = src->rate_management;
01050 dst->fill_bit_removal = src->fill_bit_removal;
01051 dst->transcoding_mmr = src->transcoding_mmr;
01052 dst->transcoding_jbig = src->transcoding_jbig;
01053 }
01054
01055 static int set_fax_t38_caps(struct ast_channel *chan, struct ast_fax_session_details *details)
01056 {
01057 switch (ast_channel_get_t38_state(chan)) {
01058 case T38_STATE_UNKNOWN:
01059 details->caps |= AST_FAX_TECH_T38;
01060 break;
01061 case T38_STATE_UNAVAILABLE:
01062 details->caps |= AST_FAX_TECH_AUDIO;
01063 break;
01064 case T38_STATE_NEGOTIATING: {
01065
01066
01067
01068
01069
01070
01071
01072 struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_PARMS, };
01073 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)) != AST_T38_REQUEST_PARMS) {
01074 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", chan->name);
01075 return -1;
01076 }
01077 details->caps |= AST_FAX_TECH_T38;
01078 break;
01079 }
01080 default:
01081 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", chan->name);
01082 return -1;
01083 }
01084
01085 return 0;
01086 }
01087
01088 static int disable_t38(struct ast_channel *chan)
01089 {
01090 int timeout_ms;
01091 struct ast_frame *frame = NULL;
01092 struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
01093 struct timeval start;
01094 int ms;
01095
01096 ast_debug(1, "Shutting down T.38 on %s\n", chan->name);
01097 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0) {
01098 ast_debug(1, "error while disabling T.38 on channel '%s'\n", chan->name);
01099 return -1;
01100 }
01101
01102
01103 timeout_ms = 5000;
01104 start = ast_tvnow();
01105 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01106 ms = ast_waitfor(chan, ms);
01107
01108 if (ms == 0) {
01109 break;
01110 }
01111 if (ms < 0) {
01112 ast_debug(1, "error while disabling T.38 on channel '%s'\n", chan->name);
01113 return -1;
01114 }
01115
01116 if (!(frame = ast_read(chan))) {
01117 return -1;
01118 }
01119 if ((frame->frametype == AST_FRAME_CONTROL) &&
01120 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01121 (frame->datalen == sizeof(t38_parameters))) {
01122 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01123
01124 switch (parameters->request_response) {
01125 case AST_T38_TERMINATED:
01126 ast_debug(1, "Shut down T.38 on %s\n", chan->name);
01127 break;
01128 case AST_T38_REFUSED:
01129 ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", chan->name);
01130 ast_frfree(frame);
01131 return -1;
01132 default:
01133 ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", chan->name);
01134 ast_frfree(frame);
01135 return -1;
01136 }
01137 ast_frfree(frame);
01138 break;
01139 }
01140 ast_frfree(frame);
01141 }
01142
01143 if (ms == 0) {
01144 ast_debug(1, "channel '%s' timed-out during T.38 shutdown\n", chan->name);
01145 }
01146
01147 return 0;
01148 }
01149
01150 static struct ast_control_t38_parameters our_t38_parameters = {
01151 .version = 0,
01152 .max_ifp = 400,
01153 .rate = AST_T38_RATE_14400,
01154 .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
01155 };
01156
01157
01158 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)
01159 {
01160 int ms;
01161 int timeout = RES_FAX_TIMEOUT;
01162 int chancount;
01163 unsigned int expected_frametype = -1;
01164 union ast_frame_subclass expected_framesubclass = { .integer = -1 };
01165 unsigned int t38negotiated = (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED);
01166 struct ast_control_t38_parameters t38_parameters;
01167 const char *tempvar;
01168 struct ast_fax_session *fax = NULL;
01169 struct ast_frame *frame = NULL;
01170 struct ast_channel *c = chan;
01171 unsigned int orig_write_format = 0, orig_read_format = 0;
01172 int remaining_time;
01173 struct timeval start;
01174
01175 chancount = 1;
01176
01177
01178 if (!(fax = fax_session_new(details, chan, reserved, token))) {
01179 ast_log(LOG_ERROR, "Can't create a FAX session, FAX attempt failed.\n");
01180 report_fax_status(chan, details, "No Available Resource");
01181 return -1;
01182 }
01183
01184 ast_channel_lock(chan);
01185
01186 if (ast_strlen_zero(details->headerinfo) && (tempvar = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO"))) {
01187 ast_string_field_set(details, headerinfo, tempvar);
01188 }
01189 if (ast_strlen_zero(details->localstationid)) {
01190 tempvar = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
01191 ast_string_field_set(details, localstationid, tempvar ? tempvar : "unknown");
01192 }
01193 ast_channel_unlock(chan);
01194
01195 report_fax_status(chan, details, "Allocating Resources");
01196
01197 if (details->caps & AST_FAX_TECH_AUDIO) {
01198 expected_frametype = AST_FRAME_VOICE;;
01199 expected_framesubclass.codec = AST_FORMAT_SLINEAR;
01200 orig_write_format = chan->writeformat;
01201 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
01202 ast_log(LOG_ERROR, "channel '%s' failed to set write format to signed linear'.\n", chan->name);
01203 ao2_lock(faxregistry.container);
01204 ao2_unlink(faxregistry.container, fax);
01205 ao2_unlock(faxregistry.container);
01206 ao2_ref(fax, -1);
01207 ast_channel_unlock(chan);
01208 return -1;
01209 }
01210 orig_read_format = chan->readformat;
01211 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
01212 ast_log(LOG_ERROR, "channel '%s' failed to set read format to signed linear.\n", chan->name);
01213 ao2_lock(faxregistry.container);
01214 ao2_unlink(faxregistry.container, fax);
01215 ao2_unlock(faxregistry.container);
01216 ao2_ref(fax, -1);
01217 ast_channel_unlock(chan);
01218 return -1;
01219 }
01220 if (fax->smoother) {
01221 ast_smoother_free(fax->smoother);
01222 fax->smoother = NULL;
01223 }
01224 if (!(fax->smoother = ast_smoother_new(320))) {
01225 ast_log(LOG_WARNING, "Channel '%s' FAX session '%d' failed to obtain a smoother.\n", chan->name, fax->id);
01226 }
01227 } else {
01228 expected_frametype = AST_FRAME_MODEM;
01229 expected_framesubclass.codec = AST_MODEM_T38;
01230 }
01231
01232 if (fax->debug_info) {
01233 fax->debug_info->base_tv = ast_tvnow();
01234 }
01235
01236
01237
01238 ast_string_field_set(details, result, "");
01239 ast_string_field_set(details, resultstr, "");
01240 ast_string_field_set(details, error, "");
01241 set_channel_variables(chan, details);
01242
01243 if (fax->tech->start_session(fax) < 0) {
01244 GENERIC_FAX_EXEC_ERROR(fax, chan, "INIT_ERROR", "failed to start FAX session");
01245 }
01246
01247 report_fax_status(chan, details, "FAX Transmission In Progress");
01248
01249 ast_debug(5, "channel %s will wait on FAX fd %d\n", chan->name, fax->fd);
01250
01251
01252 remaining_time = timeout;
01253 start = ast_tvnow();
01254 while (remaining_time > 0) {
01255 struct ast_channel *ready_chan;
01256 int ofd, exception;
01257
01258 ms = 1000;
01259 errno = 0;
01260 ready_chan = ast_waitfor_nandfds(&c, chancount, &fax->fd, 1, &exception, &ofd, &ms);
01261 if (ready_chan) {
01262 if (!(frame = ast_read(chan))) {
01263
01264
01265
01266
01267 ast_debug(1, "Channel '%s' did not return a frame; probably hung up.\n", chan->name);
01268 GENERIC_FAX_EXEC_SET_VARS(fax, chan, "HANGUP", "remote channel hungup");
01269 c = NULL;
01270 chancount = 0;
01271 remaining_time = ast_remaining_ms(start, timeout);
01272 fax->tech->cancel_session(fax);
01273 if (fax->tech->generate_silence) {
01274 fax->tech->generate_silence(fax);
01275 }
01276 continue;
01277 }
01278
01279 if ((frame->frametype == AST_FRAME_CONTROL) &&
01280 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01281 (frame->datalen == sizeof(t38_parameters))) {
01282 unsigned int was_t38 = t38negotiated;
01283 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01284
01285 switch (parameters->request_response) {
01286 case AST_T38_REQUEST_NEGOTIATE:
01287
01288
01289
01290 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01291 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01292 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01293 break;
01294 case AST_T38_NEGOTIATED:
01295 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01296 t38negotiated = 1;
01297 break;
01298 default:
01299 break;
01300 }
01301 if (t38negotiated && !was_t38) {
01302 fax->tech->switch_to_t38(fax);
01303 details->caps &= ~AST_FAX_TECH_AUDIO;
01304 expected_frametype = AST_FRAME_MODEM;
01305 expected_framesubclass.codec = AST_MODEM_T38;
01306 if (fax->smoother) {
01307 ast_smoother_free(fax->smoother);
01308 fax->smoother = NULL;
01309 }
01310
01311 report_fax_status(chan, details, "T.38 Negotiated");
01312
01313 ast_verb(3, "Channel '%s' switched to T.38 FAX session '%d'.\n", chan->name, fax->id);
01314 }
01315 } else if ((frame->frametype == expected_frametype) &&
01316 (!memcmp(&frame->subclass, &expected_framesubclass, sizeof(frame->subclass)))) {
01317 struct ast_frame *f;
01318
01319 if (fax->smoother) {
01320
01321 if (ast_smoother_feed(fax->smoother, frame) < 0) {
01322 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "Failed to feed the smoother");
01323 }
01324 while ((f = ast_smoother_read(fax->smoother)) && (f->data.ptr)) {
01325 if (fax->debug_info) {
01326 debug_check_frame_for_silence(fax, 1, f);
01327 }
01328
01329 fax->tech->write(fax, f);
01330 fax->frames_received++;
01331 if (f != frame) {
01332 ast_frfree(f);
01333 }
01334 }
01335 } else {
01336
01337 fax->tech->write(fax, frame);
01338 fax->frames_received++;
01339 }
01340 start = ast_tvnow();
01341 }
01342 ast_frfree(frame);
01343 } else if (ofd == fax->fd) {
01344
01345
01346 if (!(frame = fax->tech->read(fax))) {
01347 break;
01348 }
01349
01350 if (fax->debug_info && (frame->frametype == AST_FRAME_VOICE)) {
01351 debug_check_frame_for_silence(fax, 0, frame);
01352 }
01353
01354 ast_write(chan, frame);
01355 fax->frames_sent++;
01356 ast_frfree(frame);
01357 start = ast_tvnow();
01358 } else {
01359 if (ms && (ofd < 0)) {
01360 if ((errno == 0) || (errno == EINTR)) {
01361 remaining_time = ast_remaining_ms(start, timeout);
01362 if (remaining_time <= 0)
01363 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
01364 continue;
01365 } else {
01366 ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", chan->name);
01367 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "error polling data");
01368 break;
01369 }
01370 } else {
01371
01372 remaining_time = ast_remaining_ms(start, timeout);
01373 if (remaining_time <= 0) {
01374 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
01375 break;
01376 }
01377 }
01378 }
01379 }
01380 ast_debug(3, "channel '%s' - event loop stopped { timeout: %d, remaining_time: %d }\n", chan->name, timeout, remaining_time);
01381
01382 set_channel_variables(chan, details);
01383
01384 if (!strcasecmp(details->result, "FAILED")) {
01385 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01386 } else {
01387 ast_atomic_fetchadd_int(&faxregistry.fax_complete, 1);
01388 }
01389
01390 if (fax) {
01391 ao2_lock(faxregistry.container);
01392 ao2_unlink(faxregistry.container, fax);
01393 ao2_unlock(faxregistry.container);
01394 ao2_ref(fax, -1);
01395 }
01396
01397
01398
01399
01400 if (chancount) {
01401 if (orig_read_format) {
01402 ast_set_read_format(chan, orig_read_format);
01403 }
01404 if (orig_write_format) {
01405 ast_set_write_format(chan, orig_write_format);
01406 }
01407 }
01408
01409
01410 return chancount;
01411 }
01412
01413 static int receivefax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
01414 {
01415 int timeout_ms;
01416 struct ast_frame *frame = NULL;
01417 struct ast_control_t38_parameters t38_parameters;
01418 struct timeval start;
01419 int ms;
01420
01421 t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
01422
01423
01424 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
01425
01426 if (ast_playtones_start(chan, 1024, "!2100/3000", 1)) {
01427 ast_log(LOG_ERROR, "error generating CED tone on %s\n", chan->name);
01428 return -1;
01429 }
01430
01431 timeout_ms = 3000;
01432 start = ast_tvnow();
01433 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01434 ms = ast_waitfor(chan, ms);
01435
01436 if (ms < 0) {
01437 ast_log(LOG_ERROR, "error while generating CED tone on %s\n", chan->name);
01438 ast_playtones_stop(chan);
01439 return -1;
01440 }
01441
01442 if (ms == 0) {
01443 break;
01444 }
01445
01446 if (!(frame = ast_read(chan))) {
01447 ast_log(LOG_ERROR, "error reading frame while generating CED tone on %s\n", chan->name);
01448 ast_playtones_stop(chan);
01449 return -1;
01450 }
01451
01452 if ((frame->frametype == AST_FRAME_CONTROL) &&
01453 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01454 (frame->datalen == sizeof(t38_parameters))) {
01455 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01456
01457 switch (parameters->request_response) {
01458 case AST_T38_REQUEST_NEGOTIATE:
01459
01460
01461
01462 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01463 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01464 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01465 ast_playtones_stop(chan);
01466 break;
01467 case AST_T38_NEGOTIATED:
01468 ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
01469 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01470 details->caps &= ~AST_FAX_TECH_AUDIO;
01471 report_fax_status(chan, details, "T.38 Negotiated");
01472 break;
01473 default:
01474 break;
01475 }
01476 }
01477 ast_frfree(frame);
01478 }
01479
01480 ast_playtones_stop(chan);
01481 }
01482
01483
01484 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01485 return 0;
01486 }
01487
01488
01489 ast_debug(1, "Negotiating T.38 for receive on %s\n", chan->name);
01490
01491
01492 timeout_ms = 5000;
01493
01494
01495 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01496 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
01497 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
01498 return -1;
01499 }
01500
01501 start = ast_tvnow();
01502 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01503 int break_loop = 0;
01504
01505 ms = ast_waitfor(chan, ms);
01506 if (ms < 0) {
01507 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01508 return -1;
01509 }
01510 if (ms == 0) {
01511 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", chan->name);
01512 details->caps &= ~AST_FAX_TECH_T38;
01513 break;
01514 }
01515
01516 if (!(frame = ast_read(chan))) {
01517 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01518 return -1;
01519 }
01520
01521 if ((frame->frametype == AST_FRAME_CONTROL) &&
01522 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01523 (frame->datalen == sizeof(t38_parameters))) {
01524 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01525
01526 switch (parameters->request_response) {
01527 case AST_T38_REQUEST_NEGOTIATE:
01528 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01529 t38_parameters.request_response = AST_T38_NEGOTIATED;
01530 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01531 break;
01532 case AST_T38_NEGOTIATED:
01533 ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
01534 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01535 details->caps &= ~AST_FAX_TECH_AUDIO;
01536 report_fax_status(chan, details, "T.38 Negotiated");
01537 break_loop = 1;
01538 break;
01539 case AST_T38_REFUSED:
01540 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", chan->name);
01541 details->caps &= ~AST_FAX_TECH_T38;
01542 break_loop = 1;
01543 break;
01544 default:
01545 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", chan->name);
01546 details->caps &= ~AST_FAX_TECH_T38;
01547 break_loop = 1;
01548 break;
01549 }
01550 }
01551 ast_frfree(frame);
01552 if (break_loop) {
01553 break;
01554 }
01555 }
01556
01557
01558 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01559 return 0;
01560 }
01561
01562
01563 if (details->option.allow_audio != AST_FAX_OPTFLAG_TRUE) {
01564 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", chan->name);
01565 return -1;
01566 }
01567
01568
01569 details->caps |= AST_FAX_TECH_AUDIO;
01570
01571 return 0;
01572 }
01573
01574
01575 static int receivefax_exec(struct ast_channel *chan, const char *data)
01576 {
01577 char *parse, modems[128] = "";
01578 int channel_alive;
01579 struct ast_fax_session_details *details;
01580 struct ast_fax_session *s;
01581 struct ast_fax_tech_token *token = NULL;
01582 struct ast_fax_document *doc;
01583 AST_DECLARE_APP_ARGS(args,
01584 AST_APP_ARG(filename);
01585 AST_APP_ARG(options);
01586 );
01587 struct ast_flags opts = { 0, };
01588 struct manager_event_info info;
01589
01590
01591 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
01592 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
01593 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
01594 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
01595 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
01596
01597
01598
01599 ast_atomic_fetchadd_int(&faxregistry.fax_rx_attempts, 1);
01600
01601
01602
01603 if (!(details = find_or_create_details(chan))) {
01604 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01605 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
01606 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
01607 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
01608 return -1;
01609 }
01610
01611 ast_string_field_set(details, result, "FAILED");
01612 ast_string_field_set(details, resultstr, "error starting fax session");
01613 ast_string_field_set(details, error, "INIT_ERROR");
01614 set_channel_variables(chan, details);
01615
01616 if (details->maxrate < details->minrate) {
01617 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01618 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01619 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
01620 set_channel_variables(chan, details);
01621 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
01622 ao2_ref(details, -1);
01623 return -1;
01624 }
01625
01626 if (check_modem_rate(details->modems, details->minrate)) {
01627 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01628 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
01629 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
01630 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01631 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
01632 set_channel_variables(chan, details);
01633 ao2_ref(details, -1);
01634 return -1;
01635 }
01636
01637 if (check_modem_rate(details->modems, details->maxrate)) {
01638 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01639 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
01640 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
01641 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01642 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
01643 set_channel_variables(chan, details);
01644 ao2_ref(details, -1);
01645 return -1;
01646 }
01647
01648 if (ast_strlen_zero(data)) {
01649 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01650 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01651 ast_string_field_set(details, resultstr, "invalid arguments");
01652 set_channel_variables(chan, details);
01653 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
01654 ao2_ref(details, -1);
01655 return -1;
01656 }
01657 parse = ast_strdupa(data);
01658 AST_STANDARD_APP_ARGS(args, parse);
01659
01660 if (!ast_strlen_zero(args.options) &&
01661 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
01662 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01663 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01664 ast_string_field_set(details, resultstr, "invalid arguments");
01665 set_channel_variables(chan, details);
01666 ao2_ref(details, -1);
01667 return -1;
01668 }
01669 if (ast_strlen_zero(args.filename)) {
01670 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01671 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01672 ast_string_field_set(details, resultstr, "invalid arguments");
01673 set_channel_variables(chan, details);
01674 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
01675 ao2_ref(details, -1);
01676 return -1;
01677 }
01678
01679
01680 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
01681 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01682 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
01683 ast_string_field_set(details, resultstr, "invalid arguments");
01684 set_channel_variables(chan, details);
01685 ast_log(LOG_WARNING, "%s does not support polling\n", app_receivefax);
01686 ao2_ref(details, -1);
01687 return -1;
01688 }
01689
01690 pbx_builtin_setvar_helper(chan, "FAXERROR", "Channel Problems");
01691 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "Error before FAX transmission started.");
01692
01693 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(args.filename) + 1))) {
01694 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01695 ast_string_field_set(details, error, "MEMORY_ERROR");
01696 ast_string_field_set(details, resultstr, "error allocating memory");
01697 set_channel_variables(chan, details);
01698 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
01699 ao2_ref(details, -1);
01700 return -1;
01701 }
01702
01703 strcpy(doc->filename, args.filename);
01704 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
01705
01706 ast_verb(3, "Channel '%s' receiving FAX '%s'\n", chan->name, args.filename);
01707
01708 details->caps = AST_FAX_TECH_RECEIVE;
01709 details->option.send_ced = AST_FAX_OPTFLAG_TRUE;
01710
01711
01712 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
01713 details->option.debug = AST_FAX_OPTFLAG_TRUE;
01714 }
01715
01716
01717 if (ast_test_flag(&opts, OPT_STATUS)) {
01718 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
01719 }
01720
01721 if ((ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE) ||
01722 ast_test_flag(&opts, OPT_ALLOWAUDIO)) {
01723 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
01724 }
01725
01726 if (!(s = fax_session_reserve(details, &token))) {
01727 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01728 ast_string_field_set(details, resultstr, "error reserving fax session");
01729 set_channel_variables(chan, details);
01730 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
01731 ao2_ref(details, -1);
01732 return -1;
01733 }
01734
01735
01736 if (chan->_state != AST_STATE_UP) {
01737 if (ast_answer(chan)) {
01738 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01739 ast_string_field_set(details, resultstr, "error answering channel");
01740 set_channel_variables(chan, details);
01741 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
01742 fax_session_release(s, token);
01743 ao2_ref(s, -1);
01744 ao2_ref(details, -1);
01745 return -1;
01746 }
01747 }
01748
01749 if (set_fax_t38_caps(chan, details)) {
01750 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01751 ast_string_field_set(details, error, "T38_NEG_ERROR");
01752 ast_string_field_set(details, resultstr, "error negotiating T.38");
01753 set_channel_variables(chan, details);
01754 fax_session_release(s, token);
01755 ao2_ref(s, -1);
01756 ao2_ref(details, -1);
01757 return -1;
01758 }
01759
01760 if (details->caps & AST_FAX_TECH_T38) {
01761 if (receivefax_t38_init(chan, details)) {
01762 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01763 ast_string_field_set(details, error, "T38_NEG_ERROR");
01764 ast_string_field_set(details, resultstr, "error negotiating T.38");
01765 set_channel_variables(chan, details);
01766 fax_session_release(s, token);
01767 ao2_ref(s, -1);
01768 ao2_ref(details, -1);
01769 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
01770 return -1;
01771 }
01772 }
01773
01774 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
01775 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
01776 }
01777
01778 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01779 if (disable_t38(chan)) {
01780 ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
01781 }
01782 }
01783
01784
01785 ast_channel_lock(chan);
01786
01787 get_manager_event_info(chan, &info);
01788 manager_event(EVENT_FLAG_CALL,
01789 "ReceiveFAX",
01790 "Channel: %s\r\n"
01791 "Context: %s\r\n"
01792 "Exten: %s\r\n"
01793 "CallerID: %s\r\n"
01794 "RemoteStationID: %s\r\n"
01795 "LocalStationID: %s\r\n"
01796 "PagesTransferred: %s\r\n"
01797 "Resolution: %s\r\n"
01798 "TransferRate: %s\r\n"
01799 "FileName: %s\r\n",
01800 chan->name,
01801 info.context,
01802 info.exten,
01803 info.cid,
01804 S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
01805 S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
01806 S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
01807 S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
01808 S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
01809 args.filename);
01810 ast_channel_unlock(chan);
01811
01812 ao2_ref(s, -1);
01813 ao2_ref(details, -1);
01814
01815
01816 return (!channel_alive) ? -1 : 0;
01817 }
01818
01819 static int sendfax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
01820 {
01821 int timeout_ms;
01822 struct ast_frame *frame = NULL;
01823 struct ast_control_t38_parameters t38_parameters;
01824 struct timeval start;
01825 int ms;
01826
01827 t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
01828
01829
01830
01831
01832
01833
01834
01835 timeout_ms = 10500;
01836
01837
01838 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
01839 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000", 1)) {
01840 ast_log(LOG_ERROR, "error generating CNG tone on %s\n", chan->name);
01841 return -1;
01842 }
01843 }
01844
01845 start = ast_tvnow();
01846 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01847 int break_loop = 0;
01848 ms = ast_waitfor(chan, ms);
01849
01850 if (ms < 0) {
01851 ast_log(LOG_ERROR, "error while generating CNG tone on %s\n", chan->name);
01852 ast_playtones_stop(chan);
01853 return -1;
01854 }
01855
01856 if (ms == 0) {
01857 break;
01858 }
01859
01860 if (!(frame = ast_read(chan))) {
01861 ast_log(LOG_ERROR, "error reading frame while generating CNG tone on %s\n", chan->name);
01862 ast_playtones_stop(chan);
01863 return -1;
01864 }
01865
01866 if ((frame->frametype == AST_FRAME_CONTROL) &&
01867 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01868 (frame->datalen == sizeof(t38_parameters))) {
01869 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01870
01871 switch (parameters->request_response) {
01872 case AST_T38_REQUEST_NEGOTIATE:
01873
01874
01875
01876 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01877 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
01878 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01879 ast_playtones_stop(chan);
01880 break;
01881 case AST_T38_NEGOTIATED:
01882 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
01883 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01884 details->caps &= ~AST_FAX_TECH_AUDIO;
01885 report_fax_status(chan, details, "T.38 Negotiated");
01886 break_loop = 1;
01887 break;
01888 default:
01889 break;
01890 }
01891 }
01892 ast_frfree(frame);
01893 if (break_loop) {
01894 break;
01895 }
01896 }
01897
01898 ast_playtones_stop(chan);
01899
01900 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01901 return 0;
01902 }
01903
01904
01905 if (details->option.request_t38 == AST_FAX_OPTFLAG_TRUE) {
01906 ast_debug(1, "Negotiating T.38 for send on %s\n", chan->name);
01907
01908
01909 timeout_ms = 5000;
01910
01911
01912 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01913 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
01914 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
01915 return -1;
01916 }
01917
01918 start = ast_tvnow();
01919 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01920 int break_loop = 0;
01921
01922 ms = ast_waitfor(chan, ms);
01923 if (ms < 0) {
01924 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01925 return -1;
01926 }
01927 if (ms == 0) {
01928 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", chan->name);
01929 details->caps &= ~AST_FAX_TECH_T38;
01930 break;
01931 }
01932
01933 if (!(frame = ast_read(chan))) {
01934 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
01935 return -1;
01936 }
01937
01938 if ((frame->frametype == AST_FRAME_CONTROL) &&
01939 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
01940 (frame->datalen == sizeof(t38_parameters))) {
01941 struct ast_control_t38_parameters *parameters = frame->data.ptr;
01942
01943 switch (parameters->request_response) {
01944 case AST_T38_REQUEST_NEGOTIATE:
01945 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
01946 t38_parameters.request_response = AST_T38_NEGOTIATED;
01947 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
01948 break;
01949 case AST_T38_NEGOTIATED:
01950 ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
01951 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
01952 details->caps &= ~AST_FAX_TECH_AUDIO;
01953 report_fax_status(chan, details, "T.38 Negotiated");
01954 break_loop = 1;
01955 break;
01956 case AST_T38_REFUSED:
01957 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", chan->name);
01958 details->caps &= ~AST_FAX_TECH_T38;
01959 break_loop = 1;
01960 break;
01961 default:
01962 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", chan->name);
01963 details->caps &= ~AST_FAX_TECH_T38;
01964 break_loop = 1;
01965 break;
01966 }
01967 }
01968 ast_frfree(frame);
01969 if (break_loop) {
01970 break;
01971 }
01972 }
01973
01974
01975 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
01976 return 0;
01977 }
01978
01979
01980
01981 if (details->option.allow_audio == AST_FAX_OPTFLAG_TRUE) {
01982 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000", 1)) {
01983 ast_log(LOG_ERROR, "error generating second CNG tone on %s\n", chan->name);
01984 return -1;
01985 }
01986
01987 timeout_ms = 3500;
01988 start = ast_tvnow();
01989 while ((ms = ast_remaining_ms(start, timeout_ms))) {
01990 int break_loop = 0;
01991
01992 ms = ast_waitfor(chan, ms);
01993 if (ms < 0) {
01994 ast_log(LOG_ERROR, "error while generating second CNG tone on %s\n", chan->name);
01995 ast_playtones_stop(chan);
01996 return -1;
01997 }
01998 if (ms == 0) {
01999 break;
02000 }
02001
02002 if (!(frame = ast_read(chan))) {
02003 ast_log(LOG_ERROR, "error reading frame while generating second CNG tone on %s\n", chan->name);
02004 ast_playtones_stop(chan);
02005 return -1;
02006 }
02007
02008 if ((frame->frametype == AST_FRAME_CONTROL) &&
02009 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
02010 (frame->datalen == sizeof(t38_parameters))) {
02011 struct ast_control_t38_parameters *parameters = frame->data.ptr;
02012
02013 switch (parameters->request_response) {
02014 case AST_T38_REQUEST_NEGOTIATE:
02015
02016
02017
02018 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
02019 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
02020 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
02021 ast_playtones_stop(chan);
02022 break;
02023 case AST_T38_NEGOTIATED:
02024 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
02025 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
02026 details->caps &= ~AST_FAX_TECH_AUDIO;
02027 report_fax_status(chan, details, "T.38 Negotiated");
02028 break_loop = 1;
02029 break;
02030 default:
02031 break;
02032 }
02033 }
02034 ast_frfree(frame);
02035 if (break_loop) {
02036 break;
02037 }
02038 }
02039
02040 ast_playtones_stop(chan);
02041
02042
02043 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02044 return 0;
02045 }
02046 }
02047 }
02048
02049
02050 if (details->option.allow_audio == AST_FAX_OPTFLAG_FALSE) {
02051 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", chan->name);
02052 return -1;
02053 }
02054
02055
02056 details->caps |= AST_FAX_TECH_AUDIO;
02057
02058 return 0;
02059 }
02060
02061
02062
02063 static int sendfax_exec(struct ast_channel *chan, const char *data)
02064 {
02065 char *parse, *filenames, *c, modems[128] = "";
02066 int channel_alive, file_count;
02067 struct ast_fax_session_details *details;
02068 struct ast_fax_session *s;
02069 struct ast_fax_tech_token *token = NULL;
02070 struct ast_fax_document *doc;
02071 AST_DECLARE_APP_ARGS(args,
02072 AST_APP_ARG(filenames);
02073 AST_APP_ARG(options);
02074 );
02075 struct ast_flags opts = { 0, };
02076 struct manager_event_info info;
02077
02078
02079 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
02080 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
02081 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
02082 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
02083 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
02084
02085
02086
02087 ast_atomic_fetchadd_int(&faxregistry.fax_tx_attempts, 1);
02088
02089
02090
02091 if (!(details = find_or_create_details(chan))) {
02092 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02093 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
02094 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
02095 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
02096 return -1;
02097 }
02098
02099 ast_string_field_set(details, result, "FAILED");
02100 ast_string_field_set(details, resultstr, "error starting fax session");
02101 ast_string_field_set(details, error, "INIT_ERROR");
02102 set_channel_variables(chan, details);
02103
02104 if (details->maxrate < details->minrate) {
02105 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02106 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02107 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
02108 set_channel_variables(chan, details);
02109 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
02110 ao2_ref(details, -1);
02111 return -1;
02112 }
02113
02114 if (check_modem_rate(details->modems, details->minrate)) {
02115 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02116 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
02117 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
02118 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02119 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
02120 set_channel_variables(chan, details);
02121 ao2_ref(details, -1);
02122 return -1;
02123 }
02124
02125 if (check_modem_rate(details->modems, details->maxrate)) {
02126 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02127 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
02128 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
02129 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02130 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
02131 set_channel_variables(chan, details);
02132 ao2_ref(details, -1);
02133 return -1;
02134 }
02135
02136 if (ast_strlen_zero(data)) {
02137 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02138 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02139 ast_string_field_set(details, resultstr, "invalid arguments");
02140 set_channel_variables(chan, details);
02141 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]][,options])\n", app_sendfax);
02142 ao2_ref(details, -1);
02143 return -1;
02144 }
02145 parse = ast_strdupa(data);
02146 AST_STANDARD_APP_ARGS(args, parse);
02147
02148
02149 if (!ast_strlen_zero(args.options) &&
02150 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
02151 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02152 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02153 ast_string_field_set(details, resultstr, "invalid arguments");
02154 set_channel_variables(chan, details);
02155 ao2_ref(details, -1);
02156 return -1;
02157 }
02158 if (ast_strlen_zero(args.filenames)) {
02159 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02160 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02161 ast_string_field_set(details, resultstr, "invalid arguments");
02162 set_channel_variables(chan, details);
02163 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]],options])\n", app_sendfax);
02164 ao2_ref(details, -1);
02165 return -1;
02166 }
02167
02168
02169 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
02170 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02171 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
02172 ast_string_field_set(details, resultstr, "invalid arguments");
02173 set_channel_variables(chan, details);
02174 ast_log(LOG_WARNING, "%s does not support polling\n", app_sendfax);
02175 ao2_ref(details, -1);
02176 return -1;
02177 }
02178
02179 file_count = 0;
02180 filenames = args.filenames;
02181 while ((c = strsep(&filenames, "&"))) {
02182 if (access(c, (F_OK | R_OK)) < 0) {
02183 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02184 ast_string_field_set(details, error, "FILE_ERROR");
02185 ast_string_field_set(details, resultstr, "error reading file");
02186 set_channel_variables(chan, details);
02187 ast_log(LOG_ERROR, "access failure. Verify '%s' exists and check permissions.\n", args.filenames);
02188 ao2_ref(details, -1);
02189 return -1;
02190 }
02191
02192 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(c) + 1))) {
02193 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02194 ast_string_field_set(details, error, "MEMORY_ERROR");
02195 ast_string_field_set(details, resultstr, "error allocating memory");
02196 set_channel_variables(chan, details);
02197 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
02198 ao2_ref(details, -1);
02199 return -1;
02200 }
02201
02202 strcpy(doc->filename, c);
02203 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
02204 file_count++;
02205 }
02206
02207 if (file_count > 1) {
02208 details->caps |= AST_FAX_TECH_MULTI_DOC;
02209 }
02210
02211 ast_verb(3, "Channel '%s' sending FAX:\n", chan->name);
02212 AST_LIST_TRAVERSE(&details->documents, doc, next) {
02213 ast_verb(3, " %s\n", doc->filename);
02214 }
02215
02216 details->caps = AST_FAX_TECH_SEND;
02217
02218
02219 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
02220 details->option.debug = AST_FAX_OPTFLAG_TRUE;
02221 }
02222
02223
02224 if (ast_test_flag(&opts, OPT_STATUS)) {
02225 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
02226 }
02227
02228 if ((ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE) ||
02229 ast_test_flag(&opts, OPT_ALLOWAUDIO)) {
02230 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
02231 }
02232
02233 if (ast_test_flag(&opts, OPT_REQUEST_T38)) {
02234 details->option.request_t38 = AST_FAX_OPTFLAG_TRUE;
02235 }
02236
02237 if (!(s = fax_session_reserve(details, &token))) {
02238 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02239 ast_string_field_set(details, resultstr, "error reserving fax session");
02240 set_channel_variables(chan, details);
02241 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
02242 ao2_ref(details, -1);
02243 return -1;
02244 }
02245
02246
02247 if (chan->_state != AST_STATE_UP) {
02248 if (ast_answer(chan)) {
02249 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02250 ast_string_field_set(details, resultstr, "error answering channel");
02251 set_channel_variables(chan, details);
02252 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
02253 fax_session_release(s, token);
02254 ao2_ref(s, -1);
02255 ao2_ref(details, -1);
02256 return -1;
02257 }
02258 }
02259
02260 if (set_fax_t38_caps(chan, details)) {
02261 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02262 ast_string_field_set(details, error, "T38_NEG_ERROR");
02263 ast_string_field_set(details, resultstr, "error negotiating T.38");
02264 set_channel_variables(chan, details);
02265 fax_session_release(s, token);
02266 ao2_ref(s, -1);
02267 ao2_ref(details, -1);
02268 return -1;
02269 }
02270
02271 if (details->caps & AST_FAX_TECH_T38) {
02272 if (sendfax_t38_init(chan, details)) {
02273 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02274 ast_string_field_set(details, error, "T38_NEG_ERROR");
02275 ast_string_field_set(details, resultstr, "error negotiating T.38");
02276 set_channel_variables(chan, details);
02277 fax_session_release(s, token);
02278 ao2_ref(s, -1);
02279 ao2_ref(details, -1);
02280 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
02281 return -1;
02282 }
02283 } else {
02284 details->option.send_cng = 1;
02285 }
02286
02287 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
02288 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
02289 }
02290
02291 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
02292 if (disable_t38(chan)) {
02293 ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
02294 }
02295 }
02296
02297 if (!(filenames = generate_filenames_string(details, "FileName: ", "\r\n"))) {
02298 ast_log(LOG_ERROR, "Error generating SendFAX manager event\n");
02299 ao2_ref(s, -1);
02300 ao2_ref(details, -1);
02301 return (!channel_alive) ? -1 : 0;
02302 }
02303
02304
02305 ast_channel_lock(chan);
02306 get_manager_event_info(chan, &info);
02307 manager_event(EVENT_FLAG_CALL,
02308 "SendFAX",
02309 "Channel: %s\r\n"
02310 "Context: %s\r\n"
02311 "Exten: %s\r\n"
02312 "CallerID: %s\r\n"
02313 "RemoteStationID: %s\r\n"
02314 "LocalStationID: %s\r\n"
02315 "PagesTransferred: %s\r\n"
02316 "Resolution: %s\r\n"
02317 "TransferRate: %s\r\n"
02318 "%s\r\n",
02319 chan->name,
02320 info.context,
02321 info.exten,
02322 info.cid,
02323 S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
02324 S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
02325 S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
02326 S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
02327 S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
02328 filenames);
02329 ast_channel_unlock(chan);
02330
02331 ast_free(filenames);
02332
02333 ao2_ref(s, -1);
02334 ao2_ref(details, -1);
02335
02336
02337 return (!channel_alive) ? -1 : 0;
02338 }
02339
02340
02341 static int session_hash_cb(const void *obj, const int flags)
02342 {
02343 const struct ast_fax_session *s = obj;
02344
02345 return s->id;
02346 }
02347
02348
02349 static int session_cmp_cb(void *obj, void *arg, int flags)
02350 {
02351 struct ast_fax_session *lhs = obj, *rhs = arg;
02352
02353 return (lhs->id == rhs->id) ? CMP_MATCH | CMP_STOP : 0;
02354 }
02355
02356
02357 static char *fax_session_tab_complete(struct ast_cli_args *a)
02358 {
02359 int tklen;
02360 int wordnum = 0;
02361 char *name = NULL;
02362 struct ao2_iterator i;
02363 struct ast_fax_session *s;
02364 char tbuf[5];
02365
02366 if (a->pos != 3) {
02367 return NULL;
02368 }
02369
02370 tklen = strlen(a->word);
02371 i = ao2_iterator_init(faxregistry.container, 0);
02372 while ((s = ao2_iterator_next(&i))) {
02373 snprintf(tbuf, sizeof(tbuf), "%d", s->id);
02374 if (!strncasecmp(a->word, tbuf, tklen) && ++wordnum > a->n) {
02375 name = ast_strdup(tbuf);
02376 ao2_ref(s, -1);
02377 break;
02378 }
02379 ao2_ref(s, -1);
02380 }
02381 ao2_iterator_destroy(&i);
02382 return name;
02383 }
02384
02385 static char *cli_fax_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02386 {
02387 struct fax_module *fax;
02388
02389 switch(cmd) {
02390 case CLI_INIT:
02391 e->command = "fax show version";
02392 e->usage =
02393 "Usage: fax show version\n"
02394 " Show versions of FAX For Asterisk components.\n";
02395 return NULL;
02396 case CLI_GENERATE:
02397 return NULL;
02398 }
02399
02400 if (a->argc != 3) {
02401 return CLI_SHOWUSAGE;
02402 }
02403
02404 ast_cli(a->fd, "FAX For Asterisk Components:\n");
02405 ast_cli(a->fd, "\tApplications: %s\n", ast_get_version());
02406 AST_RWLIST_RDLOCK(&faxmodules);
02407 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02408 ast_cli(a->fd, "\t%s: %s\n", fax->tech->description, fax->tech->version);
02409 }
02410 AST_RWLIST_UNLOCK(&faxmodules);
02411 ast_cli(a->fd, "\n");
02412
02413 return CLI_SUCCESS;
02414 }
02415
02416
02417 static char *cli_fax_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02418 {
02419 int flag;
02420 const char *what;
02421
02422 switch (cmd) {
02423 case CLI_INIT:
02424 e->command = "fax set debug {on|off}";
02425 e->usage =
02426 "Usage: fax set debug { on | off }\n"
02427 " Enable/Disable FAX debugging on new FAX sessions. The basic FAX debugging will result in\n"
02428 " additional events sent to manager sessions with 'call' class permissions. When\n"
02429 " verbosity is greater than '5' events will be displayed to the console and audio versus\n"
02430 " energy analysis will be performed and displayed to the console.\n";
02431 return NULL;
02432 case CLI_GENERATE:
02433 return NULL;
02434 }
02435
02436 what = a->argv[e->args-1];
02437 if (!strcasecmp(what, "on")) {
02438 flag = 1;
02439 } else if (!strcasecmp(what, "off")) {
02440 flag = 0;
02441 } else {
02442 return CLI_SHOWUSAGE;
02443 }
02444
02445 global_fax_debug = flag;
02446 ast_cli(a->fd, "\n\nFAX Debug %s\n\n", (flag) ? "Enabled" : "Disabled");
02447
02448 return CLI_SUCCESS;
02449 }
02450
02451
02452 static char *cli_fax_show_capabilities(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02453 {
02454 struct fax_module *fax;
02455 unsigned int num_modules = 0;
02456
02457 switch (cmd) {
02458 case CLI_INIT:
02459 e->command = "fax show capabilities";
02460 e->usage =
02461 "Usage: fax show capabilities\n"
02462 " Shows the capabilities of the registered FAX technology modules\n";
02463 return NULL;
02464 case CLI_GENERATE:
02465 return NULL;
02466 }
02467
02468 ast_cli(a->fd, "\n\nRegistered FAX Technology Modules:\n\n");
02469 AST_RWLIST_RDLOCK(&faxmodules);
02470 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02471 ast_cli(a->fd, "%-15s : %s\n%-15s : %s\n%-15s : ", "Type", fax->tech->type, "Description", fax->tech->description, "Capabilities");
02472 fax->tech->cli_show_capabilities(a->fd);
02473 num_modules++;
02474 }
02475 AST_RWLIST_UNLOCK(&faxmodules);
02476 ast_cli(a->fd, "%d registered modules\n\n", num_modules);
02477
02478 return CLI_SUCCESS;
02479 }
02480
02481
02482 static char *cli_fax_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02483 {
02484 struct fax_module *fax;
02485 char modems[128] = "";
02486 struct fax_options options;
02487
02488 switch (cmd) {
02489 case CLI_INIT:
02490 e->command = "fax show settings";
02491 e->usage =
02492 "Usage: fax show settings\n"
02493 " Show the global settings and defaults of both the FAX core and technology modules\n";
02494 return NULL;
02495 case CLI_GENERATE:
02496 return NULL;
02497 }
02498
02499 get_general_options(&options);
02500
02501 ast_cli(a->fd, "FAX For Asterisk Settings:\n");
02502 ast_cli(a->fd, "\tECM: %s\n", options.ecm ? "Enabled" : "Disabled");
02503 ast_cli(a->fd, "\tStatus Events: %s\n", options.statusevents ? "On" : "Off");
02504 ast_cli(a->fd, "\tMinimum Bit Rate: %d\n", options.minrate);
02505 ast_cli(a->fd, "\tMaximum Bit Rate: %d\n", options.maxrate);
02506 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02507 ast_cli(a->fd, "\tModem Modulations Allowed: %s\n", modems);
02508 ast_cli(a->fd, "\n\nFAX Technology Modules:\n\n");
02509 AST_RWLIST_RDLOCK(&faxmodules);
02510 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02511 ast_cli(a->fd, "%s (%s) Settings:\n", fax->tech->type, fax->tech->description);
02512 fax->tech->cli_show_settings(a->fd);
02513 }
02514 AST_RWLIST_UNLOCK(&faxmodules);
02515
02516 return CLI_SUCCESS;
02517 }
02518
02519
02520 static char *cli_fax_show_session(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02521 {
02522 struct ast_fax_session *s, tmp;
02523
02524 switch (cmd) {
02525 case CLI_INIT:
02526 e->command = "fax show session";
02527 e->usage =
02528 "Usage: fax show session <session number>\n"
02529 " Shows status of the named FAX session\n";
02530 return NULL;
02531 case CLI_GENERATE:
02532 return fax_session_tab_complete(a);
02533 }
02534
02535 if (a->argc != 4) {
02536 return CLI_SHOWUSAGE;
02537 }
02538
02539 if (sscanf(a->argv[3], "%d", &tmp.id) != 1) {
02540 ast_log(LOG_ERROR, "invalid session id: '%s'\n", a->argv[3]);
02541 return RESULT_SUCCESS;
02542 }
02543
02544 ast_cli(a->fd, "\nFAX Session Details:\n--------------------\n\n");
02545 s = ao2_find(faxregistry.container, &tmp, OBJ_POINTER);
02546 if (s) {
02547 s->tech->cli_show_session(s, a->fd);
02548 ao2_ref(s, -1);
02549 }
02550 ast_cli(a->fd, "\n\n");
02551
02552 return CLI_SUCCESS;
02553 }
02554
02555
02556 static char *cli_fax_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02557 {
02558 struct fax_module *fax;
02559
02560 switch (cmd) {
02561 case CLI_INIT:
02562 e->command = "fax show stats";
02563 e->usage =
02564 "Usage: fax show stats\n"
02565 " Shows a statistical summary of FAX transmissions\n";
02566 return NULL;
02567 case CLI_GENERATE:
02568 return NULL;
02569 }
02570
02571 ast_cli(a->fd, "\nFAX Statistics:\n---------------\n\n");
02572 ast_cli(a->fd, "%-20.20s : %d\n", "Current Sessions", faxregistry.active_sessions);
02573 ast_cli(a->fd, "%-20.20s : %d\n", "Reserved Sessions", faxregistry.reserved_sessions);
02574 ast_cli(a->fd, "%-20.20s : %d\n", "Transmit Attempts", faxregistry.fax_tx_attempts);
02575 ast_cli(a->fd, "%-20.20s : %d\n", "Receive Attempts", faxregistry.fax_rx_attempts);
02576 ast_cli(a->fd, "%-20.20s : %d\n", "Completed FAXes", faxregistry.fax_complete);
02577 ast_cli(a->fd, "%-20.20s : %d\n", "Failed FAXes", faxregistry.fax_failures);
02578 AST_RWLIST_RDLOCK(&faxmodules);
02579 AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
02580 fax->tech->cli_show_stats(a->fd);
02581 }
02582 AST_RWLIST_UNLOCK(&faxmodules);
02583 ast_cli(a->fd, "\n\n");
02584
02585 return CLI_SUCCESS;
02586 }
02587
02588
02589 static char *cli_fax_show_sessions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02590 {
02591 struct ast_fax_session *s;
02592 struct ao2_iterator i;
02593 int session_count;
02594 char *filenames;
02595
02596 switch (cmd) {
02597 case CLI_INIT:
02598 e->command = "fax show sessions";
02599 e->usage =
02600 "Usage: fax show sessions\n"
02601 " Shows the current FAX sessions\n";
02602 return NULL;
02603 case CLI_GENERATE:
02604 return NULL;
02605 }
02606
02607 ast_cli(a->fd, "\nCurrent FAX Sessions:\n\n");
02608 ast_cli(a->fd, "%-20.20s %-10.10s %-10.10s %-5.5s %-10.10s %-15.15s %-30.30s\n",
02609 "Channel", "Tech", "FAXID", "Type", "Operation", "State", "File(s)");
02610 i = ao2_iterator_init(faxregistry.container, 0);
02611 while ((s = ao2_iterator_next(&i))) {
02612 ao2_lock(s);
02613
02614 if (!(filenames = generate_filenames_string(s->details, "", ", "))) {
02615 ast_log(LOG_ERROR, "Error printing filenames for 'fax show sessions' command\n");
02616 ao2_unlock(s);
02617 ao2_ref(s, -1);
02618 ao2_iterator_destroy(&i);
02619 return CLI_FAILURE;
02620 }
02621
02622 ast_cli(a->fd, "%-20.20s %-10.10s %-10d %-5.5s %-10.10s %-15.15s %-30s\n",
02623 s->channame, s->tech->type, s->id,
02624 (s->details->caps & AST_FAX_TECH_AUDIO) ? "G.711" : "T.38",
02625 (s->details->caps & AST_FAX_TECH_SEND) ? "send" : "receive",
02626 ast_fax_state_to_str(s->state), filenames);
02627
02628 ast_free(filenames);
02629 ao2_unlock(s);
02630 ao2_ref(s, -1);
02631 }
02632 ao2_iterator_destroy(&i);
02633 session_count = ao2_container_count(faxregistry.container);
02634 ast_cli(a->fd, "\n%d FAX sessions\n\n", session_count);
02635
02636 return CLI_SUCCESS;
02637 }
02638
02639 static struct ast_cli_entry fax_cli[] = {
02640 AST_CLI_DEFINE(cli_fax_show_version, "Show versions of FAX For Asterisk components"),
02641 AST_CLI_DEFINE(cli_fax_set_debug, "Enable/Disable FAX debugging on new FAX sessions"),
02642 AST_CLI_DEFINE(cli_fax_show_capabilities, "Show the capabilities of the registered FAX technology modules"),
02643 AST_CLI_DEFINE(cli_fax_show_settings, "Show the global settings and defaults of both the FAX core and technology modules"),
02644 AST_CLI_DEFINE(cli_fax_show_session, "Show the status of the named FAX sessions"),
02645 AST_CLI_DEFINE(cli_fax_show_sessions, "Show the current FAX sessions"),
02646 AST_CLI_DEFINE(cli_fax_show_stats, "Summarize FAX session history"),
02647 };
02648
02649 static void set_general_options(const struct fax_options *options)
02650 {
02651 ast_rwlock_wrlock(&options_lock);
02652 general_options = *options;
02653 ast_rwlock_unlock(&options_lock);
02654 }
02655
02656 static void get_general_options(struct fax_options *options)
02657 {
02658 ast_rwlock_rdlock(&options_lock);
02659 *options = general_options;
02660 ast_rwlock_unlock(&options_lock);
02661 }
02662
02663
02664 static int set_config(int reload)
02665 {
02666 struct ast_config *cfg;
02667 struct ast_variable *v;
02668 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
02669 char modems[128] = "";
02670 struct fax_options options;
02671 int res = 0;
02672
02673 options = default_options;
02674
02675
02676
02677
02678
02679
02680 if (!reload) {
02681 set_general_options(&options);
02682 }
02683
02684
02685 if (!(cfg = ast_config_load2(config, "res_fax", config_flags))) {
02686 ast_log(LOG_NOTICE, "Configuration file '%s' not found, %s options.\n",
02687 config, reload ? "not changing" : "using default");
02688 return 0;
02689 }
02690
02691 if (cfg == CONFIG_STATUS_FILEINVALID) {
02692 ast_log(LOG_NOTICE, "Configuration file '%s' is invalid, %s options.\n",
02693 config, reload ? "not changing" : "using default");
02694 return 0;
02695 }
02696
02697 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
02698 return 0;
02699 }
02700
02701 if (reload) {
02702 options = default_options;
02703 }
02704
02705
02706 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
02707 int rate;
02708
02709 if (!strcasecmp(v->name, "minrate")) {
02710 ast_debug(3, "reading minrate '%s' from configuration file\n", v->value);
02711 if ((rate = fax_rate_str_to_int(v->value)) == 0) {
02712 res = -1;
02713 goto end;
02714 }
02715 options.minrate = rate;
02716 } else if (!strcasecmp(v->name, "maxrate")) {
02717 ast_debug(3, "reading maxrate '%s' from configuration file\n", v->value);
02718 if ((rate = fax_rate_str_to_int(v->value)) == 0) {
02719 res = -1;
02720 goto end;
02721 }
02722 options.maxrate = rate;
02723 } else if (!strcasecmp(v->name, "statusevents")) {
02724 ast_debug(3, "reading statusevents '%s' from configuration file\n", v->value);
02725 options.statusevents = ast_true(v->value);
02726 } else if (!strcasecmp(v->name, "ecm")) {
02727 ast_debug(3, "reading ecm '%s' from configuration file\n", v->value);
02728 options.ecm = ast_true(v->value);
02729 } else if ((!strcasecmp(v->name, "modem")) || (!strcasecmp(v->name, "modems"))) {
02730 options.modems = 0;
02731 update_modem_bits(&options.modems, v->value);
02732 }
02733 }
02734
02735 if (options.maxrate < options.minrate) {
02736 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", options.maxrate, options.minrate);
02737 res = -1;
02738 goto end;
02739 }
02740
02741 if (options.minrate == 2400 && (options.modems & AST_FAX_MODEM_V27) && !(options.modems & (AST_FAX_MODEM_V34))) {
02742 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02743 ast_log(LOG_WARNING, "'modems' setting '%s' is no longer accepted with 'minrate' setting %d\n", modems, options.minrate);
02744 ast_log(LOG_WARNING, "'minrate' has been reset to 4800, please update res_fax.conf.\n");
02745 options.minrate = 4800;
02746 }
02747
02748 if (check_modem_rate(options.modems, options.minrate)) {
02749 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02750 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, options.minrate);
02751 res = -1;
02752 goto end;
02753 }
02754
02755 if (check_modem_rate(options.modems, options.maxrate)) {
02756 ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
02757 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, options.maxrate);
02758 res = -1;
02759 goto end;
02760 }
02761
02762 set_general_options(&options);
02763
02764 end:
02765 ast_config_destroy(cfg);
02766 return res;
02767 }
02768
02769
02770 static int acf_faxopt_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
02771 {
02772 struct ast_fax_session_details *details = find_details(chan);
02773 int res = 0;
02774 char *filenames;
02775
02776 if (!details) {
02777 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", chan->name, data);
02778 return -1;
02779 }
02780 if (!strcasecmp(data, "ecm")) {
02781 ast_copy_string(buf, details->option.ecm ? "yes" : "no", len);
02782 } else if (!strcasecmp(data, "error")) {
02783 ast_copy_string(buf, details->error, len);
02784 } else if (!strcasecmp(data, "filename")) {
02785 if (AST_LIST_EMPTY(&details->documents)) {
02786 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", chan->name, data);
02787 res = -1;
02788 } else {
02789 ast_copy_string(buf, AST_LIST_FIRST(&details->documents)->filename, len);
02790 }
02791 } else if (!strcasecmp(data, "filenames")) {
02792 if (AST_LIST_EMPTY(&details->documents)) {
02793 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", chan->name, data);
02794 res = -1;
02795 } else if ((filenames = generate_filenames_string(details, "", ","))) {
02796 ast_copy_string(buf, filenames, len);
02797 ast_free(filenames);
02798 } else {
02799 ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s), there was an error generating the filenames list.\n", chan->name, data);
02800 res = -1;
02801 }
02802 } else if (!strcasecmp(data, "headerinfo")) {
02803 ast_copy_string(buf, details->headerinfo, len);
02804 } else if (!strcasecmp(data, "localstationid")) {
02805 ast_copy_string(buf, details->localstationid, len);
02806 } else if (!strcasecmp(data, "maxrate")) {
02807 snprintf(buf, len, "%d", details->maxrate);
02808 } else if (!strcasecmp(data, "minrate")) {
02809 snprintf(buf, len, "%d", details->minrate);
02810 } else if (!strcasecmp(data, "pages")) {
02811 snprintf(buf, len, "%d", details->pages_transferred);
02812 } else if (!strcasecmp(data, "rate")) {
02813 ast_copy_string(buf, details->transfer_rate, len);
02814 } else if (!strcasecmp(data, "remotestationid")) {
02815 ast_copy_string(buf, details->remotestationid, len);
02816 } else if (!strcasecmp(data, "resolution")) {
02817 ast_copy_string(buf, details->resolution, len);
02818 } else if (!strcasecmp(data, "sessionid")) {
02819 snprintf(buf, len, "%d", details->id);
02820 } else if (!strcasecmp(data, "status")) {
02821 ast_copy_string(buf, details->result, len);
02822 } else if (!strcasecmp(data, "statusstr")) {
02823 ast_copy_string(buf, details->resultstr, len);
02824 } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
02825 ast_fax_modem_to_str(details->modems, buf, len);
02826 } else {
02827 ast_log(LOG_WARNING, "channel '%s' can't read FAXOPT(%s) because it is unhandled!\n", chan->name, data);
02828 res = -1;
02829 }
02830 ao2_ref(details, -1);
02831
02832 return res;
02833 }
02834
02835
02836 static int acf_faxopt_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
02837 {
02838 int res = 0;
02839 struct ast_fax_session_details *details;
02840
02841 if (!(details = find_or_create_details(chan))) {
02842 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);
02843 return -1;
02844 }
02845 ast_debug(3, "channel '%s' setting FAXOPT(%s) to '%s'\n", chan->name, data, value);
02846
02847 if (!strcasecmp(data, "ecm")) {
02848 const char *val = ast_skip_blanks(value);
02849 if (ast_true(val)) {
02850 details->option.ecm = AST_FAX_OPTFLAG_TRUE;
02851 } else if (ast_false(val)) {
02852 details->option.ecm = AST_FAX_OPTFLAG_FALSE;
02853 } else {
02854 ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(ecm).\n", value);
02855 }
02856 } else if (!strcasecmp(data, "headerinfo")) {
02857 ast_string_field_set(details, headerinfo, value);
02858 } else if (!strcasecmp(data, "localstationid")) {
02859 ast_string_field_set(details, localstationid, value);
02860 } else if (!strcasecmp(data, "maxrate")) {
02861 details->maxrate = fax_rate_str_to_int(value);
02862 if (!details->maxrate) {
02863 details->maxrate = ast_fax_maxrate();
02864 }
02865 } else if (!strcasecmp(data, "minrate")) {
02866 details->minrate = fax_rate_str_to_int(value);
02867 if (!details->minrate) {
02868 details->minrate = ast_fax_minrate();
02869 }
02870 } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
02871 update_modem_bits(&details->modems, value);
02872 } else {
02873 ast_log(LOG_WARNING, "channel '%s' set FAXOPT(%s) to '%s' is unhandled!\n", chan->name, data, value);
02874 res = -1;
02875 }
02876
02877 ao2_ref(details, -1);
02878
02879 return res;
02880 }
02881
02882
02883 struct ast_custom_function acf_faxopt = {
02884 .name = "FAXOPT",
02885 .read = acf_faxopt_read,
02886 .write = acf_faxopt_write,
02887 };
02888
02889
02890 static int unload_module(void)
02891 {
02892 ast_cli_unregister_multiple(fax_cli, ARRAY_LEN(fax_cli));
02893
02894 if (ast_custom_function_unregister(&acf_faxopt) < 0) {
02895 ast_log(LOG_WARNING, "failed to unregister function '%s'\n", acf_faxopt.name);
02896 }
02897
02898 if (ast_unregister_application(app_sendfax) < 0) {
02899 ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_sendfax);
02900 }
02901
02902 if (ast_unregister_application(app_receivefax) < 0) {
02903 ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_receivefax);
02904 }
02905
02906 if (fax_logger_level != -1) {
02907 ast_logger_unregister_level("FAX");
02908 }
02909
02910 ao2_ref(faxregistry.container, -1);
02911
02912 return 0;
02913 }
02914
02915
02916 static int load_module(void)
02917 {
02918 int res;
02919
02920
02921 faxregistry.active_sessions = 0;
02922 faxregistry.reserved_sessions = 0;
02923 if (!(faxregistry.container = ao2_container_alloc(FAX_MAXBUCKETS, session_hash_cb, session_cmp_cb))) {
02924 return AST_MODULE_LOAD_DECLINE;
02925 }
02926
02927 if (set_config(0) < 0) {
02928 ast_log(LOG_ERROR, "failed to load configuration file '%s'\n", config);
02929 ao2_ref(faxregistry.container, -1);
02930 return AST_MODULE_LOAD_DECLINE;
02931 }
02932
02933
02934 if (ast_register_application_xml(app_sendfax, sendfax_exec) < 0) {
02935 ast_log(LOG_WARNING, "failed to register '%s'.\n", app_sendfax);
02936 ao2_ref(faxregistry.container, -1);
02937 return AST_MODULE_LOAD_DECLINE;
02938 }
02939 if (ast_register_application_xml(app_receivefax, receivefax_exec) < 0) {
02940 ast_log(LOG_WARNING, "failed to register '%s'.\n", app_receivefax);
02941 ast_unregister_application(app_sendfax);
02942 ao2_ref(faxregistry.container, -1);
02943 return AST_MODULE_LOAD_DECLINE;
02944 }
02945 ast_cli_register_multiple(fax_cli, ARRAY_LEN(fax_cli));
02946 res = ast_custom_function_register(&acf_faxopt);
02947 fax_logger_level = ast_logger_register_level("FAX");
02948
02949 return res;
02950 }
02951
02952 static int reload_module(void)
02953 {
02954 set_config(1);
02955 return 0;
02956 }
02957
02958
02959 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Generic FAX Applications",
02960 .load = load_module,
02961 .unload = unload_module,
02962 .reload = reload_module,
02963 .load_pri = AST_MODPRI_APP_DEPEND,
02964 );