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