00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "asterisk.h"
00023
00024 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 357542 $")
00025
00026 #include <string.h>
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <inttypes.h>
00030 #include <pthread.h>
00031 #include <errno.h>
00032 #include <tiffio.h>
00033
00034 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
00035 #include <spandsp.h>
00036 #include <spandsp/version.h>
00037
00038 #include "asterisk/lock.h"
00039 #include "asterisk/file.h"
00040 #include "asterisk/logger.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/pbx.h"
00043 #include "asterisk/app.h"
00044 #include "asterisk/dsp.h"
00045 #include "asterisk/module.h"
00046 #include "asterisk/manager.h"
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 static const char app_sndfax_name[] = "SendFAX";
00146 static const char app_rcvfax_name[] = "ReceiveFAX";
00147
00148 #define MAX_SAMPLES 240
00149
00150
00151
00152
00153
00154
00155
00156 #define WATCHDOG_TOTAL_TIMEOUT 30 * 60
00157 #define WATCHDOG_STATE_TIMEOUT 5 * 60
00158
00159 typedef struct {
00160 struct ast_channel *chan;
00161 enum ast_t38_state t38state;
00162 int direction;
00163 int caller_mode;
00164 char *file_name;
00165 struct ast_control_t38_parameters t38parameters;
00166 volatile int finished;
00167 } fax_session;
00168
00169 static void span_message(int level, const char *msg)
00170 {
00171 if (level == SPAN_LOG_ERROR) {
00172 ast_log(LOG_ERROR, "%s", msg);
00173 } else if (level == SPAN_LOG_WARNING) {
00174 ast_log(LOG_WARNING, "%s", msg);
00175 } else {
00176 ast_debug(1, "%s", msg);
00177 }
00178 }
00179
00180 static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
00181 {
00182 struct ast_channel *chan = (struct ast_channel *) user_data;
00183
00184 struct ast_frame outf = {
00185 .frametype = AST_FRAME_MODEM,
00186 .subclass.integer = AST_MODEM_T38,
00187 .src = __FUNCTION__,
00188 };
00189
00190
00191
00192
00193 AST_FRAME_SET_BUFFER(&outf, buf, 0, len);
00194
00195 if (ast_write(chan, &outf) < 0) {
00196 ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
00197 return -1;
00198 }
00199
00200 return 0;
00201 }
00202
00203 static void phase_e_handler(t30_state_t *f, void *user_data, int result)
00204 {
00205 const char *local_ident;
00206 const char *far_ident;
00207 char buf[20];
00208 fax_session *s = (fax_session *) user_data;
00209 t30_stats_t stat;
00210 int pages_transferred;
00211
00212 ast_debug(1, "Fax phase E handler. result=%d\n", result);
00213
00214 t30_get_transfer_statistics(f, &stat);
00215
00216 s = (fax_session *) user_data;
00217
00218 if (result != T30_ERR_OK) {
00219 s->finished = -1;
00220
00221
00222 pbx_builtin_setvar_helper(s->chan, "FAXERROR", t30_completion_code_to_str(result));
00223
00224 ast_log(LOG_WARNING, "Error transmitting fax. result=%d: %s.\n", result, t30_completion_code_to_str(result));
00225
00226 return;
00227 }
00228
00229 s->finished = 1;
00230
00231 local_ident = S_OR(t30_get_tx_ident(f), "");
00232 far_ident = S_OR(t30_get_rx_ident(f), "");
00233 pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "SUCCESS");
00234 pbx_builtin_setvar_helper(s->chan, "FAXERROR", NULL);
00235 pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", far_ident);
00236 #if SPANDSP_RELEASE_DATE >= 20090220
00237 pages_transferred = (s->direction) ? stat.pages_tx : stat.pages_rx;
00238 #else
00239 pages_transferred = stat.pages_transferred;
00240 #endif
00241 snprintf(buf, sizeof(buf), "%d", pages_transferred);
00242 pbx_builtin_setvar_helper(s->chan, "FAXPAGES", buf);
00243 snprintf(buf, sizeof(buf), "%d", stat.y_resolution);
00244 pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", buf);
00245 snprintf(buf, sizeof(buf), "%d", stat.bit_rate);
00246 pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", buf);
00247
00248 ast_debug(1, "Fax transmitted successfully.\n");
00249 ast_debug(1, " Remote station ID: %s\n", far_ident);
00250 ast_debug(1, " Pages transferred: %d\n", pages_transferred);
00251 ast_debug(1, " Image resolution: %d x %d\n", stat.x_resolution, stat.y_resolution);
00252 ast_debug(1, " Transfer Rate: %d\n", stat.bit_rate);
00253
00254 ast_manager_event(s->chan, EVENT_FLAG_CALL,
00255 s->direction ? "FaxSent" : "FaxReceived",
00256 "Channel: %s\r\n"
00257 "Exten: %s\r\n"
00258 "CallerID: %s\r\n"
00259 "CallerIDName: %s\r\n"
00260 "ConnectedLineNum: %s\r\n"
00261 "ConnectedLineName: %s\r\n"
00262 "RemoteStationID: %s\r\n"
00263 "LocalStationID: %s\r\n"
00264 "PagesTransferred: %d\r\n"
00265 "Resolution: %d\r\n"
00266 "TransferRate: %d\r\n"
00267 "FileName: %s\r\n",
00268 ast_channel_name(s->chan),
00269 ast_channel_exten(s->chan),
00270 S_COR(ast_channel_caller(s->chan)->id.number.valid, ast_channel_caller(s->chan)->id.number.str, ""),
00271 S_COR(ast_channel_caller(s->chan)->id.name.valid, ast_channel_caller(s->chan)->id.name.str, ""),
00272 S_COR(ast_channel_connected(s->chan)->id.number.valid, ast_channel_connected(s->chan)->id.number.str, ""),
00273 S_COR(ast_channel_connected(s->chan)->id.name.valid, ast_channel_connected(s->chan)->id.name.str, ""),
00274 far_ident,
00275 local_ident,
00276 pages_transferred,
00277 stat.y_resolution,
00278 stat.bit_rate,
00279 s->file_name);
00280 }
00281
00282
00283
00284
00285 static int set_logging(logging_state_t *state)
00286 {
00287 int level = SPAN_LOG_WARNING + option_debug;
00288
00289 span_log_set_message_handler(state, span_message);
00290 span_log_set_level(state, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | level);
00291
00292 return 0;
00293 }
00294
00295 static void set_local_info(t30_state_t *state, fax_session *s)
00296 {
00297 const char *x;
00298
00299 x = pbx_builtin_getvar_helper(s->chan, "LOCALSTATIONID");
00300 if (!ast_strlen_zero(x))
00301 t30_set_tx_ident(state, x);
00302
00303 x = pbx_builtin_getvar_helper(s->chan, "LOCALHEADERINFO");
00304 if (!ast_strlen_zero(x))
00305 t30_set_tx_page_header_info(state, x);
00306 }
00307
00308 static void set_file(t30_state_t *state, fax_session *s)
00309 {
00310 if (s->direction)
00311 t30_set_tx_file(state, s->file_name, -1, -1);
00312 else
00313 t30_set_rx_file(state, s->file_name, -1);
00314 }
00315
00316 static void set_ecm(t30_state_t *state, int ecm)
00317 {
00318 t30_set_ecm_capability(state, ecm);
00319 t30_set_supported_compressions(state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
00320 }
00321
00322
00323
00324
00325
00326 static void *fax_generator_alloc(struct ast_channel *chan, void *params)
00327 {
00328 return params;
00329 }
00330
00331 static int fax_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
00332 {
00333 fax_state_t *fax = (fax_state_t*) data;
00334 uint8_t buffer[AST_FRIENDLY_OFFSET + MAX_SAMPLES * sizeof(uint16_t)];
00335 int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
00336
00337 struct ast_frame outf = {
00338 .frametype = AST_FRAME_VOICE,
00339 .src = __FUNCTION__,
00340 };
00341 ast_format_set(&outf.subclass.format, AST_FORMAT_SLINEAR, 0);
00342
00343 if (samples > MAX_SAMPLES) {
00344 ast_log(LOG_WARNING, "Only generating %d samples, where %d requested\n", MAX_SAMPLES, samples);
00345 samples = MAX_SAMPLES;
00346 }
00347
00348 if ((len = fax_tx(fax, buf, samples)) > 0) {
00349 outf.samples = len;
00350 AST_FRAME_SET_BUFFER(&outf, buffer, AST_FRIENDLY_OFFSET, len * sizeof(int16_t));
00351
00352 if (ast_write(chan, &outf) < 0) {
00353 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", ast_channel_name(chan), strerror(errno));
00354 return -1;
00355 }
00356 }
00357
00358 return 0;
00359 }
00360
00361 static struct ast_generator generator = {
00362 alloc: fax_generator_alloc,
00363 generate: fax_generator_generate,
00364 };
00365
00366
00367
00368
00369 static int transmit_audio(fax_session *s)
00370 {
00371 int res = -1;
00372 struct ast_format original_read_fmt;
00373 struct ast_format original_write_fmt;
00374 fax_state_t fax;
00375 t30_state_t *t30state;
00376 struct ast_frame *inf = NULL;
00377 int last_state = 0;
00378 struct timeval now, start, state_change;
00379 enum ast_t38_state t38_state;
00380 struct ast_control_t38_parameters t38_parameters = { .version = 0,
00381 .max_ifp = 800,
00382 .rate = AST_T38_RATE_14400,
00383 .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
00384 .fill_bit_removal = 1,
00385
00386
00387
00388
00389
00390
00391 };
00392
00393 ast_format_clear(&original_read_fmt);
00394 ast_format_clear(&original_write_fmt);
00395
00396
00397 if (s->caller_mode == FALSE) {
00398
00399
00400
00401
00402 if ((t38_state = ast_channel_get_t38_state(s->chan)) == T38_STATE_NEGOTIATED) {
00403 return 1;
00404 } else if ((t38_state != T38_STATE_UNAVAILABLE) &&
00405 (t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE,
00406 (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0))) {
00407
00408 unsigned int timeout = 5000;
00409 int ms;
00410
00411 ast_debug(1, "Negotiating T.38 for receive on %s\n", ast_channel_name(s->chan));
00412 while (timeout > 0) {
00413 ms = ast_waitfor(s->chan, 1000);
00414 if (ms < 0) {
00415 ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(s->chan));
00416 return -1;
00417 }
00418 if (!ms) {
00419
00420 if (timeout > 0) {
00421 timeout -= 1000;
00422 continue;
00423 } else {
00424 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(s->chan));
00425 break;
00426 }
00427 }
00428 if (!(inf = ast_read(s->chan))) {
00429 return -1;
00430 }
00431 if ((inf->frametype == AST_FRAME_CONTROL) &&
00432 (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
00433 (inf->datalen == sizeof(t38_parameters))) {
00434 struct ast_control_t38_parameters *parameters = inf->data.ptr;
00435
00436 switch (parameters->request_response) {
00437 case AST_T38_NEGOTIATED:
00438 ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(s->chan));
00439 res = 1;
00440 break;
00441 case AST_T38_REFUSED:
00442 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(s->chan));
00443 break;
00444 default:
00445 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(s->chan));
00446 break;
00447 }
00448 ast_frfree(inf);
00449 if (res == 1) {
00450 return 1;
00451 } else {
00452 break;
00453 }
00454 }
00455 ast_frfree(inf);
00456 }
00457 }
00458 }
00459
00460 #if SPANDSP_RELEASE_DATE >= 20080725
00461
00462 t30state = &fax.t30;
00463 #else
00464
00465 t30state = &fax.t30_state;
00466 #endif
00467
00468 ast_format_copy(&original_read_fmt, ast_channel_readformat(s->chan));
00469 if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
00470 res = ast_set_read_format_by_id(s->chan, AST_FORMAT_SLINEAR);
00471 if (res < 0) {
00472 ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
00473 goto done;
00474 }
00475 }
00476
00477 ast_format_copy(&original_write_fmt, ast_channel_writeformat(s->chan));
00478 if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
00479 res = ast_set_write_format_by_id(s->chan, AST_FORMAT_SLINEAR);
00480 if (res < 0) {
00481 ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
00482 goto done;
00483 }
00484 }
00485
00486
00487 fax_init(&fax, s->caller_mode);
00488
00489
00490 set_logging(&fax.logging);
00491 set_logging(&t30state->logging);
00492
00493
00494 set_local_info(t30state, s);
00495 set_file(t30state, s);
00496 set_ecm(t30state, TRUE);
00497
00498 fax_set_transmit_on_idle(&fax, TRUE);
00499
00500 t30_set_phase_e_handler(t30state, phase_e_handler, s);
00501
00502 start = state_change = ast_tvnow();
00503
00504 ast_activate_generator(s->chan, &generator, &fax);
00505
00506 while (!s->finished) {
00507 inf = NULL;
00508
00509 if ((res = ast_waitfor(s->chan, 25)) < 0) {
00510 ast_debug(1, "Error waiting for a frame\n");
00511 break;
00512 }
00513
00514
00515 now = ast_tvnow();
00516 if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
00517 ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
00518 res = -1;
00519 break;
00520 }
00521
00522 if (!res) {
00523
00524 continue;
00525 }
00526
00527
00528 res = 0;
00529
00530 if (!(inf = ast_read(s->chan))) {
00531 ast_debug(1, "Channel hangup\n");
00532 res = -1;
00533 break;
00534 }
00535
00536 ast_debug(10, "frame %d/%u, len=%d\n", inf->frametype, (unsigned int) inf->subclass.format.id, inf->datalen);
00537
00538
00539
00540
00541 if (inf->frametype == AST_FRAME_VOICE && inf->subclass.format.id == AST_FORMAT_SLINEAR) {
00542 if (fax_rx(&fax, inf->data.ptr, inf->samples) < 0) {
00543
00544 ast_log(LOG_WARNING, "fax_rx returned error\n");
00545 res = -1;
00546 break;
00547 }
00548 if (last_state != t30state->state) {
00549 state_change = ast_tvnow();
00550 last_state = t30state->state;
00551 }
00552 } else if ((inf->frametype == AST_FRAME_CONTROL) &&
00553 (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS)) {
00554 struct ast_control_t38_parameters *parameters = inf->data.ptr;
00555
00556 if (parameters->request_response == AST_T38_NEGOTIATED) {
00557
00558 s->t38parameters = *parameters;
00559 ast_debug(1, "T38 negotiated, finishing audio loop\n");
00560 res = 1;
00561 break;
00562 } else if (parameters->request_response == AST_T38_REQUEST_NEGOTIATE) {
00563 t38_parameters.request_response = AST_T38_NEGOTIATED;
00564 ast_debug(1, "T38 request received, accepting\n");
00565
00566 ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
00567
00568
00569
00570 }
00571 }
00572
00573 ast_frfree(inf);
00574 inf = NULL;
00575 }
00576
00577 ast_debug(1, "Loop finished, res=%d\n", res);
00578
00579 if (inf)
00580 ast_frfree(inf);
00581
00582 ast_deactivate_generator(s->chan);
00583
00584
00585
00586
00587 if (res > 0) {
00588 t30_set_phase_e_handler(t30state, NULL, NULL);
00589 }
00590
00591 t30_terminate(t30state);
00592 fax_release(&fax);
00593
00594 done:
00595 if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
00596 if (ast_set_write_format(s->chan, &original_write_fmt) < 0)
00597 ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", ast_channel_name(s->chan));
00598 }
00599
00600 if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
00601 if (ast_set_read_format(s->chan, &original_read_fmt) < 0)
00602 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(s->chan));
00603 }
00604
00605 return res;
00606
00607 }
00608
00609 static int transmit_t38(fax_session *s)
00610 {
00611 int res = 0;
00612 t38_terminal_state_t t38;
00613 struct ast_frame *inf = NULL;
00614 int last_state = 0;
00615 struct timeval now, start, state_change, last_frame;
00616 t30_state_t *t30state;
00617 t38_core_state_t *t38state;
00618
00619 #if SPANDSP_RELEASE_DATE >= 20080725
00620
00621 t30state = &t38.t30;
00622 t38state = &t38.t38_fe.t38;
00623 #else
00624
00625 t30state = &t38.t30_state;
00626 t38state = &t38.t38;
00627 #endif
00628
00629
00630 memset(&t38, 0, sizeof(t38));
00631 if (t38_terminal_init(&t38, s->caller_mode, t38_tx_packet_handler, s->chan) == NULL) {
00632 ast_log(LOG_WARNING, "Unable to start T.38 termination.\n");
00633 res = -1;
00634 goto disable_t38;
00635 }
00636
00637 t38_set_max_datagram_size(t38state, s->t38parameters.max_ifp);
00638
00639 if (s->t38parameters.fill_bit_removal) {
00640 t38_set_fill_bit_removal(t38state, TRUE);
00641 }
00642 if (s->t38parameters.transcoding_mmr) {
00643 t38_set_mmr_transcoding(t38state, TRUE);
00644 }
00645 if (s->t38parameters.transcoding_jbig) {
00646 t38_set_jbig_transcoding(t38state, TRUE);
00647 }
00648
00649
00650 set_logging(&t38.logging);
00651 set_logging(&t30state->logging);
00652 set_logging(&t38state->logging);
00653
00654
00655 set_local_info(t30state, s);
00656 set_file(t30state, s);
00657 set_ecm(t30state, TRUE);
00658
00659 t30_set_phase_e_handler(t30state, phase_e_handler, s);
00660
00661 now = start = state_change = ast_tvnow();
00662
00663 while (!s->finished) {
00664 inf = NULL;
00665
00666 if ((res = ast_waitfor(s->chan, 25)) < 0) {
00667 ast_debug(1, "Error waiting for a frame\n");
00668 break;
00669 }
00670
00671 last_frame = now;
00672
00673
00674 now = ast_tvnow();
00675 if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
00676 ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
00677 res = -1;
00678 break;
00679 }
00680
00681 t38_terminal_send_timeout(&t38, ast_tvdiff_us(now, last_frame) / (1000000 / 8000));
00682
00683 if (!res) {
00684
00685 continue;
00686 }
00687
00688
00689 res = 0;
00690
00691 if (!(inf = ast_read(s->chan))) {
00692 ast_debug(1, "Channel hangup\n");
00693 res = -1;
00694 break;
00695 }
00696
00697 ast_debug(10, "frame %d/%d, len=%d\n", inf->frametype, inf->subclass.integer, inf->datalen);
00698
00699 if (inf->frametype == AST_FRAME_MODEM && inf->subclass.integer == AST_MODEM_T38) {
00700 t38_core_rx_ifp_packet(t38state, inf->data.ptr, inf->datalen, inf->seqno);
00701 if (last_state != t30state->state) {
00702 state_change = ast_tvnow();
00703 last_state = t30state->state;
00704 }
00705 } else if (inf->frametype == AST_FRAME_CONTROL && inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
00706 struct ast_control_t38_parameters *parameters = inf->data.ptr;
00707 if (parameters->request_response == AST_T38_TERMINATED) {
00708 ast_debug(1, "T38 down, finishing\n");
00709 break;
00710 }
00711 }
00712
00713 ast_frfree(inf);
00714 inf = NULL;
00715 }
00716
00717 ast_debug(1, "Loop finished, res=%d\n", res);
00718
00719 if (inf)
00720 ast_frfree(inf);
00721
00722 t30_terminate(t30state);
00723 t38_terminal_release(&t38);
00724
00725 disable_t38:
00726
00727
00728
00729 if ((s->caller_mode == FALSE) &&
00730 (ast_channel_get_t38_state(s->chan) == T38_STATE_NEGOTIATED)) {
00731 struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
00732
00733 if (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0) {
00734
00735 unsigned int timeout = 5000;
00736 int ms;
00737
00738 ast_debug(1, "Shutting down T.38 on %s\n", ast_channel_name(s->chan));
00739 while (timeout > 0) {
00740 ms = ast_waitfor(s->chan, 1000);
00741 if (ms < 0) {
00742 ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(s->chan));
00743 return -1;
00744 }
00745 if (!ms) {
00746
00747 if (timeout > 0) {
00748 timeout -= 1000;
00749 continue;
00750 } else {
00751 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 shutdown.\n", ast_channel_name(s->chan));
00752 break;
00753 }
00754 }
00755 if (!(inf = ast_read(s->chan))) {
00756 return -1;
00757 }
00758 if ((inf->frametype == AST_FRAME_CONTROL) &&
00759 (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
00760 (inf->datalen == sizeof(t38_parameters))) {
00761 struct ast_control_t38_parameters *parameters = inf->data.ptr;
00762
00763 switch (parameters->request_response) {
00764 case AST_T38_TERMINATED:
00765 ast_debug(1, "Shut down T.38 on %s\n", ast_channel_name(s->chan));
00766 break;
00767 case AST_T38_REFUSED:
00768 ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", ast_channel_name(s->chan));
00769 break;
00770 default:
00771 ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", ast_channel_name(s->chan));
00772 break;
00773 }
00774 ast_frfree(inf);
00775 break;
00776 }
00777 ast_frfree(inf);
00778 }
00779 }
00780 }
00781
00782 return res;
00783 }
00784
00785 static int transmit(fax_session *s)
00786 {
00787 int res = 0;
00788
00789
00790
00791 pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "FAILED");
00792 pbx_builtin_setvar_helper(s->chan, "FAXERROR", "Channel problems");
00793
00794 pbx_builtin_setvar_helper(s->chan, "FAXMODE", NULL);
00795 pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", NULL);
00796 pbx_builtin_setvar_helper(s->chan, "FAXPAGES", "0");
00797 pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", NULL);
00798 pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", NULL);
00799
00800 if (ast_channel_state(s->chan) != AST_STATE_UP) {
00801
00802
00803 res = ast_answer(s->chan);
00804 if (res) {
00805 ast_log(LOG_WARNING, "Could not answer channel '%s'\n", ast_channel_name(s->chan));
00806 return res;
00807 }
00808 }
00809
00810 s->t38state = ast_channel_get_t38_state(s->chan);
00811 if (s->t38state != T38_STATE_NEGOTIATED) {
00812
00813 pbx_builtin_setvar_helper(s->chan, "FAXMODE", "audio");
00814 res = transmit_audio(s);
00815 if (res > 0) {
00816
00817 s->t38state = ast_channel_get_t38_state(s->chan);
00818 if (s->t38state != T38_STATE_NEGOTIATED) {
00819 ast_log(LOG_ERROR, "Audio loop reports T38 switchover but t38state != T38_STATE_NEGOTIATED\n");
00820 }
00821 }
00822 }
00823
00824 if (s->t38state == T38_STATE_NEGOTIATED) {
00825 pbx_builtin_setvar_helper(s->chan, "FAXMODE", "T38");
00826 res = transmit_t38(s);
00827 }
00828
00829 if (res) {
00830 ast_log(LOG_WARNING, "Transmission error\n");
00831 res = -1;
00832 } else if (s->finished < 0) {
00833 ast_log(LOG_WARNING, "Transmission failed\n");
00834 } else if (s->finished > 0) {
00835 ast_debug(1, "Transmission finished Ok\n");
00836 }
00837
00838 return res;
00839 }
00840
00841
00842
00843 static int sndfax_exec(struct ast_channel *chan, const char *data)
00844 {
00845 int res = 0;
00846 char *parse;
00847 fax_session session = { 0, };
00848 char restore_digit_detect = 0;
00849
00850 AST_DECLARE_APP_ARGS(args,
00851 AST_APP_ARG(file_name);
00852 AST_APP_ARG(options);
00853 );
00854
00855 if (chan == NULL) {
00856 ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
00857 return -1;
00858 }
00859
00860
00861 if (ast_strlen_zero(data)) {
00862
00863 ast_log(LOG_ERROR, "SendFAX requires an argument (filename)\n");
00864 return -1;
00865 }
00866
00867 parse = ast_strdupa(data);
00868 AST_STANDARD_APP_ARGS(args, parse);
00869
00870 session.caller_mode = TRUE;
00871
00872 if (args.options) {
00873 if (strchr(args.options, 'a'))
00874 session.caller_mode = FALSE;
00875 }
00876
00877
00878 session.direction = 1;
00879 session.file_name = args.file_name;
00880 session.chan = chan;
00881 session.finished = 0;
00882
00883
00884 {
00885 int dummy = sizeof(restore_digit_detect);
00886
00887 ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, &dummy, 0);
00888 }
00889
00890 if (restore_digit_detect) {
00891 char new_digit_detect = 0;
00892
00893 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &new_digit_detect, sizeof(new_digit_detect), 0);
00894 }
00895
00896
00897 {
00898 char new_fax_detect = 0;
00899
00900 ast_channel_setoption(chan, AST_OPTION_FAX_DETECT, &new_fax_detect, sizeof(new_fax_detect), 0);
00901 }
00902
00903 res = transmit(&session);
00904
00905 if (restore_digit_detect) {
00906 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, sizeof(restore_digit_detect), 0);
00907 }
00908
00909 return res;
00910 }
00911
00912 static int rcvfax_exec(struct ast_channel *chan, const char *data)
00913 {
00914 int res = 0;
00915 char *parse;
00916 fax_session session;
00917 char restore_digit_detect = 0;
00918
00919 AST_DECLARE_APP_ARGS(args,
00920 AST_APP_ARG(file_name);
00921 AST_APP_ARG(options);
00922 );
00923
00924 if (chan == NULL) {
00925 ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
00926 return -1;
00927 }
00928
00929
00930 if (ast_strlen_zero(data)) {
00931
00932 ast_log(LOG_ERROR, "ReceiveFAX requires an argument (filename)\n");
00933 return -1;
00934 }
00935
00936 parse = ast_strdupa(data);
00937 AST_STANDARD_APP_ARGS(args, parse);
00938
00939 session.caller_mode = FALSE;
00940
00941 if (args.options) {
00942 if (strchr(args.options, 'c'))
00943 session.caller_mode = TRUE;
00944 }
00945
00946
00947 session.direction = 0;
00948 session.file_name = args.file_name;
00949 session.chan = chan;
00950 session.finished = 0;
00951
00952
00953 {
00954 int dummy = sizeof(restore_digit_detect);
00955
00956 ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, &dummy, 0);
00957 }
00958
00959 if (restore_digit_detect) {
00960 char new_digit_detect = 0;
00961
00962 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &new_digit_detect, sizeof(new_digit_detect), 0);
00963 }
00964
00965
00966 {
00967 char new_fax_detect = 0;
00968
00969 ast_channel_setoption(chan, AST_OPTION_FAX_DETECT, &new_fax_detect, sizeof(new_fax_detect), 0);
00970 }
00971
00972 res = transmit(&session);
00973
00974 if (restore_digit_detect) {
00975 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, sizeof(restore_digit_detect), 0);
00976 }
00977
00978 return res;
00979 }
00980
00981 static int unload_module(void)
00982 {
00983 int res;
00984
00985 res = ast_unregister_application(app_sndfax_name);
00986 res |= ast_unregister_application(app_rcvfax_name);
00987
00988 return res;
00989 }
00990
00991 static int load_module(void)
00992 {
00993 int res ;
00994
00995 res = ast_register_application_xml(app_sndfax_name, sndfax_exec);
00996 res |= ast_register_application_xml(app_rcvfax_name, rcvfax_exec);
00997
00998
00999 span_set_message_handler(NULL);
01000
01001 return res;
01002 }
01003
01004
01005 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Simple FAX Application",
01006 .load = load_module,
01007 .unload = unload_module,
01008 );
01009
01010