Merged revisions 340109 via svnmerge from
[asterisk/asterisk.git] / res / res_fax.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008-2009, Digium, Inc.
5  *
6  * Dwayne M. Hubbard <dhubbard@digium.com>
7  * Kevin P. Fleming <kpfleming@digium.com>
8  * Matthew Nicholson <mnicholson@digium.com>
9  *
10  * Initial T.38-gateway code
11  * 2008, Daniel Ferenci <daniel.ferenci@nethemba.com>
12  * Created by Nethemba s.r.o. http://www.nethemba.com
13  * Sponsored by IPEX a.s. http://www.ipex.cz
14  *
15  * T.38-gateway integration into asterisk app_fax and rework
16  * 2008-2011, Gregory Hinton Nietsky <gregory@distrotech.co.za>
17  * dns Telecom http://www.dnstelecom.co.za
18  *
19  * Modified to make T.38-gateway compatible with Asterisk 1.6.2
20  * 2010, Anton Verevkin <mymail@verevkin.it>
21  * ViaNetTV http://www.vianettv.com
22  *
23  * Modified to make T.38-gateway work
24  * 2010, Klaus Darilion, IPCom GmbH, www.ipcom.at
25  *
26  * See http://www.asterisk.org for more information about
27  * the Asterisk project. Please do not directly contact
28  * any of the maintainers of this project for assistance;
29  * the project provides a web site, mailing lists and IRC
30  * channels for your use.
31  *
32  * This program is free software, distributed under the terms of
33  * the GNU General Public License Version 2. See the LICENSE file
34  * at the top of the source tree.
35  */
36
37 /*** MODULEINFO
38         <conflict>app_fax</conflict>
39 ***/
40
41 /*! \file
42  *
43  * \brief Generic FAX Resource for FAX technology resource modules
44  *
45  * \author Dwayne M. Hubbard <dhubbard@digium.com>
46  * \author Kevin P. Fleming <kpfleming@digium.com>
47  * \author Matthew Nicholson <mnicholson@digium.com>
48  * \author Gregory H. Nietsky  <gregory@distrotech.co.za>
49  * 
50  * A generic FAX resource module that provides SendFAX and ReceiveFAX applications.
51  * This module requires FAX technology modules, like res_fax_spandsp, to register with it
52  * so it can use the technology modules to perform the actual FAX transmissions.
53  * \ingroup applications
54  */
55
56 /*** MODULEINFO
57         <support_level>core</support_level>
58  ***/
59
60 #include "asterisk.h"
61
62 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
63
64 #include "asterisk/io.h"
65 #include "asterisk/file.h"
66 #include "asterisk/logger.h"
67 #include "asterisk/module.h"
68 #include "asterisk/app.h"
69 #include "asterisk/lock.h"
70 #include "asterisk/options.h"
71 #include "asterisk/strings.h"
72 #include "asterisk/cli.h"
73 #include "asterisk/utils.h"
74 #include "asterisk/config.h"
75 #include "asterisk/astobj2.h"
76 #include "asterisk/res_fax.h"
77 #include "asterisk/file.h"
78 #include "asterisk/channel.h"
79 #include "asterisk/pbx.h"
80 #include "asterisk/manager.h"
81 #include "asterisk/dsp.h"
82 #include "asterisk/indications.h"
83 #include "asterisk/ast_version.h"
84 #include "asterisk/translate.h"
85
86 /*** DOCUMENTATION
87         <application name="ReceiveFAX" language="en_US" 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, "LOCALSTATIONID", NULL);
1717         pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
1718         pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
1719         pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
1720
1721         /* Get a FAX session details structure from the channel's FAX datastore and create one if
1722          * it does not already exist. */
1723         if (!(details = find_or_create_details(chan))) {
1724                 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
1725                 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
1726                 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
1727                 return -1;
1728         }
1729
1730         ast_string_field_set(details, result, "FAILED");
1731         ast_string_field_set(details, resultstr, "error starting fax session");
1732         ast_string_field_set(details, error, "INIT_ERROR");
1733         set_channel_variables(chan, details);
1734
1735         if (details->gateway_id > 0) {
1736                 ast_string_field_set(details, resultstr, "can't receive a fax on a channel with a T.38 gateway");
1737                 set_channel_variables(chan, details);
1738                 ast_log(LOG_ERROR, "executing ReceiveFAX on a channel with a T.38 Gateway is not supported\n");
1739                 ao2_ref(details, -1);
1740                 return -1;
1741         }
1742
1743         if (details->maxrate < details->minrate) {
1744                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1745                 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
1746                 set_channel_variables(chan, details);
1747                 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
1748                 ao2_ref(details, -1);
1749                 return -1;
1750         }
1751
1752         if (check_modem_rate(details->modems, details->minrate)) {
1753                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
1754                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
1755                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1756                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
1757                 set_channel_variables(chan, details);
1758                 ao2_ref(details, -1);
1759                 return -1;
1760         }
1761
1762         if (check_modem_rate(details->modems, details->maxrate)) {
1763                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
1764                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
1765                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1766                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
1767                 set_channel_variables(chan, details);
1768                 ao2_ref(details, -1);
1769                 return -1;
1770         }
1771
1772         if (ast_strlen_zero(data)) {
1773                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1774                 ast_string_field_set(details, resultstr, "invalid arguments");
1775                 set_channel_variables(chan, details);
1776                 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
1777                 ao2_ref(details, -1);
1778                 return -1;
1779         }
1780         parse = ast_strdupa(data);
1781         AST_STANDARD_APP_ARGS(args, parse);
1782
1783         if (!ast_strlen_zero(args.options) &&
1784             ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
1785                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1786                 ast_string_field_set(details, resultstr, "invalid arguments");
1787                 set_channel_variables(chan, details);
1788                 ao2_ref(details, -1);
1789                 return -1;
1790         }
1791         if (ast_strlen_zero(args.filename)) {
1792                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1793                 ast_string_field_set(details, resultstr, "invalid arguments");
1794                 set_channel_variables(chan, details);
1795                 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
1796                 ao2_ref(details, -1);
1797                 return -1;
1798         }
1799
1800         /* check for unsupported FAX application options */
1801         if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
1802                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
1803                 ast_string_field_set(details, resultstr, "invalid arguments");
1804                 set_channel_variables(chan, details);
1805                 ast_log(LOG_WARNING, "%s does not support polling\n", app_receivefax);
1806                 ao2_ref(details, -1);
1807                 return -1;
1808         }
1809         
1810         ast_atomic_fetchadd_int(&faxregistry.fax_rx_attempts, 1);
1811
1812         pbx_builtin_setvar_helper(chan, "FAXERROR", "Channel Problems");
1813         pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "Error before FAX transmission started.");
1814
1815         if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(args.filename) + 1))) {
1816                 ast_string_field_set(details, error, "MEMORY_ERROR");
1817                 ast_string_field_set(details, resultstr, "error allocating memory");
1818                 set_channel_variables(chan, details);
1819                 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
1820                 ao2_ref(details, -1);
1821                 return -1;
1822         }
1823
1824         strcpy(doc->filename, args.filename);
1825         AST_LIST_INSERT_TAIL(&details->documents, doc, next);
1826
1827         ast_verb(3, "Channel '%s' receiving FAX '%s'\n", chan->name, args.filename);
1828
1829         details->caps = AST_FAX_TECH_RECEIVE;
1830
1831         /* check for debug */
1832         if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
1833                 details->option.debug = AST_FAX_OPTFLAG_TRUE;
1834         }
1835
1836         /* check for request for status events */
1837         if (ast_test_flag(&opts, OPT_STATUS)) {
1838                 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
1839         }
1840
1841         t38state = ast_channel_get_t38_state(chan);
1842         if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
1843             ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
1844             ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
1845                 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
1846         }
1847
1848         if (!(s = fax_session_reserve(details, &token))) {
1849                 ast_string_field_set(details, resultstr, "error reserving fax session");
1850                 set_channel_variables(chan, details);
1851                 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
1852                 ao2_ref(details, -1);
1853                 return -1;
1854         }
1855
1856         /* make sure the channel is up */
1857         if (chan->_state != AST_STATE_UP) {
1858                 if (ast_answer(chan)) {
1859                         ast_string_field_set(details, resultstr, "error answering channel");
1860                         set_channel_variables(chan, details);
1861                         ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
1862                         fax_session_release(s, token);
1863                         ao2_ref(s, -1);
1864                         ao2_ref(details, -1);
1865                         return -1;
1866                 }
1867         }
1868
1869         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
1870                 if (set_fax_t38_caps(chan, details)) {
1871                         ast_string_field_set(details, error, "T38_NEG_ERROR");
1872                         ast_string_field_set(details, resultstr, "error negotiating T.38");
1873                         set_channel_variables(chan, details);
1874                         fax_session_release(s, token);
1875                         ao2_ref(s, -1);
1876                         ao2_ref(details, -1);
1877                         return -1;
1878                 }
1879         } else {
1880                 details->caps |= AST_FAX_TECH_AUDIO;
1881         }
1882
1883         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
1884                 if (receivefax_t38_init(chan, details)) {
1885                         ast_string_field_set(details, error, "T38_NEG_ERROR");
1886                         ast_string_field_set(details, resultstr, "error negotiating T.38");
1887                         set_channel_variables(chan, details);
1888                         fax_session_release(s, token);
1889                         ao2_ref(s, -1);
1890                         ao2_ref(details, -1);
1891                         ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
1892                         return -1;
1893                 }
1894         } else {
1895                 details->option.send_ced = 1;
1896         }
1897
1898         if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
1899                 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
1900         }
1901
1902         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1903                 if (disable_t38(chan)) {
1904                         ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
1905                 }
1906         }
1907
1908         /* send out the AMI completion event */
1909         ast_channel_lock(chan);
1910
1911         get_manager_event_info(chan, &info);
1912         manager_event(EVENT_FLAG_CALL,
1913                       "ReceiveFAX", 
1914                       "Channel: %s\r\n"
1915                       "Context: %s\r\n"
1916                       "Exten: %s\r\n"
1917                       "CallerID: %s\r\n"
1918                       "RemoteStationID: %s\r\n"
1919                       "LocalStationID: %s\r\n"
1920                       "PagesTransferred: %s\r\n"
1921                       "Resolution: %s\r\n"
1922                       "TransferRate: %s\r\n"
1923                       "FileName: %s\r\n",
1924                       chan->name,
1925                       info.context,
1926                       info.exten,
1927                       info.cid,
1928                       S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
1929                       S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
1930                       S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
1931                       S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
1932                       S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
1933                       args.filename);
1934         ast_channel_unlock(chan);
1935
1936         ao2_ref(s, -1);
1937         ao2_ref(details, -1);
1938
1939         /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
1940         return (!channel_alive) ? -1 : 0;
1941 }
1942
1943 static int sendfax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
1944 {
1945         int ms;
1946         struct ast_frame *frame = NULL;
1947         struct ast_control_t38_parameters t38_parameters;
1948
1949         /* send CNG tone while listening for the receiver to initiate a switch
1950          * to T.38 mode; if they do, stop sending the CNG tone and proceed with
1951          * the switch.
1952          *
1953          * 10500 is enough time for 3 CNG tones
1954          */
1955         ms = 10500;
1956
1957         /* don't send any audio if we've already received a T.38 reinvite */
1958         if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
1959                 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000", 1)) {
1960                         ast_log(LOG_ERROR, "error generating CNG tone on %s\n", chan->name);
1961                         return -1;
1962                 }
1963         }
1964
1965         while (ms > 0) {
1966                 ms = ast_waitfor(chan, ms);
1967                 if (ms < 0) {
1968                         ast_log(LOG_ERROR, "error while generating CNG tone on %s\n", chan->name);
1969                         ast_playtones_stop(chan);
1970                         return -1;
1971                 }
1972
1973                 if (ms == 0) { /* all done, nothing happened */
1974                         break;
1975                 }
1976
1977                 if (!(frame = ast_read(chan))) {
1978                         ast_log(LOG_ERROR, "error reading frame while generating CNG tone on %s\n", chan->name);
1979                         ast_playtones_stop(chan);
1980                         return -1;
1981                 }
1982
1983                 if ((frame->frametype == AST_FRAME_CONTROL) &&
1984                                 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1985                                 (frame->datalen == sizeof(t38_parameters))) {
1986                         struct ast_control_t38_parameters *parameters = frame->data.ptr;
1987
1988                         switch (parameters->request_response) {
1989                         case AST_T38_REQUEST_NEGOTIATE:
1990                                 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1991                                  * do T.38 as well
1992                                  */
1993                                 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1994                                 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
1995                                 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1996                                 ast_playtones_stop(chan);
1997                                 break;
1998                         case AST_T38_NEGOTIATED:
1999                                 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
2000                                 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2001                                 details->caps &= ~AST_FAX_TECH_AUDIO;
2002                                 report_fax_status(chan, details, "T.38 Negotiated");
2003                                 ms = 0;
2004                                 break;
2005                         default:
2006                                 break;
2007                         }
2008                 }
2009                 ast_frfree(frame);
2010         }
2011
2012         ast_playtones_stop(chan);
2013
2014         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2015                 return 0;
2016         }
2017
2018         /* T.38 negotiation did not happen, initiate a switch if requested */
2019         if (details->option.request_t38 == AST_FAX_OPTFLAG_TRUE) {
2020                 ast_debug(1, "Negotiating T.38 for send on %s\n", chan->name);
2021
2022                 /* wait up to five seconds for negotiation to complete */
2023                 ms = 5000;
2024
2025                 /* set parameters based on the session's parameters */
2026                 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2027                 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
2028                 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
2029                         return -1;
2030                 }
2031
2032                 while (ms > 0) {
2033                         ms = ast_waitfor(chan, ms);
2034                         if (ms < 0) {
2035                                 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
2036                                 return -1;
2037                         }
2038
2039                         if (ms == 0) { /* all done, nothing happened */
2040                                 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", chan->name);
2041                                 details->caps &= ~AST_FAX_TECH_T38;
2042                                 break;
2043                         }
2044
2045                         if (!(frame = ast_read(chan))) {
2046                                 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", chan->name);
2047                                 return -1;
2048                         }
2049
2050                         if ((frame->frametype == AST_FRAME_CONTROL) &&
2051                                         (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
2052                                         (frame->datalen == sizeof(t38_parameters))) {
2053                                 struct ast_control_t38_parameters *parameters = frame->data.ptr;
2054
2055                                 switch (parameters->request_response) {
2056                                 case AST_T38_REQUEST_NEGOTIATE:
2057                                         t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2058                                         t38_parameters.request_response = AST_T38_NEGOTIATED;
2059                                         ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2060                                         break;
2061                                 case AST_T38_NEGOTIATED:
2062                                         ast_debug(1, "Negotiated T.38 for receive on %s\n", chan->name);
2063                                         t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2064                                         details->caps &= ~AST_FAX_TECH_AUDIO;
2065                                         report_fax_status(chan, details, "T.38 Negotiated");
2066                                         ms = 0;
2067                                         break;
2068                                 case AST_T38_REFUSED:
2069                                         ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", chan->name);
2070                                         details->caps &= ~AST_FAX_TECH_T38;
2071                                         ms = 0;
2072                                         break;
2073                                 default:
2074                                         ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", chan->name);
2075                                         details->caps &= ~AST_FAX_TECH_T38;
2076                                         ms = 0;
2077                                         break;
2078                                 }
2079                         }
2080                         ast_frfree(frame);
2081                 }
2082
2083                 /* if T.38 was negotiated, we are done initializing */
2084                 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2085                         return 0;
2086                 }
2087
2088                 /* send one more CNG tone to get audio going again for some
2089                  * carriers if we are going to fall back to audio mode */
2090                 if (details->option.allow_audio == AST_FAX_OPTFLAG_TRUE) {
2091                         if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000", 1)) {
2092                                 ast_log(LOG_ERROR, "error generating second CNG tone on %s\n", chan->name);
2093                                 return -1;
2094                         }
2095
2096                         ms = 3500;
2097                         while (ms > 0) {
2098                                 ms = ast_waitfor(chan, ms);
2099                                 if (ms < 0) {
2100                                         ast_log(LOG_ERROR, "error while generating second CNG tone on %s\n", chan->name);
2101                                         ast_playtones_stop(chan);
2102                                         return -1;
2103                                 }
2104
2105                                 if (ms == 0) { /* all done, nothing happened */
2106                                         break;
2107                                 }
2108
2109                                 if (!(frame = ast_read(chan))) {
2110                                         ast_log(LOG_ERROR, "error reading frame while generating second CNG tone on %s\n", chan->name);
2111                                         ast_playtones_stop(chan);
2112                                         return -1;
2113                                 }
2114
2115                                 if ((frame->frametype == AST_FRAME_CONTROL) &&
2116                                                 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
2117                                                 (frame->datalen == sizeof(t38_parameters))) {
2118                                         struct ast_control_t38_parameters *parameters = frame->data.ptr;
2119
2120                                         switch (parameters->request_response) {
2121                                         case AST_T38_REQUEST_NEGOTIATE:
2122                                                 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
2123                                                  * do T.38 as well
2124                                                  */
2125                                                 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2126                                                 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
2127                                                 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2128                                                 ast_playtones_stop(chan);
2129                                                 break;
2130                                         case AST_T38_NEGOTIATED:
2131                                                 ast_debug(1, "Negotiated T.38 for send on %s\n", chan->name);
2132                                                 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2133                                                 details->caps &= ~AST_FAX_TECH_AUDIO;
2134                                                 report_fax_status(chan, details, "T.38 Negotiated");
2135                                                 ms = 0;
2136                                                 break;
2137                                         default:
2138                                                 break;
2139                                         }
2140                                 }
2141                                 ast_frfree(frame);
2142                         }
2143
2144                         ast_playtones_stop(chan);
2145
2146                         /* if T.38 was negotiated, we are done initializing */
2147                         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2148                                 return 0;
2149                         }
2150                 }
2151         }
2152
2153         /* if we made it here, then T.38 failed, check the 'f' flag */
2154         if (details->option.allow_audio == AST_FAX_OPTFLAG_FALSE) {
2155                 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", chan->name);
2156                 return -1;
2157         }
2158
2159         /* ok, audio fallback is allowed */
2160         details->caps |= AST_FAX_TECH_AUDIO;
2161
2162         return 0;
2163 }
2164
2165
2166 /*! \brief initiate a send FAX session */
2167 static int sendfax_exec(struct ast_channel *chan, const char *data)
2168 {
2169         char *parse, *filenames, *c, modems[128] = "";
2170         int channel_alive, file_count;
2171         struct ast_fax_session_details *details;
2172         struct ast_fax_session *s;
2173         struct ast_fax_tech_token *token = NULL;
2174         struct ast_fax_document *doc;
2175         AST_DECLARE_APP_ARGS(args,
2176                 AST_APP_ARG(filenames);
2177                 AST_APP_ARG(options);
2178         );
2179         struct ast_flags opts = { 0, };
2180         struct manager_event_info info;
2181         enum ast_t38_state t38state;
2182
2183         /* initialize output channel variables */
2184         pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
2185         pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
2186         pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", NULL);
2187         pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
2188         pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
2189         pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
2190
2191         /* Get a requirement structure and set it.  This structure is used
2192          * to tell the FAX technology module about the higher level FAX session */
2193         if (!(details = find_or_create_details(chan))) {
2194                 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
2195                 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
2196                 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2197                 return -1;
2198         }
2199
2200         ast_string_field_set(details, result, "FAILED");
2201         ast_string_field_set(details, resultstr, "error starting fax session");
2202         ast_string_field_set(details, error, "INIT_ERROR");
2203         set_channel_variables(chan, details);
2204
2205         if (details->gateway_id > 0) {
2206                 ast_string_field_set(details, resultstr, "can't send a fax on a channel with a T.38 gateway");
2207                 set_channel_variables(chan, details);
2208                 ast_log(LOG_ERROR, "executing SendFAX on a channel with a T.38 Gateway is not supported\n");
2209                 ao2_ref(details, -1);
2210                 return -1;
2211         }
2212
2213         if (details->maxrate < details->minrate) {
2214                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2215                 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
2216                 set_channel_variables(chan, details);
2217                 ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", details->maxrate, details->minrate);
2218                 ao2_ref(details, -1);
2219                 return -1;
2220         }
2221
2222         if (check_modem_rate(details->modems, details->minrate)) {
2223                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2224                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, details->minrate);
2225                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2226                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
2227                 set_channel_variables(chan, details);
2228                 ao2_ref(details, -1);
2229                 return -1;
2230         }
2231
2232         if (check_modem_rate(details->modems, details->maxrate)) {
2233                 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2234                 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, details->maxrate);
2235                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2236                 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
2237                 set_channel_variables(chan, details);
2238                 ao2_ref(details, -1);
2239                 return -1;
2240         }
2241
2242         if (ast_strlen_zero(data)) {
2243                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2244                 ast_string_field_set(details, resultstr, "invalid arguments");
2245                 set_channel_variables(chan, details);
2246                 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]][,options])\n", app_sendfax);
2247                 ao2_ref(details, -1);
2248                 return -1;
2249         }
2250         parse = ast_strdupa(data);
2251         AST_STANDARD_APP_ARGS(args, parse);
2252
2253
2254         if (!ast_strlen_zero(args.options) &&
2255             ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
2256                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2257                 ast_string_field_set(details, resultstr, "invalid arguments");
2258                 set_channel_variables(chan, details);
2259                 ao2_ref(details, -1);
2260                 return -1;
2261         }
2262         if (ast_strlen_zero(args.filenames)) {
2263                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2264                 ast_string_field_set(details, resultstr, "invalid arguments");
2265                 set_channel_variables(chan, details);
2266                 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]],options])\n", app_sendfax);
2267                 ao2_ref(details, -1);
2268                 return -1;
2269         }
2270         
2271         /* check for unsupported FAX application options */
2272         if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
2273                 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2274                 ast_string_field_set(details, resultstr, "invalid arguments");
2275                 set_channel_variables(chan, details);
2276                 ast_log(LOG_WARNING, "%s does not support polling\n", app_sendfax);
2277                 ao2_ref(details, -1);
2278                 return -1;
2279         }
2280
2281         ast_atomic_fetchadd_int(&faxregistry.fax_tx_attempts, 1);
2282
2283         file_count = 0;
2284         filenames = args.filenames;
2285         while ((c = strsep(&filenames, "&"))) {
2286                 if (access(c, (F_OK | R_OK)) < 0) {
2287                         ast_string_field_set(details, error, "FILE_ERROR");
2288                         ast_string_field_set(details, resultstr, "error reading file");
2289                         set_channel_variables(chan, details);
2290                         ast_log(LOG_ERROR, "access failure.  Verify '%s' exists and check permissions.\n", args.filenames);
2291                         ao2_ref(details, -1);
2292                         return -1;
2293                 }
2294
2295                 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(c) + 1))) {
2296                         ast_string_field_set(details, error, "MEMORY_ERROR");
2297                         ast_string_field_set(details, resultstr, "error allocating memory");
2298                         set_channel_variables(chan, details);
2299                         ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2300                         ao2_ref(details, -1);
2301                         return -1;
2302                 }
2303
2304                 strcpy(doc->filename, c);
2305                 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
2306                 file_count++;
2307         }
2308
2309         ast_verb(3, "Channel '%s' sending FAX:\n", chan->name);
2310         AST_LIST_TRAVERSE(&details->documents, doc, next) {
2311                 ast_verb(3, "   %s\n", doc->filename);
2312         }
2313
2314         details->caps = AST_FAX_TECH_SEND;
2315
2316         if (file_count > 1) {
2317                 details->caps |= AST_FAX_TECH_MULTI_DOC;
2318         }
2319
2320         /* check for debug */
2321         if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
2322                 details->option.debug = AST_FAX_OPTFLAG_TRUE;
2323         }
2324
2325         /* check for request for status events */
2326         if (ast_test_flag(&opts, OPT_STATUS)) {
2327                 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
2328         }
2329
2330         t38state = ast_channel_get_t38_state(chan);
2331         if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
2332             ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
2333             ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2334                 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
2335         }
2336
2337         if (ast_test_flag(&opts, OPT_REQUEST_T38)) {
2338                 details->option.request_t38 = AST_FAX_OPTFLAG_TRUE;
2339         }
2340
2341         if (!(s = fax_session_reserve(details, &token))) {
2342                 ast_string_field_set(details, resultstr, "error reserving fax session");
2343                 set_channel_variables(chan, details);
2344                 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
2345                 ao2_ref(details, -1);
2346                 return -1;
2347         }
2348
2349         /* make sure the channel is up */
2350         if (chan->_state != AST_STATE_UP) {
2351                 if (ast_answer(chan)) {
2352                         ast_string_field_set(details, resultstr, "error answering channel");
2353                         set_channel_variables(chan, details);
2354                         ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", chan->name);
2355                         fax_session_release(s, token);
2356                         ao2_ref(s, -1);
2357                         ao2_ref(details, -1);
2358                         return -1;
2359                 }
2360         }
2361
2362         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2363                 if (set_fax_t38_caps(chan, details)) {
2364                         ast_string_field_set(details, error, "T38_NEG_ERROR");
2365                         ast_string_field_set(details, resultstr, "error negotiating T.38");
2366                         set_channel_variables(chan, details);
2367                         fax_session_release(s, token);
2368                         ao2_ref(s, -1);
2369                         ao2_ref(details, -1);
2370                         return -1;
2371                 }
2372         } else {
2373                 details->caps |= AST_FAX_TECH_AUDIO;
2374         }
2375
2376         if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
2377                 if (sendfax_t38_init(chan, details)) {
2378                         ast_string_field_set(details, error, "T38_NEG_ERROR");
2379                         ast_string_field_set(details, resultstr, "error negotiating T.38");
2380                         set_channel_variables(chan, details);
2381                         fax_session_release(s, token);
2382                         ao2_ref(s, -1);
2383                         ao2_ref(details, -1);
2384                         ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", chan->name);
2385                         return -1;
2386                 }
2387         } else {
2388                 details->option.send_cng = 1;
2389         }
2390
2391         if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
2392                 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
2393         }
2394
2395         if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2396                 if (disable_t38(chan)) {
2397                         ast_debug(1, "error disabling T.38 mode on %s\n", chan->name);
2398                 }
2399         }
2400
2401         if (!(filenames = generate_filenames_string(details, "FileName: ", "\r\n"))) {
2402                 ast_log(LOG_ERROR, "Error generating SendFAX manager event\n");
2403                 ao2_ref(s, -1);
2404                 ao2_ref(details, -1);
2405                 return (!channel_alive) ? -1 : 0;
2406         }
2407
2408         /* send out the AMI completion event */
2409         ast_channel_lock(chan);
2410         get_manager_event_info(chan, &info);
2411         manager_event(EVENT_FLAG_CALL,
2412                       "SendFAX", 
2413                       "Channel: %s\r\n"
2414                       "Context: %s\r\n"
2415                       "Exten: %s\r\n"
2416                       "CallerID: %s\r\n"
2417                       "RemoteStationID: %s\r\n"
2418                       "LocalStationID: %s\r\n"
2419                       "PagesTransferred: %s\r\n"
2420                       "Resolution: %s\r\n"
2421                       "TransferRate: %s\r\n"
2422                       "%s\r\n",
2423                       chan->name,
2424                       info.context,
2425                       info.exten,
2426                       info.cid,
2427                       S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), ""),
2428                       S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), ""),
2429                       S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), ""),
2430                       S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), ""),
2431                       S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), ""),
2432                       filenames);
2433         ast_channel_unlock(chan);
2434
2435         ast_free(filenames);
2436
2437         ao2_ref(s, -1);
2438         ao2_ref(details, -1);
2439
2440         /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
2441         return (!channel_alive) ? -1 : 0;
2442 }
2443
2444 /*! \brief destroy a FAX gateway session structure */
2445 static void destroy_gateway(void *data)
2446 {
2447         struct fax_gateway *gateway = data;
2448
2449         if (gateway->chan_dsp) {
2450                 ast_dsp_free(gateway->chan_dsp);
2451                 gateway->chan_dsp = NULL;
2452         }
2453
2454         if (gateway->peer_dsp) {
2455                 ast_dsp_free(gateway->peer_dsp);
2456                 gateway->peer_dsp = NULL;
2457         }
2458
2459         if (gateway->s) {
2460                 fax_session_release(gateway->s, gateway->token);
2461                 gateway->token = NULL;
2462
2463                 ao2_lock(faxregistry.container);
2464                 ao2_unlink(faxregistry.container, gateway->s);
2465                 ao2_unlock(faxregistry.container);
2466
2467                 ao2_ref(gateway->s, -1);
2468                 gateway->s = NULL;
2469         }
2470 }
2471
2472 /*! \brief Create a new fax gateway object.
2473  * \param details the fax session details
2474  * \return NULL or a fax gateway object
2475  */
2476 static struct fax_gateway *fax_gateway_new(struct ast_fax_session_details *details)
2477 {
2478         struct fax_gateway *gateway = ao2_alloc(sizeof(*gateway), destroy_gateway);
2479         if (!gateway) {
2480                 return NULL;
2481         }
2482
2483         gateway->chan_dsp = ast_dsp_new();
2484         if (!gateway->chan_dsp) {
2485                 ao2_ref(gateway, -1);
2486                 return NULL;
2487         }
2488
2489         gateway->peer_dsp = ast_dsp_new();
2490         if (!gateway->peer_dsp) {
2491                 ao2_ref(gateway, -1);
2492                 return NULL;
2493         }
2494
2495         gateway->framehook = -1;
2496
2497         ast_dsp_set_features(gateway->chan_dsp, DSP_FEATURE_FAX_DETECT);
2498         ast_dsp_set_faxmode(gateway->chan_dsp, DSP_FAXMODE_DETECT_V21);
2499
2500         ast_dsp_set_features(gateway->peer_dsp, DSP_FEATURE_FAX_DETECT);
2501         ast_dsp_set_faxmode(gateway->peer_dsp, DSP_FAXMODE_DETECT_V21);
2502
2503         details->caps = AST_FAX_TECH_GATEWAY;
2504         if (details->gateway_timeout && !(gateway->s = fax_session_reserve(details, &gateway->token))) {
2505                 details->caps &= ~AST_FAX_TECH_GATEWAY;
2506                 ast_log(LOG_ERROR, "Can't reserve a FAX session, gateway attempt failed.\n");
2507                 ao2_ref(gateway, -1);
2508                 return NULL;
2509         }
2510
2511         return gateway;
2512 }
2513
2514 /*! \brief Create a fax session and start T.30<->T.38 gateway mode
2515  * \param gateway a fax gateway object
2516  * \param details fax session details
2517  * \param chan active channel
2518  * \return 0 on error 1 on success*/
2519 static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session_details *details, struct ast_channel *chan)
2520 {
2521         struct ast_fax_session *s;
2522
2523         /* create the FAX session */
2524         if (!(s = fax_session_new(details, chan, gateway->s, gateway->token))) {
2525                 gateway->token = NULL;
2526                 ast_string_field_set(details, result, "FAILED");
2527                 ast_string_field_set(details, resultstr, "error starting gateway session");
2528                 ast_string_field_set(details, error, "INIT_ERROR");
2529                 set_channel_variables(chan, details);
2530                 report_fax_status(chan, details, "No Available Resource");
2531                 ast_log(LOG_ERROR, "Can't create a FAX session, gateway attempt failed.\n");
2532                 return -1;
2533         }
2534         /* release the reference for the reserved session and replace it with
2535          * the real session */
2536         ao2_ref(gateway->s, -1);
2537         gateway->s = s;
2538         gateway->token = NULL;
2539
2540         if (gateway->s->tech->start_session(gateway->s) < 0) {
2541                 ast_string_field_set(details, result, "FAILED");
2542                 ast_string_field_set(details, resultstr, "error starting gateway session");
2543                 ast_string_field_set(details, error, "INIT_ERROR");
2544                 set_channel_variables(chan, details);
2545                 return -1;
2546         }
2547
2548         gateway->timeout_start.tv_sec = 0;
2549         gateway->timeout_start.tv_usec = 0;
2550
2551         report_fax_status(chan, details, "FAX Transmission In Progress");
2552
2553         return 0;
2554 }
2555
2556 static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_frame *f)
2557 {
2558         struct ast_frame *fp;
2559         struct ast_control_t38_parameters t38_parameters = {
2560                 .request_response = AST_T38_REQUEST_NEGOTIATE,
2561         };
2562         struct ast_frame control_frame = {
2563                 .src = "res_fax",
2564                 .frametype = AST_FRAME_CONTROL,
2565                 .datalen = sizeof(t38_parameters),
2566                 .subclass.integer = AST_CONTROL_T38_PARAMETERS,
2567                 .data.ptr = &t38_parameters,
2568         };
2569
2570         struct ast_fax_session_details *details = find_details(chan);
2571
2572         if (!details) {
2573                 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", chan->name);
2574                 ast_framehook_detach(chan, gateway->framehook);
2575                 return f;
2576         }
2577
2578         t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2579         ao2_ref(details, -1);
2580
2581         if (!(fp = ast_frisolate(&control_frame))) {
2582                 ast_log(LOG_ERROR, "error generating T.38 request control frame on chan %s for T.38 gateway session\n", chan->name);
2583                 return f;
2584         }
2585
2586         gateway->t38_state = T38_STATE_NEGOTIATING;
2587         gateway->timeout_start = ast_tvnow();
2588         details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
2589
2590         ast_debug(1, "requesting T.38 for gateway session for %s\n", chan->name);
2591         return fp;
2592 }
2593
2594 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)
2595 {
2596         struct ast_frame *dfr = ast_frdup(f);
2597         struct ast_dsp *active_dsp = (active == chan) ? gateway->chan_dsp : gateway->peer_dsp;
2598         struct ast_channel *other = (active == chan) ? peer : chan;
2599
2600         if (gateway->detected_v21) {
2601                 return f;
2602         }
2603
2604         if (!dfr) {
2605                 return f;
2606         }
2607
2608         if (!(dfr = ast_dsp_process(active, active_dsp, dfr))) {
2609                 return f;
2610         }
2611
2612         if (dfr->frametype == AST_FRAME_DTMF && dfr->subclass.integer == 'g') {
2613                 gateway->detected_v21 = 1;
2614                 if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
2615                         ast_debug(1, "detected v21 preamble from %s\n", active->name);
2616                         return fax_gateway_request_t38(gateway, chan, f);
2617                 } else {
2618                         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);
2619                 }
2620         }
2621
2622         ast_frfree(dfr);
2623         return f;
2624 }
2625
2626 static int fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
2627 {
2628         if (active == chan) {
2629                 return ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
2630         } else {
2631                 return ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
2632         }
2633 }
2634
2635 /*! \brief T38 Gateway Negotiate t38 parameters
2636  * \param gateway gateway object
2637  * \param chan channel running the gateway
2638  * \param peer channel im bridged too
2639  * \param active channel the frame originated on
2640  * \param f the control frame to process
2641  * \return processed control frame or null frame
2642  */
2643 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)
2644 {
2645         struct ast_control_t38_parameters *control_params = f->data.ptr;
2646         struct ast_channel *other = (active == chan) ? peer : chan;
2647         struct ast_fax_session_details *details;
2648
2649         if (f->datalen != sizeof(struct ast_control_t38_parameters)) {
2650                 /* invalaid AST_CONTROL_T38_PARAMETERS frame, we can't
2651                  * do anything with it, pass it on */
2652                 return f;
2653         }
2654
2655         /* ignore frames from ourselves */
2656         if ((gateway->t38_state == T38_STATE_NEGOTIATED && control_params->request_response == AST_T38_NEGOTIATED)
2657                 || (gateway->t38_state == T38_STATE_REJECTED && control_params->request_response == AST_T38_REFUSED)
2658                 || (gateway->t38_state == T38_STATE_NEGOTIATING && control_params->request_response == AST_T38_REQUEST_TERMINATE)) {
2659
2660                 return f;
2661         }
2662
2663         if (!(details = find_details(chan))) {
2664                 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", chan->name);
2665                 ast_framehook_detach(chan, gateway->framehook);
2666                 return f;
2667         }
2668
2669         if (control_params->request_response == AST_T38_REQUEST_NEGOTIATE) {
2670                 enum ast_t38_state state = ast_channel_get_t38_state(other);
2671
2672                 if (state == T38_STATE_UNKNOWN) {
2673                         /* we detected a request to negotiate T.38 and the
2674                          * other channel appears to support T.38, we'll pass
2675                          * the request through and only step in if the other
2676                          * channel rejects the request */
2677                         ast_debug(1, "%s is attempting to negotiate T.38 with %s, we'll see what happens\n", active->name, other->name);
2678                         t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2679                         gateway->t38_state = T38_STATE_UNKNOWN;
2680                         gateway->timeout_start = ast_tvnow();
2681                         details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
2682                         ao2_ref(details, -1);
2683                         return f;
2684                 } else if (state == T38_STATE_UNAVAILABLE || state == T38_STATE_REJECTED) {
2685                         /* the other channel does not support T.38, we need to
2686                          * step in here */
2687                         ast_debug(1, "%s is attempting to negotiate T.38 but %s does not support it\n", active->name, other->name);
2688                         ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2689
2690                         t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2691                         t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
2692
2693                         if (fax_gateway_start(gateway, details, chan)) {
2694                                 ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2695                                 gateway->t38_state = T38_STATE_REJECTED;
2696                                 control_params->request_response = AST_T38_REFUSED;
2697
2698                                 ast_framehook_detach(chan, details->gateway_id);
2699                                 details->gateway_id = -1;
2700                         } else {
2701                                 gateway->t38_state = T38_STATE_NEGOTIATED;
2702                                 control_params->request_response = AST_T38_NEGOTIATED;
2703                                 report_fax_status(chan, details, "T.38 Negotiated");
2704                         }
2705
2706                         fax_gateway_indicate_t38(chan, active, control_params);
2707
2708                         ao2_ref(details, -1);
2709                         return &ast_null_frame;
2710                 } else if (gateway->t38_state == T38_STATE_NEGOTIATING) {
2711                         /* we got a request to negotiate T.38 after we already
2712                          * sent one to the other party based on v21 preamble
2713                          * detection. We'll just pretend we passed this request
2714                          * through in the first place. */
2715
2716                         t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2717                         gateway->t38_state = T38_STATE_UNKNOWN;
2718                         gateway->timeout_start = ast_tvnow();
2719                         details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
2720
2721                         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);
2722                         ao2_ref(details, -1);
2723                         return &ast_null_frame;
2724                 } else if (gateway->t38_state == T38_STATE_NEGOTIATED) {
2725                         /* we got a request to negotiate T.38 after we already
2726                          * sent one to the other party based on v21 preamble
2727                          * detection and received a response. We need to
2728                          * respond to this and shut down the gateway. */
2729
2730                         t38_parameters_fax_to_ast(control_params, &details->their_t38_parameters);
2731                         ast_framehook_detach(chan, details->gateway_id);
2732                         details->gateway_id = -1;
2733
2734                         control_params->request_response = AST_T38_NEGOTIATED;
2735
2736                         fax_gateway_indicate_t38(chan, active, control_params);
2737
2738                         ast_string_field_set(details, result, "SUCCESS");
2739                         ast_string_field_set(details, resultstr, "no gateway necessary");
2740                         ast_string_field_set(details, error, "NATIVE_T38");
2741                         set_channel_variables(chan, details);
2742
2743                         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);
2744                         ao2_ref(details, -1);
2745                         return &ast_null_frame;
2746                 } else {
2747                         ast_log(LOG_WARNING, "%s is attempting to negotiate T.38 while %s is in an unsupported state\n", active->name, other->name);
2748                         ao2_ref(details, -1);
2749                         return f;
2750                 }
2751         } else if (gateway->t38_state == T38_STATE_NEGOTIATING
2752                 && control_params->request_response == AST_T38_REFUSED) {
2753
2754                 ast_debug(1, "unable to negotiate T.38 on %s for fax gateway\n", active->name);
2755
2756                 /* our request to negotiate T.38 was refused, if the other
2757                  * channel supports T.38, they might still reinvite and save
2758                  * the day.  Otherwise disable the gateway. */
2759                 if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
2760                         gateway->t38_state = T38_STATE_UNAVAILABLE;
2761                 } else {
2762                         ast_framehook_detach(chan, details->gateway_id);
2763                         details->gateway_id = -1;
2764
2765                         ast_string_field_set(details, result, "FAILED");
2766                         ast_string_field_set(details, resultstr, "unable to negotiate T.38");
2767                         ast_string_field_set(details, error, "T38_NEG_ERROR");
2768                         set_channel_variables(chan, details);
2769                 }
2770
2771                 ao2_ref(details, -1);
2772                 return &ast_null_frame;
2773         } else if (gateway->t38_state == T38_STATE_NEGOTIATING
2774                 && control_params->request_response == AST_T38_NEGOTIATED) {
2775
2776                 ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2777
2778                 t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
2779
2780                 if (fax_gateway_start(gateway, details, chan)) {
2781                         ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2782                         gateway->t38_state = T38_STATE_NEGOTIATING;
2783                         control_params->request_response = AST_T38_REQUEST_TERMINATE;
2784
2785                         fax_gateway_indicate_t38(chan, active, control_params);
2786                 } else {
2787                         gateway->t38_state = T38_STATE_NEGOTIATED;
2788                         report_fax_status(chan, details, "T.38 Negotiated");
2789                 }
2790
2791                 ao2_ref(details, -1);
2792                 return &ast_null_frame;
2793         } else if (control_params->request_response == AST_T38_REFUSED) {
2794                 /* the other channel refused the request to negotiate T.38,
2795                  * we'll step in here and pretend the request was accepted */
2796
2797                 ast_debug(1, "%s attempted to negotiate T.38 but %s refused the request\n", other->name, active->name);
2798                 ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", other->name, active->name);
2799
2800                 t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
2801
2802                 if (fax_gateway_start(gateway, details, chan)) {
2803                         ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", active->name, other->name);
2804                         gateway->t38_state = T38_STATE_REJECTED;
2805                         control_params->request_response = AST_T38_REFUSED;
2806
2807                         ast_framehook_detach(chan, details->gateway_id);
2808                         details->gateway_id = -1;
2809                 } else {
2810                         gateway->t38_state = T38_STATE_NEGOTIATED;
2811                         control_params->request_response = AST_T38_NEGOTIATED;
2812                 }
2813
2814                 ao2_ref(details, -1);
2815                 return f;
2816         } else if (control_params->request_response == AST_T38_REQUEST_TERMINATE) {
2817                 /* the channel wishes to end our short relationship, we shall
2818                  * oblige */
2819
2820                 ast_debug(1, "T.38 channel %s is requesting a shutdown of T.38, disabling the gateway\n", active->name);
2821
2822                 ast_framehook_detach(chan, details->gateway_id);
2823                 details->gateway_id = -1;
2824
2825                 gateway->t38_state = T38_STATE_REJECTED;
2826                 control_params->request_response = AST_T38_TERMINATED;
2827
2828                 fax_gateway_indicate_t38(chan, active, control_params);
2829
2830                 ao2_ref(details, -1);
2831                 return &ast_null_frame;
2832         } else if (control_params->request_response == AST_T38_NEGOTIATED) {
2833                 ast_debug(1, "T.38 successfully negotiated between %s and %s, no gateway necessary\n", active->name, other->name);
2834
2835                 ast_framehook_detach(chan, details->gateway_id);
2836                 details->gateway_id = -1;
2837
2838                 ast_string_field_set(details, result, "SUCCESS");
2839                 ast_string_field_set(details, resultstr, "no gateway necessary");
2840                 ast_string_field_set(details, error, "NATIVE_T38");
2841                 set_channel_variables(chan, details);
2842
2843                 ao2_ref(details, -1);
2844                 return f;
2845         } else if (control_params->request_response == AST_T38_TERMINATED) {
2846                 ast_debug(1, "T.38 disabled on channel %s\n", active->name);
2847
2848                 ast_framehook_detach(chan, details->gateway_id);
2849                 details->gateway_id = -1;
2850
2851                 ao2_ref(details, -1);
2852                 return &ast_null_frame;
2853         }
2854
2855         ao2_ref(details, -1);
2856         return f;
2857 }
2858
2859 /*! \brief Destroy the gateway data structure when the framehook is detached
2860  * \param data framehook data (gateway data)*/
2861 static void fax_gateway_framehook_destroy(void *data) {
2862         struct fax_gateway *gateway = data;
2863
2864         if (gateway->s) {
2865                 switch (gateway->s->state) {
2866                 case AST_FAX_STATE_INITIALIZED:
2867                 case AST_FAX_STATE_OPEN:
2868                 case AST_FAX_STATE_ACTIVE:
2869                 case AST_FAX_STATE_COMPLETE:
2870                         if (gateway->s->tech->cancel_session) {
2871                                 gateway->s->tech->cancel_session(gateway->s);
2872                         }
2873                         /* fall through */
2874                 default:
2875                         break;
2876                 }
2877         }
2878
2879         ao2_ref(gateway, -1);
2880 }
2881
2882 /*! \brief T.30<->T.38 gateway framehook.
2883  *
2884  * Intercept packets on bridged channels and determine if a T.38 gateway is
2885  * required. If a gateway is required, start a gateway and handle T.38
2886  * negotiation if necessary.
2887  *
2888  * \param chan channel running the gateway
2889  * \param f frame to handle may be NULL
2890  * \param event framehook event
2891  * \param data framehook data (struct fax_gateway *)
2892  *
2893  * \return processed frame or NULL when f is NULL or a null frame
2894  */
2895 static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data) {
2896         struct fax_gateway *gateway = data;
2897         struct ast_channel *peer, *active;
2898         struct ast_fax_session_details *details;
2899
2900         if (gateway->s) {
2901                 details = gateway->s->details;
2902                 ao2_ref(details, 1);
2903         } else {
2904                 if (!(details = find_details(chan))) {
2905                         ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", chan->name);
2906                         ast_framehook_detach(chan, gateway->framehook);
2907                         details->gateway_id = -1;
2908                         return f;
2909                 }
2910         }
2911
2912         /* restore audio formats when we are detached */
2913         if (event == AST_FRAMEHOOK_EVENT_DETACHED) {
2914                 set_channel_variables(chan, details);
2915
2916                 if (gateway->bridged) {
2917                         ast_set_read_format(chan, &gateway->chan_read_format);
2918                         ast_set_read_format(chan, &gateway->chan_write_format);
2919
2920                         if ((peer = ast_bridged_channel(chan))) {
2921                                 ast_set_read_format(peer, &gateway->peer_read_format);
2922                                 ast_set_read_format(peer, &gateway->peer_write_format);
2923                                 ast_channel_make_compatible(chan, peer);
2924                         }
2925                 }
2926
2927                 ao2_ref(details, -1);
2928                 return NULL;
2929         }
2930
2931         if (!f || (event == AST_FRAMEHOOK_EVENT_ATTACHED)) {
2932                 ao2_ref(details, -1);
2933                 return NULL;
2934         };
2935
2936         /* this frame was generated by the fax gateway, pass it on */
2937         if (ast_test_flag(f, AST_FAX_FRFLAG_GATEWAY)) {
2938                 ao2_ref(details, -1);
2939                 return f;
2940         }
2941
2942         if (!(peer = ast_bridged_channel(chan))) {
2943                 /* not bridged, don't do anything */
2944                 ao2_ref(details, -1);
2945                 return f;
2946         }
2947
2948         if (!gateway->bridged && peer) {
2949                 /* don't start a gateway if neither channel can handle T.38 */
2950                 if (ast_channel_get_t38_state(chan) == T38_STATE_UNAVAILABLE && ast_channel_get_t38_state(peer) == T38_STATE_UNAVAILABLE) {
2951                         ast_debug(1, "not starting gateway for %s and %s; neither channel supports T.38\n", chan->name, peer->name);
2952                         ast_framehook_detach(chan, gateway->framehook);
2953                         details->gateway_id = -1;
2954
2955                         ast_string_field_set(details, result, "FAILED");
2956                         ast_string_field_set(details, resultstr, "neither channel supports T.38");
2957                         ast_string_field_set(details, error, "T38_NEG_ERROR");
2958                         set_channel_variables(chan, details);
2959                         ao2_ref(details, -1);
2960                         return f;
2961                 }
2962
2963                 if (details->gateway_timeout) {
2964                         gateway->timeout_start = ast_tvnow();
2965                 }
2966
2967                 /* we are bridged, change r/w formats to SLIN for v21 preamble
2968                  * detection and T.30 */
2969                 ast_format_copy(&gateway->chan_read_format, &chan->readformat);
2970                 ast_format_copy(&gateway->chan_write_format, &chan->readformat);
2971
2972                 ast_format_copy(&gateway->peer_read_format, &peer->readformat);
2973                 ast_format_copy(&gateway->peer_write_format, &peer->readformat);
2974
2975                 ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
2976                 ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
2977
2978                 ast_set_read_format_by_id(peer, AST_FORMAT_SLINEAR);
2979                 ast_set_write_format_by_id(peer, AST_FORMAT_SLINEAR);
2980
2981                 ast_channel_make_compatible(chan, peer);
2982                 gateway->bridged = 1;
2983         }
2984
2985         if (gateway->bridged && !ast_tvzero(gateway->timeout_start)) {
2986                 if (ast_tvdiff_ms(ast_tvnow(), gateway->timeout_start) > details->gateway_timeout) {
2987                         ast_debug(1, "no fax activity between %s and %s after %d ms, disabling gateway\n", chan->name, peer->name, details->gateway_timeout);
2988                         ast_framehook_detach(chan, gateway->framehook);
2989                         details->gateway_id = -1;
2990
2991                         ast_string_field_set(details, result, "FAILED");
2992                         ast_string_field_build(details, resultstr, "no fax activity after %d ms", details->gateway_timeout);
2993                         ast_string_field_set(details, error, "TIMEOUT");
2994                         set_channel_variables(chan, details);
2995                         ao2_ref(details, -1);
2996                         return f;
2997                 }
2998         }
2999
3000         /* only handle VOICE, MODEM, and CONTROL frames*/
3001         switch (f->frametype) {
3002         case AST_FRAME_VOICE:
3003                 switch (f->subclass.format.id) {
3004                 case AST_FORMAT_SLINEAR:
3005                 case AST_FORMAT_ALAW:
3006                 case AST_FORMAT_ULAW:
3007                         break;
3008                 default:
3009                         ao2_ref(details, -1);
3010                         return f;
3011                 }
3012                 break;
3013         case AST_FRAME_MODEM:
3014                 if (f->subclass.integer == AST_MODEM_T38) {
3015                         break;
3016                 }
3017                 ao2_ref(details, -1);
3018                 return f;
3019         case AST_FRAME_CONTROL:
3020                 if (f->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
3021                         break;
3022                 }
3023                 ao2_ref(details, -1);
3024                 return f;
3025         default:
3026                 ao2_ref(details, -1);
3027                 return f;
3028         }
3029
3030         /* detect the active channel */
3031         switch (event) {
3032         case AST_FRAMEHOOK_EVENT_WRITE:
3033                 active = peer;
3034                 break;
3035         case AST_FRAMEHOOK_EVENT_READ:
3036                 active = chan;
3037                 break;
3038         default:
3039                 ast_log(LOG_WARNING, "unhandled framehook event %i\n", event);
3040                 ao2_ref(details, -1);
3041                 return f;
3042         }
3043
3044         /* handle control frames */
3045         if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
3046                 ao2_ref(details, -1);
3047                 return fax_gateway_detect_t38(gateway, chan, peer, active, f);
3048         }
3049
3050         if (!gateway->detected_v21 && gateway->t38_state == T38_STATE_UNAVAILABLE && f->frametype == AST_FRAME_VOICE) {
3051                 /* not in gateway mode and have not detected v21 yet, listen
3052                  * for v21 */
3053                 ao2_ref(details, -1);
3054                 return fax_gateway_detect_v21(gateway, chan, peer, active, f);
3055         }
3056
3057         /* in gateway mode, gateway some packets */
3058         if (gateway->t38_state == T38_STATE_NEGOTIATED) {
3059                 /* framehooks are called in __ast_read() before frame format
3060                  * translation is done, so we need to translate here */
3061                 if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id != AST_FORMAT_SLINEAR)) {
3062                         if (active->readtrans && (f = ast_translate(active->readtrans, f, 1)) == NULL) {
3063                                 f = &ast_null_frame;
3064                                 ao2_ref(details, -1);
3065                                 return f;
3066                         }
3067                 }
3068
3069                 /* XXX we ignore the return value here, perhaps we should
3070                  * disable the gateway if a write fails. I am not sure how a
3071                  * write would fail, or even if a failure would be fatal so for
3072                  * now we'll just ignore the return value. */
3073                 gateway->s->tech->write(gateway->s, f);
3074                 f = &ast_null_frame;
3075                 ao2_ref(details, -1);
3076                 return f;
3077         }
3078
3079         /* force silence on the line if T.38 negotiation might be taking place */
3080         if (gateway->t38_state != T38_STATE_UNAVAILABLE && gateway->t38_state != T38_STATE_REJECTED) {
3081                 if (f->frametype == AST_FRAME_VOICE && f->subclass.format.id == AST_FORMAT_SLINEAR) {
3082                         short silence_buf[f->samples];
3083                         struct ast_frame silence_frame = {
3084                                 .frametype = AST_FRAME_VOICE,
3085                                 .data.ptr = silence_buf,
3086                                 .samples = f->samples,
3087                                 .datalen = sizeof(silence_buf),
3088                         };
3089                         ast_format_set(&silence_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
3090                         memset(silence_buf, 0, sizeof(silence_buf));
3091
3092                         ao2_ref(details, -1);
3093                         return ast_frisolate(&silence_frame);
3094                 } else {
3095                         ao2_ref(details, -1);
3096                         return &ast_null_frame;
3097                 }
3098         }
3099
3100         ao2_ref(details, -1);
3101         return f;
3102 }
3103
3104 /*! \brief Attach a gateway framehook object to a channel.
3105  * \param chan the channel to attach to
3106  * \param details fax session details
3107  * \return the framehook id of the attached framehook or -1 on error
3108  * \retval -1 error
3109  */
3110 static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details)
3111 {
3112         struct fax_gateway *gateway;
3113         struct ast_framehook_interface fr_hook = {
3114                 .version = AST_FRAMEHOOK_INTERFACE_VERSION,
3115                 .event_cb = fax_gateway_framehook,
3116                 .destroy_cb = fax_gateway_framehook_destroy,
3117         };
3118
3119         ast_string_field_set(details, result, "SUCCESS");
3120         ast_string_field_set(details, resultstr, "gateway operation started successfully");
3121         ast_string_field_set(details, error, "NO_ERROR");
3122         set_channel_variables(chan, details);
3123
3124         /* set up the frame hook*/
3125         gateway = fax_gateway_new(details);
3126         if (!gateway) {
3127                 ast_string_field_set(details, result, "FAILED");
3128                 ast_string_field_set(details, resultstr, "error initializing gateway session");
3129                 ast_string_field_set(details, error, "INIT_ERROR");
3130                 set_channel_variables(chan, details);
3131                 report_fax_status(chan, details, "No Available Resource");
3132                 return -1;
3133         }
3134
3135         fr_hook.data = gateway;
3136         ast_channel_lock(chan);
3137         gateway->framehook = ast_framehook_attach(chan, &fr_hook);
3138         ast_channel_unlock(chan);
3139
3140         if (gateway->framehook < 0) {
3141                 ao2_ref(gateway, -1);
3142                 ast_string_field_set(details, result, "FAILED");
3143                 ast_string_field_set(details, resultstr, "error attaching gateway to channel");
3144                 ast_string_field_set(details, error, "INIT_ERROR");
3145                 set_channel_variables(chan, details);
3146                 return -1;
3147         }
3148
3149         return gateway->framehook;
3150 }
3151
3152 /*! \brief destroy a FAX detect structure */
3153 static void destroy_faxdetect(void *data)
3154 {
3155         struct fax_detect *faxdetect = data;
3156
3157         if (faxdetect->dsp) {
3158                 ast_dsp_free(faxdetect->dsp);
3159                 faxdetect->dsp = NULL;
3160         }
3161         ao2_ref(faxdetect->details, -1);
3162 }
3163
3164 /*! \brief Create a new fax detect object.
3165  * \param chan the channel attaching to
3166  * \param timeout remove framehook in this time if set
3167  * \param flags required options
3168  * \return NULL or a fax gateway object
3169  */
3170 static struct fax_detect *fax_detect_new(struct ast_channel *chan, int timeout, int flags)
3171 {
3172         struct fax_detect *faxdetect = ao2_alloc(sizeof(*faxdetect), destroy_faxdetect);
3173         if (!faxdetect) {
3174                 return NULL;
3175         }
3176
3177         faxdetect->flags = flags;
3178
3179         if (timeout) {
3180                 faxdetect->timeout_start = ast_tvnow();
3181         } else {
3182                 faxdetect->timeout_start.tv_sec = 0;
3183                 faxdetect->timeout_start.tv_usec = 0;
3184         }
3185
3186         if (faxdetect->flags & FAX_DETECT_MODE_CNG) {
3187                 faxdetect->dsp = ast_dsp_new();
3188                 if (!faxdetect->dsp) {
3189                         ao2_ref(faxdetect, -1);
3190                         return NULL;
3191                 }
3192                 ast_dsp_set_features(faxdetect->dsp, DSP_FEATURE_FAX_DETECT);
3193                 ast_dsp_set_faxmode(faxdetect->dsp, DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_SQUELCH);
3194         } else {
3195                 faxdetect->dsp = NULL;
3196         }
3197
3198         return faxdetect;
3199 }
3200
3201 /*! \brief Deref the faxdetect data structure when the faxdetect framehook is detached
3202  * \param data framehook data (faxdetect data)*/
3203 static void fax_detect_framehook_destroy(void *data) {
3204         struct fax_detect *faxdetect = data;
3205
3206         ao2_ref(faxdetect, -1);
3207 }
3208
3209 /*! \brief Fax Detect Framehook
3210  *
3211  * Listen for fax tones in audio path and enable jumping to a extension when detected.
3212  *
3213  * \param chan channel
3214  * \param f frame to handle may be NULL
3215  * \param event framehook event
3216  * \param data framehook data (struct fax_detect *)
3217  *
3218  * \return processed frame or NULL when f is NULL or a null frame
3219  */
3220 static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data) {
3221         struct fax_detect *faxdetect = data;
3222         struct ast_fax_session_details *details;
3223         struct ast_control_t38_parameters *control_params;
3224         struct ast_channel *peer;
3225         int result = 0;
3226
3227         details = faxdetect->details;
3228
3229         switch (event) {
3230         case AST_FRAMEHOOK_EVENT_ATTACHED:
3231                 /* Setup format for DSP on ATTACH*/
3232                 ast_format_copy(&faxdetect->orig_format, &chan->readformat);
3233                 switch (chan->readformat.id) {
3234                         case AST_FORMAT_SLINEAR:
3235                         case AST_FORMAT_ALAW:
3236                         case AST_FORMAT_ULAW:
3237                                 break;
3238                         default:
3239                                 if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
3240                                         ast_framehook_detach(chan, details->faxdetect_id);
3241                                         details->faxdetect_id = -1;
3242                                         return f;
3243                                 }
3244                 }
3245                 return NULL;
3246         case AST_FRAMEHOOK_EVENT_DETACHED:
3247                 /* restore audio formats when we are detached */
3248                 ast_set_read_format(chan, &faxdetect->orig_format);
3249                 if ((peer = ast_bridged_channel(chan))) {
3250                         ast_channel_make_compatible(chan, peer);
3251                 }
3252                 return NULL;
3253         case AST_FRAMEHOOK_EVENT_READ:
3254                 if (f) {
3255                         break;
3256                 }
3257         default:
3258                 return f;
3259         };
3260
3261         if (details->faxdetect_id < 0) {
3262                 return f;
3263         }
3264
3265         if ((!ast_tvzero(faxdetect->timeout_start) &&
3266             (ast_tvdiff_ms(ast_tvnow(), faxdetect->timeout_start) > faxdetect->timeout))) {
3267                 ast_framehook_detach(chan, details->faxdetect_id);
3268                 details->faxdetect_id = -1;
3269                 return f;
3270         }
3271
3272         /* only handle VOICE and CONTROL frames*/
3273         switch (f->frametype) {
3274         case AST_FRAME_VOICE:
3275                 /* we have no DSP this means we not detecting CNG */
3276                 if (!faxdetect->dsp) {
3277                         break;
3278                 }
3279                 /* We can only process some formats*/
3280                 switch (f->subclass.format.id) {
3281                         case AST_FORMAT_SLINEAR:
3282                         case AST_FORMAT_ALAW:
3283                         case AST_FORMAT_ULAW:
3284                                 break;
3285                         default:
3286                                 return f;
3287                 }
3288                 break;
3289         case AST_FRAME_CONTROL:
3290                 if ((f->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
3291                     (faxdetect->flags & FAX_DETECT_MODE_T38)) {
3292                         break;
3293                 }
3294                 return f;
3295         default:
3296                 return f;
3297         }
3298
3299         if (f->frametype == AST_FRAME_VOICE) {
3300                 f = ast_dsp_process(chan, faxdetect->dsp, f);
3301                 if (f->frametype == AST_FRAME_DTMF) {
3302                         result = f->subclass.integer;
3303                 }
3304         } else if ((f->frametype == AST_FRAME_CONTROL) && (f->datalen == sizeof(struct ast_control_t38_parameters))) {
3305                 control_params = f->data.ptr;
3306                 switch (control_params->request_response) {
3307                 case AST_T38_NEGOTIATED:
3308                 case AST_T38_REQUEST_NEGOTIATE:
3309                         result = 't';
3310                         break;
3311                 default:
3312                         break;
3313                 }
3314         }
3315
3316         if (result) {
3317                 const char *target_context = S_OR(chan->macrocontext, chan->context);
3318                 switch (result) {
3319                 case 'f':
3320                 case 't':
3321                         ast_channel_unlock(chan);
3322                         if (ast_exists_extension(chan, target_context, "fax", 1,
3323                             S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
3324                                 ast_channel_lock(chan);
3325                                 ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to %s detection\n",
3326                                         chan->name, (result == 'f') ? "CNG" : "T38");
3327                                 pbx_builtin_setvar_helper(chan, "FAXEXTEN", chan->exten);
3328                                 if (ast_async_goto(chan, target_context, "fax", 1)) {
3329                                         ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", chan->name, target_context);
3330                                 }
3331                                 ast_frfree(f);
3332                                 f = &ast_null_frame;
3333                         } else {
3334                                 ast_channel_lock(chan);
3335                                 ast_log(LOG_NOTICE, "FAX %s detected but no fax extension in context (%s)\n",
3336                                         (result == 'f') ? "CNG" : "T38", target_context);
3337                         }
3338                 }
3339                 ast_framehook_detach(chan, details->faxdetect_id);
3340                 details->faxdetect_id = -1;
3341         }
3342
3343         return f;
3344 }
3345
3346 /*! \brief Attach a faxdetect framehook object to a channel.
3347  * \param chan the channel to attach to
3348  * \param timeout remove framehook in this time if set
3349  * \return the faxdetect structure or NULL on error
3350  * \param flags required options
3351  * \retval -1 error
3352  */
3353 static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags)
3354 {
3355         struct fax_detect *faxdetect;
3356         struct ast_fax_session_details *details;
3357         struct ast_framehook_interface fr_hook = {
3358                 .version = AST_FRAMEHOOK_INTERFACE_VERSION,
3359                 .event_cb = fax_detect_framehook,
3360                 .destroy_cb = fax_detect_framehook_destroy,
3361         };
3362
3363         if (!(details = find_or_create_details(chan))) {
3364                 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
3365                 return -1;
3366         }
3367
3368         /* set up the frame hook*/
3369         faxdetect = fax_detect_new(chan, timeout, flags);
3370         if (!faxdetect) {
3371                 ao2_ref(details, -1);
3372                 return -1;
3373         }
3374
3375         fr_hook.data = faxdetect;
3376         faxdetect->details = details;
3377         ast_channel_lock(chan);
3378         details->faxdetect_id = ast_framehook_attach(chan, &fr_hook);
3379         ast_channel_unlock(chan);
3380
3381         if (details->faxdetect_id < 0) {
3382                 ao2_ref(faxdetect, -1);
3383         }
3384
3385         return details->faxdetect_id;
3386 }
3387
3388 /*! \brief hash callback for ao2 */
3389 static int session_hash_cb(const void *obj, const int flags)
3390 {
3391         const struct ast_fax_session *s = obj;
3392
3393         return s->id;
3394 }
3395
3396 /*! \brief compare callback for ao2 */
3397 static int session_cmp_cb(void *obj, void *arg, int flags)
3398 {
3399         struct ast_fax_session *lhs = obj, *rhs = arg;
3400
3401         return (lhs->id == rhs->id) ? CMP_MATCH | CMP_STOP : 0;
3402 }
3403
3404 /*! \brief fax session tab completion */
3405 static char *fax_session_tab_complete(struct ast_cli_args *a)
3406 {
3407         int tklen;
3408         int wordnum = 0;
3409         char *name = NULL;
3410         struct ao2_iterator i;
3411         struct ast_fax_session *s;
3412         char tbuf[5];
3413
3414         if (a->pos != 3) {
3415                 return NULL;
3416         }
3417
3418         tklen = strlen(a->word);
3419         i = ao2_iterator_init(faxregistry.container, 0);
3420         while ((s = ao2_iterator_next(&i))) {
3421                 snprintf(tbuf, sizeof(tbuf), "%d", s->id);
3422                 if (!strncasecmp(a->word, tbuf, tklen) && ++wordnum > a->n) {
3423                         name = ast_strdup(tbuf);
3424                         ao2_ref(s, -1);
3425                         break;
3426                 }
3427                 ao2_ref(s, -1);
3428         }
3429         ao2_iterator_destroy(&i);
3430         return name;
3431 }
3432
3433 static char *cli_fax_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3434 {
3435         struct fax_module *fax;
3436
3437         switch(cmd) {
3438         case CLI_INIT:
3439                 e->command = "fax show version";
3440                 e->usage =
3441                         "Usage: fax show version\n"
3442                         "       Show versions of FAX For Asterisk components.\n";
3443                 return NULL;
3444         case CLI_GENERATE:
3445                 return NULL;
3446         }
3447
3448         if (a->argc != 3) {
3449                 return CLI_SHOWUSAGE;
3450         }
3451
3452         ast_cli(a->fd, "FAX For Asterisk Components:\n");
3453         ast_cli(a->fd, "\tApplications: %s\n", ast_get_version());
3454         AST_RWLIST_RDLOCK(&faxmodules);
3455         AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
3456                 ast_cli(a->fd, "\t%s: %s\n", fax->tech->description, fax->tech->version);
3457         }
3458         AST_RWLIST_UNLOCK(&faxmodules);
3459         ast_cli(a->fd, "\n");
3460
3461         return CLI_SUCCESS;
3462 }
3463
3464 /*! \brief enable FAX debugging */
3465 static char *cli_fax_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3466 {
3467         int flag;
3468         const char *what;
3469
3470         switch (cmd) {
3471         case CLI_INIT:
3472                 e->command = "fax set debug {on|off}";
3473                 e->usage = 
3474                         "Usage: fax set debug { on | off }\n"
3475                         "       Enable/Disable FAX debugging on new FAX sessions.  The basic FAX debugging will result in\n"
3476                         "       additional events sent to manager sessions with 'call' class permissions.  When\n"
3477                         "       verbosity is greater than '5' events will be displayed to the console and audio versus\n"
3478                         "       energy analysis will be performed and displayed to the console.\n";
3479                 return NULL;
3480         case CLI_GENERATE:
3481                 return NULL;
3482         }
3483
3484         what = a->argv[e->args-1];      /* guaranteed to exist */
3485         if (!strcasecmp(what, "on")) {
3486                 flag = 1;
3487         } else if (!strcasecmp(what, "off")) {
3488                 flag = 0;
3489         } else {
3490               &n