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