1 diff -urN asterisk-1.0.9-o/apps/app_rxfax.c asterisk-1.0.9-n/apps/app_rxfax.c
2 --- asterisk-1.0.9-o/apps/app_rxfax.c 1969-12-31 17:00:00.000000000 -0700
3 +++ asterisk-1.0.9-n/apps/app_rxfax.c 2005-09-20 13:01:02.000000000 -0600
6 + * Asterisk -- A telephony toolkit for Linux.
8 + * Trivial application to receive a TIFF FAX file
10 + * Copyright (C) 2003, Steve Underwood
12 + * Steve Underwood <steveu@coppice.org>
14 + * This program is free software, distributed under the terms of
15 + * the GNU General Public License
18 +#include <asterisk/lock.h>
19 +#include <asterisk/file.h>
20 +#include <asterisk/logger.h>
21 +#include <asterisk/channel.h>
22 +#include <asterisk/pbx.h>
23 +#include <asterisk/module.h>
24 +#include <asterisk/translate.h>
25 +#include <asterisk/dsp.h>
26 +#include <asterisk/manager.h>
36 +static char *tdesc = "Trivial FAX Receive Application";
38 +static char *app = "RxFAX";
40 +static char *synopsis = "Receive a FAX to a file";
42 +static char *descrip =
43 +" RxFAX(filename[|caller][|debug]): Receives a FAX from the channel into the\n"
44 +"given filename. If the file exists it will be overwritten. The file\n"
45 +"should be in TIFF/F format.\n"
46 +"The \"caller\" option makes the application behave as a calling machine,\n"
47 +"rather than the answering machine. The default behaviour is to behave as\n"
48 +"an answering machine.\n"
49 +"Uses LOCALSTATIONID to identify itself to the remote end.\n"
50 +" LOCALHEADERINFO to generate a header line on each page.\n"
51 +"Sets REMOTESTATIONID to the sender CSID.\n"
52 +" FAXPAGES to the number of pages received.\n"
53 +" FAXBITRATE to the transmition rate.\n"
54 +" FAXRESOLUTION to the resolution.\n"
55 +"Returns -1 when the user hangs up.\n"
56 +"Returns 0 otherwise.\n";
62 +#define MAX_BLOCK_SIZE 240
64 +static void t30_flush(t30_state_t *s, int which)
68 +/*- End of function --------------------------------------------------------*/
70 +static void phase_e_handler(t30_state_t *s, void *user_data, int result)
72 + struct ast_channel *chan;
74 + char local_ident[21];
78 + chan = (struct ast_channel *) user_data;
81 + fax_get_transfer_statistics(s, &t);
82 + fax_get_far_ident(s, far_ident);
83 + fax_get_local_ident(s, local_ident);
84 + ast_log(LOG_DEBUG, "==============================================================================\n");
85 + ast_log(LOG_DEBUG, "Fax successfully received.\n");
86 + ast_log(LOG_DEBUG, "Remote station id: %s\n", far_ident);
87 + ast_log(LOG_DEBUG, "Local station id: %s\n", local_ident);
88 + ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
89 + ast_log(LOG_DEBUG, "Image resolution: %i x %i\n", t.column_resolution, t.row_resolution);
90 + ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
91 + ast_log(LOG_DEBUG, "==============================================================================\n");
92 + manager_event(EVENT_FLAG_CALL,
93 + "FaxReceived", "Channel: %s\nExten: %s\nCallerID: %s\nRemoteStationID: %s\nLocalStationID: %s\nPagesTransferred: %i\nResolution: %i\nTransferRate: %i\nFileName: %s\n",
96 +#if (ASTERISK_VERSION_NUM <= 011000)
99 + (chan->cid.cid_num) ? chan->cid.cid_num : "",
103 + t.pages_transferred,
107 + pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", far_ident);
108 + snprintf(buf, sizeof(buf), "%i", t.pages_transferred);
109 + pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
110 + snprintf(buf, sizeof(buf), "%i", t.row_resolution);
111 + pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", buf);
112 + snprintf(buf, sizeof(buf), "%i", t.bit_rate);
113 + pbx_builtin_setvar_helper(chan, "FAXBITRATE", buf);
117 + ast_log(LOG_DEBUG, "==============================================================================\n");
118 + ast_log(LOG_DEBUG, "Fax receive not successful.\n");
119 + ast_log(LOG_DEBUG, "==============================================================================\n");
122 +/*- End of function --------------------------------------------------------*/
124 +static void phase_d_handler(t30_state_t *s, void *user_data, int result)
126 + struct ast_channel *chan;
129 + chan = (struct ast_channel *) user_data;
132 + fax_get_transfer_statistics(s, &t);
133 + ast_log(LOG_DEBUG, "==============================================================================\n");
134 + ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
135 + ast_log(LOG_DEBUG, "Image size: %i x %i\n", t.columns, t.rows);
136 + ast_log(LOG_DEBUG, "Image resolution %i x %i\n", t.column_resolution, t.row_resolution);
137 + ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
138 + ast_log(LOG_DEBUG, "Bad rows %i\n", t.bad_rows);
139 + ast_log(LOG_DEBUG, "Longest bad row run %i\n", t.longest_bad_row_run);
140 + ast_log(LOG_DEBUG, "Compression type %i\n", t.encoding);
141 + ast_log(LOG_DEBUG, "Image size (bytes) %i\n", t.image_size);
142 + ast_log(LOG_DEBUG, "==============================================================================\n");
145 +/*- End of function --------------------------------------------------------*/
147 +static int rxfax_exec(struct ast_channel *chan, void *data)
150 + char template_file[256];
151 + char target_file[256];
164 + struct localuser *u;
165 + struct ast_frame *inf = NULL;
166 + struct ast_frame outf;
168 + int original_read_fmt;
169 + int original_write_fmt;
171 + uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET];
172 + uint8_t *buf = __buf + AST_FRIENDLY_OFFSET;
176 + ast_log(LOG_WARNING, "Fax receive channel is NULL. Giving up.\n");
180 + /* The next few lines of code parse out the filename and header from the input string */
183 + /* No data implies no filename or anything is present */
184 + ast_log(LOG_WARNING, "Rxfax requires an argument (filename)\n");
188 + calling_party = FALSE;
190 + target_file[0] = '\0';
192 + for (option = 0, v = s = data; v; option++, s++)
195 + v = strchr(s, '|');
196 + s = (v) ? v : s + strlen(s);
197 + strncpy(buf, t, s - t);
201 + /* The first option is always the file name */
205 + strncpy(target_file, t, len);
206 + target_file[len] = '\0';
207 + /* Allow the use of %d in the file name for a wild card of sorts, to
208 + create a new file with the specified name scheme */
209 + if ((x = strchr(target_file, '%')) && x[1] == 'd')
211 + strcpy(template_file, target_file);
215 + snprintf(target_file, 256, template_file, 1);
218 + while (ast_fileexists(target_file, "", chan->language) != -1);
221 + else if (strncmp("caller", t, s - t) == 0)
223 + calling_party = TRUE;
225 + else if (strncmp("debug", t, s - t) == 0)
235 + if (chan->_state != AST_STATE_UP)
237 + /* Shouldn't need this, but checking to see if channel is already answered
238 + * Theoretically asterisk should already have answered before running the app */
239 + res = ast_answer(chan);
244 + original_read_fmt = chan->readformat;
245 + if (original_read_fmt != AST_FORMAT_SLINEAR)
247 + res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
250 + ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
254 + original_write_fmt = chan->writeformat;
255 + if (original_write_fmt != AST_FORMAT_SLINEAR)
257 + res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
260 + ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
261 + res = ast_set_read_format(chan, original_read_fmt);
263 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
267 + fax_init(&fax, calling_party, NULL);
268 + fax.verbose = verbose;
269 + x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
271 + fax_set_local_ident(&fax, x);
272 + x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO");
274 + fax_set_header_info(&fax, x);
275 + fax_set_rx_file(&fax, target_file);
276 + //fax_set_phase_b_handler(&fax, phase_b_handler, chan);
277 + fax_set_phase_d_handler(&fax, phase_d_handler, chan);
278 + fax_set_phase_e_handler(&fax, phase_e_handler, chan);
279 + while (ast_waitfor(chan, -1) > -1)
281 + inf = ast_read(chan);
287 + if (inf->frametype == AST_FRAME_VOICE)
289 + if (fax_rx_process(&fax, inf->data, inf->samples))
291 + samples = (inf->samples <= MAX_BLOCK_SIZE) ? inf->samples : MAX_BLOCK_SIZE;
292 + len = fax_tx_process(&fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples);
295 + memset(&outf, 0, sizeof(outf));
296 + outf.frametype = AST_FRAME_VOICE;
297 + outf.subclass = AST_FORMAT_SLINEAR;
298 + outf.datalen = len*sizeof(int16_t);
299 + outf.samples = len;
300 + outf.data = &buf[AST_FRIENDLY_OFFSET];
301 + outf.offset = AST_FRIENDLY_OFFSET;
302 + outf.src = "RxFAX";
303 + if (ast_write(chan, &outf) < 0)
305 + ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
314 + ast_log(LOG_DEBUG, "Got hangup\n");
317 + if (original_read_fmt != AST_FORMAT_SLINEAR)
319 + res = ast_set_read_format(chan, original_read_fmt);
321 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
323 + if (original_write_fmt != AST_FORMAT_SLINEAR)
325 + res = ast_set_write_format(chan, original_write_fmt);
327 + ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name);
333 + ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
335 + LOCAL_USER_REMOVE(u);
338 +/*- End of function --------------------------------------------------------*/
340 +int unload_module(void)
342 + STANDARD_HANGUP_LOCALUSERS;
343 + return ast_unregister_application(app);
345 +/*- End of function --------------------------------------------------------*/
347 +int load_module(void)
349 + return ast_register_application(app, rxfax_exec, synopsis, descrip);
352 +char *description(void)
356 +/*- End of function --------------------------------------------------------*/
361 + STANDARD_USECOUNT(res);
364 +/*- End of function --------------------------------------------------------*/
368 + return ASTERISK_GPL_KEY;
370 +/*- End of function --------------------------------------------------------*/
371 +/*- End of file ------------------------------------------------------------*/
372 diff -urN asterisk-1.0.9-o/apps/app_rxfax_test.c asterisk-1.0.9-n/apps/app_rxfax_test.c
373 --- asterisk-1.0.9-o/apps/app_rxfax_test.c 1969-12-31 17:00:00.000000000 -0700
374 +++ asterisk-1.0.9-n/apps/app_rxfax_test.c 2005-09-20 13:01:02.000000000 -0600
377 + * Asterisk -- A telephony toolkit for Linux.
379 + * Trivial application to receive a TIFF FAX file
381 + * Copyright (C) 2003, Steve Underwood
383 + * Steve Underwood <steveu@coppice.org>
385 + * This program is free software, distributed under the terms of
386 + * the GNU General Public License
389 +#include <asterisk/lock.h>
390 +#include <asterisk/file.h>
391 +#include <asterisk/logger.h>
392 +#include <asterisk/channel.h>
393 +#include <asterisk/pbx.h>
394 +#include <asterisk/module.h>
395 +#include <asterisk/translate.h>
396 +#include <asterisk/dsp.h>
397 +#include <asterisk/manager.h>
401 +#include <pthread.h>
405 +#include <spandsp.h>
407 +static char *tdesc = "Trivial FAX Receive Application";
409 +static char *app = "RxFAX";
411 +static char *synopsis = "Receive a FAX to a file";
413 +static char *descrip =
414 +" RxFAX(filename[|caller][|debug]): Receives a FAX from the channel into the\n"
415 +"given filename. If the file exists it will be overwritten. The file\n"
416 +"should be in TIFF/F format.\n"
417 +"The \"caller\" option makes the application behave as a calling machine,\n"
418 +"rather than the answering machine. The default behaviour is to behave as\n"
419 +"an answering machine.\n"
420 +"Uses LOCALSTATIONID to identify itself to the remote end.\n"
421 +" LOCALHEADERINFO to generate a header line on each page.\n"
422 +"Sets REMOTESTATIONID to the sender CSID.\n"
423 +" FAXPAGES to the number of pages received.\n"
424 +" FAXBITRATE to the transmition rate.\n"
425 +" FAXRESOLUTION to the resolution.\n"
426 +"Returns -1 when the user hangs up.\n"
427 +"Returns 0 otherwise.\n";
429 +STANDARD_LOCAL_USER;
433 +#define MAX_BLOCK_SIZE 240
435 +static void t30_flush(t30_state_t *s, int which)
439 +/*- End of function --------------------------------------------------------*/
441 +static void phase_e_handler(t30_state_t *s, void *user_data, int result)
443 + struct ast_channel *chan;
445 + char local_ident[21];
446 + char far_ident[21];
449 + chan = (struct ast_channel *) user_data;
452 + fax_get_transfer_statistics(s, &t);
453 + fax_get_far_ident(s, far_ident);
454 + fax_get_local_ident(s, local_ident);
455 + ast_log(LOG_DEBUG, "==============================================================================\n");
456 + ast_log(LOG_DEBUG, "Fax successfully received.\n");
457 + ast_log(LOG_DEBUG, "Remote station id: %s\n", far_ident);
458 + ast_log(LOG_DEBUG, "Local station id: %s\n", local_ident);
459 + ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
460 + ast_log(LOG_DEBUG, "Image resolution: %i x %i\n", t.column_resolution, t.row_resolution);
461 + ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
462 + ast_log(LOG_DEBUG, "==============================================================================\n");
463 + manager_event(EVENT_FLAG_CALL,
464 + "FaxReceived", "Channel: %s\nExten: %s\nCallerID: %s\nRemoteStationID: %s\nLocalStationID: %s\nPagesTransferred: %i\nResolution: %i\nTransferRate: %i\nFileName: %s\n",
467 +#if (ASTERISK_VERSION_NUM <= 011000)
470 + (chan->cid.cid_num) ? chan->cid.cid_num : "",
474 + t.pages_transferred,
478 + pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", far_ident);
479 + snprintf(buf, sizeof(buf), "%i", t.pages_transferred);
480 + pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
481 + snprintf(buf, sizeof(buf), "%i", t.row_resolution);
482 + pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", buf);
483 + snprintf(buf, sizeof(buf), "%i", t.bit_rate);
484 + pbx_builtin_setvar_helper(chan, "FAXBITRATE", buf);
488 + ast_log(LOG_DEBUG, "==============================================================================\n");
489 + ast_log(LOG_DEBUG, "Fax receive not successful.\n");
490 + ast_log(LOG_DEBUG, "==============================================================================\n");
493 +/*- End of function --------------------------------------------------------*/
495 +static void phase_d_handler(t30_state_t *s, void *user_data, int result)
497 + struct ast_channel *chan;
500 + chan = (struct ast_channel *) user_data;
503 + fax_get_transfer_statistics(s, &t);
504 + ast_log(LOG_DEBUG, "==============================================================================\n");
505 + ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
506 + ast_log(LOG_DEBUG, "Image size: %i x %i\n", t.columns, t.rows);
507 + ast_log(LOG_DEBUG, "Image resolution %i x %i\n", t.column_resolution, t.row_resolution);
508 + ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
509 + ast_log(LOG_DEBUG, "Bad rows %i\n", t.bad_rows);
510 + ast_log(LOG_DEBUG, "Longest bad row run %i\n", t.longest_bad_row_run);
511 + ast_log(LOG_DEBUG, "Compression type %i\n", t.encoding);
512 + ast_log(LOG_DEBUG, "Image size (bytes) %i\n", t.image_size);
513 + ast_log(LOG_DEBUG, "==============================================================================\n");
516 +/*- End of function --------------------------------------------------------*/
518 +static void *fax_gen_alloc(struct ast_channel *chan, void *params)
522 +/*- End of function --------------------------------------------------------*/
524 +static void fax_gen_release(struct ast_channel *chan, void *data)
528 +/*- End of function --------------------------------------------------------*/
530 +static int fax_gen_generate(struct ast_channel *chan, void *data, int len, int samples)
532 + struct ast_frame f;
533 + uint8_t buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET];
536 + fax = (t30_state_t *) data;
537 + if (len > sizeof (buf))
539 + ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", (int)(sizeof (buf) / sizeof (signed short)), len);
540 + len = sizeof (buf);
543 + len = fax_tx_process(fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples);
544 + f.frametype = AST_FRAME_VOICE;
545 + f.subclass = AST_FORMAT_SLINEAR;
546 + f.offset = AST_FRIENDLY_OFFSET;
548 + f.data = &buf[AST_FRIENDLY_OFFSET];
549 + f.datalen = len*sizeof(int16_t);
551 + f.src = "app_txfax";
552 + if (ast_write(chan, &f) < 0)
554 + ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
559 +/*- End of function --------------------------------------------------------*/
561 +static struct ast_generator fax_gen =
563 + alloc:fax_gen_alloc,
564 + release:fax_gen_release,
565 + generate:fax_gen_generate,
568 +static int rxfax_exec(struct ast_channel *chan, void *data)
571 + char template_file[256];
572 + char target_file[256];
583 + struct localuser *u;
584 + struct ast_frame *inf = NULL;
586 + int original_read_fmt;
587 + int original_write_fmt;
591 + ast_log(LOG_WARNING, "Fax receive channel is NULL. Giving up.\n");
595 + /* The next few lines of code parse out the filename and header from the input string */
598 + /* No data implies no filename or anything is present */
599 + ast_log(LOG_WARNING, "Rxfax requires an argument (filename)\n");
603 + calling_party = FALSE;
605 + target_file[0] = '\0';
607 + for (option = 0, v = s = data; v; option++, s++)
610 + v = strchr(s, '|');
611 + s = (v) ? v : s + strlen(s);
612 + strncpy(buf, t, s - t);
616 + /* The first option is always the file name */
620 + strncpy(target_file, t, len);
621 + target_file[len] = '\0';
622 + /* Allow the use of %d in the file name for a wild card of sorts, to
623 + create a new file with the specified name scheme */
624 + if ((x = strchr(target_file, '%')) && x[1] == 'd')
626 + strcpy(template_file, target_file);
630 + snprintf(target_file, 256, template_file, 1);
633 + while (ast_fileexists(target_file, "", chan->language) != -1);
636 + else if (strncmp("caller", t, s - t) == 0)
638 + calling_party = TRUE;
640 + else if (strncmp("debug", t, s - t) == 0)
650 + if (chan->_state != AST_STATE_UP)
652 + /* Shouldn't need this, but checking to see if channel is already answered
653 + * Theoretically asterisk should already have answered before running the app */
654 + res = ast_answer(chan);
659 + original_read_fmt = chan->readformat;
660 + if (original_read_fmt != AST_FORMAT_SLINEAR)
662 + res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
665 + ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
669 + original_write_fmt = chan->writeformat;
670 + if (original_write_fmt != AST_FORMAT_SLINEAR)
672 + res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
675 + ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
676 + res = ast_set_read_format(chan, original_read_fmt);
678 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
682 + fax_init(&fax, calling_party, NULL);
683 + fax.verbose = verbose;
684 + x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
686 + fax_set_local_ident(&fax, x);
687 + x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO");
689 + fax_set_header_info(&fax, x);
690 + fax_set_rx_file(&fax, target_file);
691 + //fax_set_phase_b_handler(&fax, phase_b_handler, chan);
692 + fax_set_phase_d_handler(&fax, phase_d_handler, chan);
693 + fax_set_phase_e_handler(&fax, phase_e_handler, chan);
694 + if (ast_activate_generator(chan, &fax_gen, &fax) < 0)
696 + LOCAL_USER_REMOVE (u);
697 + ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
701 + while (ast_waitfor(chan, -1) > -1)
703 + inf = ast_read(chan);
709 + if (inf->frametype == AST_FRAME_VOICE)
711 + if (fax_rx_process(&fax, inf->data, inf->samples))
718 + ast_log(LOG_DEBUG, "Got hangup\n");
721 + ast_deactivate_generator(chan);
722 + if (original_read_fmt != AST_FORMAT_SLINEAR)
724 + res = ast_set_read_format(chan, original_read_fmt);
726 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
728 + if (original_write_fmt != AST_FORMAT_SLINEAR)
730 + res = ast_set_write_format(chan, original_write_fmt);
732 + ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name);
737 + ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
739 + LOCAL_USER_REMOVE(u);
742 +/*- End of function --------------------------------------------------------*/
744 +int unload_module(void)
746 + STANDARD_HANGUP_LOCALUSERS;
747 + return ast_unregister_application(app);
749 +/*- End of function --------------------------------------------------------*/
751 +int load_module(void)
753 + return ast_register_application(app, rxfax_exec, synopsis, descrip);
756 +char *description(void)
760 +/*- End of function --------------------------------------------------------*/
765 + STANDARD_USECOUNT(res);
768 +/*- End of function --------------------------------------------------------*/
772 + return ASTERISK_GPL_KEY;
774 +/*- End of function --------------------------------------------------------*/
775 +/*- End of file ------------------------------------------------------------*/
776 diff -urN asterisk-1.0.9-o/apps/app_txfax.c asterisk-1.0.9-n/apps/app_txfax.c
777 --- asterisk-1.0.9-o/apps/app_txfax.c 1969-12-31 17:00:00.000000000 -0700
778 +++ asterisk-1.0.9-n/apps/app_txfax.c 2005-09-20 13:01:02.000000000 -0600
781 + * Asterisk -- A telephony toolkit for Linux.
783 + * Trivial application to send a TIFF file as a FAX
785 + * Copyright (C) 2003, Steve Underwood
787 + * Steve Underwood <steveu@coppice.org>
789 + * This program is free software, distributed under the terms of
790 + * the GNU General Public License
793 +#include <asterisk/lock.h>
794 +#include <asterisk/file.h>
795 +#include <asterisk/logger.h>
796 +#include <asterisk/channel.h>
797 +#include <asterisk/pbx.h>
798 +#include <asterisk/module.h>
799 +#include <asterisk/translate.h>
803 +#include <pthread.h>
807 +#include <spandsp.h>
809 +static char *tdesc = "Trivial FAX Transmit Application";
811 +static char *app = "TxFAX";
813 +static char *synopsis = "Send a FAX file";
815 +static char *descrip =
816 +" TxFAX(filename[|caller][|debug]): Send a given TIFF file to the channel as a FAX.\n"
817 +"The \"caller\" option makes the application behave as a calling machine,\n"
818 +"rather than the answering machine. The default behaviour is to behave as\n"
819 +"an answering machine.\n"
820 +"Uses LOCALSTATIONID to identify itself to the remote end.\n"
821 +" LOCALHEADERINFO to generate a header line on each page.\n"
822 +"Sets REMOTESTATIONID to the receiver CSID.\n"
823 +"Returns -1 when the user hangs up, or if the file does not exist.\n"
824 +"Returns 0 otherwise.\n";
826 +STANDARD_LOCAL_USER;
830 +#define MAX_BLOCK_SIZE 240
832 +static void t30_flush(t30_state_t *s, int which)
836 +/*- End of function --------------------------------------------------------*/
838 +static void phase_e_handler(t30_state_t *s, void *user_data, int result)
840 + struct ast_channel *chan;
841 + char far_ident[21];
843 + chan = (struct ast_channel *) user_data;
846 + fax_get_far_ident(s, far_ident);
847 + pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", far_ident);
851 + ast_log(LOG_DEBUG, "==============================================================================\n");
852 + ast_log(LOG_DEBUG, "Fax send not successful.\n");
853 + ast_log(LOG_DEBUG, "==============================================================================\n");
856 +/*- End of function --------------------------------------------------------*/
858 +static int txfax_exec(struct ast_channel *chan, void *data)
861 + char source_file[256];
873 + struct localuser *u;
874 + struct ast_frame *inf = NULL;
875 + struct ast_frame outf;
877 + int original_read_fmt;
878 + int original_write_fmt;
880 + uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET];
881 + uint8_t *buf = __buf + AST_FRIENDLY_OFFSET;
885 + ast_log(LOG_WARNING, "Fax transmit channel is NULL. Giving up.\n");
889 + /* The next few lines of code parse out the filename and header from the input string */
892 + /* No data implies no filename or anything is present */
893 + ast_log(LOG_WARNING, "Txfax requires an argument (filename)\n");
897 + calling_party = FALSE;
899 + source_file[0] = '\0';
901 + for (option = 0, v = s = data; v; option++, s++)
904 + v = strchr(s, '|');
905 + s = (v) ? v : s + strlen(s);
906 + strncpy(buf, t, s - t);
910 + /* The first option is always the file name */
914 + strncpy(source_file, t, len);
915 + source_file[len] = '\0';
917 + else if (strncmp("caller", t, s - t) == 0)
919 + calling_party = TRUE;
921 + else if (strncmp("debug", t, s - t) == 0)
931 + if (chan->_state != AST_STATE_UP)
933 + /* Shouldn't need this, but checking to see if channel is already answered
934 + * Theoretically asterisk should already have answered before running the app */
935 + res = ast_answer(chan);
940 + original_read_fmt = chan->readformat;
941 + if (original_read_fmt != AST_FORMAT_SLINEAR)
943 + res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
946 + ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
950 + original_write_fmt = chan->writeformat;
951 + if (original_write_fmt != AST_FORMAT_SLINEAR)
953 + res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
956 + ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
957 + res = ast_set_read_format(chan, original_read_fmt);
959 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
963 + fax_init(&fax, calling_party, NULL);
964 + fax.verbose = verbose;
966 + x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
968 + fax_set_local_ident(&fax, x);
969 + x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO");
971 + fax_set_header_info(&fax, x);
972 + fax_set_tx_file(&fax, source_file);
973 + //fax_set_phase_b_handler(&fax, phase_b_handler, chan);
974 + //fax_set_phase_d_handler(&fax, phase_d_handler, chan);
975 + fax_set_phase_e_handler(&fax, phase_e_handler, chan);
976 + while (ast_waitfor(chan, -1) > -1)
978 + inf = ast_read(chan);
984 + if (inf->frametype == AST_FRAME_VOICE)
986 + if (fax_rx_process(&fax, inf->data, inf->samples))
988 + samples = (inf->samples <= MAX_BLOCK_SIZE) ? inf->samples : MAX_BLOCK_SIZE;
989 + len = fax_tx_process(&fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples);
992 + memset(&outf, 0, sizeof(outf));
993 + outf.frametype = AST_FRAME_VOICE;
994 + outf.subclass = AST_FORMAT_SLINEAR;
995 + outf.datalen = len*sizeof(int16_t);
996 + outf.samples = len;
997 + outf.data = &buf[AST_FRIENDLY_OFFSET];
998 + outf.offset = AST_FRIENDLY_OFFSET;
999 + if (ast_write(chan, &outf) < 0)
1001 + ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
1010 + ast_log(LOG_DEBUG, "Got hangup\n");
1013 + if (original_read_fmt != AST_FORMAT_SLINEAR)
1015 + res = ast_set_read_format(chan, original_read_fmt);
1017 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
1019 + if (original_write_fmt != AST_FORMAT_SLINEAR)
1021 + res = ast_set_write_format(chan, original_write_fmt);
1023 + ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name);
1025 + fax_release(&fax);
1029 + ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
1031 + LOCAL_USER_REMOVE(u);
1034 +/*- End of function --------------------------------------------------------*/
1036 +int unload_module(void)
1038 + STANDARD_HANGUP_LOCALUSERS;
1039 + return ast_unregister_application(app);
1041 +/*- End of function --------------------------------------------------------*/
1043 +int load_module(void)
1045 + return ast_register_application(app, txfax_exec, synopsis, descrip);
1047 +/*- End of function --------------------------------------------------------*/
1049 +char *description(void)
1053 +/*- End of function --------------------------------------------------------*/
1059 + STANDARD_USECOUNT(res);
1062 +/*- End of function --------------------------------------------------------*/
1066 + return ASTERISK_GPL_KEY;
1068 +/*- End of function --------------------------------------------------------*/
1069 +/*- End of file ------------------------------------------------------------*/
1070 diff -urN asterisk-1.0.9-o/apps/app_txfax_test.c asterisk-1.0.9-n/apps/app_txfax_test.c
1071 --- asterisk-1.0.9-o/apps/app_txfax_test.c 1969-12-31 17:00:00.000000000 -0700
1072 +++ asterisk-1.0.9-n/apps/app_txfax_test.c 2005-09-20 13:01:02.000000000 -0600
1075 + * Asterisk -- A telephony toolkit for Linux.
1077 + * Trivial application to send a TIFF file as a FAX
1079 + * Copyright (C) 2003, Steve Underwood
1081 + * Steve Underwood <steveu@coppice.org>
1083 + * This program is free software, distributed under the terms of
1084 + * the GNU General Public License
1087 +#include <asterisk/lock.h>
1088 +#include <asterisk/file.h>
1089 +#include <asterisk/logger.h>
1090 +#include <asterisk/channel.h>
1091 +#include <asterisk/pbx.h>
1092 +#include <asterisk/module.h>
1093 +#include <asterisk/translate.h>
1094 +#include <string.h>
1095 +#include <stdlib.h>
1096 +#include <stdint.h>
1097 +#include <pthread.h>
1099 +#include <tiffio.h>
1101 +#include <spandsp.h>
1103 +static char *tdesc = "Trivial FAX Transmit Application";
1105 +static char *app = "TxFAX";
1107 +static char *synopsis = "Send a FAX file";
1109 +static char *descrip =
1110 +" TxFAX(filename[|caller][|debug]): Send a given TIFF file to the channel as a FAX.\n"
1111 +"The \"caller\" option makes the application behave as a calling machine,\n"
1112 +"rather than the answering machine. The default behaviour is to behave as\n"
1113 +"an answering machine.\n"
1114 +"Uses LOCALSTATIONID to identify itself to the remote end.\n"
1115 +" LOCALHEADERINFO to generate a header line on each page.\n"
1116 +"Sets REMOTESTATIONID to the receiver CSID.\n"
1117 +"Returns -1 when the user hangs up, or if the file does not exist.\n"
1118 +"Returns 0 otherwise.\n";
1120 +STANDARD_LOCAL_USER;
1124 +#define MAX_BLOCK_SIZE 240
1126 +static void t30_flush(t30_state_t *s, int which)
1130 +/*- End of function --------------------------------------------------------*/
1132 +static void phase_e_handler(t30_state_t *s, void *user_data, int result)
1134 + struct ast_channel *chan;
1135 + char far_ident[21];
1137 + chan = (struct ast_channel *) user_data;
1140 + fax_get_far_ident(s, far_ident);
1141 + pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", far_ident);
1145 + ast_log(LOG_DEBUG, "==============================================================================\n");
1146 + ast_log(LOG_DEBUG, "Fax send not successful.\n");
1147 + ast_log(LOG_DEBUG, "==============================================================================\n");
1150 +/*- End of function --------------------------------------------------------*/
1152 +static void *fax_gen_alloc(struct ast_channel *chan, void *params)
1156 +/*- End of function --------------------------------------------------------*/
1158 +static void fax_gen_release(struct ast_channel *chan, void *data)
1162 +/*- End of function --------------------------------------------------------*/
1164 +static int fax_gen_generate(struct ast_channel *chan, void *data, int len, int samples)
1166 + struct ast_frame f;
1167 + uint8_t buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET];
1170 + fax = (t30_state_t *) data;
1171 + if (len > sizeof (buf))
1173 + ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", (int)(sizeof (buf) / sizeof (signed short)), len);
1174 + len = sizeof (buf);
1175 + samples = len / 2;
1177 + len = fax_tx_process(fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples);
1178 + f.frametype = AST_FRAME_VOICE;
1179 + f.subclass = AST_FORMAT_SLINEAR;
1180 + f.offset = AST_FRIENDLY_OFFSET;
1182 + f.data = &buf[AST_FRIENDLY_OFFSET];
1183 + f.datalen = len*sizeof(int16_t);
1185 + f.src = "app_txfax";
1186 + if (ast_write(chan, &f) < 0)
1188 + ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
1193 +/*- End of function --------------------------------------------------------*/
1195 +static struct ast_generator fax_gen =
1197 + alloc:fax_gen_alloc,
1198 + release:fax_gen_release,
1199 + generate:fax_gen_generate,
1202 +static int txfax_exec(struct ast_channel *chan, void *data)
1205 + char source_file[256];
1213 + int calling_party;
1216 + struct localuser *u;
1217 + struct ast_frame *inf = NULL;
1219 + int original_read_fmt;
1220 + int original_write_fmt;
1224 + ast_log(LOG_WARNING, "Fax transmit channel is NULL. Giving up.\n");
1228 + /* The next few lines of code parse out the filename and header from the input string */
1231 + /* No data implies no filename or anything is present */
1232 + ast_log(LOG_WARNING, "Txfax requires an argument (filename)\n");
1236 + calling_party = FALSE;
1238 + source_file[0] = '\0';
1240 + for (option = 0, v = s = data; v; option++, s++)
1243 + v = strchr(s, '|');
1244 + s = (v) ? v : s + strlen(s);
1245 + strncpy(buf, t, s - t);
1246 + buf[s - t] = '\0';
1249 + /* The first option is always the file name */
1253 + strncpy(source_file, t, len);
1254 + source_file[len] = '\0';
1256 + else if (strncmp("caller", t, s - t) == 0)
1258 + calling_party = TRUE;
1260 + else if (strncmp("debug", t, s - t) == 0)
1266 + /* Done parsing */
1268 + LOCAL_USER_ADD(u);
1270 + if (chan->_state != AST_STATE_UP)
1272 + /* Shouldn't need this, but checking to see if channel is already answered
1273 + * Theoretically asterisk should already have answered before running the app */
1274 + res = ast_answer(chan);
1279 + original_read_fmt = chan->readformat;
1280 + if (original_read_fmt != AST_FORMAT_SLINEAR)
1282 + res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
1285 + ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
1289 + original_write_fmt = chan->writeformat;
1290 + if (original_write_fmt != AST_FORMAT_SLINEAR)
1292 + res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
1295 + ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
1296 + res = ast_set_read_format(chan, original_read_fmt);
1298 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
1302 + fax_init(&fax, calling_party, NULL);
1303 + fax.verbose = verbose;
1305 + x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
1307 + fax_set_local_ident(&fax, x);
1308 + x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO");
1310 + fax_set_header_info(&fax, x);
1311 + fax_set_tx_file(&fax, source_file);
1312 + //fax_set_phase_b_handler(&fax, phase_b_handler, chan);
1313 + //fax_set_phase_d_handler(&fax, phase_d_handler, chan);
1314 + fax_set_phase_e_handler(&fax, phase_e_handler, chan);
1315 + if (ast_activate_generator(chan, &fax_gen, &fax) < 0)
1317 + LOCAL_USER_REMOVE (u);
1318 + ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
1322 + while (ast_waitfor(chan, -1) > -1)
1324 + inf = ast_read(chan);
1330 + if (inf->frametype == AST_FRAME_VOICE)
1332 + if (fax_rx_process(&fax, inf->data, inf->samples))
1339 + ast_log(LOG_DEBUG, "Got hangup\n");
1342 + ast_deactivate_generator(chan);
1343 + if (original_read_fmt != AST_FORMAT_SLINEAR)
1345 + res = ast_set_read_format(chan, original_read_fmt);
1347 + ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
1349 + if (original_write_fmt != AST_FORMAT_SLINEAR)
1351 + res = ast_set_write_format(chan, original_write_fmt);
1353 + ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name);
1358 + ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
1360 + LOCAL_USER_REMOVE(u);
1363 +/*- End of function --------------------------------------------------------*/
1365 +int unload_module(void)
1367 + STANDARD_HANGUP_LOCALUSERS;
1368 + return ast_unregister_application(app);
1370 +/*- End of function --------------------------------------------------------*/
1372 +int load_module(void)
1374 + return ast_register_application(app, txfax_exec, synopsis, descrip);
1376 +/*- End of function --------------------------------------------------------*/
1378 +char *description(void)
1382 +/*- End of function --------------------------------------------------------*/
1388 + STANDARD_USECOUNT(res);
1391 +/*- End of function --------------------------------------------------------*/
1395 + return ASTERISK_GPL_KEY;
1397 +/*- End of function --------------------------------------------------------*/
1398 +/*- End of file ------------------------------------------------------------*/
1399 diff -urN asterisk-1.0.9-o/apps/Makefile asterisk-1.0.9-n/apps/Makefile
1400 --- asterisk-1.0.9-o/apps/Makefile 2004-09-24 15:32:56.000000000 -0600
1401 +++ asterisk-1.0.9-n/apps/Makefile 2005-09-20 13:01:25.000000000 -0600
1403 APPS+=$(shell if [ -f /usr/local/include/zaptel.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so app_zapscan.so" ; fi)
1404 APPS+=$(shell if [ -f /usr/include/osp/osp.h ]; then echo "app_osplookup.so" ; fi)
1406 +APPS+=$(shell if [ -f /usr/include/spandsp.h ]; then echo "app_rxfax.so app_txfax.so" ; fi)
1407 +APPS+=$(shell if [ -f /usr/local/include/spandsp.h ]; then echo "app_rxfax.so app_txfax.so" ; fi)
1411 ifeq ($(USE_POSTGRES_VM_INTERFACE),1)
1413 for x in $(APPS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
1414 rm -f $(DESTDIR)$(MODULES_DIR)/app_datetime.so
1416 +app_rxfax.so : app_rxfax.o
1417 + $(CC) $(SOLINK) -o $@ $< -lspandsp -ltiff
1419 +app_txfax.so : app_txfax.o
1420 + $(CC) $(SOLINK) -o $@ $< -lspandsp -ltiff
1422 app_voicemail.so : app_voicemail.o
1423 ifeq ($(USE_MYSQL_VM_INTERFACE),1)
1424 $(CC) $(SOLINK) -o $@ $(MLFLAGS) $< -L/usr/lib/mysql -lmysqlclient -lz