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