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