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