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