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