do v21 detection instead of CED detection for the fax gateway
[asterisk/asterisk.git] / res / res_fax.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008-2009, Digium, Inc.
5  *
6  * Dwayne M. Hubbard <dhubbard@digium.com>
7  * Kevin P. Fleming <kpfleming@digium.com>
8  * Matthew Nicholson <mnicholson@digium.com>
9  *
10  * Initial T.38-gateway code
11  * 2008, Daniel Ferenci <daniel.ferenci@nethemba.com>
12  * Created by Nethemba s.r.o. http://www.nethemba.com
13  * Sponsored by IPEX a.s. http://www.ipex.cz
14  *
15  * T.38-gateway integration into asterisk app_fax and rework
16  * 2008-2011, Gregory Hinton Nietsky <gregory@distrotech.co.za>
17  * dns Telecom http://www.dnstelecom.co.za
18  *
19  * Modified to make T.38-gateway compatible with Asterisk 1.6.2
20  * 2010, Anton Verevkin <mymail@verevkin.it>
21  * ViaNetTV http://www.vianettv.com
22  *
23  * Modified to make T.38-gateway work
24  * 2010, Klaus Darilion, IPCom GmbH, www.ipcom.at
25  *
26  * See http://www.asterisk.org for more information about
27  * the Asterisk project. Please do not directly contact
28  * any of the maintainers of this project for assistance;
29  * the project provides a web site, mailing lists and IRC
30  * channels for your use.
31  *
32  * This program is free software, distributed under the terms of
33  * the GNU General Public License Version 2. See the LICENSE file
34  * at the top of the source tree.
35  */
36
37 /*** MODULEINFO
38         <conflict>app_fax</conflict>
39 ***/
40
41 /*! \file
42  *
43  * \brief Generic FAX Resource for FAX technology resource modules
44  *
45  * \author Dwayne M. Hubbard <dhubbard@digium.com>
46  * \author Kevin P. Fleming <kpfleming@digium.com>
47  * \author Matthew Nicholson <mnicholson@digium.com>
48  * \author Gregory H. Nietsky  <gregory@distrotech.co.za>
49  * 
50  * A generic FAX resource module that provides SendFAX and ReceiveFAX applications.
51  * This module requires FAX technology modules, like res_fax_spandsp, to register with it
52  * so it can use the technology modules to perform the actual FAX transmissions.
53  * \ingroup applications
54  */
55
56 #include "asterisk.h"
57
58 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
59
60 #include "asterisk/io.h"
61 #include "asterisk/file.h"
62 #include "asterisk/logger.h"
63 #include "asterisk/module.h"
64 #include "asterisk/app.h"
65 #include "asterisk/lock.h"
66 #include "asterisk/options.h"
67 #include "asterisk/strings.h"
68 #include "asterisk/cli.h"
69 #include "asterisk/utils.h"
70 #include "asterisk/config.h"
71 #include "asterisk/astobj2.h"
72 #include "asterisk/res_fax.h"
73 #include "asterisk/file.h"
74 #include "asterisk/channel.h"
75 #include "asterisk/pbx.h"
76 #include "asterisk/manager.h"
77 #include "asterisk/dsp.h"
78 #include "asterisk/indications.h"
79 #include "asterisk/ast_version.h"
80 #include "asterisk/translate.h"
81
82 /*** DOCUMENTATION
83         <application name="ReceiveFax" language="en_US">
84                 <synopsis>
85                         Receive a FAX and save as a TIFF/F file.
86                 </synopsis>
87                 <syntax>
88                         <parameter name="filename" required="true" />
89                         <parameter name="options">
90                                 <optionlist>
91                                         <option name="d">
92                                                 <para>Enable FAX debugging.</para>
93                                         </option>
94                                         <option name="f">
95                                                 <para>Allow audio fallback FAX transfer on T.38 capable channels.</para>
96                                         </option>
97                                         <option name="F">
98                                                 <para>Force usage of audio mode on T.38 capable channels.</para>
99                                         </option>
100                                         <option name="s">
101                                                 <para>Send progress Manager events (overrides statusevents setting in res_fax.conf).</para>
102                                         </option>
103                                 </optionlist>
104                         </parameter>
105                 </syntax>
106                 <description>
107                         <para>This application is provided by res_fax, which is a FAX technology agnostic module
108                         that utilizes FAX technology resource modules to complete a FAX transmission.</para>
109                         <para>Session arguments can be set by the FAXOPT function and to check results of the ReceiveFax() application.</para>
110                 </description>
111                 <see-also>
112                         <ref type="function">FAXOPT</ref>
113                 </see-also>
114         </application>
115         <application name="SendFax" language="en_US">
116                 <synopsis>
117                         Sends a specified TIFF/F file as a FAX.
118                 </synopsis>
119                 <syntax>
120                         <parameter name="filename" required="true" argsep="&amp;">
121                                 <argument name="filename2" multiple="true">
122                                         <para>TIFF file to send as a FAX.</para>
123                                 </argument>
124                         </parameter>
125                         <parameter name="options">
126                                 <optionlist>
127                                         <option name="d">
128                                                 <para>Enable FAX debugging.</para>
129                                         </option>
130                                         <option name="f">
131                                                 <para>Allow audio fallback FAX transfer on T.38 capable channels.</para>
132                                         </option>
133                                         <option name="F">
134                                                 <para>Force usage of audio mode on T.38 capable channels.</para>
135                                         </option>
136                                         <option name="s">
137                                                 <para>Send progress Manager events (overrides statusevents setting in res_fax.conf).</para>
138                                         </option>
139                                         <option name="z">
140                                                 <para>Initiate a T.38 reinvite on the channel if the remote end does not.</para>
141                                         </option>
142                                 </optionlist>
143                         </parameter>
144                 </syntax>
145                 <description>
146                         <para>This application is provided by res_fax, which is a FAX technology agnostic module
147                         that utilizes FAX technology resource modules to complete a FAX transmission.</para>
148                         <para>Session arguments can be set by the FAXOPT function and to check results of the SendFax() application.</para>
149                 </description>
150                 <see-also>
151                         <ref type="function">FAXOPT</ref>
152                 </see-also>
153         </application>
154         <function name="FAXOPT" language="en_US">
155                 <synopsis>
156                         Gets/sets various pieces of information about a fax session.
157                 </synopsis>
158                 <syntax>
159                         <parameter name="item" required="true">
160                                 <enumlist>
161                                         <enum name="ecm">
162                                                 <para>R/W Error Correction Mode (ECM) enable with 'yes', disable with 'no'.</para>
163                                         </enum>
164                                         <enum name="error">
165                                                 <para>R/O FAX transmission error code upon failure.</para>
166                                         </enum>
167                                         <enum name="filename">
168                                                 <para>R/O Filename of the first file of the FAX transmission.</para>
169                                         </enum>
170                                         <enum name="filenames">
171                                                 <para>R/O Filenames of all of the files in the FAX transmission (comma separated).</para>
172                                         </enum>
173                                         <enum name="headerinfo">
174                                                 <para>R/W FAX header information.</para>
175                                         </enum>
176                                         <enum name="localstationid">
177                                                 <para>R/W Local Station Identification.</para>
178                                         </enum>
179                                         <enum name="minrate">
180                                                 <para>R/W Minimum transfer rate set before transmission.</para>
181                                         </enum>
182                                         <enum name="maxrate">
183                                                 <para>R/W Maximum transfer rate set before transmission.</para>
184                                         </enum>
185                                         <enum name="modem">
186                                                 <para>R/W Modem type (v17/v27/v29).</para>
187                                         </enum>
188                                         <enum name="gateway">
189                                                 <para>R/W T38 Gateway Enabled (yes/no)</para>
190                                         </enum>
191                                         <enum name="pages">
192                                                 <para>R/O Number of pages transferred.</para>
193                                         </enum>
194                                         <enum name="rate">
195                                                 <para>R/O Negotiated transmission rate.</para>
196                                         </enum>
197                                         <enum name="remotestationid">
198                                                 <para>R/O Remote Station Identification after transmission.</para>
199                                         </enum>
200                                         <enum name="resolution">
201                                                 <para>R/O Negotiated image resolution after transmission.</para>
202                                         </enum>
203                                         <enum name="sessionid">
204                                                 <para>R/O Session ID of the FAX transmission.</para>
205                                         </enum>
206                                         <enum name="status">
207                                                 <para>R/O Result Status of the FAX transmission.</para>
208                                         </enum>
209                                         <enum name="statusstr">
210                                                 <para>R/O Verbose Result Status of the FAX transmission.</para>
211                                         </enum>
212                                 </enumlist>
213                         </parameter>
214                 </syntax>
215                 <description>
216                         <para>FAXOPT can be used to override the settings for a FAX session listed in <filename>res_fax.conf</filename>,
217                         it can also be used to retreive information about a FAX session that has finished eg. pages/status.</para>
218                 </description>
219                 <see-also>
220                         <ref type="application">ReceiveFax</ref>
221                         <ref type="application">SendFax</ref>
222                 </see-also>
223         </function>
224 ***/
225
226 static const char app_receivefax[] = "ReceiveFAX";
227 static const char app_sendfax[] = "SendFAX";
228
229 struct debug_info_history {
230         unsigned int consec_frames;
231         unsigned int consec_ms;
232         unsigned char silence;
233 };
234
235 struct ast_fax_debug_info {
236         struct timeval base_tv;
237         struct debug_info_history c2s, s2c;
238         struct ast_dsp *dsp;
239 };
240
241 /*! \brief used for gateway framehook */
242 struct fax_gateway {
243         /*! \brief FAX Session */
244         struct ast_fax_session *s;
245         /*! \brief reserved fax session token */
246         struct ast_fax_tech_token *token;
247         /*! \brief the start of our timeout counter */
248         struct timeval timeout_start;
249         /*! \brief DSP Processor */
250         struct ast_dsp *chan_dsp;
251         struct ast_dsp *peer_dsp;
252         /*! \brief framehook used in gateway mode */
253         int framehook;
254         /*! \brief bridged */
255         int bridged:1;
256         /*! \brief 1 if a v21 preamble has been detected */
257         int detected_v21:1;
258         /*! \brief a flag to track the state of our negotiation */
259         enum ast_t38_state t38_state;
260         /*! \brief original audio formats */
261         struct ast_format chan_read_format;
262         struct ast_format chan_write_format;
263         struct ast_format peer_read_format;
264         struct ast_format peer_write_format;
265 };
266
267 static int fax_logger_level = -1;
268
269 /*! \brief maximum buckets for res_fax ao2 containers */
270 #define FAX_MAXBUCKETS 10
271
272 #define RES_FAX_TIMEOUT 10000
273 #define FAX_GATEWAY_TIMEOUT RES_FAX_TIMEOUT
274
275 /*! \brief The faxregistry is used to manage information and statistics for all FAX sessions. */
276 static struct {
277         /*! The number of active FAX sessions */
278         int active_sessions;
279         /*! The number of reserved FAX sessions */
280         int reserved_sessions;
281         /*! active sessions are astobj2 objects */
282         struct ao2_container *container;
283         /*! Total number of Tx FAX attempts */
284         int fax_tx_attempts;
285         /*! Total number of Rx FAX attempts */
286         int fax_rx_attempts;
287         /*! Number of successful FAX transmissions */
288         int fax_complete;
289         /*! Number of failed FAX transmissions */
290         int fax_failures;
291         /*! the next unique session name */
292         int nextsessionname;
293 } faxregistry;
294
295 /*! \brief registered FAX technology modules are put into this list */
296 struct fax_module {
297         const struct ast_fax_tech *tech;
298         AST_RWLIST_ENTRY(fax_module) list;
299 };
300 static AST_RWLIST_HEAD_STATIC(faxmodules, fax_module);
301
302 #define RES_FAX_MINRATE 2400
303 #define RES_FAX_MAXRATE 14400
304 #define RES_FAX_STATUSEVENTS 0
305 #define RES_FAX_MODEM (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29)
306
307 static struct {
308         enum ast_fax_modems modems;
309         uint32_t statusevents:1;
310         uint32_t ecm:1;
311         unsigned int minrate;   
312         unsigned int maxrate;
313 } general_options;
314
315 static const char *config = "res_fax.conf";
316
317 static int global_fax_debug = 0;
318
319 enum {
320         OPT_CALLEDMODE  = (1 << 0),
321         OPT_CALLERMODE  = (1 << 1),
322         OPT_DEBUG       = (1 << 2),
323         OPT_STATUS      = (1 << 3),
324         OPT_ALLOWAUDIO  = (1 << 5),
325         OPT_REQUEST_T38 = (1 << 6),
326         OPT_FORCE_AUDIO = (1 << 7),
327 };
328
329 AST_APP_OPTIONS(fax_exec_options, BEGIN_OPTIONS
330         AST_APP_OPTION('a', OPT_CALLEDMODE),
331         AST_APP_OPTION('c', OPT_CALLERMODE),
332         AST_APP_OPTION('d', OPT_DEBUG),
333         AST_APP_OPTION('f', OPT_ALLOWAUDIO),
334         AST_APP_OPTION('F', OPT_FORCE_AUDIO),
335         AST_APP_OPTION('s', OPT_STATUS),
336         AST_APP_OPTION('z', OPT_REQUEST_T38),
337 END_OPTIONS);
338
339 struct manager_event_info {
340         char context[AST_MAX_CONTEXT];
341         char exten[AST_MAX_EXTENSION];
342         char cid[128];
343 };
344
345 static void debug_check_frame_for_silence(struct ast_fax_session *s, unsigned int c2s, struct ast_frame *frame)
346 {       
347         struct debug_info_history *history = c2s ? &s->debug_info->c2s : &s->debug_info->s2c;
348         int dspsilence;
349         unsigned int last_consec_frames, last_consec_ms;
350         unsigned char wassil;
351         struct timeval diff;
352
353         diff = ast_tvsub(ast_tvnow(), s->debug_info->base_tv);
354
355         ast_dsp_reset(s->debug_info->dsp);
356         ast_dsp_silence(s->debug_info->dsp, frame, &dspsilence);
357
358         wassil = history->silence;
359         history->silence = (dspsilence != 0) ? 1 : 0;
360         if (history->silence != wassil) {
361                 last_consec_frames = history->consec_frames;
362                 last_consec_ms = history->consec_ms;
363                 history->consec_frames = 0;
364                 history->consec_ms = 0;
365
366                 if ((last_consec_frames != 0)) {
367                         ast_verb(6, "Channel '%s' fax session '%d', [ %.3ld.%.6ld ], %s sent %d frames (%d ms) of %s.\n",
368                                  s->channame, s->id, (long) diff.tv_sec, (long int) diff.tv_usec,
369                                  (c2s) ? "channel" : "stack", last_consec_frames, last_consec_ms,
370                                  (wassil) ? "silence" : "energy");
371                 }
372         }
373
374         history->consec_frames++;
375         history->consec_ms += (frame->samples / 8);
376 }
377
378 static void destroy_callback(void *data) 
379 {
380         if (data) {
381                 ao2_ref(data, -1);
382         }
383 }
384
385 static const struct ast_datastore_info fax_datastore = {
386         .type = "res_fax",
387         .destroy = destroy_callback,
388 };
389
390 /*! \brief returns a reference counted pointer to a fax datastore, if it exists */
391 static struct ast_fax_session_details *find_details(struct ast_channel *chan)
392 {
393         struct ast_fax_session_details *details;
394         struct ast_datastore *datastore;
395
396         ast_channel_lock(chan); 
397         if (!(datastore = ast_channel_datastore_find(chan, &fax_datastore, NULL))) {
398                 ast_channel_unlock(chan);       
399                 return NULL;
400         }
401         if (!(details = datastore->data)) {
402                 ast_log(LOG_WARNING, "Huh?  channel '%s' has a FAX datastore without data!\n", chan->name);
403                 ast_channel_unlock(chan);
404                 return NULL;
405         }
406         ao2_ref(details, 1);    
407         ast_channel_unlock(chan);       
408
409         return details;
410 }
411
412 /*! \brief destroy a FAX session details structure */
413 static void destroy_session_details(void *details)
414 {
415         struct ast_fax_session_details *d = details;
416         struct ast_fax_document *doc;
417         
418         while ((doc = AST_LIST_REMOVE_HEAD(&d->documents, next))) {
419                 ast_free(doc);
420         }
421         ast_string_field_free_memory(d);        
422 }
423
424 /*! \brief create a FAX session details structure */
425 static struct ast_fax_session_details *session_details_new(void)
426 {
427         struct ast_fax_session_details *d;
428
429         if (!(d = ao2_alloc(sizeof(*d), destroy_session_details))) {
430                 return NULL;
431         }
432         
433         if (ast_string_field_init(d, 512)) {
434                 ao2_ref(d, -1);
435                 return NULL;
436         }
437
438         AST_LIST_HEAD_INIT_NOLOCK(&d->documents);
439
440         /* These options need to be set to the configured default and may be overridden by
441          * SendFAX, ReceiveFAX, or FAXOPT */
442         d->option.request_t38 = AST_FAX_OPTFLAG_FALSE;
443         d->option.send_cng = AST_FAX_OPTFLAG_FALSE;
444         d->option.send_ced = AST_FAX_OPTFLAG_FALSE;
445         d->option.ecm = general_options.ecm;
446         d->option.statusevents = general_options.statusevents;
447         d->modems = general_options.modems;
448         d->minrate = general_options.minrate;
449         d->maxrate = general_options.maxrate;
450         d->gateway_id = -1;
451
452         return d;
453 }
454
455 static struct ast_control_t38_parameters our_t38_parameters = {
456         .version = 0,
457         .max_ifp = 400,
458         .rate = AST_T38_RATE_14400,
459         .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
460 };
461
462 static void t38_parameters_ast_to_fax(struct ast_fax_t38_parameters *dst, const struct ast_control_t38_parameters *src)
463 {
464         dst->version = src->version;
465         dst->max_ifp = src->max_ifp;
466         dst->rate = src->rate;
467         dst->rate_management = src->rate_management;
468         dst->fill_bit_removal = src->fill_bit_removal;
469         dst->transcoding_mmr = src->transcoding_mmr;
470         dst->transcoding_jbig = src->transcoding_jbig;
471 }
472
473 static void t38_parameters_fax_to_ast(struct ast_control_t38_parameters *dst, const struct ast_fax_t38_parameters *src)
474 {
475         dst->version = src->version;
476         dst->max_ifp = src->max_ifp;
477         dst->rate = src->rate;
478         dst->rate_management = src->rate_management;
479         dst->fill_bit_removal = src->fill_bit_removal;
480         dst->transcoding_mmr = src->transcoding_mmr;
481         dst->transcoding_jbig = src->transcoding_jbig;
482 }
483
484 /*! \brief returns a reference counted details structure from the channel's fax datastore.  If the datastore
485  * does not exist it will be created */ 
486 static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan)
487 {
488         struct ast_fax_session_details *details;
489         struct ast_datastore *datastore;
490
491         if ((details = find_details(chan))) {
492                 return details;
493         }
494         /* channel does not have one so we must create one */
495         if (!(details = session_details_new())) {
496                 ast_log(LOG_WARNING, "channel '%s' can't get a FAX details structure for the datastore!\n", chan->name);
497                 return NULL;
498         }
499         if (!(datastore = ast_datastore_alloc(&fax_datastore, NULL))) {
500                 ao2_ref(details, -1);
501                 ast_log(LOG_WARNING, "channel '%s' can't get a datastore!\n", chan->name);
502                 return NULL;
503         }
504         /* add the datastore to the channel and increment the refcount */
505         datastore->data = details;
506
507         /* initialize default T.38 parameters */
508         t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
509         t38_parameters_ast_to_fax(&details->their_t38_parameters, &our_t38_parameters);
510
511         ao2_ref(details, 1);
512         ast_channel_lock(chan);
513         ast_channel_datastore_add(chan, datastore);
514         ast_channel_unlock(chan);
515         return details;
516 }
517
518 unsigned int ast_fax_maxrate(void)
519 {
520         return general_options.maxrate;
521 }
522
523 unsigned int ast_fax_minrate(void)
524 {
525         return general_options.minrate;
526 }
527
528 static int update_modem_bits(enum ast_fax_modems *bits, const char *value)
529 {               
530         char *m[5], *tok, *v = (char *)value;
531         int i = 0, j;
532
533         if (!(tok = strchr(v, ','))) {
534                 m[i++] = v;
535                 m[i] = NULL;
536         } else {
537                 tok = strtok(v, ", ");
538                 while (tok && (i < 5)) {
539                         m[i++] = tok;
540                         tok = strtok(NULL, ", ");
541                 }
542                 m[i] = NULL;
543         }
544
545         *bits = 0;
546         for (j = 0; j < i; j++) {
547                 if (!strcasecmp(m[j], "v17")) {
548                         *bits |= AST_FAX_MODEM_V17;
549                 } else if (!strcasecmp(m[j], "v27")) {
550                         *bits |= AST_FAX_MODEM_V27;
551                 } else if (!strcasecmp(m[j], "v29")) {
552                         *bits |= AST_FAX_MODEM_V29;
553                 } else if (!strcasecmp(m[j], "v34")) {
554                         *bits |= AST_FAX_MODEM_V34;
555                 } else {
556                         ast_log(LOG_WARNING, "ignoring invalid modem setting: '%s', valid options {v17 | v27 | v29 | v34}\n", m[j]);
557                 }
558         }
559         return 0;
560 }
561
562 static int ast_fax_modem_to_str(enum ast_fax_modems bits, char *tbuf, size_t bufsize)
563 {
564         int count = 0;
565
566         if (bits & AST_FAX_MODEM_V17) {
567                 strcat(tbuf, "V17");
568                 count++;
569         }
570         if (bits & AST_FAX_MODEM_V27) {
571                 if (count) {
572                         strcat(tbuf, ",");
573                 }
574                 strcat(tbuf, "V27");
575                 count++;
576         }
577         if (bits & AST_FAX_MODEM_V29) {
578                 if (count) {
579                         strcat(tbuf, ",");
580                 }
581                 strcat(tbuf, "V29");
582                 count++;
583         }
584         if (bits & AST_FAX_MODEM_V34) {
585                 if (count) {
586                         strcat(tbuf, ",");
587                 }
588                 strcat(tbuf, "V34");
589                 count++;
590         }
591
592         return 0;
593 }
594
595 static int check_modem_rate(enum ast_fax_modems modems, unsigned int rate)
596 {
597         switch (rate) {
598         case 2400:
599                 if (!(modems & (AST_FAX_MODEM_V27 | AST_FAX_MODEM_V34))) {
600                         return 1;
601                 }
602                 break;
603         case 4800:
604                 if (!(modems & (AST_FAX_MODEM_V27 | AST_FAX_MODEM_V34))) {
605                         return 1;
606                 }
607                 break;
608         case 7200:
609         case 9600:
610                 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
611                         return 1;
612                 }
613                 break;
614         case 12000:
615         case 14400:
616                 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V34))) {
617                         return 1;
618                 }
619                 break;
620         case 28800:
621         case 33600:
622                 if (!(modems & AST_FAX_MODEM_V34)) {
623                         return 1;
624                 }
625                 break;
626         default:
627                 /* this should never happen */
628                 return 1;
629         }
630
631         return 0;
632 }
633
634 /*! \brief register a FAX technology module */
635 int ast_fax_tech_register(struct ast_fax_tech *tech)
636 {
637         struct fax_module *fax;
638
639         if (!(fax = ast_calloc(1, sizeof(*fax)))) {
640                 return -1;
641         }
642         fax->tech = tech;
643         AST_RWLIST_WRLOCK(&faxmodules);
644         AST_RWLIST_INSERT_TAIL(&faxmodules, fax, list);
645         AST_RWLIST_UNLOCK(&faxmodules);
646         ast_module_ref(ast_module_info->self);
647
648         ast_verb(3, "Registered handler for '%s' (%s)\n", fax->tech->type, fax->tech->description);
649
650         return 0;
651 }
652
653 /*! \brief unregister a FAX technology module */
654 void ast_fax_tech_unregister(struct ast_fax_tech *tech)
655 {
656         struct fax_module *fax;
657
658         ast_verb(3, "Unregistering FAX module type '%s'\n", tech->type);
659
660         AST_RWLIST_WRLOCK(&faxmodules);
661         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&faxmodules, fax, list) {
662                 if (fax->tech != tech) {
663                         continue;
664                 }
665                 AST_RWLIST_REMOVE_CURRENT(list);
666                 ast_module_unref(ast_module_info->self);
667                 ast_free(fax);
668                 ast_verb(4, "Unregistered FAX module type '%s'\n", tech->type);
669                 break;  
670         }
671         AST_RWLIST_TRAVERSE_SAFE_END;
672         AST_RWLIST_UNLOCK(&faxmodules);
673 }
674
675 /*! \brief convert a ast_fax_state to a string */
676 const char *ast_fax_state_to_str(enum ast_fax_state state)
677 {
678         switch (state) {
679         case AST_FAX_STATE_UNINITIALIZED:
680                 return "Uninitialized";
681         case AST_FAX_STATE_INITIALIZED:
682                 return "Initialized";
683         case AST_FAX_STATE_OPEN:
684                 return "Open";
685         case AST_FAX_STATE_ACTIVE:
686                 return "Active";
687         case AST_FAX_STATE_COMPLETE:
688                 return "Complete";
689         case AST_FAX_STATE_RESERVED:
690                 return "Reserved";
691         case AST_FAX_STATE_INACTIVE:
692                 return "Inactive";
693         default:
694                 ast_log(LOG_WARNING, "unhandled FAX state: %d\n", state);
695                 return "Unknown";
696         }
697 }
698
699 void ast_fax_log(int level, const char *file, const int line, const char *function, const char *msg)
700 {
701         if (fax_logger_level != -1) {
702                 ast_log_dynamic_level(fax_logger_level, "%s", msg);
703         } else {
704                 ast_log(level, file, line, function, "%s", msg);
705         }
706 }
707
708 /*! \brief convert a rate string to a rate */
709 static unsigned int fax_rate_str_to_int(const char *ratestr)
710 {
711         int rate;
712
713         if (sscanf(ratestr, "%d", &rate) != 1) {
714                 ast_log(LOG_ERROR, "failed to sscanf '%s' to rate\n", ratestr);
715                 return 0;
716         }
717         switch (rate) {
718         case 2400:
719         case 4800:
720         case 7200:
721         case 9600:
722         case 12000:
723         case 14400:
724         case 28800:
725         case 33600:
726                 return rate;
727         default:
728                 ast_log(LOG_WARNING, "ignoring invalid rate '%s'.  Valid options are {2400 | 4800 | 7200 | 9600 | 12000 | 14400 | 28800 | 33600}\n", ratestr);
729                 return 0;
730         }
731 }
732
733 /*! \brief Release a session token.
734  * \param s a session returned from fax_session_reserve()
735  * \param token a token generated from fax_session_reserve()
736  *
737  * This function releases the given token and marks the given session as no
738  * longer reserved. It is safe to call on a session that is not actually
739  * reserved and with a NULL token. This is so that sessions returned by
740  * technologies that do not support reserved sessions don't require extra logic
741  * to handle.
742  *
743  * \note This function DOES NOT release the given fax session, only the given
744  * token.
745  */
746 static void fax_session_release(struct ast_fax_session *s, struct ast_fax_tech_token *token)
747 {
748         if (token) {
749                 s->tech->release_token(token);
750         }
751
752         if (s->state == AST_FAX_STATE_RESERVED) {
753                 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
754                 s->state = AST_FAX_STATE_INACTIVE;
755         }
756 }
757
758 /*! \brief destroy a FAX session structure */
759 static void destroy_session(void *session)
760 {
761         struct ast_fax_session *s = session;
762
763         if (s->tech) {
764                 fax_session_release(s, NULL);
765                 if (s->tech_pvt) {
766                         s->tech->destroy_session(s);
767                 }
768                 ast_module_unref(s->tech->module);
769         }
770
771         if (s->details) {
772                 ao2_ref(s->details, -1);
773         }
774         
775         if (s->debug_info) {
776                 ast_dsp_free(s->debug_info->dsp);
777                 ast_free(s->debug_info);
778         }
779
780         if (s->smoother) {
781                 ast_smoother_free(s->smoother);
782         }
783
784         if (s->state != AST_FAX_STATE_INACTIVE) {
785                 ast_atomic_fetchadd_int(&faxregistry.active_sessions, -1);
786         }
787
788         ast_free(s->channame);
789         ast_free(s->chan_uniqueid);
790 }
791
792 /*! \brief Reserve a fax session.
793  * \param details the fax session details
794  * \param token a pointer to a place to store a token to be passed to fax_session_new() later
795  *
796  * This function reserves a fax session for use later. If the selected fax
797  * technology does not support reserving sessions a session will still be
798  * returned but token will not be set.
799  *
800  * \note The reference returned by this function does not get consumed by
801  * fax_session_new() and must always be dereferenced separately.
802  *
803  * \return NULL or an uninitialized and possibly reserved session
804  */
805 static struct ast_fax_session *fax_session_reserve(struct ast_fax_session_details *details, struct ast_fax_tech_token **token)
806 {
807         struct ast_fax_session *s;
808         struct fax_module *faxmod;
809
810         if (!(s = ao2_alloc(sizeof(*s), destroy_session))) {
811                 return NULL;
812         }
813
814         s->state = AST_FAX_STATE_INACTIVE;
815         s->details = details;
816         ao2_ref(s->details, 1);
817
818         /* locate a FAX technology module that can handle said requirements
819          * Note: the requirements have not yet been finalized as T.38
820          * negotiation has not yet occured. */
821         AST_RWLIST_RDLOCK(&faxmodules);
822         AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
823                 if ((faxmod->tech->caps & details->caps) != details->caps) {
824                         continue;
825                 }
826                 ast_debug(4, "Reserving a FAX session from '%s'.\n", faxmod->tech->description);
827                 ast_module_ref(faxmod->tech->module);
828                 s->tech = faxmod->tech;
829                 break;
830         }
831         AST_RWLIST_UNLOCK(&faxmodules);
832
833         if (!faxmod) {
834                 ast_log(LOG_ERROR, "Could not locate a FAX technology module with capabilities (0x%X)\n", details->caps);
835                 ao2_ref(s, -1);
836                 return NULL;
837         }
838
839         if (!s->tech->reserve_session) {
840                 ast_debug(1, "Selected FAX technology module (%s) does not support reserving sessions.\n", s->tech->description);
841                 return s;
842         }
843
844         if (!(*token = s->tech->reserve_session(s))) {
845                 ao2_ref(s, -1);
846                 return NULL;
847         }
848
849         s->state = AST_FAX_STATE_RESERVED;
850         ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, 1);
851
852         return s;
853 }
854
855 /*! \brief create a FAX session
856  *
857  * \param details details for the session
858  * \param chan the channel the session will run on
859  * \param reserved a reserved session to base this session on (can be NULL)
860  * \param token the token for a reserved session (can be NULL)
861  *
862  * Create a new fax session based on the given details structure.
863  *
864  * \note The given token is always consumed (by tech->new_session() or by
865  * fax_session_release() in the event of a failure). The given reference to a
866  * reserved session is never consumed and must be dereferenced separately from
867  * the reference returned by this function.
868  *
869  * \return NULL or a reference to a new fax session
870  */
871 static struct ast_fax_session *fax_session_new(struct ast_fax_session_details *details, struct ast_channel *chan, struct ast_fax_session *reserved, struct ast_fax_tech_token *token)
872 {
873         struct ast_fax_session *s = NULL;
874         struct fax_module *faxmod;
875
876         if (reserved) {
877                 s = reserved;
878                 ao2_ref(reserved, +1);
879
880                 /* NOTE: we don't consume the reference to the reserved
881                  * session. The session returned from fax_session_new() is a
882                  * new reference and must be derefed in addition to the
883                  * reserved session.
884                  */
885
886                 if (s->state == AST_FAX_STATE_RESERVED) {
887                         ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
888                         s->state = AST_FAX_STATE_UNINITIALIZED;
889                 }
890         }
891
892         if (!s && !(s = ao2_alloc(sizeof(*s), destroy_session))) {
893                 return NULL;
894         }
895
896         ast_atomic_fetchadd_int(&faxregistry.active_sessions, 1);
897         s->state = AST_FAX_STATE_UNINITIALIZED;
898
899         if (details->option.debug && (details->caps & AST_FAX_TECH_AUDIO)) {
900                 if (!(s->debug_info = ast_calloc(1, sizeof(*(s->debug_info))))) {
901                         fax_session_release(s, token);
902                         ao2_ref(s, -1);
903                         return NULL;
904                 }
905                 if (!(s->debug_info->dsp = ast_dsp_new())) {
906                         ast_free(s->debug_info);
907                         s->debug_info = NULL;
908                         fax_session_release(s, token);
909                         ao2_ref(s, -1);
910                         return NULL;
911                 }
912                 ast_dsp_set_threshold(s->debug_info->dsp, 128);
913         }       
914
915         if (!(s->channame = ast_strdup(chan->name))) {
916                 fax_session_release(s, token);
917                 ao2_ref(s, -1);
918                 return NULL;
919         }
920
921         if (!(s->chan_uniqueid = ast_strdup(chan->uniqueid))) {
922                 fax_session_release(s, token);
923                 ao2_ref(s, -1);
924                 return NULL;
925         }
926
927         s->chan = chan;
928         if (!s->details) {
929                 s->details = details;
930                 ao2_ref(s->details, 1);
931         }
932
933         details->id = s->id = ast_atomic_fetchadd_int(&faxregistry.nextsessionname, 1);
934
935         if (!token) {
936                 /* locate a FAX technology module that can handle said requirements */
937                 AST_RWLIST_RDLOCK(&faxmodules);
938                 AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
939                         if ((faxmod->tech->caps & details->caps) != details->caps) {
940                                 continue;
941                         }
942                         ast_debug(4, "Requesting a new FAX session from '%s'.\n", faxmod->tech->description);
943                         ast_module_ref(faxmod->tech->module);
944                         s->tech = faxmod->tech;
945                         break;
946                 }
947                 AST_RWLIST_UNLOCK(&faxmodules);
948
949                 if (!faxmod) {
950                         ast_log(LOG_ERROR, "Could not locate a FAX technology module with capabilities (0x%X)\n", details->caps);
951                         ao2_ref(s, -1);
952                         return NULL;
953                 }
954         }
955
956         if (!(s->tech_pvt = s->tech->new_session(s, token))) {
957                 ast_log(LOG_ERROR, "FAX session failed to initialize.\n");
958                 ao2_ref(s, -1);
959                 return NULL;
960         }
961         /* link the session to the session container */
962         if (!(ao2_link(faxregistry.container, s))) {
963                 ast_log(LOG_ERROR, "failed to add FAX session '%d' to container.\n", s->id);
964                 ao2_ref(s, -1);
965                 return NULL;
966         }
967         ast_debug(4, "channel '%s' using FAX session '%d'\n", s->channame, s->id);
968
969         return s;
970 }
971
972 static void get_manager_event_info(struct ast_channel *chan, struct manager_event_info *info)
973 {
974         pbx_substitute_variables_helper(chan, "${CONTEXT}", info->context, sizeof(info->context));
975         pbx_substitute_variables_helper(chan, "${EXTEN}", info->exten, sizeof(info->exten));
976         pbx_substitute_variables_helper(chan, "${CALLERID(num)}", info->cid, sizeof(info->cid));
977 }
978
979
980 /* \brief Generate a string of filenames using the given prefix and separator.
981  * \param details the fax session details
982  * \param prefix the prefix to each filename
983  * \param separator the separator between filenames
984  *
985  * This function generates a string of filenames from the given details
986  * structure and using the given prefix and separator.
987  *
988  * \retval NULL there was an error generating the string
989  * \return the string generated string
990  */
991 static char *generate_filenames_string(struct ast_fax_session_details *details, char *prefix, char *separator)
992 {
993         char *filenames, *c;
994         size_t size = 0;
995         int first = 1;
996         struct ast_fax_document *doc;
997
998         /* don't process empty lists */
999         if (AST_LIST_EMPTY(&details->documents)) {
1000                 return NULL;
1001         }
1002
1003         /* Calculate the total length of all of the file names */
1004         AST_LIST_TRAVERSE(&details->documents, doc, next) {
1005                 size += strlen(separator) + strlen(prefix) + strlen(doc->filename);
1006         }
1007         size += 1; /* add space for the terminating null */
1008
1009         if (!(filenames = ast_malloc(size))) {
1010                 return NULL;
1011         }
1012         c = filenames;
1013
1014         ast_build_string(&c, &size, "%s%s", prefix, AST_LIST_FIRST(&details->documents)->filename);
1015         AST_LIST_TRAVERSE(&details->documents, doc, next) {
1016                 if (first) {
1017                         first = 0;
1018                         continue;
1019                 }
1020
1021                 ast_build_string(&c, &size, "%s%s%s", separator, prefix, doc->filename);
1022         }
1023
1024         return filenames;
1025 }
1026
1027 /*! \brief send a FAX status manager event */
1028 static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details, const char *status)
1029 {
1030         char *filenames = generate_filenames_string(details, "FileName: ", "\r\n");
1031
1032         ast_channel_lock(chan);
1033         if (details->option.statusevents) {
1034                 struct manager_event_info info;
1035
1036                 get_manager_event_info(chan, &info);
1037                 manager_event(EVENT_FLAG_CALL,
1038                               "FAXStatus",
1039                               "Operation: %s\r\n"
1040                               "Status: %s\r\n"
1041                               "Channel: %s\r\n"
1042                               "Context: %s\r\n"
1043                               "Exten: %s\r\n"
1044                               "CallerID: %s\r\n"
1045                               "LocalStationID: %s\r\n"
1046                               "%s%s",
1047                               (details->caps & AST_FAX_TECH_GATEWAY) ? "gateway" : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
1048                               status,
1049                               chan->name,
1050                               info.context,
1051                               info.exten,
1052                               info.cid,
1053                               details->localstationid,
1054                               S_OR(filenames, ""),
1055                               filenames ? "\r\n" : "");
1056         }
1057         ast_channel_unlock(chan);
1058
1059         if (filenames) {
1060                 ast_free(filenames);
1061         }
1062
1063         return 0;
1064 }
1065
1066 /*! \brief Set fax related channel variables. */
1067 static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
1068 {
1069         char buf[10];
1070         pbx_builtin_setvar_helper(chan, "FAXSTATUS", S_OR(details->result, NULL));
1071         pbx_builtin_setvar_helper(chan, "FAXERROR", S_OR(details->error, NULL));
1072         pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", S_OR(details->resultstr, NULL));
1073         pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", S_OR(details->remotestationid, NULL));
1074         pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", S_OR(details->localstationid, NULL));
1075         pbx_builtin_setvar_helper(chan, "FAXBITRATE", S_OR(details->transfer_rate, NULL));
1076         pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", S_OR(details->resolution, NULL));
1077
1078         snprintf(buf, sizeof(buf), "%d", details->pages_transferred);
1079         pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
1080 }
1081
1082 #define GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason) \
1083         do {    \
1084                 if (ast_strlen_zero(fax->details->result)) \
1085                         ast_string_field_set(fax->details, result, "FAILED"); \
1086                 if (ast_strlen_zero(fax->details->resultstr)) \
1087                         ast_string_field_set(fax->details, resultstr, reason); \
1088                 if (ast_strlen_zero(fax->details->error)) \
1089                         ast_string_field_set(fax->details, error, errorstr); \
1090                 set_channel_variables(chan, fax->details); \
1091         } while (0)
1092
1093 #define GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason) \
1094         do {    \
1095                 GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason); \
1096                 res = ms = -1; \
1097         } while (0)
1098
1099 #define GENERIC_FAX_EXEC_ERROR(fax, chan, errorstr, reason)     \
1100         do {    \
1101                 ast_log(LOG_ERROR, "channel '%s' FAX session '%d' failure, reason: '%s' (%s)\n", chan->name, fax->id, reason, errorstr); \
1102                 GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason); \
1103         } while (0)
1104
1105 static int set_fax_t38_caps(struct ast_channel *chan, struct ast_fax_session_details *details)
1106 {
1107         switch (ast_channel_get_t38_state(chan)) {
1108         case T38_STATE_UNKNOWN:
1109                 details->caps |= AST_FAX_TECH_T38;
1110                 break;
1111         case T38_STATE_REJECTED:
1112         case T38_STATE_UNAVAILABLE:
1113                 details->caps |= AST_FAX_TECH_AUDIO;
1114                 break;
1115         case T38_STATE_NEGOTIATED:
1116                 /* already in T.38 mode? This should not happen. */
1117         case T38_STATE_NEGOTIATING: {
1118                 /* the other end already sent us a T.38 reinvite, so we need to prod the channel
1119                  * driver into resending their parameters to us if it supports doing so... if
1120                  * not, we can't proceed, because we can't create a proper reply without them.
1121                  * if it does work, the channel driver will send an AST_CONTROL_T38_PARAMETERS
1122                  * with a request of AST_T38_REQUEST_NEGOTIATE, which will be read by the function
1123                  * that gets called after this one completes
1124                  */
1125                 struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_PARMS, };
1126                 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters)) != AST_T38_REQUEST_PARMS) {
1127                         ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", chan->name);
1128                         return -1;
1129                 }
1130                 details->caps |= AST_FAX_TECH_T38;
1131                 break;
1132         }
1133         default:
1134                 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", chan->name);
1135                 return -1;
1136         }
1137
1138         return 0;
1139 }
1140
1141 static int disable_t38(struct ast_channel *chan)
1142 {
1143         int ms;
1144         struct ast_frame *frame = NULL;
1145         struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
1146
1147         ast_debug(1, "Shutting down T.38 on %s\n", chan->name);
1148         if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0) {
1149                 ast_debug(1, "error while disabling T.38 on channel '%s'\n", chan->name);
1150                 return -1;
1151         }
1152
1153         /* wait up to five seconds for negotiation to complete */
1154         ms = 5000;
1155
1156         while (ms > 0) {
1157                 ms = ast_waitfor(chan, ms);
1158                 if (ms < 0) {
1159                         ast_debug(1, "error while disabling T.38 on channel '%s'\n", chan->name);
1160                         return -1;
1161                 }
1162
1163                 if (ms == 0) { /* all done, nothing happened */
1164                         ast_debug(1, "channel '%s' timed-out during T.38 shutdown\n", chan->name);
1165                         break;
1166                 }
1167
1168                 if (!(frame = ast_read(chan))) {
1169                         return -1;
1170                 }
1171                 if ((frame->frametype == AST_FRAME_CONTROL) &&
1172                     (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1173                     (frame->datalen == sizeof(t38_parameters))) {
1174                         struct ast_control_t38_parameters *parameters = frame->data.ptr;
1175
1176                         switch (parameters->request_response) {
1177                         case AST_T38_TERMINATED:
1178                                 ast_debug(1, "Shut down T.38 on %s\n", chan->name);
1179                                 break;
1180                         case AST_T38_REFUSED:
1181                                 ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", chan->name);
1182                                 ast_frfree(frame);
1183                                 return -1;
1184                         default:
1185                                 ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", chan->name);
1186                                 ast_frfree(frame);
1187                                 return -1;
1188                         }
1189                         ast_frfree(frame);
1190                         break;
1191                 }
1192                 ast_frfree(frame);
1193         }
1194
1195         return 0;
1196 }
1197
1198 /*! \brief this is the generic FAX session handling function */
1199 static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_details *details, struct ast_fax_session *reserved, struct ast_fax_tech_token *token)
1200 {
1201         int ms;
1202         int timeout = RES_FAX_TIMEOUT;
1203         int res = 0, chancount;
1204         unsigned int expected_frametype = -1;
1205         union ast_frame_subclass expected_framesubclass = { .integer = -1 };
1206         unsigned int t38negotiated = (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED);
1207         struct ast_control_t38_parameters t38_parameters;
1208         const char *tempvar;
1209         struct ast_fax_session *fax = NULL;
1210         struct ast_frame *frame = NULL;
1211         struct ast_channel *c = chan;
1212         struct ast_format orig_write_format;
1213         struct ast_format orig_read_format;
1214
1215         ast_format_clear(&orig_write_format);
1216         ast_format_clear(&orig_read_format);
1217         chancount = 1;
1218
1219         /* create the FAX session */
1220         if (!(fax = fax_session_new(details, chan, reserved, token))) {
1221                 ast_log(LOG_ERROR, "Can't create a FAX session, FAX attempt failed.\n");
1222                 report_fax_status(chan, details, "No Available Resource");
1223                 return -1;
1224         }
1225
1226         ast_channel_lock(chan);
1227         /* update session details */    
1228         if (ast_strlen_zero(details->headerinfo) && (tempvar = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO"))) {
1229                 ast_string_field_set(details, headerinfo, tempvar);
1230         }
1231         if (ast_strlen_zero(details->localstationid)) {
1232                 tempvar = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
1233                 ast_string_field_set(details, localstationid, tempvar ? tempvar : "unknown");
1234         }
1235         ast_channel_unlock(chan);
1236
1237         report_fax_status(chan, details, "Allocating Resources");
1238
1239         if (details->caps & AST_FAX_TECH_AUDIO) {
1240                 expected_frametype = AST_FRAME_VOICE;;
1241                 ast_format_set(&expected_framesubclass.format, AST_FORMAT_SLINEAR, 0);
1242                 ast_format_copy(&orig_write_format, &chan->writeformat);
1243                 if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
1244                         ast_log(LOG_ERROR, "channel '%s' failed to set write format to signed linear'.\n", chan->name);
1245                         ao2_lock(faxregistry.container);
1246                         ao2_unlink(faxregistry.container, fax);
1247                         ao2_unlock(faxregistry.container);
1248                         ao2_ref(fax, -1);
1249                         ast_channel_unlock(chan);
1250                         return -1;
1251                 }
1252                 ast_format_copy(&orig_read_format, &chan->readformat);
1253                 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
1254                         ast_log(LOG_ERROR, "channel '%s' failed to set read format to signed linear.\n", chan->name);
1255                         ao2_lock(faxregistry.container);
1256                         ao2_unlink(faxregistry.container, fax);
1257                         ao2_unlock(faxregistry.container);
1258                         ao2_ref(fax, -1);
1259                         ast_channel_unlock(chan);
1260                         return -1;
1261                 }
1262                 if (fax->smoother) {
1263                         ast_smoother_free(fax->smoother);
1264                         fax->smoother = NULL;
1265                 }
1266                 if (!(fax->smoother = ast_smoother_new(320))) {
1267                         ast_log(LOG_WARNING, "Channel '%s' FAX session '%d' failed to obtain a smoother.\n", chan->name, fax->id);
1268                 }
1269         } else {
1270                 expected_frametype = AST_FRAME_MODEM;
1271                 expected_framesubclass.integer = AST_MODEM_T38;
1272         }
1273
1274         if (fax->debug_info) {
1275                 fax->debug_info->base_tv = ast_tvnow();
1276         }
1277
1278         /* reset our result fields just in case the fax tech driver wants to
1279          * set custom error messages */
1280         ast_string_field_set(details, result, "");
1281         ast_string_field_set(details, resultstr, "");
1282         ast_string_field_set(details, error, "");
1283         set_channel_variables(chan, details);
1284
1285         if (fax->tech->start_session(fax) < 0) {
1286                 GENERIC_FAX_EXEC_ERROR(fax, chan, "INIT_ERROR", "failed to start FAX session");
1287         }
1288
1289         report_fax_status(chan, details, "FAX Transmission In Progress");
1290
1291         ast_debug(5, "channel %s will wait on FAX fd %d\n", chan->name, fax->fd);
1292
1293         /* handle frames for the session */
1294         ms = 1000;
1295         while ((res > -1) && (ms > -1) && (timeout > 0)) {
1296                 struct ast_channel *ready_chan;
1297                 int ofd, exception;
1298
1299                 ms = 1000;
1300                 errno = 0;
1301                 ready_chan = ast_waitfor_nandfds(&c, chancount, &fax->fd, 1, &exception, &ofd, &ms);
1302                 if (ready_chan) {
1303                         if (!(frame = ast_read(chan))) {
1304                                 /* the channel is probably gone, so lets stop polling on it and let the
1305                                  * FAX session complete before we exit the application.  if needed,
1306                                  * send the FAX stack silence so the modems can finish their session without
1307                                  * any problems */
1308                                 ast_debug(1, "Channel '%s' did not return a frame; probably hung up.\n", chan->name);
1309                                 GENERIC_FAX_EXEC_SET_VARS(fax, chan, "HANGUP", "remote channel hungup");
1310                                 c = NULL;
1311                                 chancount = 0;
1312                                 timeout -= (1000 - ms);
1313                                 fax->tech->cancel_session(fax);
1314                                 if (fax->tech->generate_silence) {
1315                                         fax->tech->generate_silence(fax);
1316                                 }
1317                                 continue;
1318                         }
1319
1320                         if ((frame->frametype == AST_FRAME_CONTROL) &&
1321                             (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1322                             (frame->datalen == sizeof(t38_parameters))) {
1323                                 unsigned int was_t38 = t38negotiated;
1324                                 struct ast_control_t38_parameters *parameters = frame->data.ptr;
1325                                 
1326                                 switch (parameters->request_response) {
1327                                 case AST_T38_REQUEST_NEGOTIATE:
1328                                         /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1329                                          * do T.38 as well
1330                                          */
1331                                         t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1332                                         t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
1333                                         ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1334                                         break;
1335                                 case AST_T38_NEGOTIATED:
1336                                         t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1337                                         t38negotiated = 1;
1338                                         break;
1339                                 default:
1340                                         break;
1341                                 }
1342                                 if (t38negotiated && !was_t38) {
1343                                         fax->tech->switch_to_t38(fax);
1344                                         details->caps &= ~AST_FAX_TECH_AUDIO;
1345                                         expected_frametype = AST_FRAME_MODEM;
1346                                         expected_framesubclass.integer = AST_MODEM_T38;
1347                                         if (fax->smoother) {
1348                                                 ast_smoother_free(fax->smoother);
1349                                                 fax->smoother = NULL;
1350                                         }
1351                                         
1352                                         report_fax_status(chan, details, "T.38 Negotiated");
1353                                         
1354                                         ast_verb(3, "Channel '%s' switched to T.38 FAX session '%d'.\n", chan->name, fax->id);
1355                                 }
1356                         } else if ((frame->frametype == expected_frametype) &&
1357                                    (!memcmp(&frame->subclass, &expected_framesubclass, sizeof(frame->subclass)))) {
1358                                 struct ast_frame *f;
1359                                 
1360                                 if (fax->smoother) {
1361                                         /* push the frame into a smoother */
1362                                         if (ast_smoother_feed(fax->smoother, frame) < 0) {
1363                                                 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "Failed to feed the smoother");
1364                                         }
1365                                         while ((f = ast_smoother_read(fax->smoother)) && (f->data.ptr)) {
1366                                                 if (fax->debug_info) {
1367                                                         debug_check_frame_for_silence(fax, 1, f);
1368                                                 }
1369                                                 /* write the frame to the FAX stack */
1370                                                 fax->tech->write(fax, f);
1371                                                 fax->frames_received++;
1372                                                 if (f != frame) {
1373                                                         ast_frfree(f);
1374                                                 }
1375                                         }
1376                                 } else {
1377                                         /* write the frame to the FAX stack */
1378                                         fax->tech->write(fax, frame);
1379                                         fax->frames_received++;
1380                                 }
1381                                 timeout = RES_FAX_TIMEOUT;
1382                         }
1383                         ast_frfree(frame);
1384                 } else if (ofd == fax->fd) {
1385                         /* read a frame from the FAX stack and send it out the channel.
1386                          * the FAX stack will return a NULL if the FAX session has already completed */
1387                         if (!(frame = fax->tech->read(fax))) {
1388                                 break;
1389                         }
1390
1391                         if (fax->debug_info && (frame->frametype == AST_FRAME_VOICE)) {
1392                                 debug_check_frame_for_silence(fax, 0, frame);
1393                         }
1394
1395                         ast_write(chan, frame);
1396                         fax->frames_sent++;
1397                         ast_frfree(frame);
1398                         timeout = RES_FAX_TIMEOUT;
1399                 } else {
1400                         if (ms && (ofd < 0)) {
1401                                 if ((errno == 0) || (errno == EINTR)) {
1402                                         timeout -= (1000 - ms);
1403                                         if (timeout <= 0)
1404                                                 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
1405                                         continue;
1406                                 } else {
1407                                         ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", chan->name);
1408                                         GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "error polling data");
1409                                         res = ms;
1410                                         break;
1411                                 }
1412                         } else {
1413                                 /* nothing happened */
1414                                 if (timeout > 0) {
1415                                         timeout -= 1000;
1416                                         if (timeout <= 0)
1417                                                 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
1418                                         continue;
1419                                 } else {
1420                                         ast_log(LOG_WARNING, "channel '%s' timed-out during the FAX transmission.\n", chan->name);
1421                                         GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
1422                                         break;
1423                                 }
1424                         }
1425                 }
1426         }
1427         ast_debug(3, "channel '%s' - event loop stopped { timeout: %d, ms: %d, res: %d }\n", chan->name, timeout, ms, res);
1428
1429         set_channel_variables(chan, details);
1430
1431         ast_atomic_fetchadd_int(&faxregistry.fax_complete, 1);
1432         if (!strcasecmp(details->result, "FAILED")) {
1433                 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
1434         }
1435
1436         if (fax) {
1437                 ao2_lock(faxregistry.container);
1438                 ao2_unlink(faxregistry.container, fax);
1439                 ao2_unlock(faxregistry.container);
1440                 ao2_ref(fax, -1);
1441         }
1442
1443         /* if the channel is still alive, and we changed its read/write formats,
1444          * restore them now
1445          */
1446         if (chancount) {
1447                 if (orig_read_format.id) {
1448                         ast_set_read_format(chan, &orig_read_format);
1449                 }
1450                 if (orig_write_format.id) {
1451                         ast_set_write_format(chan, &orig_write_format);
1452                 }
1453         }
1454
1455         /* return the chancount so the calling function can determine if the channel hungup during this FAX session or not */
1456         return chancount;
1457 }
1458
1459 static int receivefax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
1460 {
1461         int ms;
1462         struct ast_frame *frame = NULL;
1463         struct ast_control_t38_parameters t38_parameters;
1464
1465         /* don't send any audio if we've already received a T.38 reinvite */
1466         if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
1467                 /* generate 3 seconds of CED */
1468                 if (ast_playtones_start(chan, 1024, "!2100/3000", 1)) {
1469                         ast_log(LOG_ERROR, "error generating CED tone on %s\n", chan->name);
1470                         return -1;
1471                 }
1472
1473                 ms = 3000;
1474                 while (ms > 0) {
1475                         ms = ast_waitfor(chan, ms);
1476                         if (ms < 0) {
1477                                 ast_log(LOG_ERROR, "error while generating CED tone on %s\n", chan->name);
1478                                 ast_playtones_stop(chan);
1479                                 return -1;
1480                         }
1481
1482                         if (ms == 0) { /* all done, nothing happened */
1483                                 break;
1484                         }
1485
1486                         if (!(frame = ast_read(chan))) {
1487                                 ast_log(LOG_ERROR, "error reading frame while generating CED tone on %s\n", chan->name);
1488                                 ast_playtones_stop(chan);
1489                                 return -1;
1490                         }
1491
1492                         if ((frame->frametype == AST_FRAME_CONTROL) &&
1493                             (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1494                             (frame->datalen == sizeof(t38_parameters))) {
1495                                 struct ast_control_t38_parameters *parameters = frame->data.ptr;
1496
1497                                 switch (parameters->request_response) {
1498                                 case AST_T38_REQUEST_NEGOTIATE:
1499                                         /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1500                                          * do T.38 as well
1501                                          */
1502                                         t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1503                                         t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
1504                                         ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1505                                         ast_playtones_stop(chan);
1506                                         break;
1507                                 case AST_T38_NEGOTIATED:
1508                                         ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
1509                                         t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1510                                         details->caps &= ~AST_FAX_TECH_AUDIO;
1511                                         report_fax_status(chan, details, "T.38 Negotiated");
1512                                         break;
1513                                 default:
1514                                         break;
1515                                 }
1516                         }
1517                         ast_frfree(frame);
1518                 }
1519
1520                 ast_playtones_stop(chan);
1521         }
1522
1523         /* if T.38 was negotiated, we are done initializing */
1524         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1525                 return 0;
1526         }
1527
1528         /* request T.38 */
1529         ast_debug(1, "Negotiating T.38 for receive on %s\n", chan->name);
1530
1531         /* wait up to five seconds for negotiation to complete */
1532         ms = 5000;
1533
1534         /* set parameters based on the session's parameters */
1535         t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1536         t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
1537         if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
1538                 return -1;
1539         }
1540
1541         while (ms > 0) {
1542                 ms = ast_waitfor(chan, ms);
1543                 if (ms < 0) {
1544                         ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
1545                         return -1;
1546                 }
1547
1548                 if (ms == 0) { /* all done, nothing happened */
1549                         ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", chan->name);
1550                         details->caps &= ~AST_FAX_TECH_T38;
1551                         break;
1552                 }
1553
1554                 if (!(frame = ast_read(chan))) {
1555                         ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
1556                         return -1;
1557                 }
1558
1559                 if ((frame->frametype == AST_FRAME_CONTROL) &&
1560                                 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1561                                 (frame->datalen == sizeof(t38_parameters))) {
1562                         struct ast_control_t38_parameters *parameters = frame->data.ptr;
1563
1564                         switch (parameters->request_response) {
1565                         case AST_T38_REQUEST_NEGOTIATE:
1566                                 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1567                                 t38_parameters.request_response = AST_T38_NEGOTIATED;
1568                                 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1569                                 break;
1570                         case AST_T38_NEGOTIATED:
1571                                 ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
1572                                 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1573                                 details->caps &= ~AST_FAX_TECH_AUDIO;
1574                                 report_fax_status(chan, details, "T.38 Negotiated");
1575                                 ms = 0;
1576                                 break;
1577                         case AST_T38_REFUSED:
1578                                 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", chan->name);
1579                                 details->caps &= ~AST_FAX_TECH_T38;
1580                                 ms = 0;
1581                                 break;
1582                         default:
1583                                 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", chan->name);
1584                                 details->caps &= ~AST_FAX_TECH_T38;
1585                                 ms = 0;
1586                                 break;
1587                         }
1588                 }
1589                 ast_frfree(frame);
1590         }
1591
1592         /* if T.38 was negotiated, we are done initializing */
1593         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1594                 return 0;
1595         }
1596
1597         /* if we made it here, then T.38 failed, check the 'f' flag */
1598         if (details->option.allow_audio != AST_FAX_OPTFLAG_TRUE) {
1599                 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", chan->name);
1600                 return -1;
1601         }
1602
1603         /* ok, audio fallback is allowed */
1604         details->caps |= AST_FAX_TECH_AUDIO;
1605
1606         return 0;
1607 }
1608
1609 /*! \brief initiate a receive FAX session */
1610 static int receivefax_exec(struct ast_channel *chan, const char *data)
1611 {
1612         char *parse, modems[128] = "";
1613         int channel_alive;
1614         struct ast_fax_session_details *details;
1615         struct ast_fax_session *s;
1616         struct ast_fax_tech_token *token = NULL;
1617         struct ast_fax_document *doc;
1618         AST_DECLARE_APP_ARGS(args,
1619                 AST_APP_ARG(filename);
1620                 AST_APP_ARG(options);
1621         );
1622         struct ast_flags opts = { 0, };
1623         struct manager_event_info info;
1624         enum ast_t38_state t38state;
1625
1626         /* initialize output channel variables */
1627         pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
1628         pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
1629         pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", NULL);
1630         pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
1631         pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
1632         pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
1633
1634         /* Get a FAX session details structure from the channel's FAX datastore and create one if
1635          * it does not already exist. */
1636         if (!(details = find_or_create_details(chan))) {
1637                 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
1638                 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
1639                 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
1640                 return -1;
1641         }
1642
1643         ast_string_field_set(details, result, "FAILED");
1644         ast_string_field_set(details, resultstr, "error starting fax session");
1645         ast_string_field_set(details, error, "INIT_ERROR");
1646         set_channel_variables(chan, details);
1647
1648         if (details->caps & AST_FAX_TECH_GATEWAY) {
1649                 ast_string_field_set(details, resultstr, "can't receive a fax on a channel with a T.38 gateway");
1650                 set_channel_variables(chan, details);
1651                 ast_log(LOG_ERROR, "executing ReceiveFAX on a channel with a T.38 Gateway is not supported\n");
1652                 ao2_ref(details, -1);
1653                 return -1;
1654         }
1655
1656         if (details->maxrate < details->minrate) {
1657                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1658                 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
1659                 set_channel_variables(chan, details);
1660                 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
1661                 ao2_ref(details, -1);
1662                 return -1;
1663         }
1664
1665         if (check_modem_rate(details->modems, details->minrate)) {
1666                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
1667                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
1668                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1669                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
1670                 set_channel_variables(chan, details);
1671                 ao2_ref(details, -1);
1672                 return -1;
1673         }
1674
1675         if (check_modem_rate(details->modems, details->maxrate)) {
1676                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
1677                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
1678                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1679                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
1680                 set_channel_variables(chan, details);
1681                 ao2_ref(details, -1);
1682                 return -1;
1683         }
1684
1685         if (ast_strlen_zero(data)) {
1686                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1687                 ast_string_field_set(details, resultstr, "invalid arguments");
1688                 set_channel_variables(chan, details);
1689                 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
1690                 ao2_ref(details, -1);
1691                 return -1;
1692         }
1693         parse = ast_strdupa(data);
1694         AST_STANDARD_APP_ARGS(args, parse);
1695
1696         if (!ast_strlen_zero(args.options) &&
1697             ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
1698                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1699                 ast_string_field_set(details, resultstr, "invalid arguments");
1700                 set_channel_variables(chan, details);
1701                 ao2_ref(details, -1);
1702                 return -1;
1703         }
1704         if (ast_strlen_zero(args.filename)) {
1705                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1706                 ast_string_field_set(details, resultstr, "invalid arguments");
1707                 set_channel_variables(chan, details);
1708                 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
1709                 ao2_ref(details, -1);
1710                 return -1;
1711         }
1712
1713         /* check for unsupported FAX application options */
1714         if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
1715                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1716                 ast_string_field_set(details, resultstr, "invalid arguments");
1717                 set_channel_variables(chan, details);
1718                 ast_log(LOG_WARNING, "%s does not support polling\n", app_receivefax);
1719                 ao2_ref(details, -1);
1720                 return -1;
1721         }
1722         
1723         ast_atomic_fetchadd_int(&faxregistry.fax_rx_attempts, 1);
1724
1725         pbx_builtin_setvar_helper(chan, "FAXERROR", "Channel Problems");
1726         pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "Error before FAX transmission started.");
1727
1728         if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(args.filename) + 1))) {
1729                 ast_string_field_set(details, error, "MEMORY_ERROR");
1730                 ast_string_field_set(details, resultstr, "error allocating memory");
1731                 set_channel_variables(chan, details);
1732                 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
1733                 ao2_ref(details, -1);
1734                 return -1;
1735         }
1736
1737         strcpy(doc->filename, args.filename);
1738         AST_LIST_INSERT_TAIL(&details->documents, doc, next);
1739
1740         ast_verb(3, "Channel '%s' receiving FAX '%s'\n", chan->name, args.filename);
1741
1742         details->caps = AST_FAX_TECH_RECEIVE;
1743
1744         /* check for debug */
1745         if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
1746                 details->option.debug = AST_FAX_OPTFLAG_TRUE;
1747         }
1748
1749         /* check for request for status events */
1750         if (ast_test_flag(&opts, OPT_STATUS)) {
1751                 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
1752         }
1753
1754         t38state = ast_channel_get_t38_state(chan);
1755         if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
1756             ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
1757             ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
1758                 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
1759         }
1760
1761         if (!(s = fax_session_reserve(details, &token))) {
1762                 ast_string_field_set(details, resultstr, "error reserving fax session");
1763                 set_channel_variables(chan, details);
1764                 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
1765                 ao2_ref(details, -1);
1766                 return -1;
1767         }
1768
1769         /* make sure the channel is up */
1770         if (chan->_state != AST_STATE_UP) {
1771                 if (ast_answer(chan)) {
1772                         ast_string_field_set(details, resultstr, "error answering channel");
1773                         set_channel_variables(chan, details);
1774                         ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
1775                         fax_session_release(s, token);
1776                         ao2_ref(s, -1);
1777                         ao2_ref(details, -1);
1778                         return -1;
1779                 }
1780         }
1781
1782         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
1783                 if (set_fax_t38_caps(chan, details)) {
1784                         ast_string_field_set(details, error, "T38_NEG_ERROR");
1785                         ast_string_field_set(details, resultstr, "error negotiating T.38");
1786                         set_channel_variables(chan, details);
1787                         fax_session_release(s, token);
1788                         ao2_ref(s, -1);
1789                         ao2_ref(details, -1);
1790                         return -1;
1791                 }
1792         } else {
1793                 details->caps |= AST_FAX_TECH_AUDIO;
1794         }
1795
1796         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
1797                 if (receivefax_t38_init(chan, details)) {
1798                         ast_string_field_set(details, error, "T38_NEG_ERROR");
1799                         ast_string_field_set(details, resultstr, "error negotiating T.38");
1800                         set_channel_variables(chan, details);
1801                         fax_session_release(s, token);
1802                         ao2_ref(s, -1);
1803                         ao2_ref(details, -1);
1804                         ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
1805                         return -1;
1806                 }
1807         } else {
1808                 details->option.send_ced = 1;
1809         }
1810
1811         if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
1812                 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
1813         }
1814
1815         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1816                 if (disable_t38(chan)) {
1817                         ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
1818                 }
1819         }
1820
1821         /* send out the AMI completion event */
1822         ast_channel_lock(chan);
1823
1824         get_manager_event_info(chan, &info);
1825         manager_event(EVENT_FLAG_CALL,
1826                       "ReceiveFAX", 
1827                       "Channel: %s\r\n"
1828                       "Context: %s\r\n"
1829                       "Exten: %s\r\n"
1830                       "CallerID: %s\r\n"
1831                       "RemoteStationID: %s\r\n"
1832                       "LocalStationID: %s\r\n"
1833                       "PagesTransferred: %s\r\n"
1834                       "Resolution: %s\r\n"
1835                       "TransferRate: %s\r\n"
1836                       "FileName: %s\r\n",
1837                       chan->name,
1838                       info.context,
1839                       info.exten,
1840                       info.cid,
1841                       S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
1842                       S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
1843                       S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
1844                       S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
1845                       S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
1846                       args.filename);
1847         ast_channel_unlock(chan);
1848
1849         ao2_ref(s, -1);
1850         ao2_ref(details, -1);
1851
1852         /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
1853         return (!channel_alive) ? -1 : 0;
1854 }
1855
1856 static int sendfax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
1857 {
1858         int ms;
1859         struct ast_frame *frame = NULL;
1860         struct ast_control_t38_parameters t38_parameters;
1861
1862         /* send CNG tone while listening for the receiver to initiate a switch
1863          * to T.38 mode; if they do, stop sending the CNG tone and proceed with
1864          * the switch.
1865          *
1866          * 10500 is enough time for 3 CNG tones
1867          */
1868         ms = 10500;
1869
1870         /* don't send any audio if we've already received a T.38 reinvite */
1871         if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
1872                 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000", 1)) {
1873                         ast_log(LOG_ERROR, "error generating CNG tone on %s\n", chan->name);
1874                         return -1;
1875                 }
1876         }
1877
1878         while (ms > 0) {
1879                 ms = ast_waitfor(chan, ms);
1880                 if (ms < 0) {
1881                         ast_log(LOG_ERROR, "error while generating CNG tone on %s\n", chan->name);
1882                         ast_playtones_stop(chan);
1883                         return -1;
1884                 }
1885
1886                 if (ms == 0) { /* all done, nothing happened */
1887                         break;
1888                 }
1889
1890                 if (!(frame = ast_read(chan))) {
1891                         ast_log(LOG_ERROR, "error reading frame while generating CNG tone on %s\n", chan->name);
1892                         ast_playtones_stop(chan);
1893                         return -1;
1894                 }
1895
1896                 if ((frame->frametype == AST_FRAME_CONTROL) &&
1897                                 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1898                                 (frame->datalen == sizeof(t38_parameters))) {
1899                         struct ast_control_t38_parameters *parameters = frame->data.ptr;
1900
1901                         switch (parameters->request_response) {
1902                         case AST_T38_REQUEST_NEGOTIATE:
1903                                 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1904                                  * do T.38 as well
1905                                  */
1906                                 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1907                                 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
1908                                 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1909                                 ast_playtones_stop(chan);
1910                                 break;
1911                         case AST_T38_NEGOTIATED:
1912                                 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
1913                                 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1914                                 details->caps &= ~AST_FAX_TECH_AUDIO;
1915                                 report_fax_status(chan, details, "T.38 Negotiated");
1916                                 ms = 0;
1917                                 break;
1918                         default:
1919                                 break;
1920                         }
1921                 }
1922                 ast_frfree(frame);
1923         }
1924
1925         ast_playtones_stop(chan);
1926
1927         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1928                 return 0;
1929         }
1930
1931         /* T.38 negotiation did not happen, initiate a switch if requested */
1932         if (details->option.request_t38 == AST_FAX_OPTFLAG_TRUE) {
1933                 ast_debug(1, "Negotiating T.38 for send on %s\n", chan->name);
1934
1935                 /* wait up to five seconds for negotiation to complete */
1936                 ms = 5000;
1937
1938                 /* set parameters based on the session's parameters */
1939                 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1940                 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
1941                 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
1942                         return -1;
1943                 }
1944
1945                 while (ms > 0) {
1946                         ms = ast_waitfor(chan, ms);
1947                         if (ms < 0) {
1948                                 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
1949                                 return -1;
1950                         }
1951
1952                         if (ms == 0) { /* all done, nothing happened */
1953                                 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", chan->name);
1954                                 details->caps &= ~AST_FAX_TECH_T38;
1955                                 break;
1956                         }
1957
1958                         if (!(frame = ast_read(chan))) {
1959                                 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
1960                                 return -1;
1961                         }
1962
1963                         if ((frame->frametype == AST_FRAME_CONTROL) &&
1964                                         (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1965                                         (frame->datalen == sizeof(t38_parameters))) {
1966                                 struct ast_control_t38_parameters *parameters = frame->data.ptr;
1967
1968                                 switch (parameters->request_response) {
1969                                 case AST_T38_REQUEST_NEGOTIATE:
1970                                         t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1971                                         t38_parameters.request_response = AST_T38_NEGOTIATED;
1972                                         ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1973                                         break;
1974                                 case AST_T38_NEGOTIATED:
1975                                         ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
1976                                         t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1977                                         details->caps &= ~AST_FAX_TECH_AUDIO;
1978                                         report_fax_status(chan, details, "T.38 Negotiated");
1979                                         ms = 0;
1980                                         break;
1981                                 case AST_T38_REFUSED:
1982                                         ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", chan->name);
1983                                         details->caps &= ~AST_FAX_TECH_T38;
1984                                         ms = 0;
1985                                         break;
1986                                 default:
1987                                         ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", chan->name);
1988                                         details->caps &= ~AST_FAX_TECH_T38;
1989                                         ms = 0;
1990                                         break;
1991                                 }
1992                         }
1993                         ast_frfree(frame);
1994                 }
1995
1996                 /* if T.38 was negotiated, we are done initializing */
1997                 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1998                         return 0;
1999                 }
2000
2001                 /* send one more CNG tone to get audio going again for some
2002                  * carriers if we are going to fall back to audio mode */
2003                 if (details->option.allow_audio == AST_FAX_OPTFLAG_TRUE) {
2004                         if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000", 1)) {
2005                                 ast_log(LOG_ERROR, "error generating second CNG tone on %s\n", chan->name);
2006                                 return -1;
2007                         }
2008
2009                         ms = 3500;
2010                         while (ms > 0) {
2011                                 ms = ast_waitfor(chan, ms);
2012                                 if (ms < 0) {
2013                                         ast_log(LOG_ERROR, "error while generating second CNG tone on %s\n", chan->name);
2014                                         ast_playtones_stop(chan);
2015                                         return -1;
2016                                 }
2017
2018                                 if (ms == 0) { /* all done, nothing happened */
2019                                         break;
2020                                 }
2021
2022                                 if (!(frame = ast_read(chan))) {
2023                                         ast_log(LOG_ERROR, "error reading frame while generating second CNG tone on %s\n", chan->name);
2024                                         ast_playtones_stop(chan);
2025                                         return -1;
2026                                 }
2027
2028                                 if ((frame->frametype == AST_FRAME_CONTROL) &&
2029                                                 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
2030                                                 (frame->datalen == sizeof(t38_parameters))) {
2031                                         struct ast_control_t38_parameters *parameters = frame->data.ptr;
2032
2033                                         switch (parameters->request_response) {
2034                                         case AST_T38_REQUEST_NEGOTIATE:
2035                                                 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
2036                                                  * do T.38 as well
2037                                                  */
2038                                                 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2039                                                 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
2040                                                 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2041                                                 ast_playtones_stop(chan);
2042                                                 break;
2043                                         case AST_T38_NEGOTIATED:
2044                                                 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
2045                                                 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2046                                                 details->caps &= ~AST_FAX_TECH_AUDIO;
2047                                                 report_fax_status(chan, details, "T.38 Negotiated");
2048                                                 ms = 0;
2049                                                 break;
2050                                         default:
2051                                                 break;
2052                                         }
2053                                 }
2054                                 ast_frfree(frame);
2055                         }
2056
2057                         ast_playtones_stop(chan);
2058
2059                         /* if T.38 was negotiated, we are done initializing */
2060                         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2061                                 return 0;
2062                         }
2063                 }
2064         }
2065
2066         /* if we made it here, then T.38 failed, check the 'f' flag */
2067         if (details->option.allow_audio == AST_FAX_OPTFLAG_FALSE) {
2068                 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", chan->name);
2069                 return -1;
2070         }
2071
2072         /* ok, audio fallback is allowed */
2073         details->caps |= AST_FAX_TECH_AUDIO;
2074
2075         return 0;
2076 }
2077
2078
2079 /*! \brief initiate a send FAX session */
2080 static int sendfax_exec(struct ast_channel *chan, const char *data)
2081 {
2082         char *parse, *filenames, *c, modems[128] = "";
2083         int channel_alive, file_count;
2084         struct ast_fax_session_details *details;
2085         struct ast_fax_session *s;
2086         struct ast_fax_tech_token *token = NULL;
2087         struct ast_fax_document *doc;
2088         AST_DECLARE_APP_ARGS(args,
2089                 AST_APP_ARG(filenames);
2090                 AST_APP_ARG(options);
2091         );
2092         struct ast_flags opts = { 0, };
2093         struct manager_event_info info;
2094         enum ast_t38_state t38state;
2095
2096         /* initialize output channel variables */
2097         pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
2098         pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
2099         pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", NULL);
2100         pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
2101         pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
2102         pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
2103
2104         /* Get a requirement structure and set it.  This structure is used
2105          * to tell the FAX technology module about the higher level FAX session */
2106         if (!(details = find_or_create_details(chan))) {
2107                 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
2108                 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
2109                 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2110                 return -1;
2111         }
2112
2113         ast_string_field_set(details, result, "FAILED");
2114         ast_string_field_set(details, resultstr, "error starting fax session");
2115         ast_string_field_set(details, error, "INIT_ERROR");
2116         set_channel_variables(chan, details);
2117
2118         if (details->caps & AST_FAX_TECH_GATEWAY) {
2119                 ast_string_field_set(details, resultstr, "can't send a fax on a channel with a T.38 gateway");
2120                 set_channel_variables(chan, details);
2121                 ast_log(LOG_ERROR, "executing SendFAX on a channel with a T.38 Gateway is not supported\n");
2122                 ao2_ref(details, -1);
2123                 return -1;
2124         }
2125
2126         if (details->maxrate < details->minrate) {
2127                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2128                 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
2129                 set_channel_variables(chan, details);
2130                 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
2131                 ao2_ref(details, -1);
2132                 return -1;
2133         }
2134
2135         if (check_modem_rate(details->modems, details->minrate)) {
2136                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2137                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
2138                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2139                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
2140                 set_channel_variables(chan, details);
2141                 ao2_ref(details, -1);
2142                 return -1;
2143         }
2144
2145         if (check_modem_rate(details->modems, details->maxrate)) {
2146                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2147                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
2148                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2149                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
2150                 set_channel_variables(chan, details);
2151                 ao2_ref(details, -1);
2152                 return -1;
2153         }
2154
2155         if (ast_strlen_zero(data)) {
2156                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2157                 ast_string_field_set(details, resultstr, "invalid arguments");
2158                 set_channel_variables(chan, details);
2159                 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]][,options])\n", app_sendfax);
2160                 ao2_ref(details, -1);
2161                 return -1;
2162         }
2163         parse = ast_strdupa(data);
2164         AST_STANDARD_APP_ARGS(args, parse);
2165
2166
2167         if (!ast_strlen_zero(args.options) &&
2168             ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
2169                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2170                 ast_string_field_set(details, resultstr, "invalid arguments");
2171                 set_channel_variables(chan, details);
2172                 ao2_ref(details, -1);
2173                 return -1;
2174         }
2175         if (ast_strlen_zero(args.filenames)) {
2176                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2177                 ast_string_field_set(details, resultstr, "invalid arguments");
2178                 set_channel_variables(chan, details);
2179                 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]],options])\n", app_sendfax);
2180                 ao2_ref(details, -1);
2181                 return -1;
2182         }
2183         
2184         /* check for unsupported FAX application options */
2185         if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
2186                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2187                 ast_string_field_set(details, resultstr, "invalid arguments");
2188                 set_channel_variables(chan, details);
2189                 ast_log(LOG_WARNING, "%s does not support polling\n", app_sendfax);
2190                 ao2_ref(details, -1);
2191                 return -1;
2192         }
2193
2194         ast_atomic_fetchadd_int(&faxregistry.fax_tx_attempts, 1);
2195
2196         file_count = 0;
2197         filenames = args.filenames;
2198         while ((c = strsep(&filenames, "&"))) {
2199                 if (access(c, (F_OK | R_OK)) < 0) {
2200                         ast_string_field_set(details, error, "FILE_ERROR");
2201                         ast_string_field_set(details, resultstr, "error reading file");
2202                         set_channel_variables(chan, details);
2203                         ast_log(LOG_ERROR, "access failure.  Verify '%s' exists and check permissions.\n", args.filenames);
2204                         ao2_ref(details, -1);
2205                         return -1;
2206                 }
2207
2208                 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(c) + 1))) {
2209                         ast_string_field_set(details, error, "MEMORY_ERROR");
2210                         ast_string_field_set(details, resultstr, "error allocating memory");
2211                         set_channel_variables(chan, details);
2212                         ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2213                         ao2_ref(details, -1);
2214                         return -1;
2215                 }
2216
2217                 strcpy(doc->filename, c);
2218                 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
2219                 file_count++;
2220         }
2221
2222         if (file_count > 1) {
2223                 details->caps |= AST_FAX_TECH_MULTI_DOC;
2224         }
2225
2226         ast_verb(3, "Channel '%s' sending FAX:\n", chan->name);
2227         AST_LIST_TRAVERSE(&details->documents, doc, next) {
2228                 ast_verb(3, "   %s\n", doc->filename);
2229         }
2230
2231         details->caps = AST_FAX_TECH_SEND;
2232
2233         /* check for debug */
2234         if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
2235                 details->option.debug = AST_FAX_OPTFLAG_TRUE;
2236         }
2237
2238         /* check for request for status events */
2239         if (ast_test_flag(&opts, OPT_STATUS)) {
2240                 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
2241         }
2242
2243         t38state = ast_channel_get_t38_state(chan);
2244         if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
2245             ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
2246             ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2247                 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
2248         }
2249
2250         if (ast_test_flag(&opts, OPT_REQUEST_T38)) {
2251                 details->option.request_t38 = AST_FAX_OPTFLAG_TRUE;
2252         }
2253
2254         if (!(s = fax_session_reserve(details, &token))) {
2255                 ast_string_field_set(details, resultstr, "error reserving fax session");
2256                 set_channel_variables(chan, details);
2257                 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
2258                 ao2_ref(details, -1);
2259                 return -1;
2260         }
2261
2262         /* make sure the channel is up */
2263         if (chan->_state != AST_STATE_UP) {
2264                 if (ast_answer(chan)) {
2265                         ast_string_field_set(details, resultstr, "error answering channel");
2266                         set_channel_variables(chan, details);
2267                         ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
2268                         fax_session_release(s, token);
2269                         ao2_ref(s, -1);
2270                         ao2_ref(details, -1);
2271                         return -1;
2272                 }
2273         }
2274
2275         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2276                 if (set_fax_t38_caps(chan, details)) {
2277                         ast_string_field_set(details, error, "T38_NEG_ERROR");
2278                         ast_string_field_set(details, resultstr, "error negotiating T.38");
2279                         set_channel_variables(chan, details);
2280                         fax_session_release(s, token);
2281                         ao2_ref(s, -1);
2282                         ao2_ref(details, -1);
2283                         return -1;
2284                 }
2285         } else {
2286                 details->caps |= AST_FAX_TECH_AUDIO;
2287         }
2288
2289         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
2290                 if (sendfax_t38_init(chan, details)) {
2291                         ast_string_field_set(details, error, "T38_NEG_ERROR");
2292                         ast_string_field_set(details, resultstr, "error negotiating T.38");
2293                         set_channel_variables(chan, details);
2294                         fax_session_release(s, token);
2295                         ao2_ref(s, -1);
2296                         ao2_ref(details, -1);
2297                         ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
2298                         return -1;
2299                 }
2300         } else {
2301                 details->option.send_cng = 1;
2302         }
2303
2304         if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
2305                 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
2306         }
2307
2308         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2309                 if (disable_t38(chan)) {
2310                         ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
2311                 }
2312         }
2313
2314         if (!(filenames = generate_filenames_string(details, "FileName: ", "\r\n"))) {
2315                 ast_log(LOG_ERROR, "Error generating SendFAX manager event\n");
2316                 ao2_ref(s, -1);
2317                 ao2_ref(details, -1);
2318                 return (!channel_alive) ? -1 : 0;
2319         }
2320
2321         /* send out the AMI completion event */
2322         ast_channel_lock(chan);
2323         get_manager_event_info(chan, &info);
2324         manager_event(EVENT_FLAG_CALL,
2325                       "SendFAX", 
2326                       "Channel: %s\r\n"
2327                       "Context: %s\r\n"
2328                       "Exten: %s\r\n"
2329                       "CallerID: %s\r\n"
2330                       "RemoteStationID: %s\r\n"
2331                       "LocalStationID: %s\r\n"
2332                       "PagesTransferred: %s\r\n"
2333                       "Resolution: %s\r\n"
2334                       "TransferRate: %s\r\n"
2335                       "%s\r\n",
2336                       chan->name,
2337                       info.context,
2338                       info.exten,
2339                       info.cid,
2340                       S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
2341                       S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
2342                       S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
2343                       S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
2344                       S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
2345                       filenames);
2346         ast_channel_unlock(chan);
2347
2348         ast_free(filenames);
2349
2350         ao2_ref(s, -1);
2351         ao2_ref(details, -1);
2352
2353         /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
2354         return (!channel_alive) ? -1 : 0;
2355 }
2356
2357 /*! \brief destroy a FAX gateway session structure */
2358 static void destroy_gateway(void *data)
2359 {
2360         struct fax_gateway *gateway = data;
2361
2362         if (gateway->chan_dsp) {
2363                 ast_dsp_free(gateway->chan_dsp);
2364                 gateway->chan_dsp = NULL;
2365         }
2366
2367         if (gateway->peer_dsp) {
2368                 ast_dsp_free(gateway->peer_dsp);
2369                 gateway->peer_dsp = NULL;
2370         }
2371
2372         if (gateway->s) {
2373                 fax_session_release(gateway->s, gateway->token);
2374                 gateway->token = NULL;
2375                 gateway->s->details->caps |= ~AST_FAX_TECH_GATEWAY;
2376
2377                 ao2_lock(faxregistry.container);
2378                 ao2_unlink(faxregistry.container, gateway->s);
2379                 ao2_unlock(faxregistry.container);
2380
2381                 ao2_ref(gateway->s, -1);
2382                 gateway->s = NULL;
2383         }
2384 }
2385
2386 /*! \brief Create a new fax gateway object.
2387  * \param details the fax session details
2388  * \return NULL or a fax gateway object
2389  */
2390 static struct fax_gateway *fax_gateway_new(struct ast_fax_session_details *details)
2391 {
2392         struct fax_gateway *gateway = ao2_alloc(sizeof(*gateway), destroy_gateway);
2393         if (!gateway) {
2394                 return NULL;
2395         }
2396
2397         gateway->chan_dsp = ast_dsp_new();
2398         if (!gateway->chan_dsp) {
2399                 ao2_ref(gateway, -1);
2400                 return NULL;
2401         }
2402
2403         gateway->peer_dsp = ast_dsp_new();
2404         if (!gateway->peer_dsp) {
2405                 ao2_ref(gateway, -1);
2406                 return NULL;
2407         }
2408
2409         gateway->framehook = -1;
2410
2411         ast_dsp_set_features(gateway->chan_dsp, DSP_FEATURE_FAX_DETECT);
2412         ast_dsp_set_faxmode(gateway->chan_dsp, DSP_FAXMODE_DETECT_V21);
2413
2414         ast_dsp_set_features(gateway->peer_dsp, DSP_FEATURE_FAX_DETECT);
2415         ast_dsp_set_faxmode(gateway->peer_dsp, DSP_FAXMODE_DETECT_V21);
2416
2417         details->caps = AST_FAX_TECH_GATEWAY;
2418         if (!(gateway->s = fax_session_reserve(details, &gateway->token))) {
2419                 details->caps |= ~AST_FAX_TECH_GATEWAY;
2420                 ast_log(LOG_ERROR, "Can't reserve a FAX session, gateway attempt failed.\n");
2421                 ao2_ref(gateway, -1);
2422                 return NULL;
2423         }
2424
2425         return gateway;
2426 }
2427
2428 /*! \brief Create a fax session and start T.30<->T.38 gateway mode
2429  * \param gateway a fax gateway object
2430  * \param details fax session details
2431  * \param chan active channel
2432  * \return 0 on error 1 on success*/
2433 static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session_details *details, struct ast_channel *chan)
2434 {
2435         struct ast_fax_session *s;
2436
2437         /* create the FAX session */
2438         if (!(s = fax_session_new(details, chan, gateway->s, gateway->token))) {
2439                 gateway->token = NULL;
2440                 ast_string_field_set(details, result, "FAILED");
2441                 ast_string_field_set(details, resultstr, "error starting gateway session");
2442                 ast_string_field_set(details, error, "INIT_ERROR");
2443                 set_channel_variables(chan, details);
2444                 report_fax_status(chan, details, "No Available Resource");
2445                 ast_log(LOG_ERROR, "Can't create a FAX session, gateway attempt failed.\n");
2446                 return -1;
2447         }
2448         /* release the reference for the reserved session and replace it with
2449          * the real session */
2450         ao2_ref(gateway->s, -1);
2451         gateway->s = s;
2452         gateway->token = NULL;
2453
2454         if (gateway->s->tech->start_session(gateway->s) < 0) {
2455                 ast_string_field_set(details, result, "FAILED");
2456                 ast_string_field_set(details, resultstr, "error starting gateway session");
2457                 ast_string_field_set(details, error, "INIT_ERROR");
2458                 set_channel_variables(chan, details);
2459                 return -1;
2460         }
2461
2462         gateway->timeout_start.tv_sec = 0;
2463         gateway->timeout_start.tv_usec = 0;
2464
2465         report_fax_status(chan, details, "FAX Transmission In Progress");
2466
2467         return 0;
2468 }
2469
2470 static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_frame *f)
2471 {
2472         struct ast_frame *fp;
2473         struct ast_control_t38_parameters t38_parameters = {
2474                 .request_response = AST_T38_REQUEST_NEGOTIATE,
2475         };
2476         struct ast_frame control_frame = {
2477                 .src = "res_fax",
2478                 .frametype = AST_FRAME_CONTROL,
2479                 .datalen = sizeof(t38_parameters),
2480                 .subclass.integer = AST_CONTROL_T38_PARAMETERS,
2481                 .data.ptr = &t38_parameters,
2482         };
2483
2484         struct ast_fax_session_details *details = find_details(chan);
2485
2486         if (!details) {
2487                 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", chan->name);
2488                 ast_framehook_detach(chan, gateway->framehook);
2489                 return f;
2490         }
2491
2492         t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2493         ao2_ref(details, -1);
2494
2495         if (!(fp = ast_frisolate(&control_frame))) {
2496                 ast_log(LOG_ERROR, "error generating T.38 request control frame on chan %s for T.38 gateway session\n", chan->name);
2497                 return f;
2498         }
2499
2500         gateway->t38_state = T38_STATE_NEGOTIATING;
2501         gateway->timeout_start = ast_tvnow();
2502
2503         ast_debug(1, "requesting T.38 for gateway session for %s\n", chan->name);
2504         return fp;
2505 }
2506
2507 static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f)
2508 {
2509         struct ast_frame *dfr = ast_frdup(f);
2510         struct ast_dsp *active_dsp = (active == chan) ? gateway->chan_dsp : gateway->peer_dsp;
2511         struct ast_channel *other = (active == chan) ? peer : chan;
2512
2513         if (gateway->detected_v21) {
2514                 return f;
2515         }
2516
2517         if (!dfr) {
2518                 return f;
2519         }
2520
2521         if (!(dfr = ast_dsp_process(active, active_dsp, dfr))) {
2522                 return f;
2523         }
2524
2525         if (dfr->frametype == AST_FRAME_DTMF && dfr->subclass.integer == 'g') {
2526                 gateway->detected_v21 = 1;
2527                 if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
2528                         ast_debug(1, "detected v21 preamble from %s\n", active->name);
2529                         return fax_gateway_request_t38(gateway, chan, f);
2530                 } else {
2531                         ast_debug(1, "detected v21 preamble on %s, but %s does not support T.38 for T.38 gateway session\n", active->name, other->name);
2532                 }
2533         }
2534
2535         ast_frfree(dfr);
2536         return f;
2537 }
2538
2539 static int fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
2540 {
2541         if (active == chan) {
2542                 return ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
2543         } else {
2544                 return ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
2545         }
2546 }
2547
2548 /*! \brief T38 Gateway Negotiate t38 parameters
2549  * \param gateway gateway object
2550  * \param chan channel running the gateway
2551  * \param peer channel im bridged too
2552  * \param active channel the frame originated on
2553  * \param f the control frame to process
2554  * \return processed control frame or null frame
2555  */
2556 static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f)
2557 {
2558         struct ast_control_t38_parameters *control_params = f->data.ptr;
2559         struct ast_channel *other = (active == chan) ? peer : chan;
2560         struct ast_fax_session_details *details;
2561
2562         if (f->datalen != sizeof(struct ast_control_t38_parameters)) {
2563                 /* invalaid AST_CONTROL_T38_PARAMETERS frame, we can't
2564                  * do anything with it, pass it on */
2565                 return f;
2566         }
2567
2568         /* ignore frames from ourselves */
2569         if ((gateway->t38_state == T38_STATE_NEGOTIATED && control_params->request_response == AST_T38_NEGOTIATED)
2570                 || (gateway->t38_state == T38_STATE_REJECTED && control_params->request_response == AST_T38_REFUSED)
2571                 || (gateway->t38_state == T38_STATE_NEGOTIATING && control_params->request_response == AST_T38_REQUEST_TERMINATE)) {
2572
2573                 return f;
2574         }
2575
2576         if (!(details = find_details(chan))) {
2577                 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", chan->name);
2578                 ast_framehook_detach(chan, gateway->framehook);
2579                 return f;
2580         }
2581
2582         if (control_params->request_response == AST_T38_REQUEST_NEGOTIATE) {
2583                 enum ast_t38_state state = ast_channel_get_t38_state(other);
2584
2585                 if (state == T38_STATE_UNKNOWN) {
2586                         /* we detected a request to negotiate T.38 and the
2587                          * other channel appears to support T.38, we'll pass
2588                          * the request through and only step in if the other
2589                          * channel rejects the request */
2590                         ast_debug(1, "%s is attempting to negotiate T.38 with %s, we'll see what happens\n", active->name, other->name);
2591                         t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2592                         gateway->t38_state = T38_STATE_UNKNOWN;
2593                         gateway->timeout_start = ast_tvnow();
2594                         ao2_ref(details, -1);
2595                         return f;
2596                 } else if (state == T38_STATE_UNAVAILABLE || state == T38_STATE_REJECTED) {
2597                         /* the other channel does not support T.38, we need to
2598                          * step in here */
2599                         ast_debug(1, "%s is attempting to negotiate T.38 but %s does not support it\n", active->name, other->name);
2600                         ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2601
2602                         t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2603                         t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
2604
2605                         if (fax_gateway_start(gateway, details, chan)) {
2606                                 ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2607                                 gateway->t38_state = T38_STATE_REJECTED;
2608                                 control_params->request_response = AST_T38_REFUSED;
2609
2610                                 ast_framehook_detach(chan, details->gateway_id);
2611                                 details->gateway_id = -1;
2612                         } else {
2613                                 gateway->t38_state = T38_STATE_NEGOTIATED;
2614                                 control_params->request_response = AST_T38_NEGOTIATED;
2615                                 report_fax_status(chan, details, "T.38 Negotiated");
2616                         }
2617
2618                         fax_gateway_indicate_t38(chan, active, control_params);
2619
2620                         ao2_ref(details, -1);
2621                         return &ast_null_frame;
2622                 } else if (gateway->t38_state == T38_STATE_NEGOTIATING) {
2623                         /* we got a request to negotiate T.38 after we already
2624                          * sent one to the other party based on v21 preamble
2625                          * detection. We'll just pretend we passed this request
2626                          * through in the first place. */
2627
2628                         t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2629                         gateway->t38_state = T38_STATE_UNKNOWN;
2630                         gateway->timeout_start = ast_tvnow();
2631
2632                         ast_debug(1, "%s is attempting to negotiate T.38 after we already sent a negotiation request based on v21 preamble detection\n", active->name);
2633                         ao2_ref(details, -1);
2634                         return &ast_null_frame;
2635                 } else if (gateway->t38_state == T38_STATE_NEGOTIATED) {
2636                         /* we got a request to negotiate T.38 after we already
2637                          * sent one to the other party based on v21 preamble
2638                          * detection and received a response. We need to
2639                          * respond to this and shut down the gateway. */
2640
2641                         t38_parameters_fax_to_ast(control_params, &details->their_t38_parameters);
2642                         ast_framehook_detach(chan, details->gateway_id);
2643                         details->gateway_id = -1;
2644
2645                         control_params->request_response = AST_T38_NEGOTIATED;
2646
2647                         fax_gateway_indicate_t38(chan, active, control_params);
2648
2649                         ast_string_field_set(details, result, "SUCCESS");
2650                         ast_string_field_set(details, resultstr, "no gateway necessary");
2651                         ast_string_field_set(details, error, "NATIVE_T38");
2652                         set_channel_variables(chan, details);
2653
2654                         ast_debug(1, "%s is attempting to negotiate T.38 after we already negotiated T.38 with %s, disabling the gateway\n", active->name, other->name);
2655                         ao2_ref(details, -1);
2656                         return &ast_null_frame;
2657                 } else {
2658                         ast_log(LOG_WARNING, "%s is attempting to negotiate T.38 while %s is in an unsupported state\n", active->name, other->name);
2659                         ao2_ref(details, -1);
2660                         return f;
2661                 }
2662         } else if (gateway->t38_state == T38_STATE_NEGOTIATING
2663                 && control_params->request_response == AST_T38_REFUSED) {
2664
2665                 ast_debug(1, "unable to negotiate T.38 on %s for fax gateway\n", active->name);
2666
2667                 /* our request to negotiate T.38 was refused, if the other
2668                  * channel supports T.38, they might still reinvite and save
2669                  * the day.  Otherwise disable the gateway. */
2670                 if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
2671                         gateway->t38_state = T38_STATE_UNAVAILABLE;
2672                 } else {
2673                         ast_framehook_detach(chan, details->gateway_id);
2674                         details->gateway_id = -1;
2675
2676                         ast_string_field_set(details, result, "FAILED");
2677                         ast_string_field_set(details, resultstr, "unable to negotiate T.38");
2678                         ast_string_field_set(details, error, "T38_NEG_ERROR");
2679                         set_channel_variables(chan, details);
2680                 }
2681
2682                 ao2_ref(details, -1);
2683                 return &ast_null_frame;
2684         } else if (gateway->t38_state == T38_STATE_NEGOTIATING
2685                 && control_params->request_response == AST_T38_NEGOTIATED) {
2686
2687                 ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2688
2689                 t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2690
2691                 if (fax_gateway_start(gateway, details, chan)) {
2692                         ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2693                         gateway->t38_state = T38_STATE_NEGOTIATING;
2694                         control_params->request_response = AST_T38_REQUEST_TERMINATE;
2695
2696                         fax_gateway_indicate_t38(chan, active, control_params);
2697                 } else {
2698                         gateway->t38_state = T38_STATE_NEGOTIATED;
2699                         report_fax_status(chan, details, "T.38 Negotiated");
2700                 }
2701
2702                 ao2_ref(details, -1);
2703                 return &ast_null_frame;
2704         } else if (control_params->request_response == AST_T38_REFUSED) {
2705                 /* the other channel refused the request to negotiate T.38,
2706                  * we'll step in here and pretend the request was accepted */
2707
2708                 ast_debug(1, "%s attempted to negotiate T.38 but %s refused the request\n", other->name, active->name);
2709                 ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", other->name, active->name);
2710
2711                 t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
2712
2713                 if (fax_gateway_start(gateway, details, chan)) {
2714                         ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2715                         gateway->t38_state = T38_STATE_REJECTED;
2716                         control_params->request_response = AST_T38_REFUSED;
2717
2718                         ast_framehook_detach(chan, details->gateway_id);
2719                         details->gateway_id = -1;
2720                 } else {
2721                         gateway->t38_state = T38_STATE_NEGOTIATED;
2722                         control_params->request_response = AST_T38_NEGOTIATED;
2723                 }
2724
2725                 ao2_ref(details, -1);
2726                 return f;
2727         } else if (control_params->request_response == AST_T38_REQUEST_TERMINATE) {
2728                 /* the channel wishes to end our short relationship, we shall
2729                  * oblige */
2730
2731                 ast_debug(1, "T.38 channel %s is requesting a shutdown of T.38, disabling the gateway\n", active->name);
2732
2733                 ast_framehook_detach(chan, details->gateway_id);
2734                 details->gateway_id = -1;
2735
2736                 gateway->t38_state = T38_STATE_REJECTED;
2737                 control_params->request_response = AST_T38_TERMINATED;
2738
2739                 fax_gateway_indicate_t38(chan, active, control_params);
2740
2741                 ao2_ref(details, -1);
2742                 return &ast_null_frame;
2743         } else if (control_params->request_response == AST_T38_NEGOTIATED) {
2744                 ast_debug(1, "T.38 successfully negotiated between %s and %s, no gateway necessary\n", active->name, other->name);
2745
2746                 ast_framehook_detach(chan, details->gateway_id);
2747                 details->gateway_id = -1;
2748
2749                 ast_string_field_set(details, result, "SUCCESS");
2750                 ast_string_field_set(details, resultstr, "no gateway necessary");
2751                 ast_string_field_set(details, error, "NATIVE_T38");
2752                 set_channel_variables(chan, details);
2753
2754                 ao2_ref(details, -1);
2755                 return f;
2756         } else if (control_params->request_response == AST_T38_TERMINATED) {
2757                 ast_debug(1, "T.38 disabled on channel %s\n", active->name);
2758
2759                 ast_framehook_detach(chan, details->gateway_id);
2760                 details->gateway_id = -1;
2761
2762                 ao2_ref(details, -1);
2763                 return &ast_null_frame;
2764         }
2765
2766         ao2_ref(details, -1);
2767         return f;
2768 }
2769
2770 /*! \brief Destroy the gateway data structure when the framehook is detached
2771  * \param data framehook data (gateway data)*/
2772 static void fax_gateway_framehook_destroy(void *data) {
2773         struct fax_gateway *gateway = data;
2774
2775         if (gateway->s) {
2776                 switch (gateway->s->state) {
2777                 case AST_FAX_STATE_INITIALIZED:
2778                 case AST_FAX_STATE_OPEN:
2779                 case AST_FAX_STATE_ACTIVE:
2780                 case AST_FAX_STATE_COMPLETE:
2781                         if (gateway->s->tech->cancel_session) {
2782                                 gateway->s->tech->cancel_session(gateway->s);
2783                         }
2784                         /* fall through */
2785                 default:
2786                         break;
2787                 }
2788         }
2789
2790         ao2_ref(gateway, -1);
2791 }
2792
2793 /*! \brief T.30<->T.38 gateway framehook.
2794  *
2795  * Intercept packets on bridged channels and determine if a T.38 gateway is
2796  * required. If a gateway is required, start a gateway and handle T.38
2797  * negotiation if necessary.
2798  *
2799  * \param chan channel running the gateway
2800  * \param f frame to handle may be NULL
2801  * \param event framehook event
2802  * \param data framehook data (struct fax_gateway *)
2803  *
2804  * \return processed frame or NULL when f is NULL or a null frame
2805  */
2806 static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data) {
2807         struct fax_gateway *gateway = data;
2808         struct ast_channel *peer, *active;
2809
2810         /* restore audio formats when we are detached */
2811         if (event == AST_FRAMEHOOK_EVENT_DETACHED) {
2812                 set_channel_variables(chan, gateway->s->details);
2813
2814                 if (gateway->bridged) {
2815                         ast_set_read_format(chan, &gateway->chan_read_format);
2816                         ast_set_read_format(chan, &gateway->chan_write_format);
2817
2818                         if ((peer = ast_bridged_channel(chan))) {
2819                                 ast_set_read_format(peer, &gateway->peer_read_format);
2820                                 ast_set_read_format(peer, &gateway->peer_write_format);
2821                                 ast_channel_make_compatible(chan, peer);
2822                         }
2823                 }
2824
2825                 return NULL;
2826         }
2827
2828         if (!f || (event == AST_FRAMEHOOK_EVENT_ATTACHED)) {
2829                 return NULL;
2830         };
2831
2832         /* this frame was generated by the fax gateway, pass it on */
2833         if (ast_test_flag(f, AST_FAX_FRFLAG_GATEWAY)) {
2834                 return f;
2835         }
2836
2837         if (!(peer = ast_bridged_channel(chan))) {
2838                 /* not bridged, don't do anything */
2839                 return f;
2840         }
2841
2842         if (!gateway->bridged && peer) {
2843                 /* don't start a gateway if neither channel can handle T.38 */
2844                 if (ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE && ast_channel_get_t38_state(peer) == T38_STATE_UNAVAILABLE) {
2845                         ast_debug(1, "not starting gateway for %s and %s; neither channel supports T.38\n", chan->name, peer->name);
2846                         ast_framehook_detach(chan, gateway->framehook);
2847                         gateway->s->details->gateway_id = -1;
2848
2849                         ast_string_field_set(gateway->s->details, result, "FAILED");
2850                         ast_string_field_set(gateway->s->details, resultstr, "neither channel supports T.38");
2851                         ast_string_field_set(gateway->s->details, error, "T38_NEG_ERROR");
2852                         set_channel_variables(chan, gateway->s->details);
2853                         return f;
2854                 }
2855
2856                 gateway->timeout_start = ast_tvnow();
2857
2858                 /* we are bridged, change r/w formats to SLIN for v21 preamble
2859                  * detection and T.30 */
2860                 ast_format_copy(&gateway->chan_read_format, &chan->readformat);
2861                 ast_format_copy(&gateway->chan_write_format, &chan->readformat);
2862
2863                 ast_format_copy(&gateway->peer_read_format, &peer->readformat);
2864                 ast_format_copy(&gateway->peer_write_format, &peer->readformat);
2865
2866                 ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2867                 ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
2868
2869                 ast_set_read_format_by_id(peer, AST_FORMAT_SLINEAR);
2870                 ast_set_write_format_by_id(peer, AST_FORMAT_SLINEAR);
2871
2872                 ast_channel_make_compatible(chan, peer);
2873                 gateway->bridged = 1;
2874         }
2875
2876         if (gateway->bridged && !ast_tvzero(gateway->timeout_start)) {
2877                 if (ast_tvdiff_ms(ast_tvnow(), gateway->timeout_start) > FAX_GATEWAY_TIMEOUT) {
2878                         ast_debug(1, "no fax activity between %s and %s after %d ms, disabling gateway\n", chan->name, peer->name, FAX_GATEWAY_TIMEOUT);
2879                         ast_framehook_detach(chan, gateway->framehook);
2880                         gateway->s->details->gateway_id = -1;
2881
2882                         ast_string_field_set(gateway->s->details, result, "FAILED");
2883                         ast_string_field_build(gateway->s->details, resultstr, "no fax activity after %d ms", FAX_GATEWAY_TIMEOUT);
2884                         ast_string_field_set(gateway->s->details, error, "TIMEOUT");
2885                         set_channel_variables(chan, gateway->s->details);
2886                         return f;
2887                 }
2888         }
2889
2890         /* only handle VOICE, MODEM, and CONTROL frames*/
2891         switch (f->frametype) {
2892         case AST_FRAME_VOICE:
2893                 switch (f->subclass.format.id) {
2894                 case AST_FORMAT_SLINEAR:
2895                 case AST_FORMAT_ALAW:
2896                 case AST_FORMAT_ULAW:
2897                         break;
2898                 default:
2899                         return f;
2900                 }
2901                 break;
2902         case AST_FRAME_MODEM:
2903                 if (f->subclass.integer == AST_MODEM_T38) {
2904                         break;
2905                 }
2906                 return f;
2907         case AST_FRAME_CONTROL:
2908                 if (f->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
2909                         break;
2910                 }
2911                 return f;
2912         default:
2913                 return f;
2914         }
2915
2916         /* detect the active channel */
2917         switch (event) {
2918         case AST_FRAMEHOOK_EVENT_WRITE:
2919                 active = peer;
2920                 break;
2921         case AST_FRAMEHOOK_EVENT_READ:
2922                 active = chan;
2923                 break;
2924         default:
2925                 ast_log(LOG_WARNING, "unhandled framehook event %i\n", event);
2926                 return f;
2927         }
2928
2929         /* handle control frames */
2930         if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
2931                 return fax_gateway_detect_t38(gateway, chan, peer, active, f);
2932         }
2933
2934         if (!gateway->detected_v21 && gateway->t38_state == T38_STATE_UNAVAILABLE && f->frametype == AST_FRAME_VOICE) {
2935                 /* not in gateway mode and have not detected v21 yet, listen
2936                  * for v21 */
2937                 return fax_gateway_detect_v21(gateway, chan, peer, active, f);
2938         }
2939
2940         /* in gateway mode, gateway some packets */
2941         if (gateway->t38_state == T38_STATE_NEGOTIATED) {
2942                 /* framehooks are called in __ast_read() before frame format
2943                  * translation is done, so we need to translate here */
2944                 if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id != AST_FORMAT_SLINEAR)) {
2945                         if (active->readtrans && (f = ast_translate(active->readtrans, f, 1)) == NULL) {
2946                                 f = &ast_null_frame;
2947                                 return f;
2948                         }
2949                 }
2950
2951                 /* XXX we ignore the return value here, perhaps we should
2952                  * disable the gateway if a write fails. I am not sure how a
2953                  * write would fail, or even if a failure would be fatal so for
2954                  * now we'll just ignore the return value. */
2955                 gateway->s->tech->write(gateway->s, f);
2956                 f = &ast_null_frame;
2957                 return f;
2958         }
2959
2960         /* force silence on the line if T.38 negotiation might be taking place */
2961         if (gateway->t38_state != T38_STATE_UNAVAILABLE && gateway->t38_state != T38_STATE_REJECTED) {
2962                 if (f->frametype == AST_FRAME_VOICE && f->subclass.format.id == AST_FORMAT_SLINEAR) {
2963                         short silence_buf[f->samples];
2964                         struct ast_frame silence_frame = {
2965                                 .frametype = AST_FRAME_VOICE,
2966                                 .data.ptr = silence_buf,
2967                                 .samples = f->samples,
2968                                 .datalen = sizeof(silence_buf),
2969                         };
2970                         ast_format_set(&silence_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
2971                         memset(silence_buf, 0, sizeof(silence_buf));
2972
2973                         return ast_frisolate(&silence_frame);
2974                 } else {
2975                         return &ast_null_frame;
2976                 }
2977         }
2978
2979         return f;
2980 }
2981
2982 /*! \brief Attach a gateway framehook object to a channel.
2983  * \param chan the channel to attach to
2984  * \param details fax session details
2985  * \return the framehook id of the attached framehook or -1 on error
2986  * \retval -1 error
2987  */
2988 static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details)
2989 {
2990         struct fax_gateway *gateway;
2991         struct ast_framehook_interface fr_hook = {
2992                 .version = AST_FRAMEHOOK_INTERFACE_VERSION,
2993                 .event_cb = fax_gateway_framehook,
2994                 .destroy_cb = fax_gateway_framehook_destroy,
2995         };
2996
2997         ast_string_field_set(details, result, "SUCCESS");
2998         ast_string_field_set(details, resultstr, "gateway operation started successfully");
2999         ast_string_field_set(details, error, "NO_ERROR");
3000         set_channel_variables(chan, details);
3001
3002         /* set up the frame hook*/
3003         gateway = fax_gateway_new(details);
3004         if (!gateway) {
3005                 ast_string_field_set(details, result, "FAILED");
3006                 ast_string_field_set(details, resultstr, "error initializing gateway session");
3007                 ast_string_field_set(details, error, "INIT_ERROR");
3008                 set_channel_variables(chan, details);
3009                 report_fax_status(chan, details, "No Available Resource");
3010                 return -1;
3011         }
3012
3013         fr_hook.data = gateway;
3014         ast_channel_lock(chan);
3015         gateway->framehook = ast_framehook_attach(chan, &fr_hook);
3016         ast_channel_unlock(chan);
3017
3018         if (gateway->framehook < 0) {
3019                 ao2_ref(gateway, -1);
3020                 ast_string_field_set(details, result, "FAILED");
3021                 ast_string_field_set(details, resultstr, "error attaching gateway to channel");
3022                 ast_string_field_set(details, error, "INIT_ERROR");
3023                 set_channel_variables(chan, details);
3024                 return -1;
3025         }
3026
3027         return gateway->framehook;