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