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