Asterisk - The Open Source Telephony Project  21.4.1
res_fax.c
Go to the documentation of this file.
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  <support_level>core</support_level>
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 /*! \li \ref res_fax.c uses the configuration file \ref res_fax.conf
57  * \addtogroup configuration_file Configuration Files
58  */
59 
60 /*!
61  * \page res_fax.conf res_fax.conf
62  * \verbinclude res_fax.conf.sample
63  */
64 
65 #include "asterisk.h"
66 
67 #include "asterisk/io.h"
68 #include "asterisk/file.h"
69 #include "asterisk/logger.h"
70 #include "asterisk/module.h"
71 #include "asterisk/app.h"
72 #include "asterisk/lock.h"
73 #include "asterisk/options.h"
74 #include "asterisk/strings.h"
75 #include "asterisk/cli.h"
76 #include "asterisk/utils.h"
77 #include "asterisk/config.h"
78 #include "asterisk/astobj2.h"
79 #include "asterisk/res_fax.h"
80 #include "asterisk/file.h"
81 #include "asterisk/channel.h"
82 #include "asterisk/pbx.h"
83 #include "asterisk/dsp.h"
84 #include "asterisk/indications.h"
85 #include "asterisk/ast_version.h"
86 #include "asterisk/translate.h"
87 #include "asterisk/stasis.h"
88 #include "asterisk/stasis_channels.h"
89 #include "asterisk/smoother.h"
90 #include "asterisk/format_cache.h"
91 
92 /*** DOCUMENTATION
93  <application name="ReceiveFAX" language="en_US" module="res_fax">
94  <synopsis>
95  Receive a FAX and save as a TIFF/F file.
96  </synopsis>
97  <syntax>
98  <parameter name="filename" required="true" />
99  <parameter name="options">
100  <optionlist>
101  <option name="d">
102  <para>Enable FAX debugging.</para>
103  </option>
104  <option name="f">
105  <para>Allow audio fallback FAX transfer on T.38 capable channels.</para>
106  </option>
107  <option name="F">
108  <para>Force usage of audio mode on T.38 capable channels.</para>
109  </option>
110  <option name="s">
111  <para>Send progress Manager events (overrides statusevents setting in res_fax.conf).</para>
112  </option>
113  </optionlist>
114  </parameter>
115  </syntax>
116  <description>
117  <para>This application is provided by res_fax, which is a FAX technology agnostic module
118  that utilizes FAX technology resource modules to complete a FAX transmission.</para>
119  <para>Session arguments can be set by the FAXOPT function and to check results of the ReceiveFAX() application.</para>
120  </description>
121  <see-also>
122  <ref type="function">FAXOPT</ref>
123  </see-also>
124  </application>
125  <application name="SendFAX" language="en_US" module="res_fax">
126  <synopsis>
127  Sends a specified TIFF/F file as a FAX.
128  </synopsis>
129  <syntax>
130  <parameter name="filename" required="true" argsep="&amp;">
131  <argument name="filename2" multiple="true">
132  <para>TIFF file to send as a FAX.</para>
133  </argument>
134  </parameter>
135  <parameter name="options">
136  <optionlist>
137  <option name="d">
138  <para>Enable FAX debugging.</para>
139  </option>
140  <option name="f">
141  <para>Allow audio fallback FAX transfer on T.38 capable channels.</para>
142  </option>
143  <option name="F">
144  <para>Force usage of audio mode on T.38 capable channels.</para>
145  </option>
146  <option name="s">
147  <para>Send progress Manager events (overrides statusevents setting in res_fax.conf).</para>
148  </option>
149  <option name="z">
150  <para>Initiate a T.38 reinvite on the channel if the remote end does not.</para>
151  </option>
152  </optionlist>
153  </parameter>
154  </syntax>
155  <description>
156  <para>This application is provided by res_fax, which is a FAX technology agnostic module
157  that utilizes FAX technology resource modules to complete a FAX transmission.</para>
158  <para>Session arguments can be set by the FAXOPT function and to check results of the SendFAX() application.</para>
159  </description>
160  <see-also>
161  <ref type="function">FAXOPT</ref>
162  </see-also>
163  </application>
164  <function name="FAXOPT" language="en_US" module="res_fax">
165  <synopsis>
166  Gets/sets various pieces of information about a fax session.
167  </synopsis>
168  <syntax>
169  <parameter name="item" required="true">
170  <enumlist>
171  <enum name="ecm">
172  <para>R/W Error Correction Mode (ECM) enable with 'yes', disable with 'no'.</para>
173  </enum>
174  <enum name="error">
175  <para>R/O FAX transmission error code upon failure.</para>
176  </enum>
177  <enum name="filename">
178  <para>R/O Filename of the first file of the FAX transmission.</para>
179  </enum>
180  <enum name="filenames">
181  <para>R/O Filenames of all of the files in the FAX transmission (comma separated).</para>
182  </enum>
183  <enum name="headerinfo">
184  <para>R/W FAX header information.</para>
185  </enum>
186  <enum name="localstationid">
187  <para>R/W Local Station Identification.</para>
188  </enum>
189  <enum name="minrate">
190  <para>R/W Minimum transfer rate set before transmission.</para>
191  </enum>
192  <enum name="maxrate">
193  <para>R/W Maximum transfer rate set before transmission.</para>
194  </enum>
195  <enum name="modem">
196  <para>R/W Modem type (v17/v27/v29).</para>
197  </enum>
198  <enum name="gateway">
199  <para>R/W T38 fax gateway, with optional fax activity timeout in seconds (yes[,timeout]/no)</para>
200  </enum>
201  <enum name="faxdetect">
202  <para>R/W Enable FAX detect with optional timeout in seconds (yes,t38,cng[,timeout]/no)</para>
203  </enum>
204  <enum name="pages">
205  <para>R/O Number of pages transferred.</para>
206  </enum>
207  <enum name="rate">
208  <para>R/O Negotiated transmission rate.</para>
209  </enum>
210  <enum name="remotestationid">
211  <para>R/O Remote Station Identification after transmission.</para>
212  </enum>
213  <enum name="resolution">
214  <para>R/O Negotiated image resolution after transmission.</para>
215  </enum>
216  <enum name="sessionid">
217  <para>R/O Session ID of the FAX transmission.</para>
218  </enum>
219  <enum name="status">
220  <para>R/O Result Status of the FAX transmission.</para>
221  </enum>
222  <enum name="statusstr">
223  <para>R/O Verbose Result Status of the FAX transmission.</para>
224  </enum>
225  <enum name="t38timeout">
226  <para>R/W The timeout used for T.38 negotiation.</para>
227  </enum>
228  <enum name="negotiate_both">
229  <para>R/W Upon v21 detection allow gateway to send negotiation requests to both T.38 endpoints, and do not wait on the "other" side to initiate (yes|no)</para>
230  </enum>
231  </enumlist>
232  </parameter>
233  </syntax>
234  <description>
235  <para>FAXOPT can be used to override the settings for a FAX session listed in <filename>res_fax.conf</filename>,
236  it can also be used to retrieve information about a FAX session that has finished eg. pages/status.</para>
237  </description>
238  <see-also>
239  <ref type="application">ReceiveFAX</ref>
240  <ref type="application">SendFAX</ref>
241  </see-also>
242  </function>
243  <manager name="FAXSessions" language="en_US">
244  <synopsis>
245  Lists active FAX sessions
246  </synopsis>
247  <syntax>
248  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
249  </syntax>
250  <description>
251  <para>Will generate a series of FAXSession events with information about each FAXSession. Closes with
252  a FAXSessionsComplete event which includes a count of the included FAX sessions. This action works in
253  the same manner as the CLI command 'fax show sessions'</para>
254  </description>
255  </manager>
256  <managerEvent language="en_US" name="FAXSessionsEntry">
257  <managerEventInstance class="EVENT_FLAG_REPORTING">
258  <synopsis>A single list item for the FAXSessions AMI command</synopsis>
259  <syntax>
260  <parameter name="ActionID" required="false"/>
261  <parameter name="Channel">
262  <para>Name of the channel responsible for the FAX session</para>
263  </parameter>
264  <parameter name="Technology">
265  <para>The FAX technology that the FAX session is using</para>
266  </parameter>
267  <parameter name="SessionNumber">
268  <para>The numerical identifier for this particular session</para>
269  </parameter>
270  <parameter name="SessionType">
271  <para>FAX session passthru/relay type</para>
272  <enumlist>
273  <enum name="G.711" />
274  <enum name="T.38" />
275  </enumlist>
276  </parameter>
277  <parameter name="Operation">
278  <para>FAX session operation type</para>
279  <enumlist>
280  <enum name="gateway" />
281  <enum name="V.21" />
282  <enum name="send" />
283  <enum name="receive" />
284  <enum name="none" />
285  </enumlist>
286  </parameter>
287  <parameter name="State">
288  <para>Current state of the FAX session</para>
289  <enumlist>
290  <enum name="Uninitialized" />
291  <enum name="Initialized" />
292  <enum name="Open" />
293  <enum name="Active" />
294  <enum name="Complete" />
295  <enum name="Reserved" />
296  <enum name="Inactive" />
297  <enum name="Unknown" />
298  </enumlist>
299  </parameter>
300  <parameter name="Files">
301  <para>File or list of files associated with this FAX session</para>
302  </parameter>
303  </syntax>
304  </managerEventInstance>
305  </managerEvent>
306  <managerEvent language="en_US" name="FAXSessionsComplete">
307  <managerEventInstance class="EVENT_FLAG_CALL">
308  <synopsis>Raised when all FAXSession events are completed for a FAXSessions command</synopsis>
309  <syntax>
310  <parameter name="ActionID" required="false"/>
311  <parameter name="Total">
312  <para>Count of FAXSession events sent in response to FAXSessions action</para>
313  </parameter>
314  </syntax>
315  </managerEventInstance>
316  </managerEvent>
317  <manager name="FAXSession" language="en_US">
318  <synopsis>
319  Responds with a detailed description of a single FAX session
320  </synopsis>
321  <syntax>
322  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
323  <parameter name="SessionNumber" required="true">
324  <para>The session ID of the fax the user is interested in.</para>
325  </parameter>
326  </syntax>
327  <description>
328  <para>Provides details about a specific FAX session. The response will include a common subset of
329  the output from the CLI command 'fax show session &lt;session_number&gt;' for each technology. If the
330  FAX technolgy used by this session does not include a handler for FAXSession, then this action
331  will fail.</para>
332  </description>
333  </manager>
334  <managerEvent language="en_US" name="FAXSession">
335  <managerEventInstance class="EVENT_FLAG_REPORTING">
336  <synopsis>Raised in response to FAXSession manager command</synopsis>
337  <syntax>
338  <parameter name="ActionID" required="false"/>
339  <parameter name="SessionNumber">
340  <para>The numerical identifier for this particular session</para>
341  </parameter>
342  <xi:include xpointer="xpointer(/docs/managerEvent[@name='FAXSessionsEntry']/managerEventInstance/syntax/parameter[@name='Operation'])" />
343  <xi:include xpointer="xpointer(/docs/managerEvent[@name='FAXSessionsEntry']/managerEventInstance/syntax/parameter[@name='State'])" />
344  <parameter name="ErrorCorrectionMode" required="false">
345  <para>Whether error correcting mode is enabled for the FAX session. This field is not
346  included when operation is 'V.21 Detect' or if operation is 'gateway' and state is
347  'Uninitialized'
348  </para>
349  <enumlist>
350  <enum name="yes" />
351  <enum name="no" />
352  </enumlist>
353  </parameter>
354  <parameter name="DataRate" required="false">
355  <para>Bit rate of the FAX. This field is not included when operation is 'V.21 Detect' or
356  if operation is 'gateway' and state is 'Uninitialized'.</para>
357  </parameter>
358  <parameter name="ImageResolution" required="false">
359  <para>Resolution of each page of the FAX. Will be in the format of X_RESxY_RES. This field
360  is not included if the operation is anything other than Receive/Transmit.</para>
361  </parameter>
362  <parameter name="PageNumber" required="false">
363  <para>Current number of pages transferred during this FAX session. May change as the FAX
364  progresses. This field is not included when operation is 'V.21 Detect' or if operation is
365  'gateway' and state is 'Uninitialized'.</para>
366  </parameter>
367  <parameter name="FileName" required="false">
368  <para>Filename of the image being sent/received for this FAX session. This field is not
369  included if Operation isn't 'send' or 'receive'.</para>
370  </parameter>
371  <parameter name="PagesTransmitted" required="false">
372  <para>Total number of pages sent during this session. This field is not included if
373  Operation isn't 'send' or 'receive'. Will always be 0 for 'receive'.</para>
374  </parameter>
375  <parameter name="PagesReceived" required="false">
376  <para>Total number of pages received during this session. This field is not included if
377  Operation is not 'send' or 'receive'. Will be 0 for 'send'.</para>
378  </parameter>
379  <parameter name="TotalBadLines" required="false">
380  <para>Total number of bad lines sent/received during this session. This field is not
381  included if Operation is not 'send' or 'received'.</para>
382  </parameter>
383  </syntax>
384  </managerEventInstance>
385  </managerEvent>
386  <manager name="FAXStats" language="en_US">
387  <synopsis>
388  Responds with fax statistics
389  </synopsis>
390  <syntax>
391  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
392  </syntax>
393  <description>
394  <para>Provides FAX statistics including the number of active sessions, reserved sessions, completed
395  sessions, failed sessions, and the number of receive/transmit attempts. This command provides all
396  of the non-technology specific information provided by the CLI command 'fax show stats'</para>
397  </description>
398  </manager>
399  <managerEvent language="en_US" name="FAXStats">
400  <managerEventInstance class="EVENT_FLAG_REPORTING">
401  <synopsis>Raised in response to FAXStats manager command</synopsis>
402  <syntax>
403  <parameter name="ActionID" required="false"/>
404  <parameter name="CurrentSessions" required="true">
405  <para>Number of active FAX sessions</para>
406  </parameter>
407  <parameter name="ReservedSessions" required="true">
408  <para>Number of reserved FAX sessions</para>
409  </parameter>
410  <parameter name="TransmitAttempts" required="true">
411  <para>Total FAX sessions for which Asterisk is/was the transmitter</para>
412  </parameter>
413  <parameter name="ReceiveAttempts" required="true">
414  <para>Total FAX sessions for which Asterisk is/was the recipient</para>
415  </parameter>
416  <parameter name="CompletedFAXes" required="true">
417  <para>Total FAX sessions which have been completed successfully</para>
418  </parameter>
419  <parameter name="FailedFAXes" required="true">
420  <para>Total FAX sessions which failed to complete successfully</para>
421  </parameter>
422  </syntax>
423  </managerEventInstance>
424  </managerEvent>
425 ***/
426 
427 static const char app_receivefax[] = "ReceiveFAX";
428 static const char app_sendfax[] = "SendFAX";
429 
431  unsigned int consec_frames;
432  unsigned int consec_ms;
433  unsigned char silence;
434 };
435 
437  struct timeval base_tv;
438  struct debug_info_history c2s, s2c;
439  struct ast_dsp *dsp;
440 };
441 
442 /*! \brief used for gateway framehook */
443 struct fax_gateway {
444  /*! \brief FAX Session */
446  struct ast_fax_session *peer_v21_session;
447  struct ast_fax_session *chan_v21_session;
448  /*! \brief reserved fax session token */
449  struct ast_fax_tech_token *token;
450  /*! \brief the start of our timeout counter */
451  struct timeval timeout_start;
452  /*! \brief framehook used in gateway mode */
454  /*! \brief bridged */
455  int bridged:1;
456  /*! \brief 1 if a v21 preamble has been detected */
458  /*! \brief a flag to track the state of our negotiation */
460  /*! \brief original audio formats */
462  struct ast_format *chan_write_format;
463  struct ast_format *peer_read_format;
464  struct ast_format *peer_write_format;
465 };
466 
467 /*! \brief used for fax detect framehook */
468 struct fax_detect {
469  /*! \brief the start of our timeout counter */
470  struct timeval timeout_start;
471  /*! \brief DSP Processor */
472  struct ast_dsp *dsp;
473  /*! \brief original audio formats */
475  /*! \brief fax session details */
477  /*! \brief mode */
478  int flags;
479 };
480 
481 /*! \brief FAX Detect flags */
482 #define FAX_DETECT_MODE_CNG (1 << 0)
483 #define FAX_DETECT_MODE_T38 (1 << 1)
484 #define FAX_DETECT_MODE_BOTH (FAX_DETECT_MODE_CNG | FAX_DETECT_MODE_T38)
485 
486 static int fax_logger_level = -1;
487 
488 /*! \brief maximum buckets for res_fax ao2 containers */
489 #define FAX_MAXBUCKETS 10
490 
491 #define RES_FAX_TIMEOUT 10000
492 #define FAX_GATEWAY_TIMEOUT RES_FAX_TIMEOUT
493 
494 /*! \brief The faxregistry is used to manage information and statistics for all FAX sessions. */
495 static struct {
496  /*! The number of active FAX sessions */
498  /*! The number of reserved FAX sessions */
500  /*! active sessions are astobj2 objects */
502  /*! Total number of Tx FAX attempts */
504  /*! Total number of Rx FAX attempts */
506  /*! Number of successful FAX transmissions */
508  /*! Number of failed FAX transmissions */
510  /*! the next unique session name */
512 } faxregistry;
513 
514 /*! \brief registered FAX technology modules are put into this list */
515 struct fax_module {
516  const struct ast_fax_tech *tech;
517  AST_RWLIST_ENTRY(fax_module) list;
518 };
520 
521 #define RES_FAX_MINRATE 4800
522 #define RES_FAX_MAXRATE 14400
523 #define RES_FAX_STATUSEVENTS 0
524 #define RES_FAX_MODEM (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27TER | AST_FAX_MODEM_V29)
525 #define RES_FAX_T38TIMEOUT 5000
526 
527 struct fax_options {
528  enum ast_fax_modems modems;
529  uint32_t statusevents:1;
530  uint32_t ecm:1;
531  unsigned int minrate;
532  unsigned int maxrate;
533  unsigned int t38timeout;
534 };
535 
536 static struct fax_options general_options;
537 
538 static const struct fax_options default_options = {
539  .minrate = RES_FAX_MINRATE,
540  .maxrate = RES_FAX_MAXRATE,
541  .statusevents = RES_FAX_STATUSEVENTS,
542  .modems = RES_FAX_MODEM,
543  .ecm = AST_FAX_OPTFLAG_TRUE,
544  .t38timeout = RES_FAX_T38TIMEOUT,
545 };
546 
547 AST_RWLOCK_DEFINE_STATIC(options_lock);
548 
549 static void get_general_options(struct fax_options* options);
550 static void set_general_options(const struct fax_options* options);
551 
552 static const char *config = "res_fax.conf";
553 
554 static int global_fax_debug = 0;
555 
556 enum {
557  OPT_CALLEDMODE = (1 << 0),
558  OPT_CALLERMODE = (1 << 1),
559  OPT_DEBUG = (1 << 2),
560  OPT_STATUS = (1 << 3),
561  OPT_ALLOWAUDIO = (1 << 5),
562  OPT_REQUEST_T38 = (1 << 6),
563  OPT_FORCE_AUDIO = (1 << 7),
564 };
565 
566 AST_APP_OPTIONS(fax_exec_options, BEGIN_OPTIONS
567  AST_APP_OPTION('a', OPT_CALLEDMODE),
568  AST_APP_OPTION('c', OPT_CALLERMODE),
569  AST_APP_OPTION('d', OPT_DEBUG),
570  AST_APP_OPTION('f', OPT_ALLOWAUDIO),
571  AST_APP_OPTION('F', OPT_FORCE_AUDIO),
572  AST_APP_OPTION('s', OPT_STATUS),
573  AST_APP_OPTION('z', OPT_REQUEST_T38),
574 END_OPTIONS);
575 
576 static void debug_check_frame_for_silence(struct ast_fax_session *s, unsigned int c2s, struct ast_frame *frame)
577 {
578  struct debug_info_history *history = c2s ? &s->debug_info->c2s : &s->debug_info->s2c;
579  int dspsilence;
580  unsigned int last_consec_frames, last_consec_ms;
581  unsigned char wassil;
582  struct timeval diff;
583 
584  diff = ast_tvsub(ast_tvnow(), s->debug_info->base_tv);
585 
586  ast_dsp_reset(s->debug_info->dsp);
587  ast_dsp_silence(s->debug_info->dsp, frame, &dspsilence);
588 
589  wassil = history->silence;
590  history->silence = (dspsilence != 0) ? 1 : 0;
591  if (history->silence != wassil) {
592  last_consec_frames = history->consec_frames;
593  last_consec_ms = history->consec_ms;
594  history->consec_frames = 0;
595  history->consec_ms = 0;
596 
597  if ((last_consec_frames != 0)) {
598  ast_verb(0, "Channel '%s' fax session '%u', [ %.3ld.%.6ld ], %s sent %u frames (%u ms) of %s.\n",
599  s->channame, s->id, (long) diff.tv_sec, (long int) diff.tv_usec,
600  (c2s) ? "channel" : "stack", last_consec_frames, last_consec_ms,
601  (wassil) ? "silence" : "energy");
602  }
603  }
604 
605  history->consec_frames++;
606  history->consec_ms += (frame->samples / 8);
607 }
608 
609 static void destroy_callback(void *data)
610 {
611  if (data) {
612  ao2_ref(data, -1);
613  }
614 }
615 
616 static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
617 
618 static const struct ast_datastore_info fax_datastore = {
619  .type = "res_fax",
620  .destroy = destroy_callback,
621  .chan_fixup = fixup_callback,
622 };
623 
624 static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details);
625 static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags);
626 static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan);
627 static struct ast_fax_session *fax_v21_session_new (struct ast_channel *chan);
628 
629 
630 /*! \brief Copies fax detection and gateway framehooks during masquerades
631  *
632  * \note must be called with both old_chan and new_chan locked. Since this
633  * is only called by do_masquerade, that shouldn't be an issue.
634  */
635 static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
636 {
637  struct ast_fax_session_details *old_details = data;
638  struct ast_datastore *datastore = ast_channel_datastore_find(old_chan, &fax_datastore, NULL);
639 
640  if (old_details->gateway_id >= 0) {
641  struct ast_fax_session_details *new_details = find_or_create_details(new_chan);
642 
643  ast_framehook_detach(old_chan, old_details->gateway_id);
644  new_details->is_t38_negotiated = old_details->is_t38_negotiated;
645  fax_gateway_attach(new_chan, new_details);
646  ao2_cleanup(new_details);
647  }
648 
649  if (old_details->faxdetect_id >= 0) {
650  ast_framehook_detach(old_chan, old_details->faxdetect_id);
651  fax_detect_attach(new_chan, old_details->faxdetect_timeout, old_details->faxdetect_flags);
652  }
653 
654  if (datastore) {
655  ast_channel_datastore_remove(old_chan, datastore);
656  ast_datastore_free(datastore);
657  }
658 }
659 
660 /*! \brief returns a reference counted pointer to a fax datastore, if it exists */
662 {
663  struct ast_fax_session_details *details;
664  struct ast_datastore *datastore;
665 
666  ast_channel_lock(chan);
667  if (!(datastore = ast_channel_datastore_find(chan, &fax_datastore, NULL))) {
668  ast_channel_unlock(chan);
669  return NULL;
670  }
671  if (!(details = datastore->data)) {
672  ast_log(LOG_WARNING, "Huh? channel '%s' has a FAX datastore without data!\n", ast_channel_name(chan));
673  ast_channel_unlock(chan);
674  return NULL;
675  }
676  ao2_ref(details, 1);
677  ast_channel_unlock(chan);
678 
679  return details;
680 }
681 
682 /*! \brief destroy a FAX session details structure */
683 static void destroy_session_details(void *details)
684 {
685  struct ast_fax_session_details *d = details;
686  struct ast_fax_document *doc;
687 
688  while ((doc = AST_LIST_REMOVE_HEAD(&d->documents, next))) {
689  ast_free(doc);
690  }
692 }
693 
694 /*! \brief create a FAX session details structure */
696 {
697  struct ast_fax_session_details *d;
698  struct fax_options options;
699 
700  if (!(d = ao2_alloc(sizeof(*d), destroy_session_details))) {
701  return NULL;
702  }
703 
704  if (ast_string_field_init(d, 512)) {
705  ao2_ref(d, -1);
706  return NULL;
707  }
708 
709  get_general_options(&options);
710 
712 
713  /* These options need to be set to the configured default and may be overridden by
714  * SendFAX, ReceiveFAX, or FAXOPT */
715  d->option.request_t38 = AST_FAX_OPTFLAG_FALSE;
716  d->option.send_cng = AST_FAX_OPTFLAG_FALSE;
717  d->option.send_ced = AST_FAX_OPTFLAG_FALSE;
718  d->option.ecm = options.ecm;
719  d->option.statusevents = options.statusevents;
720  d->modems = options.modems;
721  d->minrate = options.minrate;
722  d->maxrate = options.maxrate;
723  d->t38timeout = options.t38timeout;
724  d->gateway_id = -1;
725  d->faxdetect_id = -1;
726  d->gateway_timeout = 0;
727  d->negotiate_both = 0;
728 
729  return d;
730 }
731 
732 static struct ast_control_t38_parameters our_t38_parameters = {
733  .version = 0,
734  .max_ifp = 400,
735  .rate = AST_T38_RATE_14400,
736  .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
737 };
738 
739 static void t38_parameters_ast_to_fax(struct ast_fax_t38_parameters *dst, const struct ast_control_t38_parameters *src)
740 {
741  dst->version = src->version;
742  dst->max_ifp = src->max_ifp;
743  dst->rate = src->rate;
744  dst->rate_management = src->rate_management;
746  dst->transcoding_mmr = src->transcoding_mmr;
748 }
749 
750 static void t38_parameters_fax_to_ast(struct ast_control_t38_parameters *dst, const struct ast_fax_t38_parameters *src)
751 {
752  dst->version = src->version;
753  dst->max_ifp = src->max_ifp;
754  dst->rate = src->rate;
755  dst->rate_management = src->rate_management;
757  dst->transcoding_mmr = src->transcoding_mmr;
759 }
760 
761 /*! \brief returns a reference counted details structure from the channel's fax datastore. If the datastore
762  * does not exist it will be created */
764 {
765  struct ast_fax_session_details *details;
766  struct ast_datastore *datastore;
767 
768  if ((details = find_details(chan))) {
769  return details;
770  }
771  /* channel does not have one so we must create one */
772  if (!(details = session_details_new())) {
773  ast_log(LOG_WARNING, "channel '%s' can't get a FAX details structure for the datastore!\n", ast_channel_name(chan));
774  return NULL;
775  }
776  if (!(datastore = ast_datastore_alloc(&fax_datastore, NULL))) {
777  ao2_ref(details, -1);
778  ast_log(LOG_WARNING, "channel '%s' can't get a datastore!\n", ast_channel_name(chan));
779  return NULL;
780  }
781  /* add the datastore to the channel and increment the refcount */
782  datastore->data = details;
783 
784  /* initialize default T.38 parameters */
785  t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
786  t38_parameters_ast_to_fax(&details->their_t38_parameters, &our_t38_parameters);
787 
788  ao2_ref(details, 1);
789  ast_channel_lock(chan);
790  ast_channel_datastore_add(chan, datastore);
791  ast_channel_unlock(chan);
792  return details;
793 }
794 
795 unsigned int ast_fax_maxrate(void)
796 {
797  struct fax_options options;
798  get_general_options(&options);
799 
800  return options.maxrate;
801 }
802 
803 unsigned int ast_fax_minrate(void)
804 {
805  struct fax_options options;
806  get_general_options(&options);
807 
808  return options.minrate;
809 }
810 
811 static int update_modem_bits(enum ast_fax_modems *bits, const char *value)
812 {
813  char *m[5], *tok, *v = (char *) value, *rest;
814  int i = 0, j;
815 
816  if (!strchr(v, ',')) {
817  m[i++] = v;
818  m[i] = NULL;
819  } else {
820  tok = strtok_r(v, ", ", &rest);
821  while (tok && i < ARRAY_LEN(m) - 1) {
822  m[i++] = tok;
823  tok = strtok_r(NULL, ", ", &rest);
824  }
825  m[i] = NULL;
826  }
827 
828  *bits = 0;
829  for (j = 0; j < i; j++) {
830  if (!strcasecmp(m[j], "v17")) {
831  *bits |= AST_FAX_MODEM_V17;
832  } else if (!strcasecmp(m[j], "v27")) {
833  *bits |= AST_FAX_MODEM_V27TER;
834  } else if (!strcasecmp(m[j], "v29")) {
835  *bits |= AST_FAX_MODEM_V29;
836  } else if (!strcasecmp(m[j], "v34")) {
837  *bits |= AST_FAX_MODEM_V34;
838  } else {
839  ast_log(LOG_WARNING, "ignoring invalid modem setting: '%s', valid options {v17 | v27 | v29 | v34}\n", m[j]);
840  }
841  }
842  return 0;
843 }
844 
845 static char *ast_fax_caps_to_str(enum ast_fax_capabilities caps, char *buf, size_t bufsize)
846 {
847  char *out = buf;
848  size_t size = bufsize;
849  int first = 1;
850 
851  if (caps & AST_FAX_TECH_SEND) {
852  if (!first) {
853  ast_build_string(&buf, &size, ",");
854  }
855  ast_build_string(&buf, &size, "SEND");
856  first = 0;
857  }
858  if (caps & AST_FAX_TECH_RECEIVE) {
859  if (!first) {
860  ast_build_string(&buf, &size, ",");
861  }
862  ast_build_string(&buf, &size, "RECEIVE");
863  first = 0;
864  }
865  if (caps & AST_FAX_TECH_AUDIO) {
866  if (!first) {
867  ast_build_string(&buf, &size, ",");
868  }
869  ast_build_string(&buf, &size, "AUDIO");
870  first = 0;
871  }
872  if (caps & AST_FAX_TECH_T38) {
873  if (!first) {
874  ast_build_string(&buf, &size, ",");
875  }
876  ast_build_string(&buf, &size, "T38");
877  first = 0;
878  }
879  if (caps & AST_FAX_TECH_MULTI_DOC) {
880  if (!first) {
881  ast_build_string(&buf, &size, ",");
882  }
883  ast_build_string(&buf, &size, "MULTI_DOC");
884  first = 0;
885  }
886  if (caps & AST_FAX_TECH_GATEWAY) {
887  if (!first) {
888  ast_build_string(&buf, &size, ",");
889  }
890  ast_build_string(&buf, &size, "GATEWAY");
891  first = 0;
892  }
893  if (caps & AST_FAX_TECH_V21_DETECT) {
894  if (!first) {
895  ast_build_string(&buf, &size, ",");
896  }
897  ast_build_string(&buf, &size, "V21");
898  first = 0;
899  }
900 
901  return out;
902 }
903 
904 static int ast_fax_modem_to_str(enum ast_fax_modems bits, char *tbuf, size_t bufsize)
905 {
906  int count = 0;
907 
908  if (bits & AST_FAX_MODEM_V17) {
909  strcat(tbuf, "V17");
910  count++;
911  }
912  if (bits & AST_FAX_MODEM_V27TER) {
913  if (count) {
914  strcat(tbuf, ",");
915  }
916  strcat(tbuf, "V27");
917  count++;
918  }
919  if (bits & AST_FAX_MODEM_V29) {
920  if (count) {
921  strcat(tbuf, ",");
922  }
923  strcat(tbuf, "V29");
924  count++;
925  }
926  if (bits & AST_FAX_MODEM_V34) {
927  if (count) {
928  strcat(tbuf, ",");
929  }
930  strcat(tbuf, "V34");
931  count++;
932  }
933 
934  return 0;
935 }
936 
937 static int check_modem_rate(enum ast_fax_modems modems, unsigned int rate)
938 {
939  switch (rate) {
940  case 2400:
941  case 4800:
942  if (!(modems & (AST_FAX_MODEM_V27TER | AST_FAX_MODEM_V34))) {
943  return 1;
944  }
945  break;
946  case 7200:
947  case 9600:
948  if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
949  return 1;
950  }
951  break;
952  case 12000:
953  case 14400:
954  if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V34))) {
955  return 1;
956  }
957  break;
958  case 28800:
959  case 33600:
960  if (!(modems & AST_FAX_MODEM_V34)) {
961  return 1;
962  }
963  break;
964  default:
965  /* this should never happen */
966  return 1;
967  }
968 
969  return 0;
970 }
971 
972 /*! \brief register a FAX technology module */
974 {
975  struct fax_module *fax;
976 
977  if (!(fax = ast_calloc(1, sizeof(*fax)))) {
978  return -1;
979  }
980  fax->tech = tech;
982  AST_RWLIST_INSERT_TAIL(&faxmodules, fax, list);
984 
985  ast_verb(3, "Registered handler for '%s' (%s)\n", fax->tech->type, fax->tech->description);
986 
987  return 0;
988 }
989 
990 /*! \brief unregister a FAX technology module */
992 {
993  struct fax_module *fax;
994 
995  ast_verb(3, "Unregistering FAX module type '%s'\n", tech->type);
996 
998  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&faxmodules, fax, list) {
999  if (fax->tech != tech) {
1000  continue;
1001  }
1002  AST_RWLIST_REMOVE_CURRENT(list);
1003  ast_free(fax);
1004  ast_verb(4, "Unregistered FAX module type '%s'\n", tech->type);
1005  break;
1006  }
1007  AST_RWLIST_TRAVERSE_SAFE_END;
1009 }
1010 
1011 /*! \brief convert a ast_fax_state to a string */
1012 const char *ast_fax_state_to_str(enum ast_fax_state state)
1013 {
1014  switch (state) {
1015  case AST_FAX_STATE_UNINITIALIZED:
1016  return "Uninitialized";
1017  case AST_FAX_STATE_INITIALIZED:
1018  return "Initialized";
1019  case AST_FAX_STATE_OPEN:
1020  return "Open";
1021  case AST_FAX_STATE_ACTIVE:
1022  return "Active";
1023  case AST_FAX_STATE_COMPLETE:
1024  return "Complete";
1025  case AST_FAX_STATE_RESERVED:
1026  return "Reserved";
1027  case AST_FAX_STATE_INACTIVE:
1028  return "Inactive";
1029  default:
1030  ast_log(LOG_WARNING, "unhandled FAX state: %u\n", state);
1031  return "Unknown";
1032  }
1033 }
1034 
1035 void ast_fax_log(int level, const char *file, const int line, const char *function, const char *msg)
1036 {
1037  if (fax_logger_level != -1) {
1038  ast_log_dynamic_level(fax_logger_level, "%s", msg);
1039  } else {
1040  ast_log(level, file, line, function, "%s", msg);
1041  }
1042 }
1043 
1044 /*! \brief convert a rate string to a rate */
1045 static unsigned int fax_rate_str_to_int(const char *ratestr)
1046 {
1047  int rate;
1048 
1049  if (sscanf(ratestr, "%d", &rate) != 1) {
1050  ast_log(LOG_ERROR, "failed to sscanf '%s' to rate\n", ratestr);
1051  return 0;
1052  }
1053  switch (rate) {
1054  case 2400:
1055  case 4800:
1056  case 7200:
1057  case 9600:
1058  case 12000:
1059  case 14400:
1060  case 28800:
1061  case 33600:
1062  return rate;
1063  default:
1064  ast_log(LOG_WARNING, "ignoring invalid rate '%s'. Valid options are {2400 | 4800 | 7200 | 9600 | 12000 | 14400 | 28800 | 33600}\n", ratestr);
1065  return 0;
1066  }
1067 }
1068 
1069 /*! \brief Release a session token.
1070  * \param s a session returned from fax_session_reserve()
1071  * \param token a token generated from fax_session_reserve()
1072  *
1073  * This function releases the given token and marks the given session as no
1074  * longer reserved. It is safe to call on a session that is not actually
1075  * reserved and with a NULL token. This is so that sessions returned by
1076  * technologies that do not support reserved sessions don't require extra logic
1077  * to handle.
1078  *
1079  * \note This function DOES NOT release the given fax session, only the given
1080  * token.
1081  */
1082 static void fax_session_release(struct ast_fax_session *s, struct ast_fax_tech_token *token)
1083 {
1084  if (token) {
1085  s->tech->release_token(token);
1086  }
1087 
1088  if (s->state == AST_FAX_STATE_RESERVED) {
1089  ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
1090  s->state = AST_FAX_STATE_INACTIVE;
1091  }
1092 }
1093 
1094 /*! \brief destroy a FAX session structure */
1095 static void destroy_session(void *session)
1096 {
1097  struct ast_fax_session *s = session;
1098 
1099  if (s->tech) {
1100  fax_session_release(s, NULL);
1101  if (s->tech_pvt) {
1102  s->tech->destroy_session(s);
1103  }
1105  }
1106 
1107  if (s->details) {
1108  if (s->details->caps & AST_FAX_TECH_GATEWAY) {
1109  s->details->caps &= ~AST_FAX_TECH_GATEWAY;
1110  }
1111  ao2_ref(s->details, -1);
1112  s->details = NULL;
1113  }
1114 
1115  if (s->debug_info) {
1116  ast_dsp_free(s->debug_info->dsp);
1117  ast_free(s->debug_info);
1118  }
1119 
1120  if (s->smoother) {
1121  ast_smoother_free(s->smoother);
1122  }
1123 
1124  if (s->state != AST_FAX_STATE_INACTIVE) {
1125  ast_atomic_fetchadd_int(&faxregistry.active_sessions, -1);
1126  }
1127 
1128  ast_free(s->channame);
1129  ast_free(s->chan_uniqueid);
1130 }
1131 
1132 /*! \brief Reserve a fax session.
1133  * \param details the fax session details
1134  * \param token a pointer to a place to store a token to be passed to fax_session_new() later
1135  *
1136  * This function reserves a fax session for use later. If the selected fax
1137  * technology does not support reserving sessions a session will still be
1138  * returned but token will not be set.
1139  *
1140  * \note The reference returned by this function does not get consumed by
1141  * fax_session_new() and must always be dereferenced separately.
1142  *
1143  * \return NULL or an uninitialized and possibly reserved session
1144  */
1145 static struct ast_fax_session *fax_session_reserve(struct ast_fax_session_details *details, struct ast_fax_tech_token **token)
1146 {
1147  struct ast_fax_session *s;
1148  struct fax_module *faxmod;
1149 
1150  if (!(s = ao2_alloc(sizeof(*s), destroy_session))) {
1151  return NULL;
1152  }
1153 
1154  s->state = AST_FAX_STATE_INACTIVE;
1155  s->details = details;
1156  ao2_ref(s->details, 1);
1157 
1158  /* locate a FAX technology module that can handle said requirements
1159  * Note: the requirements have not yet been finalized as T.38
1160  * negotiation has not yet occured. */
1162  AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
1163  if ((faxmod->tech->caps & details->caps) != details->caps) {
1164  continue;
1165  }
1166  if (!ast_module_running_ref(faxmod->tech->module)) {
1167  continue;
1168  }
1169  ast_debug(4, "Reserving a FAX session from '%s'.\n", faxmod->tech->description);
1170  s->tech = faxmod->tech;
1171  break;
1172  }
1174 
1175  if (!faxmod) {
1176  char caps[128] = "";
1177  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)));
1178  ao2_ref(s, -1);
1179  return NULL;
1180  }
1181 
1182  if (!s->tech->reserve_session) {
1183  ast_debug(1, "Selected FAX technology module (%s) does not support reserving sessions.\n", s->tech->description);
1184  return s;
1185  }
1186 
1187  if (!(*token = s->tech->reserve_session(s))) {
1188  ao2_ref(s, -1);
1189  return NULL;
1190  }
1191 
1192  s->state = AST_FAX_STATE_RESERVED;
1193  ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, 1);
1194 
1195  return s;
1196 }
1197 
1198 /*! \brief create a FAX session
1199  *
1200  * \param details details for the session
1201  * \param chan the channel the session will run on
1202  * \param reserved a reserved session to base this session on (can be NULL)
1203  * \param token the token for a reserved session (can be NULL)
1204  *
1205  * Create a new fax session based on the given details structure.
1206  *
1207  * \note The given token is always consumed (by tech->new_session() or by
1208  * fax_session_release() in the event of a failure). The given reference to a
1209  * reserved session is never consumed and must be dereferenced separately from
1210  * the reference returned by this function.
1211  *
1212  * \return NULL or a reference to a new fax session
1213  */
1214 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)
1215 {
1216  struct ast_fax_session *s = NULL;
1217  struct fax_module *faxmod;
1218 
1219  if (reserved) {
1220  s = reserved;
1221  ao2_ref(reserved, +1);
1222  ao2_unlink(faxregistry.container, reserved);
1223 
1224  /* NOTE: we don't consume the reference to the reserved
1225  * session. The session returned from fax_session_new() is a
1226  * new reference and must be derefed in addition to the
1227  * reserved session.
1228  */
1229 
1230  if (s->state == AST_FAX_STATE_RESERVED) {
1231  ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
1232  s->state = AST_FAX_STATE_UNINITIALIZED;
1233  }
1234  }
1235 
1236  if (!s && !(s = ao2_alloc(sizeof(*s), destroy_session))) {
1237  return NULL;
1238  }
1239 
1240  ast_atomic_fetchadd_int(&faxregistry.active_sessions, 1);
1241  s->state = AST_FAX_STATE_UNINITIALIZED;
1242 
1243  if (details->option.debug && (details->caps & AST_FAX_TECH_AUDIO)) {
1244  if (!(s->debug_info = ast_calloc(1, sizeof(*(s->debug_info))))) {
1245  fax_session_release(s, token);
1246  ao2_ref(s, -1);
1247  return NULL;
1248  }
1249  if (!(s->debug_info->dsp = ast_dsp_new())) {
1250  ast_free(s->debug_info);
1251  s->debug_info = NULL;
1252  fax_session_release(s, token);
1253  ao2_ref(s, -1);
1254  return NULL;
1255  }
1256  ast_dsp_set_threshold(s->debug_info->dsp, 128);
1257  }
1258 
1259  if (!(s->channame = ast_strdup(ast_channel_name(chan)))) {
1260  fax_session_release(s, token);
1261  ao2_ref(s, -1);
1262  return NULL;
1263  }
1264 
1265  if (!(s->chan_uniqueid = ast_strdup(ast_channel_uniqueid(chan)))) {
1266  fax_session_release(s, token);
1267  ao2_ref(s, -1);
1268  return NULL;
1269  }
1270 
1271  s->chan = chan;
1272  if (!s->details) {
1273  s->details = details;
1274  ao2_ref(s->details, 1);
1275  }
1276 
1277  details->id = s->id = ast_atomic_fetchadd_int(&faxregistry.nextsessionname, 1);
1278 
1279  if (!token) {
1280  /* locate a FAX technology module that can handle said requirements */
1282  AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
1283  if ((faxmod->tech->caps & details->caps) != details->caps) {
1284  continue;
1285  }
1286  if (!ast_module_running_ref(faxmod->tech->module)) {
1287  continue;
1288  }
1289  ast_debug(4, "Requesting a new FAX session from '%s'.\n", faxmod->tech->description);
1290  if (reserved) {
1291  /* Balance module ref from reserved session */
1292  ast_module_unref(reserved->tech->module);
1293  }
1294  s->tech = faxmod->tech;
1295  break;
1296  }
1298 
1299  if (!faxmod) {
1300  char caps[128] = "";
1301  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)));
1302  ao2_ref(s, -1);
1303  return NULL;
1304  }
1305  }
1306 
1307  if (!(s->tech_pvt = s->tech->new_session(s, token))) {
1308  ast_log(LOG_ERROR, "FAX session failed to initialize.\n");
1309  ao2_ref(s, -1);
1310  return NULL;
1311  }
1312  /* link the session to the session container */
1313  if (!(ao2_link(faxregistry.container, s))) {
1314  ast_log(LOG_ERROR, "failed to add FAX session '%u' to container.\n", s->id);
1315  ao2_ref(s, -1);
1316  return NULL;
1317  }
1318  ast_debug(4, "channel '%s' using FAX session '%u'\n", s->channame, s->id);
1319 
1320  return s;
1321 }
1322 
1323 /*!
1324  * \internal
1325  * \brief Convert the filenames in a fax session into a JSON array
1326  * \retval NULL on error
1327  * \retval A \ref ast_json array on success
1328  */
1329 static struct ast_json *generate_filenames_json(struct ast_fax_session_details *details)
1330 {
1331  RAII_VAR(struct ast_json *, json_array, ast_json_array_create(), ast_json_unref);
1332  struct ast_fax_document *doc;
1333 
1334  if (!details || !json_array) {
1335  return NULL;
1336  }
1337 
1338  /* don't process empty lists */
1339  if (AST_LIST_EMPTY(&details->documents)) {
1340  return NULL;
1341  }
1342 
1343  AST_LIST_TRAVERSE(&details->documents, doc, next) {
1344  struct ast_json *entry = ast_json_string_create(doc->filename);
1345  if (!entry) {
1346  return NULL;
1347  }
1348  if (ast_json_array_append(json_array, entry)) {
1349  return NULL;
1350  }
1351  }
1352 
1353  ast_json_ref(json_array);
1354  return json_array;
1355 }
1356 
1357 /*!
1358  * \brief Generate a string of filenames using the given prefix and separator.
1359  * \param details the fax session details
1360  * \param prefix the prefix to each filename
1361  * \param separator the separator between filenames
1362  *
1363  * This function generates a string of filenames from the given details
1364  * structure and using the given prefix and separator.
1365  *
1366  * \retval NULL there was an error generating the string
1367  * \return the string generated string
1368  */
1369 static char *generate_filenames_string(struct ast_fax_session_details *details, char *prefix, char *separator)
1370 {
1371  char *filenames, *c;
1372  size_t size = 0;
1373  int first = 1;
1374  struct ast_fax_document *doc;
1375 
1376  /* don't process empty lists */
1377  if (AST_LIST_EMPTY(&details->documents)) {
1378  return ast_strdup("");
1379  }
1380 
1381  /* Calculate the total length of all of the file names */
1382  AST_LIST_TRAVERSE(&details->documents, doc, next) {
1383  size += strlen(separator) + strlen(prefix) + strlen(doc->filename);
1384  }
1385  size += 1; /* add space for the terminating null */
1386 
1387  if (!(filenames = ast_malloc(size))) {
1388  return NULL;
1389  }
1390  c = filenames;
1391 
1392  ast_build_string(&c, &size, "%s%s", prefix, AST_LIST_FIRST(&details->documents)->filename);
1393  AST_LIST_TRAVERSE(&details->documents, doc, next) {
1394  if (first) {
1395  first = 0;
1396  continue;
1397  }
1398 
1399  ast_build_string(&c, &size, "%s%s%s", separator, prefix, doc->filename);
1400  }
1401 
1402  return filenames;
1403 }
1404 
1405 /*! \brief send a FAX status manager event */
1406 static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details, const char *status)
1407 {
1408  RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1409  RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
1410  struct ast_json *json_filenames = NULL;
1411 
1412  if (!details->option.statusevents) {
1413  return 0;
1414  }
1415 
1416  json_filenames = generate_filenames_json(details);
1417  if (!json_filenames) {
1418  return -1;
1419  }
1420 
1421  json_object = ast_json_pack("{s: s, s: s, s: s, s: s, s: o}",
1422  "type", "status",
1423  "operation", (details->caps & AST_FAX_TECH_GATEWAY)
1424  ? "gateway"
1425  : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
1426  "status", status,
1427  "local_station_id", AST_JSON_UTF8_VALIDATE(details->localstationid),
1428  "filenames", json_filenames);
1429  if (!json_object) {
1430  return -1;
1431  }
1432 
1433  {
1434  SCOPED_CHANNELLOCK(lock, chan);
1435 
1436  message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), ast_channel_fax_type(), json_object);
1437  if (!message) {
1438  return -1;
1439  }
1441  }
1442  return 0;
1443 }
1444 
1445 /*! \brief Set fax related channel variables. */
1446 static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
1447 {
1448  char buf[10];
1449 
1450  pbx_builtin_setvar_helper(chan, "FAXSTATUS", S_OR(details->result, NULL));
1451  pbx_builtin_setvar_helper(chan, "FAXERROR", S_OR(details->error, NULL));
1452  pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", S_OR(details->resultstr, NULL));
1453  pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", AST_JSON_UTF8_VALIDATE(details->remotestationid));
1454  pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", AST_JSON_UTF8_VALIDATE(details->localstationid));
1455  pbx_builtin_setvar_helper(chan, "FAXBITRATE", S_OR(details->transfer_rate, NULL));
1456  pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", S_OR(details->resolution, NULL));
1457 
1458  if (details->is_t38_negotiated) {
1459  pbx_builtin_setvar_helper(chan, "FAXMODE", "T38");
1460  } else {
1461  pbx_builtin_setvar_helper(chan, "FAXMODE", "audio");
1462  }
1463 
1464  snprintf(buf, sizeof(buf), "%u", details->pages_transferred);
1465  pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
1466 }
1467 
1468 #define GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason) \
1469  do { \
1470  if (ast_strlen_zero(fax->details->result)) \
1471  ast_string_field_set(fax->details, result, "FAILED"); \
1472  if (ast_strlen_zero(fax->details->resultstr)) \
1473  ast_string_field_set(fax->details, resultstr, reason); \
1474  if (ast_strlen_zero(fax->details->error)) \
1475  ast_string_field_set(fax->details, error, errorstr); \
1476  set_channel_variables(chan, fax->details); \
1477  } while (0)
1478 
1479 #define GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason) \
1480  do { \
1481  GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason); \
1482  } while (0)
1483 
1484 #define GENERIC_FAX_EXEC_ERROR(fax, chan, errorstr, reason) \
1485  do { \
1486  ast_log(LOG_ERROR, "channel '%s' FAX session '%u' failure, reason: '%s' (%s)\n", ast_channel_name(chan), fax->id, reason, errorstr); \
1487  GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason); \
1488  } while (0)
1489 
1490 static int set_fax_t38_caps(struct ast_channel *chan, struct ast_fax_session_details *details)
1491 {
1492  switch (ast_channel_get_t38_state(chan)) {
1493  case T38_STATE_UNKNOWN:
1494  details->caps |= AST_FAX_TECH_T38;
1495  break;
1496  case T38_STATE_REJECTED:
1497  case T38_STATE_UNAVAILABLE:
1498  details->caps |= AST_FAX_TECH_AUDIO;
1499  break;
1500  case T38_STATE_NEGOTIATED:
1501  /* already in T.38 mode? This should not happen. */
1502  case T38_STATE_NEGOTIATING: {
1503  /* the other end already sent us a T.38 reinvite, so we need to prod the channel
1504  * driver into resending their parameters to us if it supports doing so... if
1505  * not, we can't proceed, because we can't create a proper reply without them.
1506  * if it does work, the channel driver will send an AST_CONTROL_T38_PARAMETERS
1507  * with a request of AST_T38_REQUEST_NEGOTIATE, which will be read by the function
1508  * that gets called after this one completes
1509  */
1511  if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters)) != AST_T38_REQUEST_PARMS) {
1512  ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", ast_channel_name(chan));
1513  return -1;
1514  }
1515  details->caps |= AST_FAX_TECH_T38;
1516  break;
1517  }
1518  default:
1519  ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", ast_channel_name(chan));
1520  return -1;
1521  }
1522 
1523  return 0;
1524 }
1525 
1526 static int disable_t38(struct ast_channel *chan)
1527 {
1528  int timeout_ms;
1529  struct ast_frame *frame = NULL;
1531  struct timeval start;
1532  int ms;
1533 
1534  ast_debug(1, "Shutting down T.38 on %s\n", ast_channel_name(chan));
1535  if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0) {
1536  ast_debug(1, "error while disabling T.38 on channel '%s'\n", ast_channel_name(chan));
1537  return -1;
1538  }
1539 
1540  /* wait up to five seconds for negotiation to complete */
1541  timeout_ms = 5000;
1542  start = ast_tvnow();
1543  while ((ms = ast_remaining_ms(start, timeout_ms))) {
1544  ms = ast_waitfor(chan, ms);
1545 
1546  if (ms == 0) {
1547  break;
1548  }
1549  if (ms < 0) {
1550  ast_debug(1, "error while disabling T.38 on channel '%s'\n", ast_channel_name(chan));
1551  return -1;
1552  }
1553 
1554  if (!(frame = ast_read(chan))) {
1555  return -1;
1556  }
1557  if ((frame->frametype == AST_FRAME_CONTROL) &&
1559  (frame->datalen == sizeof(t38_parameters))) {
1560  struct ast_control_t38_parameters *parameters = frame->data.ptr;
1561 
1562  switch (parameters->request_response) {
1563  case AST_T38_TERMINATED:
1564  ast_debug(1, "Shut down T.38 on %s\n", ast_channel_name(chan));
1565  break;
1566  case AST_T38_REFUSED:
1567  ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", ast_channel_name(chan));
1568  ast_frfree(frame);
1569  return -1;
1570  default:
1571  ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", ast_channel_name(chan));
1572  ast_frfree(frame);
1573  return -1;
1574  }
1575  ast_frfree(frame);
1576  break;
1577  }
1578  ast_frfree(frame);
1579  }
1580 
1581  if (ms == 0) { /* all done, nothing happened */
1582  ast_debug(1, "channel '%s' timed-out during T.38 shutdown\n", ast_channel_name(chan));
1583  }
1584 
1585  return 0;
1586 }
1587 
1588 /*! \brief this is the generic FAX session handling function */
1589 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)
1590 {
1591  int ms;
1592  int timeout = RES_FAX_TIMEOUT;
1593  int chancount;
1594  unsigned int expected_frametype = -1;
1595  struct ast_frame_subclass expected_framesubclass = { .integer = 0, };
1596  unsigned int t38negotiated = (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED);
1597  struct ast_control_t38_parameters t38_parameters;
1598  const char *tempvar;
1599  struct ast_fax_session *fax = NULL;
1600  struct ast_frame *frame = NULL;
1601  struct ast_channel *c = chan;
1602  RAII_VAR(struct ast_format *, orig_write_format, NULL, ao2_cleanup);
1603  RAII_VAR(struct ast_format *, orig_read_format, NULL, ao2_cleanup);
1604  int remaining_time;
1605  struct timeval start;
1606 
1607  chancount = 1;
1608 
1609  /* Make sure one or the other is set to avoid race condition */
1610  if (t38negotiated) {
1611  details->caps |= AST_FAX_TECH_T38;
1612  } else {
1613  details->caps |= AST_FAX_TECH_AUDIO;
1614  }
1615 
1616  /* create the FAX session */
1617  if (!(fax = fax_session_new(details, chan, reserved, token))) {
1618  ast_log(LOG_ERROR, "Can't create a FAX session, FAX attempt failed.\n");
1619  report_fax_status(chan, details, "No Available Resource");
1620  return -1;
1621  }
1622 
1623  ast_channel_lock(chan);
1624  /* update session details */
1625  if (ast_strlen_zero(details->headerinfo) && (tempvar = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO"))) {
1626  ast_string_field_set(details, headerinfo, tempvar);
1627  }
1628  if (ast_strlen_zero(details->localstationid)) {
1629  tempvar = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
1630  ast_string_field_set(details, localstationid, tempvar ? tempvar : "unknown");
1631  }
1632  ast_channel_unlock(chan);
1633 
1634  report_fax_status(chan, details, "Allocating Resources");
1635 
1636  if (details->caps & AST_FAX_TECH_AUDIO) {
1637  expected_frametype = AST_FRAME_VOICE;
1638  expected_framesubclass.format = ast_format_slin;
1639  orig_write_format = ao2_bump(ast_channel_writeformat(chan));
1640  if (ast_set_write_format(chan, ast_format_slin) < 0) {
1641  ast_log(LOG_ERROR, "channel '%s' failed to set write format to signed linear'.\n", ast_channel_name(chan));
1642  ao2_unlink(faxregistry.container, fax);
1643  ao2_ref(fax, -1);
1644  return -1;
1645  }
1646  orig_read_format = ao2_bump(ast_channel_readformat(chan));
1647  if (ast_set_read_format(chan, ast_format_slin) < 0) {
1648  ast_log(LOG_ERROR, "channel '%s' failed to set read format to signed linear.\n", ast_channel_name(chan));
1649  ao2_unlink(faxregistry.container, fax);
1650  ao2_ref(fax, -1);
1651  return -1;
1652  }
1653  if (fax->smoother) {
1654  ast_smoother_free(fax->smoother);
1655  fax->smoother = NULL;
1656  }
1657  if (!(fax->smoother = ast_smoother_new(320))) {
1658  ast_log(LOG_WARNING, "Channel '%s' FAX session '%u' failed to obtain a smoother.\n", ast_channel_name(chan), fax->id);
1659  }
1660  } else {
1661  expected_frametype = AST_FRAME_MODEM;
1662  expected_framesubclass.integer = AST_MODEM_T38;
1663  }
1664 
1665  if (fax->debug_info) {
1666  fax->debug_info->base_tv = ast_tvnow();
1667  }
1668 
1669  /* reset our result fields just in case the fax tech driver wants to
1670  * set custom error messages */
1671  ast_string_field_set(details, result, "");
1672  ast_string_field_set(details, resultstr, "");
1673  ast_string_field_set(details, error, "");
1674  details->is_t38_negotiated = t38negotiated;
1675  set_channel_variables(chan, details);
1676 
1677  if (fax->tech->start_session(fax) < 0) {
1678  GENERIC_FAX_EXEC_ERROR(fax, chan, "INIT_ERROR", "failed to start FAX session");
1679  }
1680 
1681  report_fax_status(chan, details, "FAX Transmission In Progress");
1682 
1683  ast_debug(5, "channel %s will wait on FAX fd %d\n", ast_channel_name(chan), fax->fd);
1684 
1685  /* handle frames for the session */
1686  remaining_time = timeout;
1687  start = ast_tvnow();
1688  while (remaining_time > 0) {
1689  struct ast_channel *ready_chan;
1690  int ofd, exception;
1691 
1692  ms = 1000;
1693  errno = 0;
1694  ready_chan = ast_waitfor_nandfds(&c, chancount, &fax->fd, 1, &exception, &ofd, &ms);
1695  if (ready_chan) {
1696  if (!(frame = ast_read(chan))) {
1697  /* the channel is probably gone, so lets stop polling on it and let the
1698  * FAX session complete before we exit the application. if needed,
1699  * send the FAX stack silence so the modems can finish their session without
1700  * any problems */
1701  ast_debug(1, "Channel '%s' did not return a frame; probably hung up.\n", ast_channel_name(chan));
1702  GENERIC_FAX_EXEC_SET_VARS(fax, chan, "HANGUP", "remote channel hungup");
1703  c = NULL;
1704  chancount = 0;
1705  remaining_time = ast_remaining_ms(start, timeout);
1706  fax->tech->cancel_session(fax);
1707  if (fax->tech->generate_silence) {
1708  fax->tech->generate_silence(fax);
1709  }
1710  continue;
1711  }
1712 
1713  if ((frame->frametype == AST_FRAME_CONTROL) &&
1715  (frame->datalen == sizeof(t38_parameters))) {
1716  unsigned int was_t38 = t38negotiated;
1717  struct ast_control_t38_parameters *parameters = frame->data.ptr;
1718 
1719  switch (parameters->request_response) {
1721  /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1722  * do T.38 as well
1723  */
1724  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1725  if (details->caps & AST_FAX_TECH_T38) {
1726  details->is_t38_negotiated = 1;
1727  t38_parameters.request_response = AST_T38_NEGOTIATED;
1728  } else {
1729  t38_parameters.request_response = AST_T38_REFUSED;
1730  }
1731  ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1732  break;
1733  case AST_T38_NEGOTIATED:
1734  t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1735  t38negotiated = 1;
1736  details->is_t38_negotiated = 1;
1737  break;
1738  default:
1739  break;
1740  }
1741  if (t38negotiated && !was_t38) {
1742  if (fax->tech->switch_to_t38(fax)) {
1743  GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "T.38 switch failed");
1744  break;
1745  }
1746  details->caps &= ~AST_FAX_TECH_AUDIO;
1747  expected_frametype = AST_FRAME_MODEM;
1748  expected_framesubclass.integer = AST_MODEM_T38;
1749  if (fax->smoother) {
1750  ast_smoother_free(fax->smoother);
1751  fax->smoother = NULL;
1752  }
1753 
1754  report_fax_status(chan, details, "T.38 Negotiated");
1755 
1756  ast_verb(3, "Channel '%s' switched to T.38 FAX session '%u'.\n", ast_channel_name(chan), fax->id);
1757  }
1758  } else if ((frame->frametype == expected_frametype) && (expected_framesubclass.integer == frame->subclass.integer) &&
1759  ((!frame->subclass.format && !expected_framesubclass.format) ||
1760  (frame->subclass.format && expected_framesubclass.format &&
1761  (ast_format_cmp(frame->subclass.format, expected_framesubclass.format) != AST_FORMAT_CMP_NOT_EQUAL)))) {
1762  struct ast_frame *f;
1763 
1764  if (fax->smoother) {
1765  /* push the frame into a smoother */
1766  if (ast_smoother_feed(fax->smoother, frame) < 0) {
1767  GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "Failed to feed the smoother");
1768  }
1769  while ((f = ast_smoother_read(fax->smoother)) && (f->data.ptr)) {
1770  if (fax->debug_info) {
1771  debug_check_frame_for_silence(fax, 1, f);
1772  }
1773  /* write the frame to the FAX stack */
1774  fax->tech->write(fax, f);
1775  fax->frames_received++;
1776  if (f != frame) {
1777  ast_frfree(f);
1778  }
1779  }
1780  } else {
1781  /* write the frame to the FAX stack */
1782  fax->tech->write(fax, frame);
1783  fax->frames_received++;
1784  }
1785  start = ast_tvnow();
1786  }
1787  ast_frfree(frame);
1788  } else if (ofd == fax->fd) {
1789  /* read a frame from the FAX stack and send it out the channel.
1790  * the FAX stack will return a NULL if the FAX session has already completed */
1791  if (!(frame = fax->tech->read(fax))) {
1792  break;
1793  }
1794 
1795  if (fax->debug_info && (frame->frametype == AST_FRAME_VOICE)) {
1796  debug_check_frame_for_silence(fax, 0, frame);
1797  }
1798 
1799  ast_write(chan, frame);
1800  fax->frames_sent++;
1801  ast_frfree(frame);
1802  start = ast_tvnow();
1803  } else {
1804  if (ms && (ofd < 0)) {
1805  if ((errno == 0) || (errno == EINTR)) {
1806  remaining_time = ast_remaining_ms(start, timeout);
1807  if (remaining_time <= 0)
1808  GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
1809  continue;
1810  } else {
1811  ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(chan));
1812  GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "error polling data");
1813  break;
1814  }
1815  } else {
1816  /* nothing happened */
1817  remaining_time = ast_remaining_ms(start, timeout);
1818  if (remaining_time <= 0) {
1819  GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
1820  break;
1821  }
1822  }
1823  }
1824  }
1825  ast_debug(3, "channel '%s' - event loop stopped { timeout: %d, remaining_time: %d }\n", ast_channel_name(chan), timeout, remaining_time);
1826 
1827  set_channel_variables(chan, details);
1828 
1829  ast_atomic_fetchadd_int(&faxregistry.fax_complete, 1);
1830  if (!strcasecmp(details->result, "FAILED")) {
1831  ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
1832  }
1833 
1834  if (fax) {
1835  ao2_unlink(faxregistry.container, fax);
1836  ao2_ref(fax, -1);
1837  }
1838 
1839  /* if the channel is still alive, and we changed its read/write formats,
1840  * restore them now
1841  */
1842  if (chancount) {
1843  if (orig_read_format) {
1844  ast_set_read_format(chan, orig_read_format);
1845  }
1846  if (orig_write_format) {
1847  ast_set_write_format(chan, orig_write_format);
1848  }
1849  }
1850 
1851  /* return the chancount so the calling function can determine if the channel hungup during this FAX session or not */
1852  return chancount;
1853 }
1854 
1855 static int receivefax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
1856 {
1857  int timeout_ms;
1858  struct ast_frame *frame = NULL;
1859  struct ast_control_t38_parameters t38_parameters;
1860  struct timeval start;
1861  int ms;
1862 
1863  /* don't send any audio if we've already received a T.38 reinvite */
1865  /* generate 3 seconds of CED */
1866  if (ast_playtones_start(chan, 1024, "!2100/3000", 1)) {
1867  ast_log(LOG_ERROR, "error generating CED tone on %s\n", ast_channel_name(chan));
1868  return -1;
1869  }
1870 
1871  timeout_ms = 3000;
1872  start = ast_tvnow();
1873  while ((ms = ast_remaining_ms(start, timeout_ms))) {
1874  ms = ast_waitfor(chan, ms);
1875 
1876  if (ms < 0) {
1877  ast_log(LOG_ERROR, "error while generating CED tone on %s\n", ast_channel_name(chan));
1878  ast_playtones_stop(chan);
1879  return -1;
1880  }
1881 
1882  if (ms == 0) { /* all done, nothing happened */
1883  break;
1884  }
1885 
1886  if (!(frame = ast_read(chan))) {
1887  ast_log(LOG_ERROR, "error reading frame while generating CED tone on %s\n", ast_channel_name(chan));
1888  ast_playtones_stop(chan);
1889  return -1;
1890  }
1891 
1892  if ((frame->frametype == AST_FRAME_CONTROL) &&
1894  (frame->datalen == sizeof(t38_parameters))) {
1895  struct ast_control_t38_parameters *parameters = frame->data.ptr;
1896 
1897  switch (parameters->request_response) {
1899  /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1900  * do T.38 as well
1901  */
1902  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1903  t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
1904  ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1905  ast_playtones_stop(chan);
1906  break;
1907  case AST_T38_NEGOTIATED:
1908  ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
1909  t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1910  details->caps &= ~AST_FAX_TECH_AUDIO;
1911  report_fax_status(chan, details, "T.38 Negotiated");
1912  break;
1913  default:
1914  break;
1915  }
1916  }
1917  ast_frfree(frame);
1918  }
1919 
1920  ast_playtones_stop(chan);
1921  }
1922 
1923  /* if T.38 was negotiated, we are done initializing */
1925  return 0;
1926  }
1927 
1928  /* request T.38 */
1929  ast_debug(1, "Negotiating T.38 for receive on %s\n", ast_channel_name(chan));
1930 
1931  /* wait for negotiation to complete */
1932  timeout_ms = details->t38timeout;
1933 
1934  /* set parameters based on the session's parameters */
1935  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1937  if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
1938  return -1;
1939  }
1940 
1941  start = ast_tvnow();
1942  while ((ms = ast_remaining_ms(start, timeout_ms))) {
1943  int break_loop = 0;
1944 
1945  ms = ast_waitfor(chan, ms);
1946  if (ms < 0) {
1947  ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
1948  return -1;
1949  }
1950  if (ms == 0) { /* all done, nothing happened */
1951  ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(chan));
1952  details->caps &= ~AST_FAX_TECH_T38;
1953  break;
1954  }
1955 
1956  if (!(frame = ast_read(chan))) {
1957  ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
1958  return -1;
1959  }
1960 
1961  if ((frame->frametype == AST_FRAME_CONTROL) &&
1963  (frame->datalen == sizeof(t38_parameters))) {
1964  struct ast_control_t38_parameters *parameters = frame->data.ptr;
1965 
1966  switch (parameters->request_response) {
1968  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1969  t38_parameters.request_response = AST_T38_NEGOTIATED;
1970  ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1971  break;
1972  case AST_T38_NEGOTIATED:
1973  ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
1974  t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1975  details->caps &= ~AST_FAX_TECH_AUDIO;
1976  report_fax_status(chan, details, "T.38 Negotiated");
1977  break_loop = 1;
1978  break;
1979  case AST_T38_REFUSED:
1980  ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(chan));
1981  details->caps &= ~AST_FAX_TECH_T38;
1982  break_loop = 1;
1983  break;
1984  default:
1985  ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(chan));
1986  details->caps &= ~AST_FAX_TECH_T38;
1987  break_loop = 1;
1988  break;
1989  }
1990  }
1991  ast_frfree(frame);
1992  if (break_loop) {
1993  break;
1994  }
1995  }
1996 
1997  /* if T.38 was negotiated, we are done initializing */
1999  return 0;
2000  }
2001 
2002  /* if we made it here, then T.38 failed, check the 'f' flag */
2003  if (details->option.allow_audio != AST_FAX_OPTFLAG_TRUE) {
2004  ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", ast_channel_name(chan));
2005  return -1;
2006  }
2007 
2008  /* ok, audio fallback is allowed */
2009  details->caps |= AST_FAX_TECH_AUDIO;
2010 
2011  return 0;
2012 }
2013 
2014 /*! \brief Report on the final state of a receive fax operation
2015  * \note This will lock the \ref ast_channel
2016  */
2017 static int report_receive_fax_status(struct ast_channel *chan, const char *filename)
2018 {
2019  RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
2020  RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
2021  RAII_VAR(struct ast_json *, json_array, ast_json_array_create(), ast_json_unref);
2022  struct ast_json *json_filename = ast_json_string_create(filename);
2023 
2024  if (!json_array || !json_filename) {
2025  ast_json_unref(json_filename);
2026  return -1;
2027  }
2028  ast_json_array_append(json_array, json_filename);
2029 
2030  {
2031  const char *remote_station_id;
2032  const char *local_station_id;
2033  const char *fax_pages;
2034  const char *fax_resolution;
2035  const char *fax_bitrate;
2036  SCOPED_CHANNELLOCK(lock, chan);
2037 
2038  remote_station_id = AST_JSON_UTF8_VALIDATE(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"));
2039  if (!ast_strlen_zero(remote_station_id)) {
2040  remote_station_id = ast_strdupa(remote_station_id);
2041  }
2042  local_station_id = AST_JSON_UTF8_VALIDATE(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"));
2043  if (!ast_strlen_zero(local_station_id)) {
2044  local_station_id = ast_strdupa(local_station_id);
2045  }
2046  fax_pages = S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), "");
2047  if (!ast_strlen_zero(fax_pages)) {
2048  fax_pages = ast_strdupa(fax_pages);
2049  }
2050  fax_resolution = S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), "");
2051  if (!ast_strlen_zero(fax_resolution)) {
2052  fax_resolution = ast_strdupa(fax_resolution);
2053  }
2054  fax_bitrate = S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), "");
2055  if (!ast_strlen_zero(fax_bitrate)) {
2056  fax_bitrate = ast_strdupa(fax_bitrate);
2057  }
2058 
2059  json_object = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o}",
2060  "type", "receive",
2061  "remote_station_id", S_OR(remote_station_id, ""),
2062  "local_station_id", S_OR(local_station_id, ""),
2063  "fax_pages", S_OR(fax_pages, ""),
2064  "fax_resolution", S_OR(fax_resolution, ""),
2065  "fax_bitrate", S_OR(fax_bitrate, ""),
2066  "filenames", ast_json_ref(json_array));
2067  if (!json_object) {
2068  return -1;
2069  }
2070 
2071  message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), ast_channel_fax_type(), json_object);
2072  if (!message) {
2073  return -1;
2074  }
2076  }
2077  return 0;
2078 }
2079 
2080 /*! \brief initiate a receive FAX session */
2081 static int receivefax_exec(struct ast_channel *chan, const char *data)
2082 {
2083  char *parse, modems[128] = "";
2084  int channel_alive;
2085  RAII_VAR(struct ast_fax_session *, s, NULL, ao2_cleanup);
2086  RAII_VAR(struct ast_fax_session_details *, details, NULL, ao2_cleanup);
2087  struct ast_fax_tech_token *token = NULL;
2088  struct ast_fax_document *doc;
2089  AST_DECLARE_APP_ARGS(args,
2090  AST_APP_ARG(filename);
2091  AST_APP_ARG(options);
2092  );
2093  struct ast_flags opts = { 0, };
2094  enum ast_t38_state t38state;
2095 
2096  /* initialize output channel variables */
2097  pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
2098  pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
2099  pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
2100  pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
2101  pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
2102  pbx_builtin_setvar_helper(chan, "FAXMODE", NULL);
2103 
2104  /* Get a FAX session details structure from the channel's FAX datastore and create one if
2105  * it does not already exist. */
2106  if (!(details = find_or_create_details(chan))) {
2107  pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
2108  pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
2109  ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2110  return -1;
2111  }
2112 
2113  ast_string_field_set(details, result, "FAILED");
2114  ast_string_field_set(details, resultstr, "error starting fax session");
2115  ast_string_field_set(details, error, "INIT_ERROR");
2116  set_channel_variables(chan, details);
2117 
2118  if (details->gateway_id > 0) {
2119  ast_string_field_set(details, resultstr, "can't receive a fax on a channel with a T.38 gateway");
2120  set_channel_variables(chan, details);
2121  ast_log(LOG_ERROR, "executing ReceiveFAX on a channel with a T.38 Gateway is not supported\n");
2122  return -1;
2123  }
2124 
2125  if (details->maxrate < details->minrate) {
2126  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2127  ast_string_field_set(details, resultstr, "maxrate is less than minrate");
2128  set_channel_variables(chan, details);
2129  ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", details->maxrate, details->minrate);
2130  return -1;
2131  }
2132 
2133  if (check_modem_rate(details->modems, details->minrate)) {
2134  ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2135  ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, details->minrate);
2136  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2137  ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
2138  set_channel_variables(chan, details);
2139  return -1;
2140  }
2141 
2142  if (check_modem_rate(details->modems, details->maxrate)) {
2143  ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2144  ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, details->maxrate);
2145  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2146  ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
2147  set_channel_variables(chan, details);
2148  return -1;
2149  }
2150 
2151  if (ast_strlen_zero(data)) {
2152  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2153  ast_string_field_set(details, resultstr, "invalid arguments");
2154  set_channel_variables(chan, details);
2155  ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
2156  return -1;
2157  }
2158  parse = ast_strdupa(data);
2159  AST_STANDARD_APP_ARGS(args, parse);
2160 
2161  if (!ast_strlen_zero(args.options) &&
2162  ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
2163  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2164  ast_string_field_set(details, resultstr, "invalid arguments");
2165  set_channel_variables(chan, details);
2166  return -1;
2167  }
2168  if (ast_strlen_zero(args.filename)) {
2169  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2170  ast_string_field_set(details, resultstr, "invalid arguments");
2171  set_channel_variables(chan, details);
2172  ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
2173  return -1;
2174  }
2175 
2176  /* check for unsupported FAX application options */
2177  if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
2178  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2179  ast_string_field_set(details, resultstr, "invalid arguments");
2180  set_channel_variables(chan, details);
2181  ast_log(LOG_WARNING, "%s does not support polling\n", app_receivefax);
2182  return -1;
2183  }
2184 
2185  ast_atomic_fetchadd_int(&faxregistry.fax_rx_attempts, 1);
2186 
2187  pbx_builtin_setvar_helper(chan, "FAXERROR", "Channel Problems");
2188  pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "Error before FAX transmission started.");
2189 
2190  if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(args.filename) + 1))) {
2191  ast_string_field_set(details, error, "MEMORY_ERROR");
2192  ast_string_field_set(details, resultstr, "error allocating memory");
2193  set_channel_variables(chan, details);
2194  ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2195  return -1;
2196  }
2197 
2198  strcpy(doc->filename, args.filename);
2199  AST_LIST_INSERT_TAIL(&details->documents, doc, next);
2200 
2201  ast_verb(3, "Channel '%s' receiving FAX '%s'\n", ast_channel_name(chan), args.filename);
2202 
2203  details->caps = AST_FAX_TECH_RECEIVE;
2204  details->option.send_ced = AST_FAX_OPTFLAG_TRUE;
2205 
2206  /* check for debug */
2207  if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
2208  details->option.debug = AST_FAX_OPTFLAG_TRUE;
2209  }
2210 
2211  /* check for request for status events */
2212  if (ast_test_flag(&opts, OPT_STATUS)) {
2213  details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
2214  }
2215 
2216  t38state = ast_channel_get_t38_state(chan);
2217  if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
2218  ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
2219  ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2220  details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
2221  }
2222 
2223  if (!(s = fax_session_reserve(details, &token))) {
2224  ast_string_field_set(details, resultstr, "error reserving fax session");
2225  set_channel_variables(chan, details);
2226  ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
2227  return -1;
2228  }
2229 
2230  /* make sure the channel is up */
2231  if (ast_channel_state(chan) != AST_STATE_UP) {
2232  if (ast_answer(chan)) {
2233  ast_string_field_set(details, resultstr, "error answering channel");
2234  set_channel_variables(chan, details);
2235  ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", ast_channel_name(chan));
2236  fax_session_release(s, token);
2237  return -1;
2238  }
2239  }
2240 
2241  if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2242  if (set_fax_t38_caps(chan, details)) {
2243  ast_string_field_set(details, error, "T38_NEG_ERROR");
2244  ast_string_field_set(details, resultstr, "error negotiating T.38");
2245  set_channel_variables(chan, details);
2246  fax_session_release(s, token);
2247  return -1;
2248  }
2249  } else {
2250  details->caps |= AST_FAX_TECH_AUDIO;
2251  }
2252 
2253  if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
2254  if (receivefax_t38_init(chan, details)) {
2255  ast_string_field_set(details, error, "T38_NEG_ERROR");
2256  ast_string_field_set(details, resultstr, "error negotiating T.38");
2257  set_channel_variables(chan, details);
2258  fax_session_release(s, token);
2259  ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", ast_channel_name(chan));
2260  return -1;
2261  }
2262  }
2263 
2264  if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
2265  ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
2266  }
2267 
2269  if (disable_t38(chan)) {
2270  ast_debug(1, "error disabling T.38 mode on %s\n", ast_channel_name(chan));
2271  }
2272  }
2273 
2274  if (report_receive_fax_status(chan, args.filename)) {
2275  ast_log(AST_LOG_ERROR, "Error publishing ReceiveFAX status message\n");
2276  }
2277 
2278  /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
2279  return (!channel_alive) ? -1 : 0;
2280 }
2281 
2282 static int sendfax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
2283 {
2284  int timeout_ms;
2285  struct ast_frame *frame = NULL;
2286  struct ast_control_t38_parameters t38_parameters;
2287  struct timeval start;
2288  int ms;
2289 
2290  /* send CNG tone while listening for the receiver to initiate a switch
2291  * to T.38 mode; if they do, stop sending the CNG tone and proceed with
2292  * the switch.
2293  *
2294  * 10500 is enough time for 3 CNG tones
2295  */
2296  timeout_ms = 10500;
2297 
2298  /* don't send any audio if we've already received a T.38 reinvite */
2300  if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000", 1)) {
2301  ast_log(LOG_ERROR, "error generating CNG tone on %s\n", ast_channel_name(chan));
2302  return -1;
2303  }
2304  }
2305 
2306  start = ast_tvnow();
2307  while ((ms = ast_remaining_ms(start, timeout_ms))) {
2308  int break_loop = 0;
2309  ms = ast_waitfor(chan, ms);
2310 
2311  if (ms < 0) {
2312  ast_log(LOG_ERROR, "error while generating CNG tone on %s\n", ast_channel_name(chan));
2313  ast_playtones_stop(chan);
2314  return -1;
2315  }
2316 
2317  if (ms == 0) { /* all done, nothing happened */
2318  break;
2319  }
2320 
2321  if (!(frame = ast_read(chan))) {
2322  ast_log(LOG_ERROR, "error reading frame while generating CNG tone on %s\n", ast_channel_name(chan));
2323  ast_playtones_stop(chan);
2324  return -1;
2325  }
2326 
2327  if ((frame->frametype == AST_FRAME_CONTROL) &&
2329  (frame->datalen == sizeof(t38_parameters))) {
2330  struct ast_control_t38_parameters *parameters = frame->data.ptr;
2331 
2332  switch (parameters->request_response) {
2334  /* the other end has requested a switch to T.38, so reply that we are willing, if we can
2335  * do T.38 as well
2336  */
2337  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2338  t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
2339  ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2340  ast_playtones_stop(chan);
2341  break;
2342  case AST_T38_NEGOTIATED:
2343  ast_debug(1, "Negotiated T.38 for send on %s\n", ast_channel_name(chan));
2344  t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2345  details->caps &= ~AST_FAX_TECH_AUDIO;
2346  report_fax_status(chan, details, "T.38 Negotiated");
2347  break_loop = 1;
2348  break;
2349  default:
2350  break;
2351  }
2352  }
2353  ast_frfree(frame);
2354  if (break_loop) {
2355  break;
2356  }
2357  }
2358 
2359  ast_playtones_stop(chan);
2360 
2362  return 0;
2363  }
2364 
2365  /* T.38 negotiation did not happen, initiate a switch if requested */
2366  if (details->option.request_t38 == AST_FAX_OPTFLAG_TRUE) {
2367  ast_debug(1, "Negotiating T.38 for send on %s\n", ast_channel_name(chan));
2368 
2369  /* wait up to five seconds for negotiation to complete */
2370  timeout_ms = 5000;
2371 
2372  /* set parameters based on the session's parameters */
2373  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2375  if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
2376  return -1;
2377  }
2378 
2379  start = ast_tvnow();
2380  while ((ms = ast_remaining_ms(start, timeout_ms))) {
2381  int break_loop = 0;
2382 
2383  ms = ast_waitfor(chan, ms);
2384  if (ms < 0) {
2385  ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
2386  return -1;
2387  }
2388  if (ms == 0) { /* all done, nothing happened */
2389  ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(chan));
2390  details->caps &= ~AST_FAX_TECH_T38;
2391  break;
2392  }
2393 
2394  if (!(frame = ast_read(chan))) {
2395  ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
2396  return -1;
2397  }
2398 
2399  if ((frame->frametype == AST_FRAME_CONTROL) &&
2401  (frame->datalen == sizeof(t38_parameters))) {
2402  struct ast_control_t38_parameters *parameters = frame->data.ptr;
2403 
2404  switch (parameters->request_response) {
2406  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2407  t38_parameters.request_response = AST_T38_NEGOTIATED;
2408  ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2409  break;
2410  case AST_T38_NEGOTIATED:
2411  ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
2412  t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2413  details->caps &= ~AST_FAX_TECH_AUDIO;
2414  report_fax_status(chan, details, "T.38 Negotiated");
2415  break_loop = 1;
2416  break;
2417  case AST_T38_REFUSED:
2418  ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(chan));
2419  details->caps &= ~AST_FAX_TECH_T38;
2420  break_loop = 1;
2421  break;
2422  default:
2423  ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(chan));
2424  details->caps &= ~AST_FAX_TECH_T38;
2425  break_loop = 1;
2426  break;
2427  }
2428  }
2429  ast_frfree(frame);
2430  if (break_loop) {
2431  break;
2432  }
2433  }
2434 
2435  /* if T.38 was negotiated, we are done initializing */
2437  return 0;
2438  }
2439 
2440  /* send one more CNG tone to get audio going again for some
2441  * carriers if we are going to fall back to audio mode */
2442  if (details->option.allow_audio == AST_FAX_OPTFLAG_TRUE) {
2443  if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000", 1)) {
2444  ast_log(LOG_ERROR, "error generating second CNG tone on %s\n", ast_channel_name(chan));
2445  return -1;
2446  }
2447 
2448  timeout_ms = 3500;
2449  start = ast_tvnow();
2450  while ((ms = ast_remaining_ms(start, timeout_ms))) {
2451  int break_loop = 0;
2452 
2453  ms = ast_waitfor(chan, ms);
2454  if (ms < 0) {
2455  ast_log(LOG_ERROR, "error while generating second CNG tone on %s\n", ast_channel_name(chan));
2456  ast_playtones_stop(chan);
2457  return -1;
2458  }
2459  if (ms == 0) { /* all done, nothing happened */
2460  break;
2461  }
2462 
2463  if (!(frame = ast_read(chan))) {
2464  ast_log(LOG_ERROR, "error reading frame while generating second CNG tone on %s\n", ast_channel_name(chan));
2465  ast_playtones_stop(chan);
2466  return -1;
2467  }
2468 
2469  if ((frame->frametype == AST_FRAME_CONTROL) &&
2471  (frame->datalen == sizeof(t38_parameters))) {
2472  struct ast_control_t38_parameters *parameters = frame->data.ptr;
2473 
2474  switch (parameters->request_response) {
2476  /* the other end has requested a switch to T.38, so reply that we are willing, if we can
2477  * do T.38 as well
2478  */
2479  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2480  t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
2481  ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2482  ast_playtones_stop(chan);
2483  break;
2484  case AST_T38_NEGOTIATED:
2485  ast_debug(1, "Negotiated T.38 for send on %s\n", ast_channel_name(chan));
2486  t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2487  details->caps &= ~AST_FAX_TECH_AUDIO;
2488  report_fax_status(chan, details, "T.38 Negotiated");
2489  break_loop = 1;
2490  break;
2491  default:
2492  break;
2493  }
2494  }
2495  ast_frfree(frame);
2496  if (break_loop) {
2497  break;
2498  }
2499  }
2500 
2501  ast_playtones_stop(chan);
2502 
2503  /* if T.38 was negotiated, we are done initializing */
2505  return 0;
2506  }
2507  }
2508  }
2509 
2510  /* if we made it here, then T.38 failed, check the 'f' flag */
2511  if (details->option.allow_audio == AST_FAX_OPTFLAG_FALSE) {
2512  ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", ast_channel_name(chan));
2513  return -1;
2514  }
2515 
2516  /* ok, audio fallback is allowed */
2517  details->caps |= AST_FAX_TECH_AUDIO;
2518 
2519  return 0;
2520 }
2521 
2522 /*!
2523  * \brief Report on the status of a completed fax send attempt
2524  * \note This will lock the \ref ast_channel
2525  */
2526 static int report_send_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details)
2527 {
2528  RAII_VAR(struct ast_json *, json_obj, NULL, ast_json_unref);
2529  RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
2530  struct ast_json *json_filenames;
2531 
2532  json_filenames = generate_filenames_json(details);
2533  if (!json_filenames) {
2534  return -1;
2535  }
2536 
2537  {
2538  const char *remote_station_id;
2539  const char *local_station_id;
2540  const char *fax_pages;
2541  const char *fax_resolution;
2542  const char *fax_bitrate;
2543  SCOPED_CHANNELLOCK(lock, chan);
2544 
2545  remote_station_id = AST_JSON_UTF8_VALIDATE(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"));
2546  if (!ast_strlen_zero(remote_station_id)) {
2547  remote_station_id = ast_strdupa(remote_station_id);
2548  }
2549  local_station_id = AST_JSON_UTF8_VALIDATE(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"));
2550  if (!ast_strlen_zero(local_station_id)) {
2551  local_station_id = ast_strdupa(local_station_id);
2552  }
2553  fax_pages = S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), "");
2554  if (!ast_strlen_zero(fax_pages)) {
2555  fax_pages = ast_strdupa(fax_pages);
2556  }
2557  fax_resolution = S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), "");
2558  if (!ast_strlen_zero(fax_resolution)) {
2559  fax_resolution = ast_strdupa(fax_resolution);
2560  }
2561  fax_bitrate = S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), "");
2562  if (!ast_strlen_zero(fax_bitrate)) {
2563  fax_bitrate = ast_strdupa(fax_bitrate);
2564  }
2565  json_obj = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o}",
2566  "type", "send",
2567  "remote_station_id", S_OR(remote_station_id, ""),
2568  "local_station_id", S_OR(local_station_id, ""),
2569  "fax_pages", S_OR(fax_pages, ""),
2570  "fax_resolution", S_OR(fax_resolution, ""),
2571  "fax_bitrate", S_OR(fax_bitrate, ""),
2572  "filenames", json_filenames);
2573  if (!json_obj) {
2574  return -1;
2575  }
2576 
2577  message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), ast_channel_fax_type(), json_obj);
2578  if (!message) {
2579  return -1;
2580  }
2582  }
2583  return 0;
2584 }
2585 
2586 
2587 
2588 /*! \brief initiate a send FAX session */
2589 static int sendfax_exec(struct ast_channel *chan, const char *data)
2590 {
2591  char *parse, *filenames, *c, modems[128] = "";
2592  int channel_alive, file_count;
2593  RAII_VAR(struct ast_fax_session_details *, details, NULL, ao2_cleanup);
2594  RAII_VAR(struct ast_fax_session *, s, NULL, ao2_cleanup);
2595  struct ast_fax_tech_token *token = NULL;
2596  struct ast_fax_document *doc;
2597  AST_DECLARE_APP_ARGS(args,
2598  AST_APP_ARG(filenames);
2599  AST_APP_ARG(options);
2600  );
2601  struct ast_flags opts = { 0, };
2602  enum ast_t38_state t38state;
2603 
2604  /* initialize output channel variables */
2605  pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
2606  pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
2607  pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
2608  pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
2609  pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
2610  pbx_builtin_setvar_helper(chan, "FAXMODE", NULL);
2611 
2612  /* Get a requirement structure and set it. This structure is used
2613  * to tell the FAX technology module about the higher level FAX session */
2614  if (!(details = find_or_create_details(chan))) {
2615  pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
2616  pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
2617  ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2618  return -1;
2619  }
2620 
2621  ast_string_field_set(details, result, "FAILED");
2622  ast_string_field_set(details, resultstr, "error starting fax session");
2623  ast_string_field_set(details, error, "INIT_ERROR");
2624  set_channel_variables(chan, details);
2625 
2626  if (details->gateway_id > 0) {
2627  ast_string_field_set(details, resultstr, "can't send a fax on a channel with a T.38 gateway");
2628  set_channel_variables(chan, details);
2629  ast_log(LOG_ERROR, "executing SendFAX on a channel with a T.38 Gateway is not supported\n");
2630  return -1;
2631  }
2632 
2633  if (details->maxrate < details->minrate) {
2634  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2635  ast_string_field_set(details, resultstr, "maxrate is less than minrate");
2636  set_channel_variables(chan, details);
2637  ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", details->maxrate, details->minrate);
2638  return -1;
2639  }
2640 
2641  if (check_modem_rate(details->modems, details->minrate)) {
2642  ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2643  ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, details->minrate);
2644  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2645  ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
2646  set_channel_variables(chan, details);
2647  return -1;
2648  }
2649 
2650  if (check_modem_rate(details->modems, details->maxrate)) {
2651  ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2652  ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, details->maxrate);
2653  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2654  ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
2655  set_channel_variables(chan, details);
2656  return -1;
2657  }
2658 
2659  if (ast_strlen_zero(data)) {
2660  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2661  ast_string_field_set(details, resultstr, "invalid arguments");
2662  set_channel_variables(chan, details);
2663  ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]][,options])\n", app_sendfax);
2664  return -1;
2665  }
2666  parse = ast_strdupa(data);
2667  AST_STANDARD_APP_ARGS(args, parse);
2668 
2669 
2670  if (!ast_strlen_zero(args.options) &&
2671  ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
2672  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2673  ast_string_field_set(details, resultstr, "invalid arguments");
2674  set_channel_variables(chan, details);
2675  return -1;
2676  }
2677  if (ast_strlen_zero(args.filenames)) {
2678  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2679  ast_string_field_set(details, resultstr, "invalid arguments");
2680  set_channel_variables(chan, details);
2681  ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]],options])\n", app_sendfax);
2682  return -1;
2683  }
2684 
2685  /* check for unsupported FAX application options */
2686  if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
2687  ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2688  ast_string_field_set(details, resultstr, "invalid arguments");
2689  set_channel_variables(chan, details);
2690  ast_log(LOG_WARNING, "%s does not support polling\n", app_sendfax);
2691  return -1;
2692  }
2693 
2694  ast_atomic_fetchadd_int(&faxregistry.fax_tx_attempts, 1);
2695 
2696  file_count = 0;
2697  filenames = args.filenames;
2698  while ((c = strsep(&filenames, "&"))) {
2699  if (access(c, (F_OK | R_OK)) < 0) {
2700  ast_string_field_set(details, error, "FILE_ERROR");
2701  ast_string_field_set(details, resultstr, "error reading file");
2702  set_channel_variables(chan, details);
2703  ast_log(LOG_ERROR, "access failure. Verify '%s' exists and check permissions.\n", args.filenames);
2704  return -1;
2705  }
2706 
2707  if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(c) + 1))) {
2708  ast_string_field_set(details, error, "MEMORY_ERROR");
2709  ast_string_field_set(details, resultstr, "error allocating memory");
2710  set_channel_variables(chan, details);
2711  ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2712  return -1;
2713  }
2714 
2715  strcpy(doc->filename, c);
2716  AST_LIST_INSERT_TAIL(&details->documents, doc, next);
2717  file_count++;
2718  }
2719 
2720  ast_verb(3, "Channel '%s' sending FAX:\n", ast_channel_name(chan));
2721  AST_LIST_TRAVERSE(&details->documents, doc, next) {
2722  ast_verb(3, " %s\n", doc->filename);
2723  }
2724 
2725  details->caps = AST_FAX_TECH_SEND;
2726 
2727  if (file_count > 1) {
2728  details->caps |= AST_FAX_TECH_MULTI_DOC;
2729  }
2730 
2731  /* check for debug */
2732  if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
2733  details->option.debug = AST_FAX_OPTFLAG_TRUE;
2734  }
2735 
2736  /* check for request for status events */
2737  if (ast_test_flag(&opts, OPT_STATUS)) {
2738  details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
2739  }
2740 
2741  t38state = ast_channel_get_t38_state(chan);
2742  if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
2743  ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
2744  ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2745  details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
2746  }
2747 
2748  if (ast_test_flag(&opts, OPT_REQUEST_T38)) {
2749  details->option.request_t38 = AST_FAX_OPTFLAG_TRUE;
2750  }
2751 
2752  if (!(s = fax_session_reserve(details, &token))) {
2753  ast_string_field_set(details, resultstr, "error reserving fax session");
2754  set_channel_variables(chan, details);
2755  ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
2756  return -1;
2757  }
2758 
2759  /* make sure the channel is up */
2760  if (ast_channel_state(chan) != AST_STATE_UP) {
2761  if (ast_answer(chan)) {
2762  ast_string_field_set(details, resultstr, "error answering channel");
2763  set_channel_variables(chan, details);
2764  ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", ast_channel_name(chan));
2765  fax_session_release(s, token);
2766  return -1;
2767  }
2768  }
2769 
2770  if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2771  if (set_fax_t38_caps(chan, details)) {
2772  ast_string_field_set(details, error, "T38_NEG_ERROR");
2773  ast_string_field_set(details, resultstr, "error negotiating T.38");
2774  set_channel_variables(chan, details);
2775  fax_session_release(s, token);
2776  return -1;
2777  }
2778  } else {
2779  details->caps |= AST_FAX_TECH_AUDIO;
2780  }
2781 
2782  if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
2783  if (sendfax_t38_init(chan, details)) {
2784  ast_string_field_set(details, error, "T38_NEG_ERROR");
2785  ast_string_field_set(details, resultstr, "error negotiating T.38");
2786  set_channel_variables(chan, details);
2787  fax_session_release(s, token);
2788  ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", ast_channel_name(chan));
2789  return -1;
2790  }
2791  } else {
2792  details->option.send_cng = 1;
2793  }
2794 
2795  if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
2796  ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
2797  }
2798 
2800  if (disable_t38(chan)) {
2801  ast_debug(1, "error disabling T.38 mode on %s\n", ast_channel_name(chan));
2802  }
2803  }
2804 
2805  if (!(filenames = generate_filenames_string(details, "FileName: ", "\r\n"))) {
2806  ast_log(LOG_ERROR, "Error generating SendFAX manager event\n");
2807  return (!channel_alive) ? -1 : 0;
2808  }
2809 
2810  /* send out the AMI completion event */
2811  if (report_send_fax_status(chan, details)) {
2812  ast_log(AST_LOG_ERROR, "Error publishing SendFAX status message\n");
2813  }
2814 
2815  /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
2816  return (!channel_alive) ? -1 : 0;
2817 }
2818 
2819 /*! \brief destroy the v21 detection parts of a fax gateway session */
2820 static void destroy_v21_sessions(struct fax_gateway *gateway)
2821 {
2822  if (gateway->chan_v21_session) {
2823  ao2_unlink(faxregistry.container, gateway->chan_v21_session);
2824 
2825  ao2_ref(gateway->chan_v21_session, -1);
2826  gateway->chan_v21_session = NULL;
2827  }
2828 
2829  if (gateway->peer_v21_session) {
2830  ao2_unlink(faxregistry.container, gateway->peer_v21_session);
2831 
2832  ao2_ref(gateway->peer_v21_session, -1);
2833  gateway->peer_v21_session = NULL;
2834  }
2835 }
2836 
2837 /*! \brief destroy a FAX gateway session structure */
2838 static void destroy_gateway(void *data)
2839 {
2840  struct fax_gateway *gateway = data;
2841 
2842  destroy_v21_sessions(gateway);
2843 
2844  if (gateway->s) {
2845  fax_session_release(gateway->s, gateway->token);
2846  gateway->token = NULL;
2847 
2848  ao2_unlink(faxregistry.container, gateway->s);
2849 
2850  ao2_ref(gateway->s, -1);
2851  gateway->s = NULL;
2852  }
2853 
2854  ao2_cleanup(gateway->chan_read_format);
2855  ao2_cleanup(gateway->chan_write_format);
2856  ao2_cleanup(gateway->peer_read_format);
2857  ao2_cleanup(gateway->peer_write_format);
2858 }
2859 
2860 static struct ast_fax_session *fax_v21_session_new (struct ast_channel *chan) {
2861  struct ast_fax_session_details *v21_details;
2862  struct ast_fax_session *v21_session;
2863 
2864  if (!chan || !(v21_details = session_details_new())) {
2865  return NULL;
2866  }
2867 
2868  v21_details->caps = AST_FAX_TECH_V21_DETECT;
2869  v21_session = fax_session_new(v21_details, chan, NULL, NULL);
2870  ao2_ref(v21_details, -1);
2871  return v21_session;
2872 }
2873 
2874 /*! \brief Create a new fax gateway object.
2875  * \param chan the channel the gateway object will be attached to
2876  * \param details the fax session details
2877  * \return NULL or a fax gateway object
2878  */
2879 static struct fax_gateway *fax_gateway_new(struct ast_channel *chan, struct ast_fax_session_details *details)
2880 {
2881  struct fax_gateway *gateway = ao2_alloc(sizeof(*gateway), destroy_gateway);
2882  if (!gateway) {
2883  return NULL;
2884  }
2885 
2886  if (!(gateway->chan_v21_session = fax_v21_session_new(chan))) {
2887  ast_log(LOG_ERROR, "Can't create V21 session on chan %s for T.38 gateway session\n", ast_channel_name(chan));
2888  ao2_ref(gateway, -1);
2889  return NULL;
2890  }
2891 
2892  gateway->framehook = -1;
2893 
2894  details->caps = AST_FAX_TECH_GATEWAY;
2895  if (details->gateway_timeout && !(gateway->s = fax_session_reserve(details, &gateway->token))) {
2896  details->caps &= ~AST_FAX_TECH_GATEWAY;
2897  ast_log(LOG_ERROR, "Can't reserve a FAX session, gateway attempt failed.\n");
2898  ao2_ref(gateway, -1);
2899  return NULL;
2900  }
2901 
2902  return gateway;
2903 }
2904 
2905 /*!
2906  * \brief Create a fax session and start T.30<->T.38 gateway mode
2907  *
2908  * \param gateway a fax gateway object
2909  * \param details fax session details
2910  * \param chan active channel
2911  *
2912  * \pre chan is locked on entry
2913  *
2914  * \return 0 on error 1 on success
2915  */
2916 static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session_details *details, struct ast_channel *chan)
2917 {
2918  struct ast_fax_session *s;
2919  int start_res;
2920 
2921  /* if the fax gateway is already started then do nothing */
2922  if (gateway->s &&
2923  gateway->s->state != AST_FAX_STATE_RESERVED && gateway->s->state != AST_FAX_STATE_INACTIVE) {
2924  return 0;
2925  }
2926 
2927  /* if we start gateway we don't need v21 detection sessions any more */
2928  destroy_v21_sessions(gateway);
2929 
2930  /* create the FAX session */
2931  if (!(s = fax_session_new(details, chan, gateway->s, gateway->token))) {
2932  gateway->token = NULL;
2933  ast_string_field_set(details, result, "FAILED");
2934  ast_string_field_set(details, resultstr, "error starting gateway session");
2935  ast_string_field_set(details, error, "INIT_ERROR");
2936  details->is_t38_negotiated = 0;
2937  set_channel_variables(chan, details);
2938  report_fax_status(chan, details, "No Available Resource");
2939  ast_log(LOG_ERROR, "Can't create a FAX session, gateway attempt failed.\n");
2940  return -1;
2941  }
2942  /* release the reference for the reserved session and replace it with
2943  * the real session */
2944  if (gateway->s) {
2945  ao2_ref(gateway->s, -1);
2946  }
2947  gateway->s = s;
2948  gateway->token = NULL;
2949 
2950  ast_channel_unlock(chan);
2951  start_res = gateway->s->tech->start_session(gateway->s);
2952  ast_channel_lock(chan);
2953  if (start_res < 0) {
2954  ast_string_field_set(details, result, "FAILED");
2955  ast_string_field_set(details, resultstr, "error starting gateway session");
2956  ast_string_field_set(details, error, "INIT_ERROR");
2957  details->is_t38_negotiated = 0;
2958  set_channel_variables(chan, details);
2959  return -1;
2960  }
2961 
2962  gateway->timeout_start.tv_sec = 0;
2963  gateway->timeout_start.tv_usec = 0;
2964 
2965  report_fax_status(chan, details, "FAX Transmission In Progress");
2966 
2967  return 0;
2968 }
2969 
2970 /*! \pre chan is locked on entry */
2971 static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan)
2972 {
2973  struct ast_frame *fp;
2974  struct ast_control_t38_parameters t38_parameters = {
2976  };
2977  struct ast_frame control_frame = {
2978  .src = "res_fax",
2979  .frametype = AST_FRAME_CONTROL,
2980  .datalen = sizeof(t38_parameters),
2982  .data.ptr = &t38_parameters,
2983  };
2984 
2985  struct ast_fax_session_details *details = find_details(chan);
2986 
2987  if (!details) {
2988  ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
2989  ast_framehook_detach(chan, gateway->framehook);
2990  return NULL;
2991  }
2992 
2993  t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2994  ao2_ref(details, -1);
2995 
2996  if (!(fp = ast_frisolate(&control_frame))) {
2997  ast_log(LOG_ERROR, "error generating T.38 request control frame on chan %s for T.38 gateway session\n", ast_channel_name(chan));
2998  return NULL;
2999  }
3000 
3001  gateway->t38_state = T38_STATE_NEGOTIATING;
3002  gateway->timeout_start = ast_tvnow();
3003  details->is_t38_negotiated = 0;
3004  details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
3005 
3006  ast_debug(1, "requesting T.38 for gateway session for %s\n", ast_channel_name(chan));
3007  return fp;
3008 }
3009 
3010 /*! \pre chan is locked on entry */
3011 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)
3012 {
3013  struct ast_channel *other = (active == chan) ? peer : chan;
3014  struct ast_fax_session *active_v21_session = (active == chan) ? gateway->chan_v21_session : gateway->peer_v21_session;
3015 
3016  if (!active_v21_session || gateway->detected_v21) {
3017  return f;
3018  }
3019 
3020  if (active_v21_session->tech->write(active_v21_session, f) == 0 &&
3021  active_v21_session->details->option.v21_detected) {
3022  gateway->detected_v21 = 1;
3023  }
3024 
3025  if (gateway->detected_v21) {
3026  enum ast_t38_state state_other;
3027  enum ast_t38_state state_active;
3028  struct ast_frame *fp;
3029  struct ast_fax_session_details *details;
3030  int negotiate_both = 0;
3031 
3032  /*
3033  * The default behavior is to wait for the active endpoint to initiate negotiation.
3034  * Find out if this has been overridden. If so, instead of waiting have Asterisk
3035  * initiate the negotiation requests out to both endpoints.
3036  */
3037  details = find_or_create_details(active);
3038  if (details) {
3039  negotiate_both = details->negotiate_both;
3040  ao2_ref(details, -1);
3041  } else {
3042  ast_log(LOG_WARNING, "Detect v21 - no session details for channel '%s'\n",
3043  ast_channel_name(chan));
3044  }
3045 
3046  destroy_v21_sessions(gateway);
3047 
3048  ast_channel_unlock(chan);
3049  state_active = ast_channel_get_t38_state(active);
3050  state_other = ast_channel_get_t38_state(other);
3051  ast_channel_lock(chan);
3052 
3053  ast_debug(1, "detected v21 preamble from %s\n", ast_channel_name(active));
3054 
3055  if (state_active == T38_STATE_UNKNOWN || state_other == T38_STATE_UNKNOWN) {
3056  if (!(fp = fax_gateway_request_t38(gateway, chan))) {
3057  return f;
3058  }
3059  /* May be called endpoint is improperly configured to rely on the calling endpoint
3060  * to initiate T.38 re-INVITEs, send T.38 negotiation request to called endpoint */
3061  if (negotiate_both && state_active == T38_STATE_UNKNOWN) {
3062  ast_debug(1, "sending T.38 negotiation request to %s\n", ast_channel_name(active));
3063  if (active == chan) {
3064  ast_channel_unlock(chan);
3065  }
3066  ast_write(active, fp);
3067  if (active == chan) {
3068  ast_channel_lock(chan);
3069  }
3070  }
3071  if (state_other == T38_STATE_UNKNOWN) {
3072  ast_debug(1, "sending T.38 negotiation request to %s\n", ast_channel_name(other));
3073  return fp;
3074  }
3075  } else {
3076  ast_debug(1, "neither %s nor %s support T.38 for T.38 gateway session\n", ast_channel_name(active), ast_channel_name(other));
3077  }
3078  }
3079 
3080  return f;
3081 }
3082 
3083 /*! \pre chan is locked on entry */
3084 static void fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
3085 {
3086  if (active == chan) {
3087  ast_channel_unlock(chan);
3088  ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
3089  ast_channel_lock(chan);
3090  } else {
3091  ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));
3092  }
3093 }
3094 
3095 /*!
3096  * \brief T38 Gateway Negotiate t38 parameters
3097  *
3098  * \param gateway gateway object
3099  * \param chan channel running the gateway
3100  * \param peer channel im bridged too
3101  * \param active channel the frame originated on
3102  * \param f the control frame to process
3103  *
3104  * \pre chan is locked on entry
3105  *
3106  * \return processed control frame or null frame
3107  */
3108 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)
3109 {
3110  struct ast_control_t38_parameters *control_params = f->data.ptr;
3111  struct ast_channel *other = (active == chan) ? peer : chan;
3112  struct ast_fax_session_details *details;
3113  enum ast_t38_state state_other;
3114 
3115  if (f->datalen != sizeof(struct ast_control_t38_parameters)) {
3116  /* invalaid AST_CONTROL_T38_PARAMETERS frame, we can't
3117  * do anything with it, pass it on */
3118  return f;
3119  }
3120 
3121  /* ignore frames from ourselves */
3122  if ((gateway->t38_state == T38_STATE_NEGOTIATED && control_params->request_response == AST_T38_NEGOTIATED)
3123  || (gateway->t38_state == T38_STATE_REJECTED && control_params->request_response == AST_T38_REFUSED)
3124  || (gateway->t38_state == T38_STATE_NEGOTIATING && control_params->request_response == AST_T38_REQUEST_TERMINATE)) {
3125 
3126  return f;
3127  }
3128 
3129  if (!(details = find_details(chan))) {
3130  ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
3131  ast_framehook_detach(chan, gateway->framehook);
3132  return f;
3133  }
3134 
3135  if (control_params->request_response == AST_T38_REQUEST_NEGOTIATE) {
3136  ast_channel_unlock(chan);
3137  state_other = ast_channel_get_t38_state(other);
3138  ast_channel_lock(chan);
3139 
3140  if (state_other == T38_STATE_UNKNOWN) {
3141  /* we detected a request to negotiate T.38 and the
3142  * other channel appears to support T.38, we'll pass
3143  * the request through and only step in if the other
3144  * channel rejects the request */
3145  ast_debug(1, "%s is attempting to negotiate T.38 with %s, we'll see what happens\n", ast_channel_name(active), ast_channel_name(other));
3146  t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
3147  gateway->t38_state = T38_STATE_UNKNOWN;
3148  gateway->timeout_start = ast_tvnow();
3149  details->is_t38_negotiated = 0;
3150  details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
3151  ao2_ref(details, -1);
3152  return f;
3153  } else if (state_other == T38_STATE_UNAVAILABLE || state_other == T38_STATE_REJECTED) {
3154  /* the other channel does not support T.38, we need to
3155  * step in here */
3156  ast_debug(1, "%s is attempting to negotiate T.38 but %s does not support it\n", ast_channel_name(active), ast_channel_name(other));
3157  ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
3158 
3159  t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
3160  t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
3161 
3162  if (fax_gateway_start(gateway, details, chan)) {
3163  ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
3164  gateway->t38_state = T38_STATE_REJECTED;
3165  details->is_t38_negotiated = 0;
3166  control_params->request_response = AST_T38_REFUSED;
3167 
3168  ast_framehook_detach(chan, details->gateway_id);
3169  details->gateway_id = -1;
3170  } else {
3171  gateway->t38_state = T38_STATE_NEGOTIATED;
3172  details->is_t38_negotiated = chan == active;
3173  control_params->request_response = AST_T38_NEGOTIATED;
3174  report_fax_status(chan, details, "T.38 Negotiated");
3175  }
3176 
3177  fax_gateway_indicate_t38(chan, active, control_params);
3178 
3179  ao2_ref(details, -1);
3180  return &ast_null_frame;
3181  } else if (gateway->t38_state == T38_STATE_NEGOTIATING) {
3182  /* we got a request to negotiate T.38 after we already
3183  * sent one to the other party based on v21 preamble
3184  * detection. We'll just pretend we passed this request
3185  * through in the first place. */
3186 
3187  t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
3188  gateway->t38_state = T38_STATE_UNKNOWN;
3189  gateway->timeout_start = ast_tvnow();
3190  details->is_t38_negotiated = 0;
3191  details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
3192 
3193  ast_debug(1, "%s is attempting to negotiate T.38 after we already sent a negotiation request based on v21 preamble detection\n", ast_channel_name(active));
3194  ao2_ref(details, -1);
3195  return &ast_null_frame;
3196  } else if (gateway->t38_state == T38_STATE_NEGOTIATED) {
3197  /* we got a request to negotiate T.38 after we already
3198  * sent one to the other party based on v21 preamble
3199  * detection and received a response. We need to
3200  * respond to this and shut down the gateway. */
3201 
3202  t38_parameters_fax_to_ast(control_params, &details->their_t38_parameters);
3203  ast_framehook_detach(chan, details->gateway_id);
3204  details->gateway_id = -1;
3205 
3206  control_params->request_response = AST_T38_NEGOTIATED;
3207 
3208  fax_gateway_indicate_t38(chan, active, control_params);
3209 
3210  ast_string_field_set(details, result, "SUCCESS");
3211  ast_string_field_set(details, resultstr, "no gateway necessary");
3212  ast_string_field_set(details, error, "NATIVE_T38");
3213  details->is_t38_negotiated = 1;
3214  set_channel_variables(chan, details);
3215 
3216  ast_debug(1, "%s is attempting to negotiate T.38 after we already negotiated T.38 with %s, disabling the gateway\n", ast_channel_name(active), ast_channel_name(other));
3217  ao2_ref(details, -1);
3218  return &ast_null_frame;
3219  } else {
3220  ast_log(LOG_WARNING, "%s is attempting to negotiate T.38 while %s is in an unsupported state\n", ast_channel_name(active), ast_channel_name(other));
3221  ao2_ref(details, -1);
3222  return f;
3223  }
3224  } else if (gateway->t38_state == T38_STATE_NEGOTIATING
3225  && control_params->request_response == AST_T38_REFUSED) {
3226 
3227  ast_debug(1, "unable to negotiate T.38 on %s for fax gateway\n", ast_channel_name(active));
3228  details->is_t38_negotiated = 0;
3229 
3230  /* our request to negotiate T.38 was refused, if the other
3231  * channel supports T.38, they might still reinvite and save
3232  * the day. Otherwise disable the gateway. */
3233  ast_channel_unlock(chan);
3234  state_other = ast_channel_get_t38_state(other);
3235  ast_channel_lock(chan);
3236  if (state_other == T38_STATE_UNKNOWN) {
3237  gateway->t38_state = T38_STATE_UNAVAILABLE;
3238  } else if (state_other != T38_STATE_NEGOTIATING) {
3239  ast_framehook_detach(chan, details->gateway_id);
3240  details->gateway_id = -1;
3241 
3242  ast_string_field_set(details, result, "FAILED");
3243  ast_string_field_set(details, resultstr, "unable to negotiate T.38");
3244  ast_string_field_set(details, error, "T38_NEG_ERROR");
3245  set_channel_variables(chan, details);
3246  }
3247 
3248  ao2_ref(details, -1);
3249  return &ast_null_frame;
3250  } else if (gateway->t38_state == T38_STATE_NEGOTIATING
3251  && control_params->request_response == AST_T38_NEGOTIATED) {
3252 
3253  ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
3254 
3255  t38_parameters_ast_to_fax(&details->their_t38_parameters, control_params);
3256 
3257  if (fax_gateway_start(gateway, details, chan)) {
3258  ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(active), ast_channel_name(other));
3259  gateway->t38_state = T38_STATE_NEGOTIATING;
3260  details->is_t38_negotiated = 0;
3261  control_params->request_response = AST_T38_REQUEST_TERMINATE;
3262 
3263  fax_gateway_indicate_t38(chan, active, control_params);
3264  } else {
3265  gateway->t38_state = T38_STATE_NEGOTIATED;
3266  details->is_t38_negotiated = chan == active;
3267  report_fax_status(chan, details, "T.38 Negotiated");
3268  }
3269 
3270  ao2_ref(details, -1);
3271  return &ast_null_frame;
3272  } else if (control_params->request_response == AST_T38_REFUSED) {
3273  /* the other channel refused the request to negotiate T.38,
3274  * we'll step in here and pretend the request was accepted */
3275 
3276  ast_debug(1, "%s attempted to negotiate T.38 but %s refused the request\n", ast_channel_name(other), ast_channel_name(active));
3277  ast_debug(1, "starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(other), ast_channel_name(active));
3278 
3279  t38_parameters_fax_to_ast(control_params, &details->our_t38_parameters);
3280 
3281  if (fax_gateway_start(gateway, details, chan)) {
3282  ast_log(LOG_ERROR, "error starting T.38 gateway for T.38 channel %s and G.711 channel %s\n", ast_channel_name(other), ast_channel_name(active));
3283  gateway->t38_state = T38_STATE_REJECTED;
3284  details->is_t38_negotiated = 0;
3285  control_params->request_response = AST_T38_REFUSED;
3286 
3287  ast_framehook_detach(chan, details->gateway_id);
3288  details->gateway_id = -1;
3289  } else {
3290  gateway->t38_state = T38_STATE_NEGOTIATED;
3291  details->is_t38_negotiated = chan == other;
3292  control_params->request_response = AST_T38_NEGOTIATED;
3293  }
3294 
3295  ao2_ref(details, -1);
3296  return f;
3297  } else if (control_params->request_response == AST_T38_REQUEST_TERMINATE) {
3298  /* the channel wishes to end our short relationship, we shall
3299  * oblige */
3300 
3301  ast_debug(1, "T.38 channel %s is requesting a shutdown of T.38, disabling the gateway\n", ast_channel_name(active));
3302 
3303  ast_framehook_detach(chan, details->gateway_id);
3304  details->gateway_id = -1;
3305 
3306  gateway->t38_state = T38_STATE_REJECTED;
3307  details->is_t38_negotiated = 0;
3308  control_params->request_response = AST_T38_TERMINATED;
3309 
3310  fax_gateway_indicate_t38(chan, active, control_params);
3311 
3312  ao2_ref(details, -1);
3313  return &ast_null_frame;
3314  } else if (control_params->request_response == AST_T38_NEGOTIATED) {
3315  ast_debug(1, "T.38 successfully negotiated between %s and %s, no gateway necessary\n", ast_channel_name(active), ast_channel_name(other));
3316 
3317  ast_framehook_detach(chan, details->gateway_id);
3318  details->gateway_id = -1;
3319 
3320  ast_string_field_set(details, result, "SUCCESS");
3321  ast_string_field_set(details, resultstr, "no gateway necessary");
3322  ast_string_field_set(details, error, "NATIVE_T38");
3323  details->is_t38_negotiated = 1;
3324  set_channel_variables(chan, details);
3325 
3326  ao2_ref(details, -1);
3327  return f;
3328  } else if (control_params->request_response == AST_T38_TERMINATED) {
3329  ast_debug(1, "T.38 disabled on channel %s\n", ast_channel_name(active));
3330 
3331  ast_framehook_detach(chan, details->gateway_id);
3332  details->gateway_id = -1;
3333 
3334  ao2_ref(details, -1);
3335  return &ast_null_frame;
3336  }
3337 
3338  ao2_ref(details, -1);
3339  return f;
3340 }
3341 
3342 /*! \brief Destroy the gateway data structure when the framehook is detached
3343  * \param data framehook data (gateway data)*/
3344 static void fax_gateway_framehook_destroy(void *data)
3345 {
3346  struct fax_gateway *gateway = data;
3347 
3348  if (gateway->s) {
3349  switch (gateway->s->state) {
3350  case AST_FAX_STATE_INITIALIZED:
3351  case AST_FAX_STATE_OPEN:
3352  case AST_FAX_STATE_ACTIVE:
3353  case AST_FAX_STATE_COMPLETE:
3354  if (gateway->s->tech->cancel_session) {
3355  gateway->s->tech->cancel_session(gateway->s);
3356  }
3357  /* fall through */
3358  default:
3359  break;
3360  }
3361  }
3362 
3363  ao2_ref(gateway, -1);
3364 }
3365 
3366 /*!
3367  * \brief T.30<->T.38 gateway framehook.
3368  *
3369  * Intercept packets on bridged channels and determine if a T.38 gateway is
3370  * required. If a gateway is required, start a gateway and handle T.38
3371  * negotiation if necessary.
3372  *
3373  * \param chan channel running the gateway
3374  * \param f frame to handle may be NULL
3375  * \param event framehook event
3376  * \param data framehook data (struct fax_gateway *)
3377  *
3378  * \pre chan is locked on entry
3379  *
3380  * \return processed frame or NULL when f is NULL or a null frame
3381  */
3382 static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
3383 {
3384  struct fax_gateway *gateway = data;
3385  struct ast_channel *active;
3386  RAII_VAR(struct ast_fax_session_details *, details, NULL, ao2_cleanup);
3387  RAII_VAR(struct ast_channel *, peer, NULL, ao2_cleanup);
3388  RAII_VAR(struct ast_channel *, chan_ref, chan, ao2_cleanup);
3389 
3390  /* Ref bump channel for when we have to unlock it */
3391  ao2_ref(chan_ref, 1);
3392 
3393  if (gateway->s) {
3394  details = gateway->s->details;
3395  ao2_ref(details, 1);
3396  } else {
3397  if (!(details = find_details(chan))) {
3398  ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
3399  ast_framehook_detach(chan, gateway->framehook);
3400  return f;
3401  }
3402  }
3403 
3404  /* restore audio formats when we are detached */
3405  if (event == AST_FRAMEHOOK_EVENT_DETACHED) {
3406  set_channel_variables(chan, details);
3407 
3408  if (gateway->bridged) {
3409  ast_set_read_format(chan, gateway->chan_read_format);
3410  ast_set_write_format(chan, gateway->chan_write_format);
3411 
3412  ast_channel_unlock(chan);
3413  peer = ast_channel_bridge_peer(chan);
3414  if (peer) {
3415  ast_set_read_format(peer, gateway->peer_read_format);
3416  ast_set_write_format(peer, gateway->peer_write_format);
3417  ast_channel_make_compatible(chan, peer);
3418  }
3419  ast_channel_lock(chan);
3420  }
3421  return NULL;
3422  }
3423 
3424  if (!f || (event == AST_FRAMEHOOK_EVENT_ATTACHED)) {
3425  return NULL;
3426  };
3427 
3428  /* this frame was generated by the fax gateway, pass it on */
3429  if (ast_test_flag(f, AST_FAX_FRFLAG_GATEWAY)) {
3430  return f;
3431  }
3432 
3433  /* If we aren't bridged or we don't have a peer, don't do anything */
3434  ast_channel_unlock(chan);
3435  peer = ast_channel_bridge_peer(chan);
3436  ast_channel_lock(chan);
3437  if (!peer) {
3438  return f;
3439  }
3440 
3441  if (!gateway->bridged) {
3442  enum ast_t38_state state_chan;
3443  enum ast_t38_state state_peer;
3444  int chan_is_hungup;
3445  int peer_is_hungup;
3446 
3447  chan_is_hungup = ast_check_hangup(chan);
3448  peer_is_hungup = ast_check_hangup(peer);
3449  /* Don't start a gateway if either channel is hung up */
3450  if (chan_is_hungup || peer_is_hungup) {
3451  return f;
3452  }
3453 
3454  ast_channel_unlock(chan);
3455  state_chan = ast_channel_get_t38_state(chan);
3456  state_peer = ast_channel_get_t38_state(peer);
3457  ast_channel_lock(chan);
3458 
3459  /* don't start a gateway if neither channel can handle T.38 */
3460  if (state_chan == T38_STATE_UNAVAILABLE && state_peer == T38_STATE_UNAVAILABLE) {
3461  ast_debug(1, "not starting gateway for %s and %s; neither channel supports T.38\n", ast_channel_name(chan), ast_channel_name(peer));
3462  ast_framehook_detach(chan, gateway->framehook);
3463  details->gateway_id = -1;
3464 
3465  ast_string_field_set(details, result, "FAILED");
3466  ast_string_field_set(details, resultstr, "neither channel supports T.38");
3467  ast_string_field_set(details, error, "T38_NEG_ERROR");
3468  details->is_t38_negotiated = 0;
3469  set_channel_variables(chan, details);
3470  return f;
3471  }
3472 
3473  if (details->gateway_timeout) {
3474  gateway->timeout_start = ast_tvnow();
3475  }
3476 
3477  ast_channel_unlock(chan);
3478  ast_channel_lock_both(chan, peer);
3479 
3480  /* we are bridged, change r/w formats to SLIN for v21 preamble
3481  * detection and T.30 */
3482  ao2_replace(gateway->chan_read_format, ast_channel_readformat(chan));
3483  ao2_replace(gateway->chan_write_format, ast_channel_writeformat(chan));
3484 
3485  ao2_replace(gateway->peer_read_format, ast_channel_readformat(peer));
3486  ao2_replace(gateway->peer_write_format, ast_channel_writeformat(peer));
3487 
3490 
3493 
3494  ast_channel_unlock(peer);
3495 
3496  gateway->bridged = 1;
3497  if (!(gateway->peer_v21_session = fax_v21_session_new(peer))) {
3498  ast_log(LOG_ERROR, "Can't create V21 session on chan %s for T.38 gateway session\n", ast_channel_name(peer));
3499  ast_framehook_detach(chan, gateway->framehook);
3500  return f;
3501  }
3502  }
3503 
3504  if (gateway->bridged && !ast_tvzero(gateway->timeout_start)) {
3505  if (ast_tvdiff_ms(ast_tvnow(), gateway->timeout_start) > details->gateway_timeout) {
3506  ast_debug(1, "no fax activity between %s and %s after %d ms, disabling gateway\n", ast_channel_name(chan), ast_channel_name(peer), details->gateway_timeout);
3507  ast_framehook_detach(chan, gateway->framehook);
3508  details->gateway_id = -1;
3509 
3510  ast_string_field_set(details, result, "FAILED");
3511  ast_string_field_build(details, resultstr, "no fax activity after %d ms", details->gateway_timeout);
3512  ast_string_field_set(details, error, "TIMEOUT");
3513  details->is_t38_negotiated = 0;
3514  set_channel_variables(chan, details);
3515  return f;
3516  }
3517  }
3518 
3519  /* only handle VOICE, MODEM, and CONTROL frames*/
3520  switch (f->frametype) {
3521  case AST_FRAME_VOICE:
3525  return f;
3526  }
3527  break;
3528  case AST_FRAME_MODEM:
3529  if (f->subclass.integer == AST_MODEM_T38) {
3530  break;
3531  }
3532  return f;
3533  case AST_FRAME_CONTROL:
3535  break;
3536  }
3537  return f;
3538  default:
3539  return f;
3540  }
3541 
3542  /* detect the active channel */
3543  switch (event) {
3545  active = peer;
3546  break;
3548  active = chan;
3549  break;
3550  default:
3551  ast_log(LOG_WARNING, "unhandled framehook event %u\n", event);
3552  return f;
3553  }
3554 
3555  /* handle control frames */
3557  return fax_gateway_detect_t38(gateway, chan, peer, active, f);
3558  }
3559 
3560  if (!gateway->detected_v21 && gateway->t38_state == T38_STATE_UNAVAILABLE && f->frametype == AST_FRAME_VOICE) {
3561  /* not in gateway mode and have not detected v21 yet, listen
3562  * for v21 */
3563  return fax_gateway_detect_v21(gateway, chan, peer, active, f);
3564  }
3565 
3566  /* in gateway mode, gateway some packets */
3567  if (gateway->t38_state == T38_STATE_NEGOTIATED) {
3568  struct ast_trans_pvt *readtrans;
3569 
3570  if (!gateway->s || !gateway->s->tech_pvt) {
3571  ast_log(LOG_ERROR, "no FAX session on chan %s for T.38 gateway session, odd", ast_channel_name(chan));
3572  return f;
3573  }
3574 
3575  /* framehooks are called in __ast_read() before frame format
3576  * translation is done, so we need to translate here */
3578  && (readtrans = ast_channel_readtrans(active))) {
3579  if ((f = ast_translate(readtrans, f, event == AST_FRAMEHOOK_EVENT_WRITE ? 0 : 1)) == NULL) {
3580  f = &ast_null_frame;
3581  return f;
3582  }
3583  /* XXX we ignore the return value here, perhaps we should
3584  * disable the gateway if a write fails. I am not sure how a
3585  * write would fail, or even if a failure would be fatal so for
3586  * now we'll just ignore the return value. */
3587  gateway->s->tech->write(gateway->s, f);
3588  ast_frfree(f);
3589  } else {
3590  gateway->s->tech->write(gateway->s, f);
3591  }
3592 
3593  f = &ast_null_frame;
3594  return f;
3595  }
3596 
3597  /* force silence on the line if T.38 negotiation might be taking place */
3598  if (gateway->t38_state != T38_STATE_UNAVAILABLE && gateway->t38_state != T38_STATE_REJECTED) {
3599  if (f->frametype == AST_FRAME_VOICE &&
3601  short silence_buf[f->samples];
3602  struct ast_frame silence_frame = {
3604  .subclass.format = ast_format_slin,
3605  .data.ptr = silence_buf,
3606  .samples = f->samples,
3607  .datalen = sizeof(silence_buf),
3608  };
3609  memset(silence_buf, 0, sizeof(silence_buf));
3610  return ast_frisolate(&silence_frame);
3611  } else {
3612  return &ast_null_frame;
3613  }
3614  }
3615 
3616  return f;
3617 }
3618 
3619 /*! \brief Attach a gateway framehook object to a channel.
3620  * \param chan the channel to attach to
3621  * \param details fax session details
3622  * \return the framehook id of the attached framehook or -1 on error
3623  * \retval -1 error
3624  */
3625 static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details)
3626 {
3627  struct fax_gateway *gateway;
3628  struct ast_framehook_interface fr_hook = {
3629  .version = AST_FRAMEHOOK_INTERFACE_VERSION,
3630  .event_cb = fax_gateway_framehook,
3631  .destroy_cb = fax_gateway_framehook_destroy,
3632  .disable_inheritance = 1, /* Masquerade inheritance is handled through the datastore fixup */
3633  };
3634 
3635  if (global_fax_debug) {
3636  details->option.debug = AST_FAX_OPTFLAG_TRUE;
3637  }
3638 
3639  ast_string_field_set(details, result, "SUCCESS");
3640  ast_string_field_set(details, resultstr, "gateway operation started successfully");
3641  ast_string_field_set(details, error, "NO_ERROR");
3642  set_channel_variables(chan, details);
3643 
3644  /* set up the frame hook*/
3645  gateway = fax_gateway_new(chan, details);
3646  if (!gateway) {
3647  ast_string_field_set(details, result, "FAILED");
3648  ast_string_field_set(details, resultstr, "error initializing gateway session");
3649  ast_string_field_set(details, error, "INIT_ERROR");
3650  details->is_t38_negotiated = 0;
3651  set_channel_variables(chan, details);
3652  report_fax_status(chan, details, "No Available Resource");
3653  return -1;
3654  }
3655 
3656  fr_hook.data = gateway;
3657  ast_channel_lock(chan);
3658  gateway->framehook = ast_framehook_attach(chan, &fr_hook);
3659  ast_channel_unlock(chan);
3660 
3661  if (gateway->framehook < 0) {
3662  ao2_ref(gateway, -1);
3663  ast_string_field_set(details, result, "FAILED");
3664  ast_string_field_set(details, resultstr, "error attaching gateway to channel");
3665  ast_string_field_set(details, error, "INIT_ERROR");
3666  details->is_t38_negotiated = 0;
3667  set_channel_variables(chan, details);
3668  return -1;
3669  }
3670 
3671  return gateway->framehook;
3672 }
3673 
3674 /*! \brief destroy a FAX detect structure */
3675 static void destroy_faxdetect(void *data)
3676 {
3677  struct fax_detect *faxdetect = data;
3678 
3679  if (faxdetect->dsp) {
3680  ast_dsp_free(faxdetect->dsp);
3681  faxdetect->dsp = NULL;
3682  }
3683  ao2_cleanup(faxdetect->details);
3684  ao2_cleanup(faxdetect->orig_format);
3685 }
3686 
3687 /*! \brief Create a new fax detect object.
3688  * \param chan the channel attaching to
3689  * \param timeout in ms to remove framehook in this time if not zero
3690  * \param flags required options
3691  * \return NULL or a fax gateway object
3692  */
3693 static struct fax_detect *fax_detect_new(struct ast_channel *chan, int timeout, int flags)
3694 {
3695  struct fax_detect *faxdetect = ao2_alloc(sizeof(*faxdetect), destroy_faxdetect);
3696  if (!faxdetect) {
3697  return NULL;
3698  }
3699 
3700  faxdetect->flags = flags;
3701 
3702  if (timeout) {
3703  faxdetect->timeout_start = ast_tvnow();
3704  } else {
3705  faxdetect->timeout_start.tv_sec = 0;
3706  faxdetect->timeout_start.tv_usec = 0;
3707  }
3708 
3709  if (faxdetect->flags & FAX_DETECT_MODE_CNG) {
3710  faxdetect->dsp = ast_dsp_new();
3711  if (!faxdetect->dsp) {
3712  ao2_ref(faxdetect, -1);
3713  return NULL;
3714  }
3715  ast_dsp_set_features(faxdetect->dsp, DSP_FEATURE_FAX_DETECT);
3716  ast_dsp_set_faxmode(faxdetect->dsp, DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_SQUELCH);
3717  } else {
3718  faxdetect->dsp = NULL;
3719  }
3720 
3721  return faxdetect;
3722 }
3723 
3724 /*! \brief Deref the faxdetect data structure when the faxdetect framehook is detached
3725  * \param data framehook data (faxdetect data)*/
3726 static void fax_detect_framehook_destroy(void *data)
3727 {
3728  struct fax_detect *faxdetect = data;
3729 
3730  ao2_ref(faxdetect, -1);
3731 }
3732 
3733 /*! \brief Fax Detect Framehook
3734  *
3735  * Listen for fax tones in audio path and enable jumping to a extension when detected.
3736  *
3737  * \param chan channel
3738  * \param f frame to handle may be NULL
3739  * \param event framehook event
3740  * \param data framehook data (struct fax_detect *)
3741  *
3742  * \return processed frame or NULL when f is NULL or a null frame
3743  */
3744 static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
3745 {
3746  struct fax_detect *faxdetect = data;
3747  struct ast_fax_session_details *details;
3748  struct ast_control_t38_parameters *control_params;
3749  RAII_VAR(struct ast_channel *, peer, NULL, ao2_cleanup);
3750  RAII_VAR(struct ast_channel *, chan_ref, chan, ao2_cleanup);
3751  int result = 0;
3752 
3753  /* Ref bump the channel for when we have to unlock it */
3754  ao2_ref(chan, 1);
3755 
3756  details = faxdetect->details;
3757 
3758  switch (event) {
3760  /* Setup format for DSP on ATTACH*/
3761  ao2_replace(faxdetect->orig_format, ast_channel_readformat(chan));
3762 
3763  if ((ast_format_cmp(ast_channel_readformat(chan), ast_format_slin) != AST_FORMAT_CMP_EQUAL) &&
3764  (ast_format_cmp(ast_channel_readformat(chan), ast_format_alaw) != AST_FORMAT_CMP_EQUAL) &&
3765  (ast_format_cmp(ast_channel_readformat(chan), ast_format_ulaw) != AST_FORMAT_CMP_EQUAL)) {
3766  if (ast_set_read_format(chan, ast_format_slin)) {
3767  ast_framehook_detach(chan, details->faxdetect_id);
3768  details->faxdetect_id = -1;
3769  return f;
3770  }
3771  }
3772 
3773  return NULL;
3775  /* restore audio formats when we are detached */
3776  ast_set_read_format(chan, faxdetect->orig_format);
3777  ast_channel_unlock(chan);
3778  peer = ast_channel_bridge_peer(chan);
3779  if (peer) {
3780  ast_channel_make_compatible(chan, peer);
3781  }
3782  ast_channel_lock(chan);
3783  return NULL;
3785  if (f) {
3786  break;
3787  }
3788  default:
3789  return f;
3790  };
3791 
3792  if (details->faxdetect_id < 0) {
3793  return f;
3794  }
3795 
3796  if (!ast_tvzero(faxdetect->timeout_start)
3797  && ast_tvdiff_ms(ast_tvnow(), faxdetect->timeout_start) > details->faxdetect_timeout) {
3798  ast_debug(1, "FAXOPT(faxdetect) timeout on %s\n", ast_channel_name(chan));
3799  ast_framehook_detach(chan, details->faxdetect_id);
3800  details->faxdetect_id = -1;
3801  return f;
3802  }
3803 
3804  /* only handle VOICE and CONTROL frames*/
3805  switch (f->frametype) {
3806  case AST_FRAME_VOICE:
3807  /* we have no DSP this means we not detecting CNG */
3808  if (!faxdetect->dsp) {
3809  return f;
3810  }
3811  /* We can only process some formats*/
3815  return f;
3816  }
3817  break;
3818  case AST_FRAME_CONTROL:
3820  (faxdetect->flags & FAX_DETECT_MODE_T38)) {
3821  break;
3822  }
3823  return f;
3824  default:
3825  return f;
3826  }
3827 
3828  if (f->frametype == AST_FRAME_VOICE) {
3829  f = ast_dsp_process(chan, faxdetect->dsp, f);
3830  if (f->frametype == AST_FRAME_DTMF) {
3831  result = f->subclass.integer;
3832  }
3833  } else if ((f->frametype == AST_FRAME_CONTROL) && (f->datalen == sizeof(struct ast_control_t38_parameters))) {
3834  control_params = f->data.ptr;
3835  switch (control_params->request_response) {
3836  case AST_T38_NEGOTIATED:
3838  result = 't';
3839  break;
3840  default:
3841  break;
3842  }
3843  }
3844 
3845  if (result) {
3846  const char *target_context;
3847 
3848  switch (result) {
3849  case 'f':
3850  case 't':
3851  target_context = ast_channel_context(chan);
3852 
3853  ast_channel_unlock(chan);
3854  ast_frfree(f);
3855  f = &ast_null_frame;
3856  if (ast_exists_extension(chan, target_context, "fax", 1,
3857  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
3858  ast_verb(2, "Redirecting '%s' to fax extension due to %s detection\n",
3859  ast_channel_name(chan), (result == 'f') ? "CNG" : "T38");
3860  pbx_builtin_setvar_helper(chan, "FAXEXTEN", ast_channel_exten(chan));
3861  if (ast_async_goto(chan, target_context, "fax", 1)) {
3862  ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(chan), target_context);
3863  }
3864  } else {
3865  ast_log(LOG_NOTICE, "FAX %s detected but no fax extension in context (%s)\n",
3866  (result == 'f') ? "CNG" : "T38", target_context);
3867  }
3868  ast_channel_lock(chan);
3869 
3870  ast_framehook_detach(chan, details->faxdetect_id);
3871  details->faxdetect_id = -1;
3872  break;
3873  default:
3874  break;
3875  }
3876  }
3877 
3878  return f;
3879 }
3880 
3881 /*! \brief Attach a faxdetect framehook object to a channel.
3882  * \param chan the channel to attach to
3883  * \param timeout in ms to remove framehook in this time if not zero
3884  * \return the faxdetect structure or NULL on error
3885  * \param flags required options
3886  * \retval -1 error
3887  */
3888 static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags)
3889 {
3890  struct fax_detect *faxdetect;
3891  struct ast_fax_session_details *details;
3892  struct ast_framehook_interface fr_hook = {
3893  .version = AST_FRAMEHOOK_INTERFACE_VERSION,
3894  .event_cb = fax_detect_framehook,
3895  .destroy_cb = fax_detect_framehook_destroy,
3896  };
3897 
3898  if (!(details = find_or_create_details(chan))) {
3899  ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
3900  return -1;
3901  }
3902 
3903  /* set up the frame hook*/
3904  faxdetect = fax_detect_new(chan, timeout, flags);
3905  if (!faxdetect) {
3906  ao2_ref(details, -1);
3907  return -1;
3908  }
3909 
3910  fr_hook.data = faxdetect;
3911  faxdetect->details = details;
3912  ast_channel_lock(chan);
3913  details->faxdetect_id = ast_framehook_attach(chan, &fr_hook);
3914  details->faxdetect_timeout = timeout;
3915  details->faxdetect_flags = flags;
3916  ast_channel_unlock(chan);
3917 
3918  if (details->faxdetect_id < 0) {
3919  ao2_ref(faxdetect, -1);
3920  }
3921 
3922  return details->faxdetect_id;
3923 }
3924 
3925 /*! \brief hash callback for ao2 */
3926 static int session_hash_cb(const void *obj, const int flags)
3927 {
3928  const struct ast_fax_session *s = obj;
3929 
3930  return s->id;
3931 }
3932 
3933 /*! \brief compare callback for ao2 */
3934 static int session_cmp_cb(void *obj, void *arg, int flags)
3935 {
3936  struct ast_fax_session *lhs = obj, *rhs = arg;
3937 
3938  return (lhs->id == rhs->id) ? CMP_MATCH | CMP_STOP : 0;
3939 }
3940 
3941 /*! \brief fax session tab completion */
3943 {
3944  int tklen;
3945  int wordnum = 0;
3946  char *name = NULL;
3947  struct ao2_iterator i;
3948  struct ast_fax_session *s;
3949  char tbuf[5];
3950 
3951  if (a->pos != 3) {
3952  return NULL;
3953  }
3954 
3955  tklen = strlen(a->word);
3956  i = ao2_iterator_init(faxregistry.container, 0);
3957  while ((s = ao2_iterator_next(&i))) {
3958  snprintf(tbuf, sizeof(tbuf), "%u", s->id);
3959  if (!strncasecmp(a->word, tbuf, tklen) && ++wordnum > a->n) {
3960  name = ast_strdup(tbuf);
3961  ao2_ref(s, -1);
3962  break;
3963  }
3964  ao2_ref(s, -1);
3965  }
3967  return name;
3968 }
3969 
3970 static char *cli_fax_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3971 {
3972  struct fax_module *fax;
3973 
3974  switch(cmd) {
3975  case CLI_INIT:
3976  e->command = "fax show version";
3977  e->usage =
3978  "Usage: fax show version\n"
3979  " Show versions of FAX For Asterisk components.\n";
3980  return NULL;
3981  case CLI_GENERATE:
3982  return NULL;
3983  }
3984 
3985  if (a->argc != 3) {
3986  return CLI_SHOWUSAGE;
3987  }
3988 
3989  ast_cli(a->fd, "FAX For Asterisk Components:\n");
3990  ast_cli(a->fd, "\tApplications: %s\n", ast_get_version());
3992  AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
3993  ast_cli(a->fd, "\t%s: %s\n", fax->tech->description, fax->tech->version);
3994  }
3996  ast_cli(a->fd, "\n");
3997 
3998  return CLI_SUCCESS;
3999 }
4000 
4001 /*! \brief enable FAX debugging */
4002 static char *cli_fax_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4003 {
4004  int flag;
4005  const char *what;
4006 
4007  switch (cmd) {
4008  case CLI_INIT:
4009  e->command = "fax set debug {on|off}";
4010  e->usage =
4011  "Usage: fax set debug { on | off }\n"
4012  " Enable/Disable FAX debugging on new FAX sessions. The basic FAX debugging will result in\n"
4013  " additional events sent to manager sessions with 'call' class permissions. When\n"
4014  " verbosity is greater than '5' events will be displayed to the console and audio versus\n"
4015  " energy analysis will be performed and displayed to the console.\n";
4016  return NULL;
4017  case CLI_GENERATE:
4018  return NULL;
4019  }
4020 
4021  what = a->argv[e->args-1]; /* guaranteed to exist */
4022  if (!strcasecmp(what, "on")) {
4023  flag = 1;
4024  } else if (!strcasecmp(what, "off")) {
4025  flag = 0;
4026  } else {
4027  return CLI_SHOWUSAGE;
4028  }
4029 
4030  global_fax_debug = flag;
4031  ast_cli(a->fd, "\n\nFAX Debug %s\n\n", (flag) ? "Enabled" : "Disabled");
4032 
4033  return CLI_SUCCESS;
4034 }
4035 
4036 /*! \brief display registered FAX capabilities */
4037 static char *cli_fax_show_capabilities(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4038 {
4039  struct fax_module *fax;
4040  unsigned int num_modules = 0;
4041 
4042  switch (cmd) {
4043  case CLI_INIT:
4044  e->command = "fax show capabilities";
4045  e->usage =
4046  "Usage: fax show capabilities\n"
4047  " Shows the capabilities of the registered FAX technology modules\n";
4048  return NULL;
4049  case CLI_GENERATE:
4050  return NULL;
4051  }
4052 
4053  ast_cli(a->fd, "\n\nRegistered FAX Technology Modules:\n\n");
4055  AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
4056  ast_cli(a->fd, "%-15s : %s\n%-15s : %s\n%-15s : ", "Type", fax->tech->type, "Description", fax->tech->description, "Capabilities");
4057  fax->tech->cli_show_capabilities(a->fd);
4058  num_modules++;
4059  }
4061  ast_cli(a->fd, "%u registered modules\n\n", num_modules);
4062 
4063  return CLI_SUCCESS;
4064 }
4065 
4066 /*! \brief display global defaults and settings */
4067 static char *cli_fax_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4068 {
4069  struct fax_module *fax;
4070  char modems[128] = "";
4071  struct fax_options options;
4072 
4073  switch (cmd) {
4074  case CLI_INIT:
4075  e->command = "fax show settings";
4076  e->usage =
4077  "Usage: fax show settings\n"
4078  " Show the global settings and defaults of both the FAX core and technology modules\n";
4079  return NULL;
4080  case CLI_GENERATE:
4081  return NULL;
4082  }
4083 
4084  get_general_options(&options);
4085 
4086  ast_cli(a->fd, "FAX For Asterisk Settings:\n");
4087  ast_cli(a->fd, "\tECM: %s\n", options.ecm ? "Enabled" : "Disabled");
4088  ast_cli(a->fd, "\tStatus Events: %s\n", options.statusevents ? "On" : "Off");
4089  ast_cli(a->fd, "\tMinimum Bit Rate: %u\n", options.minrate);
4090  ast_cli(a->fd, "\tMaximum Bit Rate: %u\n", options.maxrate);
4091  ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
4092  ast_cli(a->fd, "\tModem Modulations Allowed: %s\n", modems);
4093  ast_cli(a->fd, "\tT.38 Negotiation Timeout: %u\n", options.t38timeout);
4094  ast_cli(a->fd, "\n\nFAX Technology Modules:\n\n");
4096  AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
4097  ast_cli(a->fd, "%s (%s) Settings:\n", fax->tech->type, fax->tech->description);
4098  fax->tech->cli_show_settings(a->fd);
4099  }
4101 
4102  return CLI_SUCCESS;
4103 }
4104 
4105 /*! \brief display details of a specified fax session */
4106 static char *cli_fax_show_session(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4107 {
4108  struct ast_fax_session *s, tmp;
4109 
4110  switch (cmd) {
4111  case CLI_INIT:
4112  e->command = "fax show session";
4113  e->usage =
4114  "Usage: fax show session <session number>\n"
4115  " Shows status of the named FAX session\n";
4116  return NULL;
4117  case CLI_GENERATE:
4118  return fax_session_tab_complete(a);
4119  }
4120 
4121  if (a->argc != 4) {
4122  return CLI_SHOWUSAGE;
4123  }
4124 
4125  if (sscanf(a->argv[3], "%u", &tmp.id) != 1) {
4126  ast_log(LOG_ERROR, "invalid session id: '%s'\n", a->argv[3]);
4127  return RESULT_SUCCESS;
4128  }
4129 
4130  ast_cli(a->fd, "\nFAX Session Details:\n--------------------\n\n");
4131  s = ao2_find(faxregistry.container, &tmp, OBJ_POINTER);
4132  if (s) {
4133  ast_cli(a->fd, "%-22s : %s\n", "channel", s->channame);
4134  s->tech->cli_show_session(s, a->fd);
4135  ao2_ref(s, -1);
4136  }
4137  ast_cli(a->fd, "\n\n");
4138 
4139  return CLI_SUCCESS;
4140 }
4141 
4142 static int manager_fax_session(struct mansession *s, const struct message *m)
4143 {
4144  const char *action_id = astman_get_header(m, "ActionID");
4145  const char *session_number = astman_get_header(m, "SessionNumber");
4146  char id_text[256] = "";
4147  struct ast_fax_session *session;
4149 
4150  if (sscanf(session_number, "%30u", &find_session.id) != 1) {
4151  astman_send_error(s, m, "Invalid session ID");
4152  return 0;
4153  }
4154 
4155  session = ao2_find(faxregistry.container, &find_session, OBJ_POINTER);
4156  if (!session) {
4157  astman_send_error(s, m, "Session not found");
4158  return 0;
4159  }
4160 
4161  if (!session->tech->manager_fax_session) {
4162  astman_send_error(s, m, "Fax technology doesn't provide a handler for FAXSession");
4163  ao2_ref(session, -1);
4164  return 0;
4165  }
4166 
4167  if (!ast_strlen_zero(action_id)) {
4168  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", action_id);
4169  }
4170 
4171  astman_send_ack(s, m, "FAXSession event will follow");
4172 
4173  session->tech->manager_fax_session(s, id_text, session);
4174  ao2_ref(session, -1);
4175 
4176  return 0;
4177 }
4178 
4179 /*! \brief display fax stats */
4180 static char *cli_fax_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4181 {
4182  struct fax_module *fax;
4183 
4184  switch (cmd) {
4185  case CLI_INIT:
4186  e->command = "fax show stats";
4187  e->usage =
4188  "Usage: fax show stats\n"
4189  " Shows a statistical summary of FAX transmissions\n";
4190  return NULL;
4191  case CLI_GENERATE:
4192  return NULL;
4193  }
4194 
4195  ast_cli(a->fd, "\nFAX Statistics:\n---------------\n\n");
4196  ast_cli(a->fd, "%-20.20s : %d\n", "Current Sessions", faxregistry.active_sessions);
4197  ast_cli(a->fd, "%-20.20s : %d\n", "Reserved Sessions", faxregistry.reserved_sessions);
4198  ast_cli(a->fd, "%-20.20s : %d\n", "Transmit Attempts", faxregistry.fax_tx_attempts);
4199  ast_cli(a->fd, "%-20.20s : %d\n", "Receive Attempts", faxregistry.fax_rx_attempts);
4200  ast_cli(a->fd, "%-20.20s : %d\n", "Completed FAXes", faxregistry.fax_complete);
4201  ast_cli(a->fd, "%-20.20s : %d\n", "Failed FAXes", faxregistry.fax_failures);
4203  AST_RWLIST_TRAVERSE(&faxmodules, fax, list) {
4204  fax->tech->cli_show_stats(a->fd);
4205  }
4207  ast_cli(a->fd, "\n\n");
4208 
4209  return CLI_SUCCESS;
4210 }
4211 
4212 static int manager_fax_stats(struct mansession *s, const struct message *m)
4213 {
4214  const char *action_id = astman_get_header(m, "ActionID");
4215 
4216  char id_text[256] = "";
4217 
4218  astman_send_ack(s, m, "FAXStats event will follow");
4219 
4220  if (!ast_strlen_zero(action_id)) {
4221  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", action_id);
4222  }
4223 
4224  astman_append(s, "Event: FAXStats\r\n"
4225  "%s"
4226  "CurrentSessions: %d\r\n"
4227  "ReservedSessions: %d\r\n"
4228  "TransmitAttempts: %d\r\n"
4229  "ReceiveAttempts: %d\r\n"
4230  "CompletedFAXes: %d\r\n"
4231  "FailedFAXes: %d\r\n"
4232  "\r\n",
4233  id_text,
4234  faxregistry.active_sessions, faxregistry.reserved_sessions,
4235  faxregistry.fax_tx_attempts, faxregistry.fax_rx_attempts,
4236  faxregistry.fax_complete, faxregistry.fax_failures);
4237 
4238  return 0;
4239 }
4240 
4241 static const char *fax_session_type(struct ast_fax_session *s)
4242 {
4243  if (s->details->caps & AST_FAX_TECH_AUDIO) {
4244  return "G.711";
4245  }
4246  if (s->details->caps & AST_FAX_TECH_T38) {
4247  return "T.38";
4248  }
4249 
4250  return "none";
4251 }
4252 
4254 {
4255  if (s->details->caps & AST_FAX_TECH_GATEWAY) {
4256  return "gateway";
4257  }
4258  if (s->details->caps & AST_FAX_TECH_SEND) {
4259  return "send";
4260  }
4261  if (s->details->caps & AST_FAX_TECH_RECEIVE) {
4262  return "receive";
4263  }
4264  if (s->details->caps & AST_FAX_TECH_V21_DETECT) {
4265  return "V.21";
4266  }
4267 
4268  return "none";
4269 }
4270 
4271 /*! \brief display fax sessions */
4272 static char *cli_fax_show_sessions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
4273 {
4274  struct ast_fax_session *s;
4275  struct ao2_iterator i;
4276  int session_count;
4277  char *filenames;
4278 
4279  switch (cmd) {
4280  case CLI_INIT:
4281  e->command = "fax show sessions";
4282  e->usage =
4283  "Usage: fax show sessions\n"
4284  " Shows the current FAX sessions\n";
4285  return NULL;
4286  case CLI_GENERATE:
4287  return NULL;
4288  }
4289 
4290  ast_cli(a->fd, "\nCurrent FAX Sessions:\n\n");
4291  ast_cli(a->fd, "%-30.30s %-10.10s %-10.10s %-5.5s %-10.10s %-15.15s %-30.30s\n",
4292  "Channel", "Tech", "FAXID", "Type", "Operation", "State", "File(s)");
4293  i = ao2_iterator_init(faxregistry.container, 0);
4294  while ((s = ao2_iterator_next(&i))) {
4295  ao2_lock(s);
4296 
4297  filenames = generate_filenames_string(s->details, "", ", ");
4298 
4299  ast_cli(a->fd, "%-30.30s %-10.10s %-10u %-5.5s %-10.10s %-15.15s %-30s\n",
4300  s->channame, s->tech->type, s->id,
4301  fax_session_type(s),
4303  ast_fax_state_to_str(s->state), S_OR(filenames, ""));
4304 
4305  ast_free(filenames);
4306  ao2_unlock(s);
4307  ao2_ref(s, -1);
4308  }
4310  session_count = ao2_container_count(faxregistry.container);
4311  ast_cli(a->fd, "\n%d FAX sessions\n\n", session_count);
4312 
4313  return CLI_SUCCESS;
4314 }
4315 
4316 static int manager_fax_sessions_entry(struct mansession *s,
4317  struct ast_fax_session *session, const char *id_text)
4318 {
4319  char *filenames;
4320 
4321  ao2_lock(session);
4322  filenames = generate_filenames_string(session->details, "", ",");
4323 
4324  if (!filenames) {
4325  ast_log(LOG_ERROR, "Error generating Files string");
4326  ao2_unlock(session);
4327  return -1;
4328  }
4329 
4330  astman_append(s, "Event: FAXSessionsEntry\r\n"
4331  "%s" /* ActionID if present */
4332  "Channel: %s\r\n" /* Channel name */
4333  "Technology: %s\r\n" /* Fax session technology */
4334  "SessionNumber: %u\r\n" /* Session ID */
4335  "SessionType: %s\r\n" /* G711 or T38 */
4336  "Operation: %s\r\n"
4337  "State: %s\r\n"
4338  "Files: %s\r\n"
4339  "\r\n",
4340  id_text, session->channame, session->tech->type, session->id,
4341  fax_session_type(session), ast_fax_session_operation_str(session),
4342  ast_fax_state_to_str(session->state), S_OR(filenames, ""));
4343  ast_free(filenames);
4344  ao2_unlock(session);
4345  return 0;
4346 }
4347 
4348 static int manager_fax_sessions(struct mansession *s, const struct message *m)
4349 {
4350  const char *action_id = astman_get_header(m, "ActionID");
4351  char id_text[256];
4352  struct ast_fax_session *session;
4353  struct ao2_iterator iter;
4354  int session_count = 0;
4355 
4356  id_text[0] = '\0';
4357  if (!ast_strlen_zero(action_id)) {
4358  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", action_id);
4359  }
4360 
4361  astman_send_listack(s, m, "FAXSessionsEntry event list will follow", "Start");
4362 
4363  iter = ao2_iterator_init(faxregistry.container, 0);
4364  while ((session = ao2_iterator_next(&iter))) {
4365  if (!manager_fax_sessions_entry(s, session, id_text)) {
4366  session_count++;
4367  }
4368  ao2_ref(session, -1);
4369  }
4370  ao2_iterator_destroy(&iter);
4371 
4372  astman_send_list_complete_start(s, m, "FAXSessionsComplete", session_count);
4373  astman_append(s, "Total: %d\r\n", session_count);
4375 
4376  return 0;
4377 }
4378 
4379 static struct ast_cli_entry fax_cli[] = {
4380  AST_CLI_DEFINE(cli_fax_show_version, "Show versions of FAX For Asterisk components"),
4381  AST_CLI_DEFINE(cli_fax_set_debug, "Enable/Disable FAX debugging on new FAX sessions"),
4382  AST_CLI_DEFINE(cli_fax_show_capabilities, "Show the capabilities of the registered FAX technology modules"),
4383  AST_CLI_DEFINE(cli_fax_show_settings, "Show the global settings and defaults of both the FAX core and technology modules"),
4384  AST_CLI_DEFINE(cli_fax_show_session, "Show the status of the named FAX sessions"),
4385  AST_CLI_DEFINE(cli_fax_show_sessions, "Show the current FAX sessions"),
4386  AST_CLI_DEFINE(cli_fax_show_stats, "Summarize FAX session history"),
4387 };
4388 
4389 static void set_general_options(const struct fax_options *options)
4390 {
4391  ast_rwlock_wrlock(&options_lock);
4392  general_options = *options;
4393  ast_rwlock_unlock(&options_lock);
4394 }
4395 
4396 static void get_general_options(struct fax_options *options)
4397 {
4398  ast_rwlock_rdlock(&options_lock);
4399  *options = general_options;
4400  ast_rwlock_unlock(&options_lock);
4401 }
4402 
4403 static int set_t38timeout(const char *value, unsigned int *t38timeout)
4404 {
4405  unsigned int timeout;
4406 
4407  if (sscanf(value, "%u", &timeout) != 1) {
4408  ast_log(LOG_ERROR, "Unable to get timeout from '%s'\n", value);
4409  return -1;
4410  } else if (timeout) {
4411  *t38timeout = timeout;
4412  } else {
4413  ast_log(LOG_ERROR, "T.38 negotiation timeout must be non-zero\n");
4414  return -1;
4415  }
4416 
4417  return 0;
4418 }
4419 
4420 /*! \brief configure res_fax */
4421 static int set_config(int reload)
4422 {
4423  struct ast_config *cfg;
4424  struct ast_variable *v;
4425  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
4426  char modems[128] = "";
4427  struct fax_options options;
4428  int res = 0;
4429 
4430  options = default_options;
4431 
4432  /* When we're not reloading, we have to be certain to set the general options
4433  * to the defaults in case config loading goes wrong at some point. On a reload,
4434  * the general options need to stay the same as what they were prior to the
4435  * reload rather than being reset to the defaults.
4436  */
4437  if (!reload) {
4438  set_general_options(&options);
4439  }
4440 
4441  /* read configuration */
4442  if (!(cfg = ast_config_load2(config, "res_fax", config_flags))) {
4443  ast_log(LOG_NOTICE, "Configuration file '%s' not found, %s options.\n",
4444  config, reload ? "not changing" : "using default");
4445  return 0;
4446  }
4447 
4448  if (cfg == CONFIG_STATUS_FILEINVALID) {
4449  ast_log(LOG_NOTICE, "Configuration file '%s' is invalid, %s options.\n",
4450  config, reload ? "not changing" : "using default");
4451  return 0;
4452  }
4453 
4454  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
4455  return 0;
4456  }
4457 
4458  if (reload) {
4459  options = default_options;
4460  }
4461 
4462  /* create configuration */
4463  for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
4464  int rate;
4465 
4466  if (!strcasecmp(v->name, "minrate")) {
4467  ast_debug(3, "reading minrate '%s' from configuration file\n", v->value);
4468  if ((rate = fax_rate_str_to_int(v->value)) == 0) {
4469  res = -1;
4470  goto end;
4471  }
4472  options.minrate = rate;
4473  } else if (!strcasecmp(v->name, "maxrate")) {
4474  ast_debug(3, "reading maxrate '%s' from configuration file\n", v->value);
4475  if ((rate = fax_rate_str_to_int(v->value)) == 0) {
4476  res = -1;
4477  goto end;
4478  }
4479  options.maxrate = rate;
4480  } else if (!strcasecmp(v->name, "statusevents")) {
4481  ast_debug(3, "reading statusevents '%s' from configuration file\n", v->value);
4482  options.statusevents = ast_true(v->value);
4483  } else if (!strcasecmp(v->name, "ecm")) {
4484  ast_debug(3, "reading ecm '%s' from configuration file\n", v->value);
4485  options.ecm = ast_true(v->value);
4486  } else if ((!strcasecmp(v->name, "modem")) || (!strcasecmp(v->name, "modems"))) {
4487  options.modems = 0;
4488  update_modem_bits(&options.modems, v->value);
4489  } else if (!strcasecmp(v->name, "t38timeout")) {
4490  if (set_t38timeout(v->value, &options.t38timeout)) {
4491  res = -1;
4492  goto end;
4493  }
4494  }
4495  }
4496 
4497  if (options.maxrate < options.minrate) {
4498  ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", options.maxrate, options.minrate);
4499  res = -1;
4500  goto end;
4501  }
4502 
4503  if (check_modem_rate(options.modems, options.minrate)) {
4504  ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
4505  ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, options.minrate);
4506  res = -1;
4507  goto end;
4508  }
4509 
4510  if (check_modem_rate(options.modems, options.maxrate)) {
4511  ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
4512  ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, options.maxrate);
4513  res = -1;
4514  goto end;
4515  }
4516 
4517  set_general_options(&options);
4518 
4519 end:
4520  ast_config_destroy(cfg);
4521  return res;
4522 }
4523 
4524 /*! \brief FAXOPT read function returns the contents of a FAX option */
4525 static int acf_faxopt_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
4526 {
4527  struct ast_fax_session_details *details = find_details(chan);
4528  int res = 0;
4529  char *filenames;
4530 
4531  if (!details) {
4532  ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", ast_channel_name(chan), data);
4533  return -1;
4534  }
4535  if (!strcasecmp(data, "ecm")) {
4536  ast_copy_string(buf, details->option.ecm ? "yes" : "no", len);
4537  } else if (!strcasecmp(data, "t38gateway") || !strcasecmp(data, "gateway") ||
4538  !strcasecmp(data, "t38_gateway") || !strcasecmp(data, "faxgateway")) {
4539  ast_copy_string(buf, details->gateway_id != -1 ? "yes" : "no", len);
4540  } else if (!strcasecmp(data, "faxdetect")) {
4541  ast_copy_string(buf, details->faxdetect_id != -1 ? "yes" : "no", len);
4542  } else if (!strcasecmp(data, "error")) {
4543  ast_copy_string(buf, details->error, len);
4544  } else if (!strcasecmp(data, "filename")) {
4545  if (AST_LIST_EMPTY(&details->documents)) {
4546  ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", ast_channel_name(chan), data);
4547  res = -1;
4548  } else {
4549  ast_copy_string(buf, AST_LIST_FIRST(&details->documents)->filename, len);
4550  }
4551  } else if (!strcasecmp(data, "filenames")) {
4552  if (AST_LIST_EMPTY(&details->documents)) {
4553  ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s) because it has never been written.\n", ast_channel_name(chan), data);
4554  res = -1;
4555  } else if ((filenames = generate_filenames_string(details, "", ","))) {
4556  ast_copy_string(buf, filenames, len);
4557  ast_free(filenames);
4558  } else {
4559  ast_log(LOG_ERROR, "channel '%s' can't read FAXOPT(%s), there was an error generating the filenames list.\n", ast_channel_name(chan), data);
4560  res = -1;
4561  }
4562  } else if (!strcasecmp(data, "headerinfo")) {
4563  ast_copy_string(buf, details->headerinfo, len);
4564  } else if (!strcasecmp(data, "localstationid")) {
4565  ast_copy_string(buf, details->localstationid, len);
4566  } else if (!strcasecmp(data, "maxrate")) {
4567  snprintf(buf, len, "%u", details->maxrate);
4568  } else if (!strcasecmp(data, "minrate")) {
4569  snprintf(buf, len, "%u", details->minrate);
4570  } else if (!strcasecmp(data, "pages")) {
4571  snprintf(buf, len, "%u", details->pages_transferred);
4572  } else if (!strcasecmp(data, "rate")) {
4573  ast_copy_string(buf, details->transfer_rate, len);
4574  } else if (!strcasecmp(data, "remotestationid")) {
4575  ast_copy_string(buf, details->remotestationid, len);
4576  } else if (!strcasecmp(data, "resolution")) {
4577  ast_copy_string(buf, details->resolution, len);
4578  } else if (!strcasecmp(data, "sessionid")) {
4579  snprintf(buf, len, "%u", details->id);
4580  } else if (!strcasecmp(data, "status")) {
4581  ast_copy_string(buf, details->result, len);
4582  } else if (!strcasecmp(data, "statusstr")) {
4583  ast_copy_string(buf, details->resultstr, len);
4584  } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
4585  ast_fax_modem_to_str(details->modems, buf, len);
4586  } else if (!strcasecmp(data, "t38timeout")) {
4587  snprintf(buf, len, "%u", details->t38timeout);
4588  } else if (!strcasecmp(data, "negotiate_both")) {
4589  ast_copy_string(buf, details->negotiate_both != -1 ? "yes" : "no", len);
4590  } else {
4591  ast_log(LOG_WARNING, "channel '%s' can't read FAXOPT(%s) because it is unhandled!\n", ast_channel_name(chan), data);
4592  res = -1;
4593  }
4594  ao2_ref(details, -1);
4595 
4596  return res;
4597 }
4598 
4599 /*! \brief FAXOPT write function modifies the contents of a FAX option */
4600 static int acf_faxopt_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
4601 {
4602  int res = 0;
4603  struct ast_fax_session_details *details;
4604 
4605  if (!(details = find_or_create_details(chan))) {
4606  ast_log(LOG_WARNING, "channel '%s' can't set FAXOPT(%s) to '%s' because it failed to create a datastore.\n", ast_channel_name(chan), data, value);
4607  return -1;
4608  }
4609  ast_debug(3, "channel '%s' setting FAXOPT(%s) to '%s'\n", ast_channel_name(chan), data, value);
4610 
4611  if (!strcasecmp(data, "ecm")) {
4612  const char *val = ast_skip_blanks(value);
4613  if (ast_true(val)) {
4614  details->option.ecm = AST_FAX_OPTFLAG_TRUE;
4615  } else if (ast_false(val)) {
4616  details->option.ecm = AST_FAX_OPTFLAG_FALSE;
4617  } else {
4618  ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(ecm).\n", value);
4619  }
4620  } else if (!strcasecmp(data, "t38gateway") || !strcasecmp(data, "gateway") ||
4621  !strcasecmp(data, "t38_gateway") || !strcasecmp(data, "faxgateway")) {
4622  const char *val = ast_skip_blanks(value);
4623  char *timeout = strchr(val, ',');
4624 
4625  if (timeout) {
4626  *timeout++ = '\0';
4627  }
4628 
4629  if (ast_true(val)) {
4630  if (details->gateway_id < 0) {
4631  details->gateway_timeout = 0;
4632  if (timeout) {
4633  unsigned int gwtimeout;
4634 
4635  if (sscanf(timeout, "%30u", &gwtimeout) == 1) {
4636  details->gateway_timeout = gwtimeout * 1000;
4637  } else {
4638  ast_log(LOG_WARNING, "Unsupported timeout '%s' passed to FAXOPT(%s).\n", timeout, data);
4639  }
4640  }
4641 
4642  details->gateway_id = fax_gateway_attach(chan, details);
4643  if (details->gateway_id < 0) {
4644  ast_log(LOG_ERROR, "Error attaching T.38 gateway to channel %s.\n", ast_channel_name(chan));
4645  res = -1;
4646  } else {
4647  ast_debug(1, "Attached T.38 gateway to channel %s.\n", ast_channel_name(chan));
4648  }
4649  } else {
4650  ast_log(LOG_WARNING, "Attempt to attach a T.38 gateway on channel (%s) with gateway already running.\n", ast_channel_name(chan));
4651  }
4652  } else if (ast_false(val)) {
4653  ast_channel_lock(chan);
4654  ast_framehook_detach(chan, details->gateway_id);
4655  ast_channel_unlock(chan);
4656  details->gateway_id = -1;
4657  } else {
4658  ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(%s).\n", value, data);
4659  }
4660  } else if (!strcasecmp(data, "faxdetect")) {
4661  const char *val = ast_skip_blanks(value);
4662  char *timeout = strchr(val, ',');
4663  unsigned int fdtimeout = 0;
4664  int flags;
4665  int faxdetect;
4666 
4667  if (timeout) {
4668  *timeout++ = '\0';
4669  }
4670 
4671  if (ast_true(val) || !strcasecmp(val, "t38") || !strcasecmp(val, "cng")) {
4672  if (details->faxdetect_id < 0) {
4673  if (timeout) {
4674  if (sscanf(timeout, "%30u", &fdtimeout) == 1) {
4675  fdtimeout *= 1000;
4676  } else {
4677  ast_log(LOG_WARNING, "Unsupported timeout '%s' passed to FAXOPT(%s).\n",
4678  timeout, data);
4679  }
4680  }
4681 
4682  if (!strcasecmp(val, "t38")) {
4683  flags = FAX_DETECT_MODE_T38;
4684  } else if (!strcasecmp(val, "cng")) {
4685  flags = FAX_DETECT_MODE_CNG;
4686  } else {
4687  flags = FAX_DETECT_MODE_BOTH;
4688  }
4689 
4690  faxdetect = fax_detect_attach(chan, fdtimeout, flags);
4691  if (faxdetect < 0) {
4692  ast_log(LOG_ERROR, "Error attaching FAX detect to channel %s.\n", ast_channel_name(chan));
4693  res = -1;
4694  } else {
4695  ast_debug(1, "Attached FAX detect to channel %s.\n", ast_channel_name(chan));
4696  }
4697  } else {
4698  ast_log(LOG_WARNING, "Attempt to attach a FAX detect on channel (%s) with FAX detect already running.\n", ast_channel_name(chan));
4699  }
4700  } else if (ast_false(val)) {
4701  ast_channel_lock(chan);
4702  ast_framehook_detach(chan, details->faxdetect_id);
4703  ast_channel_unlock(chan);
4704  details->faxdetect_id = -1;
4705  } else {
4706  ast_log(LOG_WARNING, "Unsupported value '%s' passed to FAXOPT(%s).\n", value, data);
4707  }
4708  } else if (!strcasecmp(data, "headerinfo")) {
4709  ast_string_field_set(details, headerinfo, value);
4710  } else if (!strcasecmp(data, "localstationid")) {
4711  ast_string_field_set(details, localstationid, value);
4712  } else if (!strcasecmp(data, "maxrate")) {
4713  details->maxrate = fax_rate_str_to_int(value);
4714  if (!details->maxrate) {
4715  details->maxrate = ast_fax_maxrate();
4716  }
4717  } else if (!strcasecmp(data, "minrate")) {
4718  details->minrate = fax_rate_str_to_int(value);
4719  if (!details->minrate) {
4720  details->minrate = ast_fax_minrate();
4721  }
4722  } else if (!strcasecmp(data, "t38timeout")) {
4723  if (set_t38timeout(value, &details->t38timeout)) {
4724  res = -1;
4725  }
4726  } else if ((!strcasecmp(data, "modem")) || (!strcasecmp(data, "modems"))) {
4727  update_modem_bits(&details->modems, value);
4728  } else if (!strcasecmp(data, "negotiate_both")) {
4729  details->negotiate_both = ast_true(ast_skip_blanks(value));
4730  } else {
4731  ast_log(LOG_WARNING, "channel '%s' set FAXOPT(%s) to '%s' is unhandled!\n", ast_channel_name(chan), data, value);
4732  res = -1;
4733  }
4734 
4735  ao2_ref(details, -1);
4736 
4737  return res;
4738 }
4739 
4740 /*! \brief FAXOPT dialplan function */
4742  .name = "FAXOPT",
4743  .read = acf_faxopt_read,
4744  .write = acf_faxopt_write,
4745 };
4746 
4747 /*! \brief unload res_fax */
4748 static int unload_module(void)
4749 {
4750  ast_cli_unregister_multiple(fax_cli, ARRAY_LEN(fax_cli));
4751 
4752  if (ast_custom_function_unregister(&acf_faxopt) < 0) {
4753  ast_log(LOG_WARNING, "failed to unregister function '%s'\n", acf_faxopt.name);
4754  }
4755 
4756  if (ast_unregister_application(app_sendfax) < 0) {
4757  ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_sendfax);
4758  }
4759 
4760  if (ast_unregister_application(app_receivefax) < 0) {
4761  ast_log(LOG_WARNING, "failed to unregister '%s'\n", app_receivefax);
4762  }
4763 
4764  ast_manager_unregister("FAXSessions");
4765  ast_manager_unregister("FAXSession");
4766  ast_manager_unregister("FAXStats");
4767 
4768  if (fax_logger_level != -1) {
4770  }
4771 
4772  ao2_ref(faxregistry.container, -1);
4773 
4774  return 0;
4775 }
4776 
4777 /*!
4778  * \brief Load the module
4779  *
4780  * Module loading including tests for configuration or dependencies.
4781  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
4782  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
4783  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
4784  * configuration file or other non-critical problem return
4785  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
4786  */
4787 static int load_module(void)
4788 {
4789  int res;
4790 
4791  /* initialize the registry */
4792  faxregistry.active_sessions = 0;
4793  faxregistry.reserved_sessions = 0;
4796  if (!faxregistry.container) {
4797  return AST_MODULE_LOAD_DECLINE;
4798  }
4799 
4800  if (set_config(0) < 0) {
4801  ast_log(LOG_ERROR, "failed to load configuration file '%s'\n", config);
4802  ao2_ref(faxregistry.container, -1);
4803  return AST_MODULE_LOAD_DECLINE;
4804  }
4805 
4806  /* register CLI operations and applications */
4807  if (ast_register_application_xml(app_sendfax, sendfax_exec) < 0) {
4808  ast_log(LOG_WARNING, "failed to register '%s'.\n", app_sendfax);
4809  ao2_ref(faxregistry.container, -1);
4810  return AST_MODULE_LOAD_DECLINE;
4811  }
4812  if (ast_register_application_xml(app_receivefax, receivefax_exec) < 0) {
4813  ast_log(LOG_WARNING, "failed to register '%s'.\n", app_receivefax);
4814  ast_unregister_application(app_sendfax);
4815  ao2_ref(faxregistry.container, -1);
4816  return AST_MODULE_LOAD_DECLINE;
4817  }
4818 
4819  if (ast_manager_register_xml("FAXSessions", EVENT_FLAG_CALL, manager_fax_sessions)) {
4820  ast_log(LOG_WARNING, "failed to register 'FAXSessions' AMI command.\n");
4821  ast_unregister_application(app_receivefax);
4822  ast_unregister_application(app_sendfax);
4823  ao2_ref(faxregistry.container, -1);
4824  return AST_MODULE_LOAD_DECLINE;
4825  }
4826 
4827  if (ast_manager_register_xml("FAXSession", EVENT_FLAG_CALL, manager_fax_session)) {
4828  ast_log(LOG_WARNING, "failed to register 'FAXSession' AMI command.\n");
4829  ast_manager_unregister("FAXSession");
4830  ast_unregister_application(app_receivefax);
4831  ast_unregister_application(app_sendfax);
4832  ao2_ref(faxregistry.container, -1);
4833  return AST_MODULE_LOAD_DECLINE;
4834  }
4835 
4836  if (ast_manager_register_xml("FAXStats", EVENT_FLAG_REPORTING, manager_fax_stats)) {
4837  ast_log(LOG_WARNING, "failed to register 'FAXStats' AMI command.\n");
4838  ast_manager_unregister("FAXSession");
4839  ast_manager_unregister("FAXSessions");
4840  ast_unregister_application(app_receivefax);
4841  ast_unregister_application(app_sendfax);
4842  ao2_ref(faxregistry.container, -1);
4843  return AST_MODULE_LOAD_DECLINE;
4844  }
4845 
4846  ast_cli_register_multiple(fax_cli, ARRAY_LEN(fax_cli));
4847  res = ast_custom_function_register(&acf_faxopt);
4848  fax_logger_level = ast_logger_register_level("FAX");
4849 
4850  return res;
4851 }
4852 
4853 static int reload_module(void)
4854 {
4855  set_config(1);
4856  return 0;
4857 }
4858 
4859 
4860 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Generic FAX Applications",
4861  .support_level = AST_MODULE_SUPPORT_CORE,
4862  .load = load_module,
4863  .unload = unload_module,
4864  .reload = reload_module,
4865  .load_pri = AST_MODPRI_APP_DEPEND,
4866 );
const char * name
Definition: pbx.h:119
static int receivefax_exec(struct ast_channel *chan, const char *data)
initiate a receive FAX session
Definition: res_fax.c:2081
const char * type
Definition: datastore.h:32
struct ast_variable * next
static enum ast_t38_state ast_channel_get_t38_state(struct ast_channel *chan)
Retrieves the current T38 state of a channel.
Definition: channel.h:2850
const ast_string_field result
Definition: res_fax.h:142
int(*const switch_to_t38)(struct ast_fax_session *)
Definition: res_fax.h:265
int fax_complete
Definition: res_fax.c:507
Tone Indication Support.
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1499
Main Channel structure associated with a channel.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
int fax_tx_attempts
Definition: res_fax.c:503
Asterisk locking-related definitions:
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3310
Asterisk main include file. File version handling, generic pbx functions.
const struct ast_fax_tech * tech
Definition: res_fax.h:214
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
unsigned int t38timeout
Definition: res_fax.h:179
int active_sessions
Definition: res_fax.c:497
static void destroy_faxdetect(void *data)
destroy a FAX detect structure
Definition: res_fax.c:3675
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static void destroy_session_details(void *details)
destroy a FAX session details structure
Definition: res_fax.c:683
int(*const generate_silence)(struct ast_fax_session *)
Definition: res_fax.h:263
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
String manipulation functions.
int bridged
bridged
Definition: res_fax.c:455
static struct @442 faxregistry
The faxregistry is used to manage information and statistics for all FAX sessions.
unsigned long frames_sent
Definition: res_fax.h:212
int fax_rx_attempts
Definition: res_fax.c:505
const ast_string_field headerinfo
Definition: res_fax.h:142
static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session_details *details, struct ast_channel *chan)
Create a fax session and start T.30<->T.38 gateway mode.
Definition: res_fax.c:2916
unsigned long frames_received
Definition: res_fax.h:210
static unsigned int fax_rate_str_to_int(const char *ratestr)
convert a rate string to a rate
Definition: res_fax.c:1045
Asterisk version information.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
unsigned int id
Definition: res_fax.h:204
Support for translation of data formats. translate.c.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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)
this is the generic FAX session handling function
Definition: res_fax.c:1589
char *(*const cli_show_stats)(int)
Definition: res_fax.h:274
const char * ast_get_version(void)
Retrieve the Asterisk version string.
Definition: version.c:18
used for gateway framehook
Definition: res_fax.c:443
Convenient Signal Processing routines.
#define OBJ_POINTER
Definition: astobj2.h:1150
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
struct ast_frame f
Definition: translate.h:215
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3467
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
descriptor for a cli entry.
Definition: cli.h:171
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
Definition: framehook.h:151
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1758
const char *const type
Definition: res_fax.h:237
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
static void destroy_session(void *session)
destroy a FAX session structure
Definition: res_fax.c:1095
void ast_fax_tech_unregister(struct ast_fax_tech *tech)
unregister a FAX technology module
Definition: res_fax.c:991
#define ast_log_dynamic_level(level,...)
Send a log message to a dynamically registered log level.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
Structure for variables, used for configurations and for channel variables.
const ast_string_field transfer_rate
Definition: res_fax.h:142
int framehook
framehook used in gateway mode
Definition: res_fax.c:453
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
void(*const release_token)(struct ast_fax_tech_token *)
Definition: res_fax.h:249
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4257
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)
Definition: res_fax.c:3011
static struct fax_detect * fax_detect_new(struct ast_channel *chan, int timeout, int flags)
Create a new fax detect object.
Definition: res_fax.c:3693
struct ast_smoother * smoother
Definition: res_fax.h:228
enum ast_control_t38 request_response
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
static int session_hash_cb(const void *obj, const int flags)
hash callback for ao2
Definition: res_fax.c:3926
Structure for a data store type.
Definition: datastore.h:31
ast_channel_state
ast_channel states
Definition: channelstate.h:35
used for fax detect framehook
Definition: res_fax.c:468
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4653
static int report_send_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details)
Report on the status of a completed fax send attempt.
Definition: res_fax.c:2526
void ast_logger_unregister_level(const char *name)
Unregister a previously registered logger level.
Definition: logger.c:2909
Definition: astman.c:222
Definition of a media format.
Definition: format.c:43
ast_t38_state
Possible T38 states on channels.
Definition: channel.h:878
int(*const cancel_session)(struct ast_fax_session *)
Definition: res_fax.h:261
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
enum ast_control_t38_rate rate
Definition: res_fax.h:95
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3421
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition: translate.c:566
static int session_cmp_cb(void *obj, void *arg, int flags)
compare callback for ao2
Definition: res_fax.c:3934
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
static void fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
Definition: res_fax.c:3084
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition: channel.c:2988
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
const char *const description
Definition: res_fax.h:239
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
static struct ast_frame * fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan)
Definition: res_fax.c:2971
static struct ast_fax_session_details * session_details_new(void)
create a FAX session details structure
Definition: res_fax.c:695
I/O Management (derived from Cheops-NG)
struct ast_channel * chan
Definition: res_fax.h:224
void ast_fax_log(int level, const char *file, const int line, const char *function, const char *msg)
Log message at FAX or recommended level.
Definition: res_fax.c:1035
struct ast_fax_session * s
FAX Session.
Definition: res_fax.c:445
static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details)
Attach a gateway framehook object to a channel.
Definition: res_fax.c:3625
static struct ast_frame * fax_gateway_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
T.30<->T.38 gateway framehook.
Definition: res_fax.c:3382
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
Asterisk internal frame definitions.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
Utility functions.
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3050
static int load_module(void)
Load the module.
Definition: res_fax.c:4787
static struct mansession_session * find_session(uint32_t ident, int incinuse)
Definition: manager.c:8276
static struct ast_frame * fax_detect_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
Fax Detect Framehook.
Definition: res_fax.c:3744
unsigned int id
Definition: res_fax.h:117
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
Definition: linkedlists.h:333
Number structure.
Definition: app_followme.c:154
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static char * cli_fax_show_sessions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
display fax sessions
Definition: res_fax.c:4272
static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
Copies fax detection and gateway framehooks during masquerades.
Definition: res_fax.c:635
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
Configuration File Parser.
struct ast_fax_debug_info * debug_info
Definition: res_fax.h:226
static int acf_faxopt_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
FAXOPT write function modifies the contents of a FAX option.
Definition: res_fax.c:4600
struct ast_fax_t38_parameters our_t38_parameters
Definition: res_fax.h:175
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6720
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
Definition: utils.c:2167
ast_mutex_t lock
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619
General Asterisk PBX channel definitions.
static char * cli_fax_show_session(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
display details of a specified fax session
Definition: res_fax.c:4106
enum ast_fax_capabilities caps
Definition: res_fax.h:243
struct ast_fax_tech_token *(*const reserve_session)(struct ast_fax_session *)
Definition: res_fax.h:247
const char * src
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3475
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5762
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:278
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Definition: dsp.c:407
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
Data structure associated with a custom dialplan function.
Definition: pbx.h:118
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static void destroy_gateway(void *data)
destroy a FAX gateway session structure
Definition: res_fax.c:2838
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
struct ast_fax_session_details * details
Definition: res_fax.h:208
enum ast_control_t38_rate rate
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
Definition: manager.c:1785
int detected_v21
1 if a v21 preamble has been detected
Definition: res_fax.c:457
unsigned int ast_fax_minrate(void)
get the minimum supported fax rate
Definition: res_fax.c:803
struct ast_fax_session_details * details
fax session details
Definition: res_fax.c:476
int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
Set fax mode.
Definition: dsp.c:1883
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)
create a FAX session
Definition: res_fax.c:1214
static void destroy_v21_sessions(struct fax_gateway *gateway)
destroy the v21 detection parts of a fax gateway session
Definition: res_fax.c:2820
char * channame
Definition: res_fax.h:220
The data communicated between the high level applications and the generic fax function.
Definition: res_fax.h:110
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
struct ao2_container * container
Definition: res_fax.c:501
#define ast_debug(level,...)
Log a DEBUG message.
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5803
static int sendfax_exec(struct ast_channel *chan, const char *data)
initiate a send FAX session
Definition: res_fax.c:2589
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
struct ast_module * module
Definition: res_fax.h:245
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
struct ast_format * chan_read_format
original audio formats
Definition: res_fax.c:461
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
const ast_string_field remotestationid
Definition: res_fax.h:142
Core PBX routines and definitions.
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
Set the minimum average magnitude threshold to determine talking by the DSP.
Definition: dsp.c:1788
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
void ast_dsp_reset(struct ast_dsp *dsp)
Reset total silence count.
Definition: dsp.c:1843
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
unsigned int transcoding_mmr
Definition: res_fax.h:98
unsigned int transcoding_jbig
Definition: res_fax.h:99
static void fax_gateway_framehook_destroy(void *data)
Destroy the gateway data structure when the framehook is detached.
Definition: res_fax.c:3344
static struct ast_fax_session_details * find_or_create_details(struct ast_channel *chan)
returns a reference counted details structure from the channel's fax datastore. If the datastore does...
Definition: res_fax.c:763
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define FAX_DETECT_MODE_CNG
FAX Detect flags.
Definition: res_fax.c:482
void(*const destroy_session)(struct ast_fax_session *)
Definition: res_fax.h:253
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: utils.c:2199
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)
T38 Gateway Negotiate t38 parameters.
Definition: res_fax.c:3108
unsigned int pages_transferred
Definition: res_fax.h:144
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
static void fax_session_release(struct ast_fax_session *s, struct ast_fax_tech_token *token)
Release a session token.
Definition: res_fax.c:1082
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
static void destroy_callback(void *data)
Helper function used by datastores to destroy the speech structure upon hangup.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2281
unsigned int max_ifp
Definition: res_fax.h:94
struct timeval timeout_start
the start of our timeout counter
Definition: res_fax.c:470
static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
Set fax related channel variables.
Definition: res_fax.c:1446
struct ast_fax_documents documents
Definition: res_fax.h:119
used to register a FAX technology module with res_fax
Definition: res_fax.h:235
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
#define FAX_MAXBUCKETS
maximum buckets for res_fax ao2 containers
Definition: res_fax.c:489
unsigned int minrate
Definition: res_fax.h:171
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
int reserved_sessions
Definition: res_fax.c:499
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1768
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
union ast_frame::@224 data
char * command
Definition: cli.h:186
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
const char *const version
Definition: res_fax.h:241
static int acf_faxopt_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
FAXOPT read function returns the contents of a FAX option.
Definition: res_fax.c:4525
static char * cli_fax_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
enable FAX debugging
Definition: res_fax.c:4002
void *(*const new_session)(struct ast_fax_session *, struct ast_fax_tech_token *)
Definition: res_fax.h:251
enum ast_fax_modems modems
Definition: res_fax.h:115
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5144
void(*const manager_fax_session)(struct mansession *, const char *, struct ast_fax_session *)
Definition: res_fax.h:271
Support for logging to various files, console and syslog Configuration in file logger.conf.
enum ast_fax_state state
Definition: res_fax.h:218
struct ast_format * orig_format
original audio formats
Definition: res_fax.c:474
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
static int unload_module(void)
unload res_fax
Definition: res_fax.c:4748
enum ast_t38_state t38_state
a flag to track the state of our negotiation
Definition: res_fax.c:459
unsigned int ast_fax_maxrate(void)
get the maxiumum supported fax rate
Definition: res_fax.c:795
int flags
mode
Definition: res_fax.c:478
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
Structure used to handle boolean flags.
Definition: utils.h:199
struct stasis_message * ast_channel_blob_create_from_cache(const char *uniqueid, struct stasis_message_type *type, struct ast_json *blob)
Create a ast_channel_blob message, pulling channel state from the cache.
const char * usage
Definition: cli.h:177
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static void fax_detect_framehook_destroy(void *data)
Deref the faxdetect data structure when the faxdetect framehook is detached.
Definition: res_fax.c:3726
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:469
struct ast_frame ast_null_frame
Definition: main/frame.c:79
unsigned int version
Definition: res_fax.h:93
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
static struct ast_fax_session * fax_session_reserve(struct ast_fax_session_details *details, struct ast_fax_tech_token **token)
Reserve a fax session.
Definition: res_fax.c:1145
registered FAX technology modules are put into this list
Definition: res_fax.c:515
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
Definition: dsp.c:1488
void * data
Definition: datastore.h:66
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
char *(*const cli_show_session)(struct ast_fax_session *, int)
Definition: res_fax.h:269
int ast_logger_register_level(const char *name)
Register a new logger level.
Definition: logger.c:2851
static int set_config(int reload)
configure res_fax
Definition: res_fax.c:4421
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3162
const char * ast_fax_session_operation_str(struct ast_fax_session *s)
get string representation of a FAX session's operation
Definition: res_fax.c:4253
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Standard Command Line Interface.
static int report_receive_fax_status(struct ast_channel *chan, const char *filename)
Report on the final state of a receive fax operation.
Definition: res_fax.c:2017
union ast_fax_session_details::@249 option
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
static struct ast_fax_session_details * find_details(struct ast_channel *chan)
returns a reference counted pointer to a fax datastore, if it exists
Definition: res_fax.c:661
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
struct ast_frame *(*const read)(struct ast_fax_session *)
Definition: res_fax.h:255
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: channel.c:10564
struct ast_fax_tech_token * token
reserved fax session token
Definition: res_fax.c:449
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: utils.c:2216
static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags)
Attach a faxdetect framehook object to a channel.
Definition: res_fax.c:3888
static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details, const char *status)
send a FAX status manager event
Definition: res_fax.c:1406
int fax_failures
Definition: res_fax.c:509
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:6969
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
static struct fax_gateway * fax_gateway_new(struct ast_channel *chan, struct ast_fax_session_details *details)
Create a new fax gateway object.
Definition: res_fax.c:2879
enum ast_control_t38_rate_management rate_management
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
The data required to handle a fax session.
Definition: res_fax.h:202
static char * fax_session_tab_complete(struct ast_cli_args *a)
fax session tab completion
Definition: res_fax.c:3942
#define AST_MODEM_T38
struct ast_dsp * dsp
DSP Processor.
Definition: res_fax.c:472
Data structure associated with a single frame of data.
enum ast_control_t38_rate_management rate_management
Definition: res_fax.h:96
static char * cli_fax_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
display global defaults and settings
Definition: res_fax.c:4067
enum ast_fax_capabilities caps
Definition: res_fax.h:113
char * chan_uniqueid
Definition: res_fax.h:222
int ast_fax_tech_register(struct ast_fax_tech *tech)
register a FAX technology module
Definition: res_fax.c:973
Abstract JSON element (object, array, string, int, ...).
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
void * tech_pvt
Definition: res_fax.h:216
Options provided by main asterisk program.
int(*const write)(struct ast_fax_session *, const struct ast_frame *)
Definition: res_fax.h:257
Definition: search.h:40
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297
const ast_string_field resultstr
Definition: res_fax.h:142
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
enum ast_frame_type frametype
const ast_string_field localstationid
Definition: res_fax.h:142
unsigned int maxrate
Definition: res_fax.h:173
Generic container type.
static char * cli_fax_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
display fax stats
Definition: res_fax.c:4180
const char * ast_fax_state_to_str(enum ast_fax_state state)
convert a ast_fax_state to a string
Definition: res_fax.c:1012
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
const ast_string_field error
Definition: res_fax.h:142
struct ast_format * format
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
int nextsessionname
Definition: res_fax.c:511
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
struct timeval timeout_start
the start of our timeout counter
Definition: res_fax.c:451
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
char *(*const cli_show_capabilities)(int)
Definition: res_fax.h:267
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int(*const start_session)(struct ast_fax_session *)
Definition: res_fax.h:259
char *(*const cli_show_settings)(int)
Definition: res_fax.h:276
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3389
Asterisk module definitions.
unsigned int fill_bit_removal
Definition: res_fax.h:97
static char * cli_fax_show_capabilities(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
display registered FAX capabilities
Definition: res_fax.c:4037
struct ast_fax_t38_parameters their_t38_parameters
Definition: res_fax.h:177
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
struct stasis_message_type * ast_channel_fax_type(void)
Message type for a fax operation.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define AST_JSON_UTF8_VALIDATE(str)
Check str for UTF-8 and replace with an empty string if fails the check.
Definition: json.h:224
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field resolution
Definition: res_fax.h:142
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
static struct ast_custom_function acf_faxopt
FAXOPT dialplan function.
Definition: res_fax.c:4741
Media Format Cache API.
static char * generate_filenames_string(struct ast_fax_session_details *details, char *prefix, char *separator)
Generate a string of filenames using the given prefix and separator.
Definition: res_fax.c:1369
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3431
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532