Merged revisions 320823 via svnmerge from
[asterisk/asterisk.git] / apps / app_fax.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Simple fax applications
5  * 
6  * 2007-2008, Dmitry Andrianov <asterisk@dima.spb.ru>
7  *
8  * Code based on original implementation by Steve Underwood <steveu@coppice.org>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  *
13  */
14
15 /*** MODULEINFO
16         <defaultenabled>no</defaultenabled>
17         <depend>spandsp</depend>
18         <conflict>res_fax</conflict>
19 ***/
20
21 #include "asterisk.h"
22
23 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
24
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <inttypes.h>
29 #include <pthread.h>
30 #include <errno.h>
31 #include <tiffio.h>
32
33 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
34 #include <spandsp.h>
35 #include <spandsp/version.h>
36
37 #include "asterisk/lock.h"
38 #include "asterisk/file.h"
39 #include "asterisk/logger.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/pbx.h"
42 #include "asterisk/app.h"
43 #include "asterisk/dsp.h"
44 #include "asterisk/module.h"
45 #include "asterisk/manager.h"
46
47 /*** DOCUMENTATION
48         <application name="SendFAX" language="en_US">
49                 <synopsis>
50                         Send a Fax
51                 </synopsis>
52                 <syntax>
53                         <parameter name="filename" required="true">
54                                 <para>Filename of TIFF file to fax</para>
55                         </parameter>
56                         <parameter name="a" required="false">
57                                 <para>Makes the application behave as the answering machine</para>
58                                 <para>(Default behavior is as calling machine)</para>
59                         </parameter>
60                 </syntax>
61                 <description>
62                         <para>Send a given TIFF file to the channel as a FAX.</para>
63                         <para>This application sets the following channel variables:</para>
64                         <variablelist>
65                                 <variable name="LOCALSTATIONID">
66                                         <para>To identify itself to the remote end</para>
67                                 </variable>
68                                 <variable name="LOCALHEADERINFO">
69                                         <para>To generate a header line on each page</para>
70                                 </variable>
71                                 <variable name="FAXSTATUS">
72                                         <value name="SUCCESS"/>
73                                         <value name="FAILED"/>
74                                 </variable>
75                                 <variable name="FAXERROR">
76                                         <para>Cause of failure</para>
77                                 </variable>
78                                 <variable name="REMOTESTATIONID">
79                                         <para>The CSID of the remote side</para>
80                                 </variable>
81                                 <variable name="FAXPAGES">
82                                         <para>Number of pages sent</para>
83                                 </variable>
84                                 <variable name="FAXBITRATE">
85                                         <para>Transmission rate</para>
86                                 </variable>
87                                 <variable name="FAXRESOLUTION">
88                                         <para>Resolution of sent fax</para>
89                                 </variable>
90                         </variablelist>
91                 </description>
92         </application>
93         <application name="ReceiveFAX" language="en_US">
94                 <synopsis>
95                         Receive a Fax
96                 </synopsis>
97                 <syntax>
98                         <parameter name="filename" required="true">
99                                 <para>Filename of TIFF file save incoming fax</para>
100                         </parameter>
101                         <parameter name="c" required="false">
102                                 <para>Makes the application behave as the calling machine</para> 
103                                 <para>(Default behavior is as answering machine)</para>
104                         </parameter>
105                 </syntax>
106                 <description>
107                         <para>Receives a FAX from the channel into the given filename 
108                         overwriting the file if it already exists.</para>
109                         <para>File created will be in TIFF format.</para>
110
111                         <para>This application sets the following channel variables:</para>
112                         <variablelist>
113                                 <variable name="LOCALSTATIONID">
114                                         <para>To identify itself to the remote end</para>
115                                 </variable>
116                                 <variable name="LOCALHEADERINFO">
117                                         <para>To generate a header line on each page</para>
118                                 </variable>
119                                 <variable name="FAXSTATUS">
120                                         <value name="SUCCESS"/>
121                                         <value name="FAILED"/>
122                                 </variable>
123                                 <variable name="FAXERROR">
124                                         <para>Cause of failure</para>
125                                 </variable>
126                                 <variable name="REMOTESTATIONID">
127                                         <para>The CSID of the remote side</para>
128                                 </variable>
129                                 <variable name="FAXPAGES">
130                                         <para>Number of pages sent</para>
131                                 </variable>
132                                 <variable name="FAXBITRATE">
133                                         <para>Transmission rate</para>
134                                 </variable>
135                                 <variable name="FAXRESOLUTION">
136                                         <para>Resolution of sent fax</para>
137                                 </variable>
138                         </variablelist>
139                 </description>
140         </application>
141
142  ***/
143
144 static const char app_sndfax_name[] = "SendFAX";
145 static const char app_rcvfax_name[] = "ReceiveFAX";
146
147 #define MAX_SAMPLES 240
148
149 /* Watchdog. I have seen situations when remote fax disconnects (because of poor line
150    quality) while SpanDSP continues staying in T30_STATE_IV_CTC state forever.
151    To avoid this, we terminate when we see that T30 state does not change for 5 minutes.
152    We also terminate application when more than 30 minutes passed regardless of
153    state changes. This is just a precaution measure - no fax should take that long */
154
155 #define WATCHDOG_TOTAL_TIMEOUT  30 * 60
156 #define WATCHDOG_STATE_TIMEOUT  5 * 60
157
158 typedef struct {
159         struct ast_channel *chan;
160         enum ast_t38_state t38state;    /* T38 state of the channel */
161         int direction;                  /* Fax direction: 0 - receiving, 1 - sending */
162         int caller_mode;
163         char *file_name;
164         struct ast_control_t38_parameters t38parameters;
165         volatile int finished;
166 } fax_session;
167
168 static void span_message(int level, const char *msg)
169 {
170         if (level == SPAN_LOG_ERROR) {
171                 ast_log(LOG_ERROR, "%s", msg);
172         } else if (level == SPAN_LOG_WARNING) {
173                 ast_log(LOG_WARNING, "%s", msg);
174         } else {
175                 ast_debug(1, "%s", msg);
176         }
177 }
178
179 static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
180 {
181         struct ast_channel *chan = (struct ast_channel *) user_data;
182
183         struct ast_frame outf = {
184                 .frametype = AST_FRAME_MODEM,
185                 .subclass.integer = AST_MODEM_T38,
186                 .src = __FUNCTION__,
187         };
188
189         /* TODO: Asterisk does not provide means of resending the same packet multiple
190           times so count is ignored at the moment */
191
192         AST_FRAME_SET_BUFFER(&outf, buf, 0, len);
193
194         if (ast_write(chan, &outf) < 0) {
195                 ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
196                 return -1;
197         }
198
199         return 0;
200 }
201
202 static void phase_e_handler(t30_state_t *f, void *user_data, int result)
203 {
204         const char *local_ident;
205         const char *far_ident;
206         char buf[20];
207         fax_session *s = (fax_session *) user_data;
208         t30_stats_t stat;
209         int pages_transferred;
210
211         ast_debug(1, "Fax phase E handler. result=%d\n", result);
212
213         t30_get_transfer_statistics(f, &stat);
214
215         s = (fax_session *) user_data;
216
217         if (result != T30_ERR_OK) {
218                 s->finished = -1;
219
220                 /* FAXSTATUS is already set to FAILED */
221                 pbx_builtin_setvar_helper(s->chan, "FAXERROR", t30_completion_code_to_str(result));
222
223                 ast_log(LOG_WARNING, "Error transmitting fax. result=%d: %s.\n", result, t30_completion_code_to_str(result));
224
225                 return;
226         }
227
228         s->finished = 1;
229
230         local_ident = S_OR(t30_get_tx_ident(f), "");
231         far_ident = S_OR(t30_get_rx_ident(f), "");
232         pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "SUCCESS");
233         pbx_builtin_setvar_helper(s->chan, "FAXERROR", NULL);
234         pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", far_ident);
235 #if SPANDSP_RELEASE_DATE >= 20090220
236         pages_transferred = (s->direction) ? stat.pages_tx : stat.pages_rx;
237 #else
238         pages_transferred = stat.pages_transferred;
239 #endif
240         snprintf(buf, sizeof(buf), "%d", pages_transferred);
241         pbx_builtin_setvar_helper(s->chan, "FAXPAGES", buf);
242         snprintf(buf, sizeof(buf), "%d", stat.y_resolution);
243         pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", buf);
244         snprintf(buf, sizeof(buf), "%d", stat.bit_rate);
245         pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", buf);
246
247         ast_debug(1, "Fax transmitted successfully.\n");
248         ast_debug(1, "  Remote station ID: %s\n", far_ident);
249         ast_debug(1, "  Pages transferred: %d\n", pages_transferred);
250         ast_debug(1, "  Image resolution:  %d x %d\n", stat.x_resolution, stat.y_resolution);
251         ast_debug(1, "  Transfer Rate:     %d\n", stat.bit_rate);
252
253         ast_manager_event(s->chan, EVENT_FLAG_CALL,
254                 s->direction ? "FaxSent" : "FaxReceived",
255                 "Channel: %s\r\n"
256                 "Exten: %s\r\n"
257                 "CallerID: %s\r\n"
258                 "CallerIDName: %s\r\n"
259                 "ConnectedLineNum: %s\r\n"
260                 "ConnectedLineName: %s\r\n"
261                 "RemoteStationID: %s\r\n"
262                 "LocalStationID: %s\r\n"
263                 "PagesTransferred: %d\r\n"
264                 "Resolution: %d\r\n"
265                 "TransferRate: %d\r\n"
266                 "FileName: %s\r\n",
267                 s->chan->name,
268                 s->chan->exten,
269                 S_COR(s->chan->caller.id.number.valid, s->chan->caller.id.number.str, ""),
270                 S_COR(s->chan->caller.id.name.valid, s->chan->caller.id.name.str, ""),
271                 S_COR(s->chan->connected.id.number.valid, s->chan->connected.id.number.str, ""),
272                 S_COR(s->chan->connected.id.name.valid, s->chan->connected.id.name.str, ""),
273                 far_ident,
274                 local_ident,
275                 pages_transferred,
276                 stat.y_resolution,
277                 stat.bit_rate,
278                 s->file_name);
279 }
280
281 /* === Helper functions to configure fax === */
282
283 /* Setup SPAN logging according to Asterisk debug level */
284 static int set_logging(logging_state_t *state)
285 {
286         int level = SPAN_LOG_WARNING + option_debug;
287
288         span_log_set_message_handler(state, span_message);
289         span_log_set_level(state, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | level); 
290
291         return 0;
292 }
293
294 static void set_local_info(t30_state_t *state, fax_session *s)
295 {
296         const char *x;
297
298         x = pbx_builtin_getvar_helper(s->chan, "LOCALSTATIONID");
299         if (!ast_strlen_zero(x))
300                 t30_set_tx_ident(state, x);
301
302         x = pbx_builtin_getvar_helper(s->chan, "LOCALHEADERINFO");
303         if (!ast_strlen_zero(x))
304                 t30_set_tx_page_header_info(state, x);
305 }
306
307 static void set_file(t30_state_t *state, fax_session *s)
308 {
309         if (s->direction)
310                 t30_set_tx_file(state, s->file_name, -1, -1);
311         else
312                 t30_set_rx_file(state, s->file_name, -1);
313 }
314
315 static void set_ecm(t30_state_t *state, int ecm)
316 {
317         t30_set_ecm_capability(state, ecm);
318         t30_set_supported_compressions(state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
319 }
320
321 /* === Generator === */
322
323 /* This function is only needed to return passed params so
324    generator_activate will save it to channel's generatordata */
325 static void *fax_generator_alloc(struct ast_channel *chan, void *params)
326 {
327         return params;
328 }
329
330 static int fax_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
331 {
332         fax_state_t *fax = (fax_state_t*) data;
333         uint8_t buffer[AST_FRIENDLY_OFFSET + MAX_SAMPLES * sizeof(uint16_t)];
334         int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
335     
336         struct ast_frame outf = {
337                 .frametype = AST_FRAME_VOICE,
338                 .src = __FUNCTION__,
339         };
340         ast_format_set(&outf.subclass.format, AST_FORMAT_SLINEAR, 0);
341
342         if (samples > MAX_SAMPLES) {
343                 ast_log(LOG_WARNING, "Only generating %d samples, where %d requested\n", MAX_SAMPLES, samples);
344                 samples = MAX_SAMPLES;
345         }
346         
347         if ((len = fax_tx(fax, buf, samples)) > 0) {
348                 outf.samples = len;
349                 AST_FRAME_SET_BUFFER(&outf, buffer, AST_FRIENDLY_OFFSET, len * sizeof(int16_t));
350
351                 if (ast_write(chan, &outf) < 0) {
352                         ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
353                         return -1;
354                 }
355         }
356
357         return 0;
358 }
359
360 static struct ast_generator generator = {
361         alloc:          fax_generator_alloc,
362         generate:       fax_generator_generate,
363 };
364
365
366 /* === Transmission === */
367
368 static int transmit_audio(fax_session *s)
369 {
370         int res = -1;
371         struct ast_format original_read_fmt;
372         struct ast_format original_write_fmt;
373         fax_state_t fax;
374         t30_state_t *t30state;
375         struct ast_frame *inf = NULL;
376         int last_state = 0;
377         struct timeval now, start, state_change;
378         enum ast_t38_state t38_state;
379         struct ast_control_t38_parameters t38_parameters = { .version = 0,
380                                                              .max_ifp = 800,
381                                                              .rate = AST_T38_RATE_14400,
382                                                              .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
383                                                              .fill_bit_removal = 1,
384 /*
385  * spandsp has API calls to support MMR and JBIG transcoding, but they aren't
386  * implemented quite yet... so don't offer them to the remote endpoint
387  *                                                           .transcoding_mmr = 1,
388  *                                                           .transcoding_jbig = 1,
389 */
390         };
391
392         ast_format_clear(&original_read_fmt);
393         ast_format_clear(&original_write_fmt);
394
395         /* if in called party mode, try to use T.38 */
396         if (s->caller_mode == FALSE) {
397                 /* check if we are already in T.38 mode (unlikely), or if we can request
398                  * a switch... if so, request it now and wait for the result, rather
399                  * than starting an audio FAX session that will have to be cancelled
400                  */
401                 if ((t38_state = ast_channel_get_t38_state(s->chan)) == T38_STATE_NEGOTIATED) {
402                         return 1;
403                 } else if ((t38_state != T38_STATE_UNAVAILABLE) &&
404                            (t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE,
405                             (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0))) {
406                         /* wait up to five seconds for negotiation to complete */
407                         unsigned int timeout = 5000;
408                         int ms;
409
410                         ast_debug(1, "Negotiating T.38 for receive on %s\n", s->chan->name);
411                         while (timeout > 0) {
412                                 ms = ast_waitfor(s->chan, 1000);
413                                 if (ms < 0) {
414                                         ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", s->chan->name);
415                                         return -1;
416                                 }
417                                 if (!ms) {
418                                         /* nothing happened */
419                                         if (timeout > 0) {
420                                                 timeout -= 1000;
421                                                 continue;
422                                         } else {
423                                                 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", s->chan->name);
424                                                 break;
425                                         }
426                                 }
427                                 if (!(inf = ast_read(s->chan))) {
428                                         return -1;
429                                 }
430                                 if ((inf->frametype == AST_FRAME_CONTROL) &&
431                                     (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
432                                     (inf->datalen == sizeof(t38_parameters))) {
433                                         struct ast_control_t38_parameters *parameters = inf->data.ptr;
434
435                                         switch (parameters->request_response) {
436                                         case AST_T38_NEGOTIATED:
437                                                 ast_debug(1, "Negotiated T.38 for receive on %s\n", s->chan->name);
438                                                 res = 1;
439                                                 break;
440                                         case AST_T38_REFUSED:
441                                                 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", s->chan->name);
442                                                 break;
443                                         default:
444                                                 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", s->chan->name);
445                                                 break;
446                                         }
447                                         ast_frfree(inf);
448                                         if (res == 1) {
449                                                 return 1;
450                                         } else {
451                                                 break;
452                                         }
453                                 }
454                                 ast_frfree(inf);
455                         }
456                 }
457         }
458
459 #if SPANDSP_RELEASE_DATE >= 20080725
460         /* for spandsp shaphots 0.0.6 and higher */
461         t30state = &fax.t30;
462 #else
463         /* for spandsp release 0.0.5 */
464         t30state = &fax.t30_state;
465 #endif
466
467         ast_format_copy(&original_read_fmt, &s->chan->readformat);
468         if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
469                 res = ast_set_read_format_by_id(s->chan, AST_FORMAT_SLINEAR);
470                 if (res < 0) {
471                         ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
472                         goto done;
473                 }
474         }
475
476         ast_format_copy(&original_write_fmt, &s->chan->writeformat);
477         if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
478                 res = ast_set_write_format_by_id(s->chan, AST_FORMAT_SLINEAR);
479                 if (res < 0) {
480                         ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
481                         goto done;
482                 }
483         }
484
485         /* Initialize T30 terminal */
486         fax_init(&fax, s->caller_mode);
487
488         /* Setup logging */
489         set_logging(&fax.logging);
490         set_logging(&t30state->logging);
491
492         /* Configure terminal */
493         set_local_info(t30state, s);
494         set_file(t30state, s);
495         set_ecm(t30state, TRUE);
496
497         fax_set_transmit_on_idle(&fax, TRUE);
498
499         t30_set_phase_e_handler(t30state, phase_e_handler, s);
500
501         start = state_change = ast_tvnow();
502
503         ast_activate_generator(s->chan, &generator, &fax);
504
505         while (!s->finished) {
506                 inf = NULL;
507
508                 if ((res = ast_waitfor(s->chan, 25)) < 0) {
509                         ast_debug(1, "Error waiting for a frame\n");
510                         break;
511                 }
512
513                 /* Watchdog */
514                 now = ast_tvnow();
515                 if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
516                         ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
517                         res = -1;
518                         break;
519                 }
520
521                 if (!res) {
522                         /* There was timeout waiting for a frame. Loop around and wait again */
523                         continue;
524                 }
525
526                 /* There is a frame available. Get it */
527                 res = 0;
528
529                 if (!(inf = ast_read(s->chan))) {
530                         ast_debug(1, "Channel hangup\n");
531                         res = -1;
532                         break;
533                 }
534
535                 ast_debug(10, "frame %d/%u, len=%d\n", inf->frametype, (unsigned int) inf->subclass.format.id, inf->datalen);
536
537                 /* Check the frame type. Format also must be checked because there is a chance
538                    that a frame in old format was already queued before we set channel format
539                    to slinear so it will still be received by ast_read */
540                 if (inf->frametype == AST_FRAME_VOICE && inf->subclass.format.id == AST_FORMAT_SLINEAR) {
541                         if (fax_rx(&fax, inf->data.ptr, inf->samples) < 0) {
542                                 /* I know fax_rx never returns errors. The check here is for good style only */
543                                 ast_log(LOG_WARNING, "fax_rx returned error\n");
544                                 res = -1;
545                                 break;
546                         }
547                         if (last_state != t30state->state) {
548                                 state_change = ast_tvnow();
549                                 last_state = t30state->state;
550                         }
551                 } else if ((inf->frametype == AST_FRAME_CONTROL) &&
552                            (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS)) {
553                         struct ast_control_t38_parameters *parameters = inf->data.ptr;
554
555                         if (parameters->request_response == AST_T38_NEGOTIATED) {
556                                 /* T38 switchover completed */
557                                 s->t38parameters = *parameters;
558                                 ast_debug(1, "T38 negotiated, finishing audio loop\n");
559                                 res = 1;
560                                 break;
561                         } else if (parameters->request_response == AST_T38_REQUEST_NEGOTIATE) {
562                                 t38_parameters.request_response = AST_T38_NEGOTIATED;
563                                 ast_debug(1, "T38 request received, accepting\n");
564                                 /* Complete T38 switchover */
565                                 ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
566                                 /* Do not break audio loop, wait until channel driver finally acks switchover
567                                  * with AST_T38_NEGOTIATED
568                                  */
569                         }
570                 }
571
572                 ast_frfree(inf);
573                 inf = NULL;
574         }
575
576         ast_debug(1, "Loop finished, res=%d\n", res);
577
578         if (inf)
579                 ast_frfree(inf);
580
581         ast_deactivate_generator(s->chan);
582
583         /* If we are switching to T38, remove phase E handler. Otherwise it will be executed
584            by t30_terminate, display diagnostics and set status variables although no transmittion
585            has taken place yet. */
586         if (res > 0) {
587                 t30_set_phase_e_handler(t30state, NULL, NULL);
588         }
589
590         t30_terminate(t30state);
591         fax_release(&fax);
592
593 done:
594         if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
595                 if (ast_set_write_format(s->chan, &original_write_fmt) < 0)
596                         ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", s->chan->name);
597         }
598
599         if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
600                 if (ast_set_read_format(s->chan, &original_read_fmt) < 0)
601                         ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", s->chan->name);
602         }
603
604         return res;
605
606 }
607
608 static int transmit_t38(fax_session *s)
609 {
610         int res = 0;
611         t38_terminal_state_t t38;
612         struct ast_frame *inf = NULL;
613         int last_state = 0;
614         struct timeval now, start, state_change, last_frame;
615         t30_state_t *t30state;
616         t38_core_state_t *t38state;
617
618 #if SPANDSP_RELEASE_DATE >= 20080725
619         /* for spandsp shaphots 0.0.6 and higher */
620         t30state = &t38.t30;
621         t38state = &t38.t38_fe.t38;
622 #else
623         /* for spandsp releases 0.0.5 */
624         t30state = &t38.t30_state;
625         t38state = &t38.t38;
626 #endif
627
628         /* Initialize terminal */
629         memset(&t38, 0, sizeof(t38));
630         if (t38_terminal_init(&t38, s->caller_mode, t38_tx_packet_handler, s->chan) == NULL) {
631                 ast_log(LOG_WARNING, "Unable to start T.38 termination.\n");
632                 res = -1;
633                 goto disable_t38;
634         }
635
636         t38_set_max_datagram_size(t38state, s->t38parameters.max_ifp);
637
638         if (s->t38parameters.fill_bit_removal) {
639                 t38_set_fill_bit_removal(t38state, TRUE);
640         }
641         if (s->t38parameters.transcoding_mmr) {
642                 t38_set_mmr_transcoding(t38state, TRUE);
643         }
644         if (s->t38parameters.transcoding_jbig) {
645                 t38_set_jbig_transcoding(t38state, TRUE);
646         }
647
648         /* Setup logging */
649         set_logging(&t38.logging);
650         set_logging(&t30state->logging);
651         set_logging(&t38state->logging);
652
653         /* Configure terminal */
654         set_local_info(t30state, s);
655         set_file(t30state, s);
656         set_ecm(t30state, TRUE);
657
658         t30_set_phase_e_handler(t30state, phase_e_handler, s);
659
660         now = start = state_change = ast_tvnow();
661
662         while (!s->finished) {
663                 inf = NULL;
664
665                 if ((res = ast_waitfor(s->chan, 25)) < 0) {
666                         ast_debug(1, "Error waiting for a frame\n");
667                         break;
668                 }
669
670                 last_frame = now;
671
672                 /* Watchdog */
673                 now = ast_tvnow();
674                 if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
675                         ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
676                         res = -1;
677                         break;
678                 }
679
680                 t38_terminal_send_timeout(&t38, ast_tvdiff_us(now, last_frame) / (1000000 / 8000));
681
682                 if (!res) {
683                         /* There was timeout waiting for a frame. Loop around and wait again */
684                         continue;
685                 }
686
687                 /* There is a frame available. Get it */
688                 res = 0;
689
690                 if (!(inf = ast_read(s->chan))) {
691                         ast_debug(1, "Channel hangup\n");
692                         res = -1;
693                         break;
694                 }
695
696                 ast_debug(10, "frame %d/%d, len=%d\n", inf->frametype, inf->subclass.integer, inf->datalen);
697
698                 if (inf->frametype == AST_FRAME_MODEM && inf->subclass.integer == AST_MODEM_T38) {
699                         t38_core_rx_ifp_packet(t38state, inf->data.ptr, inf->datalen, inf->seqno);
700                         if (last_state != t30state->state) {
701                                 state_change = ast_tvnow();
702                                 last_state = t30state->state;
703                         }
704                 } else if (inf->frametype == AST_FRAME_CONTROL && inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
705                         struct ast_control_t38_parameters *parameters = inf->data.ptr;
706                         if (parameters->request_response == AST_T38_TERMINATED) {
707                                 ast_debug(1, "T38 down, finishing\n");
708                                 break;
709                         }
710                 }
711
712                 ast_frfree(inf);
713                 inf = NULL;
714         }
715
716         ast_debug(1, "Loop finished, res=%d\n", res);
717
718         if (inf)
719                 ast_frfree(inf);
720
721         t30_terminate(t30state);
722         t38_terminal_release(&t38);
723
724 disable_t38:
725         /* if we are not the caller, it's our job to shut down the T.38
726          * session when the FAX transmisson is complete.
727          */
728         if ((s->caller_mode == FALSE) &&
729             (ast_channel_get_t38_state(s->chan) == T38_STATE_NEGOTIATED)) {
730                 struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
731
732                 if (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0) {
733                         /* wait up to five seconds for negotiation to complete */
734                         unsigned int timeout = 5000;
735                         int ms;
736
737                         ast_debug(1, "Shutting down T.38 on %s\n", s->chan->name);
738                         while (timeout > 0) {
739                                 ms = ast_waitfor(s->chan, 1000);
740                                 if (ms < 0) {
741                                         ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", s->chan->name);
742                                         return -1;
743                                 }
744                                 if (!ms) {
745                                         /* nothing happened */
746                                         if (timeout > 0) {
747                                                 timeout -= 1000;
748                                                 continue;
749                                         } else {
750                                                 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 shutdown.\n", s->chan->name);
751                                                 break;
752                                         }
753                                 }
754                                 if (!(inf = ast_read(s->chan))) {
755                                         return -1;
756                                 }
757                                 if ((inf->frametype == AST_FRAME_CONTROL) &&
758                                     (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
759                                     (inf->datalen == sizeof(t38_parameters))) {
760                                         struct ast_control_t38_parameters *parameters = inf->data.ptr;
761
762                                         switch (parameters->request_response) {
763                                         case AST_T38_TERMINATED:
764                                                 ast_debug(1, "Shut down T.38 on %s\n", s->chan->name);
765                                                 break;
766                                         case AST_T38_REFUSED:
767                                                 ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", s->chan->name);
768                                                 break;
769                                         default:
770                                                 ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", s->chan->name);
771                                                 break;
772                                         }
773                                         ast_frfree(inf);
774                                         break;
775                                 }
776                                 ast_frfree(inf);
777                         }
778                 }
779         }
780
781         return res;
782 }
783
784 static int transmit(fax_session *s)
785 {
786         int res = 0;
787
788         /* Clear all channel variables which to be set by the application.
789            Pre-set status to error so in case of any problems we can just leave */
790         pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "FAILED"); 
791         pbx_builtin_setvar_helper(s->chan, "FAXERROR", "Channel problems"); 
792
793         pbx_builtin_setvar_helper(s->chan, "FAXMODE", NULL);
794         pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", NULL);
795         pbx_builtin_setvar_helper(s->chan, "FAXPAGES", "0");
796         pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", NULL);
797         pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", NULL); 
798
799         if (s->chan->_state != AST_STATE_UP) {
800                 /* Shouldn't need this, but checking to see if channel is already answered
801                  * Theoretically asterisk should already have answered before running the app */
802                 res = ast_answer(s->chan);
803                 if (res) {
804                         ast_log(LOG_WARNING, "Could not answer channel '%s'\n", s->chan->name);
805                         return res;
806                 }
807         }
808
809         s->t38state = ast_channel_get_t38_state(s->chan);
810         if (s->t38state != T38_STATE_NEGOTIATED) {
811                 /* T38 is not negotiated on the channel yet. First start regular transmission. If it switches to T38, follow */ 
812                 pbx_builtin_setvar_helper(s->chan, "FAXMODE", "audio"); 
813                 res = transmit_audio(s);
814                 if (res > 0) {
815                         /* transmit_audio reports switchover to T38. Update t38state */
816                         s->t38state = ast_channel_get_t38_state(s->chan);
817                         if (s->t38state != T38_STATE_NEGOTIATED) {
818                                 ast_log(LOG_ERROR, "Audio loop reports T38 switchover but t38state != T38_STATE_NEGOTIATED\n");
819                         }
820                 }
821         }
822
823         if (s->t38state == T38_STATE_NEGOTIATED) {
824                 pbx_builtin_setvar_helper(s->chan, "FAXMODE", "T38"); 
825                 res = transmit_t38(s);
826         }
827
828         if (res) {
829                 ast_log(LOG_WARNING, "Transmission error\n");
830                 res = -1;
831         } else if (s->finished < 0) {
832                 ast_log(LOG_WARNING, "Transmission failed\n");
833         } else if (s->finished > 0) {
834                 ast_debug(1, "Transmission finished Ok\n");
835         }
836
837         return res;
838 }
839
840 /* === Application functions === */
841
842 static int sndfax_exec(struct ast_channel *chan, const char *data)
843 {
844         int res = 0;
845         char *parse;
846         fax_session session = { 0, };
847         char restore_digit_detect = 0;
848
849         AST_DECLARE_APP_ARGS(args,
850                 AST_APP_ARG(file_name);
851                 AST_APP_ARG(options);
852         );
853
854         if (chan == NULL) {
855                 ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
856                 return -1;
857         }
858
859         /* The next few lines of code parse out the filename and header from the input string */
860         if (ast_strlen_zero(data)) {
861                 /* No data implies no filename or anything is present */
862                 ast_log(LOG_ERROR, "SendFAX requires an argument (filename)\n");
863                 return -1;
864         }
865
866         parse = ast_strdupa(data);
867         AST_STANDARD_APP_ARGS(args, parse);
868         
869         session.caller_mode = TRUE;
870
871         if (args.options) {
872                 if (strchr(args.options, 'a'))
873                         session.caller_mode = FALSE;
874         }
875
876         /* Done parsing */
877         session.direction = 1;
878         session.file_name = args.file_name;
879         session.chan = chan;
880         session.finished = 0;
881
882         /* get current digit detection mode, then disable digit detection if enabled */
883         {
884                 int dummy = sizeof(restore_digit_detect);
885
886                 ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, &dummy, 0);
887         }
888
889         if (restore_digit_detect) {
890                 char new_digit_detect = 0;
891
892                 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &new_digit_detect, sizeof(new_digit_detect), 0);
893         }
894
895         /* disable FAX tone detection if enabled */
896         {
897                 char new_fax_detect = 0;
898
899                 ast_channel_setoption(chan, AST_OPTION_FAX_DETECT, &new_fax_detect, sizeof(new_fax_detect), 0);
900         }
901
902         res = transmit(&session);
903
904         if (restore_digit_detect) {
905                 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, sizeof(restore_digit_detect), 0);
906         }
907
908         return res;
909 }
910
911 static int rcvfax_exec(struct ast_channel *chan, const char *data)
912 {
913         int res = 0;
914         char *parse;
915         fax_session session;
916         char restore_digit_detect = 0;
917
918         AST_DECLARE_APP_ARGS(args,
919                 AST_APP_ARG(file_name);
920                 AST_APP_ARG(options);
921         );
922
923         if (chan == NULL) {
924                 ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
925                 return -1;
926         }
927
928         /* The next few lines of code parse out the filename and header from the input string */
929         if (ast_strlen_zero(data)) {
930                 /* No data implies no filename or anything is present */
931                 ast_log(LOG_ERROR, "ReceiveFAX requires an argument (filename)\n");
932                 return -1;
933         }
934
935         parse = ast_strdupa(data);
936         AST_STANDARD_APP_ARGS(args, parse);
937         
938         session.caller_mode = FALSE;
939
940         if (args.options) {
941                 if (strchr(args.options, 'c'))
942                         session.caller_mode = TRUE;
943         }
944
945         /* Done parsing */
946         session.direction = 0;
947         session.file_name = args.file_name;
948         session.chan = chan;
949         session.finished = 0;
950
951         /* get current digit detection mode, then disable digit detection if enabled */
952         {
953                 int dummy = sizeof(restore_digit_detect);
954
955                 ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, &dummy, 0);
956         }
957
958         if (restore_digit_detect) {
959                 char new_digit_detect = 0;
960
961                 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &new_digit_detect, sizeof(new_digit_detect), 0);
962         }
963
964         /* disable FAX tone detection if enabled */
965         {
966                 char new_fax_detect = 0;
967
968                 ast_channel_setoption(chan, AST_OPTION_FAX_DETECT, &new_fax_detect, sizeof(new_fax_detect), 0);
969         }
970
971         res = transmit(&session);
972
973         if (restore_digit_detect) {
974                 ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, sizeof(restore_digit_detect), 0);
975         }
976
977         return res;
978 }
979
980 static int unload_module(void)
981 {
982         int res;
983
984         res = ast_unregister_application(app_sndfax_name);      
985         res |= ast_unregister_application(app_rcvfax_name);     
986
987         return res;
988 }
989
990 static int load_module(void)
991 {
992         int res ;
993
994         res = ast_register_application_xml(app_sndfax_name, sndfax_exec);
995         res |= ast_register_application_xml(app_rcvfax_name, rcvfax_exec);
996
997         /* The default SPAN message handler prints to stderr. It is something we do not want */
998         span_set_message_handler(NULL);
999
1000         return res;
1001 }
1002
1003
1004 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Simple FAX Application",
1005                 .load = load_module,
1006                 .unload = unload_module,
1007                 );
1008
1009