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