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