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