2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2008-2009, Digium, Inc.
6 * Dwayne M. Hubbard <dhubbard@digium.com>
7 * Kevin P. Fleming <kpfleming@digium.com>
8 * Matthew Nicholson <mnicholson@digium.com>
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
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
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
23 * Modified to make T.38-gateway work
24 * 2010, Klaus Darilion, IPCom GmbH, www.ipcom.at
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.
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.
38 <conflict>app_fax</conflict>
39 <support_level>core</support_level>
44 * \brief Generic FAX Resource for FAX technology resource modules
46 * \author Dwayne M. Hubbard <dhubbard@digium.com>
47 * \author Kevin P. Fleming <kpfleming@digium.com>
48 * \author Matthew Nicholson <mnicholson@digium.com>
49 * \author Gregory H. Nietsky <gregory@distrotech.co.za>
51 * A generic FAX resource module that provides SendFAX and ReceiveFAX applications.
52 * This module requires FAX technology modules, like res_fax_spandsp, to register with it
53 * so it can use the technology modules to perform the actual FAX transmissions.
54 * \ingroup applications
57 /*! \li \ref res_fax.c uses the configuration file \ref res_fax.conf
58 * \addtogroup configuration_file Configuration Files
62 * \page res_fax.conf res_fax.conf
63 * \verbinclude res_fax.conf.sample
68 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
70 #include "asterisk/io.h"
71 #include "asterisk/file.h"
72 #include "asterisk/logger.h"
73 #include "asterisk/module.h"
74 #include "asterisk/app.h"
75 #include "asterisk/lock.h"
76 #include "asterisk/options.h"
77 #include "asterisk/strings.h"
78 #include "asterisk/cli.h"
79 #include "asterisk/utils.h"
80 #include "asterisk/config.h"
81 #include "asterisk/astobj2.h"
82 #include "asterisk/res_fax.h"
83 #include "asterisk/file.h"
84 #include "asterisk/channel.h"
85 #include "asterisk/pbx.h"
86 #include "asterisk/dsp.h"
87 #include "asterisk/indications.h"
88 #include "asterisk/ast_version.h"
89 #include "asterisk/translate.h"
90 #include "asterisk/stasis.h"
91 #include "asterisk/stasis_channels.h"
92 #include "asterisk/smoother.h"
93 #include "asterisk/format_cache.h"
96 <application name="ReceiveFAX" language="en_US" module="res_fax">
98 Receive a FAX and save as a TIFF/F file.
101 <parameter name="filename" required="true" />
102 <parameter name="options">
105 <para>Enable FAX debugging.</para>
108 <para>Allow audio fallback FAX transfer on T.38 capable channels.</para>
111 <para>Force usage of audio mode on T.38 capable channels.</para>
114 <para>Send progress Manager events (overrides statusevents setting in res_fax.conf).</para>
120 <para>This application is provided by res_fax, which is a FAX technology agnostic module
121 that utilizes FAX technology resource modules to complete a FAX transmission.</para>
122 <para>Session arguments can be set by the FAXOPT function and to check results of the ReceiveFax() application.</para>
125 <ref type="function">FAXOPT</ref>
128 <application name="SendFAX" language="en_US" module="res_fax">
130 Sends a specified TIFF/F file as a FAX.
133 <parameter name="filename" required="true" argsep="&">
134 <argument name="filename2" multiple="true">
135 <para>TIFF file to send as a FAX.</para>
138 <parameter name="options">
141 <para>Enable FAX debugging.</para>
144 <para>Allow audio fallback FAX transfer on T.38 capable channels.</para>
147 <para>Force usage of audio mode on T.38 capable channels.</para>
150 <para>Send progress Manager events (overrides statusevents setting in res_fax.conf).</para>
153 <para>Initiate a T.38 reinvite on the channel if the remote end does not.</para>
159 <para>This application is provided by res_fax, which is a FAX technology agnostic module
160 that utilizes FAX technology resource modules to complete a FAX transmission.</para>
161 <para>Session arguments can be set by the FAXOPT function and to check results of the SendFax() application.</para>
164 <ref type="function">FAXOPT</ref>
167 <function name="FAXOPT" language="en_US" module="res_fax">
169 Gets/sets various pieces of information about a fax session.
172 <parameter name="item" required="true">
175 <para>R/W Error Correction Mode (ECM) enable with 'yes', disable with 'no'.</para>
178 <para>R/O FAX transmission error code upon failure.</para>
180 <enum name="filename">
181 <para>R/O Filename of the first file of the FAX transmission.</para>
183 <enum name="filenames">
184 <para>R/O Filenames of all of the files in the FAX transmission (comma separated).</para>
186 <enum name="headerinfo">
187 <para>R/W FAX header information.</para>
189 <enum name="localstationid">
190 <para>R/W Local Station Identification.</para>
192 <enum name="minrate">
193 <para>R/W Minimum transfer rate set before transmission.</para>
195 <enum name="maxrate">
196 <para>R/W Maximum transfer rate set before transmission.</para>
199 <para>R/W Modem type (v17/v27/v29).</para>
201 <enum name="gateway">
202 <para>R/W T38 fax gateway, with optional fax activity timeout in seconds (yes[,timeout]/no)</para>
204 <enum name="faxdetect">
205 <para>R/W Enable FAX detect with optional timeout in seconds (yes,t38,cng[,timeout]/no)</para>
208 <para>R/O Number of pages transferred.</para>
211 <para>R/O Negotiated transmission rate.</para>
213 <enum name="remotestationid">
214 <para>R/O Remote Station Identification after transmission.</para>
216 <enum name="resolution">
217 <para>R/O Negotiated image resolution after transmission.</para>
219 <enum name="sessionid">
220 <para>R/O Session ID of the FAX transmission.</para>
223 <para>R/O Result Status of the FAX transmission.</para>
225 <enum name="statusstr">
226 <para>R/O Verbose Result Status of the FAX transmission.</para>
228 <enum name="t38timeout">
229 <para>R/W The timeout used for T.38 negotiation.</para>
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 retreive information about a FAX session that has finished eg. pages/status.</para>
239 <ref type="application">ReceiveFax</ref>
240 <ref type="application">SendFax</ref>
243 <manager name="FAXSessions" language="en_US">
245 Lists active FAX sessions
248 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
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>
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>
260 <parameter name="ActionID" required="false"/>
261 <parameter name="Channel">
262 <para>Name of the channel responsible for the FAX session</para>
264 <parameter name="Technology">
265 <para>The FAX technology that the FAX session is using</para>
267 <parameter name="SessionNumber">
268 <para>The numerical identifier for this particular session</para>
270 <parameter name="SessionType">
271 <para>FAX session passthru/relay type</para>
273 <enum name="G.711" />
277 <parameter name="Operation">
278 <para>FAX session operation type</para>
280 <enum name="gateway" />
283 <enum name="receive" />
287 <parameter name="State">
288 <para>Current state of the FAX session</para>
290 <enum name="Uninitialized" />
291 <enum name="Initialized" />
293 <enum name="Active" />
294 <enum name="Complete" />
295 <enum name="Reserved" />
296 <enum name="Inactive" />
297 <enum name="Unknown" />
300 <parameter name="Files">
301 <para>File or list of files associated with this FAX session</para>
304 </managerEventInstance>
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>
310 <parameter name="ActionID" required="false"/>
311 <parameter name="Total">
312 <para>Count of FAXSession events sent in response to FAXSessions action</para>
315 </managerEventInstance>
317 <manager name="FAXSession" language="en_US">
319 Responds with a detailed description of a single FAX session
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>
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 <session_number>' for each technology. If the
330 FAX technolgy used by this session does not include a handler for FAXSession, then this action
334 <managerEvent language="en_US" name="FAXSession">
335 <managerEventInstance class="EVENT_FLAG_REPORTING">
336 <synopsis>Raised in response to FAXSession manager command</synopsis>
338 <parameter name="ActionID" required="false"/>
339 <parameter name="SessionNumber">
340 <para>The numerical identifier for this particular session</para>
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
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>
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>
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>
367 <parameter name="FileName" required="false">
368 <para>Filename of the image being sent/recieved for this FAX session. This field is not
369 included if Operation isn't 'send' or 'receive'.</para>
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>
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>
379 <parameter name="TotalBadLines" required="false">
380 <para>Total number of bad lines sent/recieved during this session. This field is not
381 included if Operation is not 'send' or 'received'.</para>
384 </managerEventInstance>
386 <manager name="FAXStats" language="en_US">
388 Responds with fax statistics
391 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
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>
399 <managerEvent language="en_US" name="FAXStats">
400 <managerEventInstance class="EVENT_FLAG_REPORTING">
401 <synopsis>Raised in response to FAXStats manager command</synopsis>
403 <parameter name="ActionID" required="false"/>
404 <parameter name="CurrentSessions" required="true">
405 <para>Number of active FAX sessions</para>
407 <parameter name="ReservedSessions" required="true">
408 <para>Number of reserved FAX sessions</para>
410 <parameter name="TransmitAttempts" required="true">
411 <para>Total FAX sessions for which Asterisk is/was the transmitter</para>
413 <parameter name="ReceiveAttempts" required="true">
414 <para>Total FAX sessions for which Asterisk is/was the recipient</para>
416 <parameter name="CompletedFAXes" required="true">
417 <para>Total FAX sessions which have been completed successfully</para>
419 <parameter name="FailedFAXes" required="true">
420 <para>Total FAX sessions which failed to complete successfully</para>
423 </managerEventInstance>
427 static const char app_receivefax[] = "ReceiveFAX";
428 static const char app_sendfax[] = "SendFAX";
430 struct debug_info_history {
431 unsigned int consec_frames;
432 unsigned int consec_ms;
433 unsigned char silence;
436 struct ast_fax_debug_info {
437 struct timeval base_tv;
438 struct debug_info_history c2s, s2c;
442 /*! \brief used for gateway framehook */
444 /*! \brief FAX Session */
445 struct ast_fax_session *s;
446 struct ast_fax_session *peer_v21_session;
447 struct ast_fax_session *chan_v21_session;
448 /*! \brief reserved fax session token */
449 struct ast_fax_tech_token *token;
450 /*! \brief the start of our timeout counter */
451 struct timeval timeout_start;
452 /*! \brief framehook used in gateway mode */
454 /*! \brief bridged */
456 /*! \brief 1 if a v21 preamble has been detected */
458 /*! \brief a flag to track the state of our negotiation */
459 enum ast_t38_state t38_state;
460 /*! \brief original audio formats */
461 struct ast_format *chan_read_format;
462 struct ast_format *chan_write_format;
463 struct ast_format *peer_read_format;
464 struct ast_format *peer_write_format;
467 /*! \brief used for fax detect framehook */
469 /*! \brief the start of our timeout counter */
470 struct timeval timeout_start;
471 /*! \brief faxdetect timeout */
473 /*! \brief DSP Processor */
475 /*! \brief original audio formats */
476 struct ast_format *orig_format;
477 /*! \brief fax session details */
478 struct ast_fax_session_details *details;
483 /*! \brief FAX Detect flags */
484 #define FAX_DETECT_MODE_CNG (1 << 0)
485 #define FAX_DETECT_MODE_T38 (1 << 1)
486 #define FAX_DETECT_MODE_BOTH (FAX_DETECT_MODE_CNG | FAX_DETECT_MODE_T38)
488 static int fax_logger_level = -1;
490 /*! \brief maximum buckets for res_fax ao2 containers */
491 #define FAX_MAXBUCKETS 10
493 #define RES_FAX_TIMEOUT 10000
494 #define FAX_GATEWAY_TIMEOUT RES_FAX_TIMEOUT
496 /*! \brief The faxregistry is used to manage information and statistics for all FAX sessions. */
498 /*! The number of active FAX sessions */
500 /*! The number of reserved FAX sessions */
501 int reserved_sessions;
502 /*! active sessions are astobj2 objects */
503 struct ao2_container *container;
504 /*! Total number of Tx FAX attempts */
506 /*! Total number of Rx FAX attempts */
508 /*! Number of successful FAX transmissions */
510 /*! Number of failed FAX transmissions */
512 /*! the next unique session name */
516 /*! \brief registered FAX technology modules are put into this list */
518 const struct ast_fax_tech *tech;
519 AST_RWLIST_ENTRY(fax_module) list;
521 static AST_RWLIST_HEAD_STATIC(faxmodules, fax_module);
523 #define RES_FAX_MINRATE 4800
524 #define RES_FAX_MAXRATE 14400
525 #define RES_FAX_STATUSEVENTS 0
526 #define RES_FAX_MODEM (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29)
527 #define RES_FAX_T38TIMEOUT 5000
530 enum ast_fax_modems modems;
531 uint32_t statusevents:1;
533 unsigned int minrate;
534 unsigned int maxrate;
535 unsigned int t38timeout;
538 static struct fax_options general_options;
540 static const struct fax_options default_options = {
541 .minrate = RES_FAX_MINRATE,
542 .maxrate = RES_FAX_MAXRATE,
543 .statusevents = RES_FAX_STATUSEVENTS,
544 .modems = RES_FAX_MODEM,
545 .ecm = AST_FAX_OPTFLAG_TRUE,
546 .t38timeout = RES_FAX_T38TIMEOUT,
549 AST_RWLOCK_DEFINE_STATIC(options_lock);
551 static void get_general_options(struct fax_options* options);
552 static void set_general_options(const struct fax_options* options);
554 static const char *config = "res_fax.conf";
556 static int global_fax_debug = 0;
559 OPT_CALLEDMODE = (1 << 0),
560 OPT_CALLERMODE = (1 << 1),
561 OPT_DEBUG = (1 << 2),
562 OPT_STATUS = (1 << 3),
563 OPT_ALLOWAUDIO = (1 << 5),
564 OPT_REQUEST_T38 = (1 << 6),
565 OPT_FORCE_AUDIO = (1 << 7),
568 AST_APP_OPTIONS(fax_exec_options, BEGIN_OPTIONS
569 AST_APP_OPTION('a', OPT_CALLEDMODE),
570 AST_APP_OPTION('c', OPT_CALLERMODE),
571 AST_APP_OPTION('d', OPT_DEBUG),
572 AST_APP_OPTION('f', OPT_ALLOWAUDIO),
573 AST_APP_OPTION('F', OPT_FORCE_AUDIO),
574 AST_APP_OPTION('s', OPT_STATUS),
575 AST_APP_OPTION('z', OPT_REQUEST_T38),
578 static void debug_check_frame_for_silence(struct ast_fax_session *s, unsigned int c2s, struct ast_frame *frame)
580 struct debug_info_history *history = c2s ? &s->debug_info->c2s : &s->debug_info->s2c;
582 unsigned int last_consec_frames, last_consec_ms;
583 unsigned char wassil;
586 diff = ast_tvsub(ast_tvnow(), s->debug_info->base_tv);
588 ast_dsp_reset(s->debug_info->dsp);
589 ast_dsp_silence(s->debug_info->dsp, frame, &dspsilence);
591 wassil = history->silence;
592 history->silence = (dspsilence != 0) ? 1 : 0;
593 if (history->silence != wassil) {
594 last_consec_frames = history->consec_frames;
595 last_consec_ms = history->consec_ms;
596 history->consec_frames = 0;
597 history->consec_ms = 0;
599 if ((last_consec_frames != 0)) {
600 ast_verb(0, "Channel '%s' fax session '%u', [ %.3ld.%.6ld ], %s sent %u frames (%u ms) of %s.\n",
601 s->channame, s->id, (long) diff.tv_sec, (long int) diff.tv_usec,
602 (c2s) ? "channel" : "stack", last_consec_frames, last_consec_ms,
603 (wassil) ? "silence" : "energy");
607 history->consec_frames++;
608 history->consec_ms += (frame->samples / 8);
611 static void destroy_callback(void *data)
618 static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
620 static const struct ast_datastore_info fax_datastore = {
622 .destroy = destroy_callback,
623 .chan_fixup = fixup_callback,
626 static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details);
627 static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags);
628 static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan);
630 /*! \brief Copies fax detection and gateway framehooks during masquerades
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.
635 static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
637 struct ast_fax_session_details *old_details = data;
638 struct ast_datastore *datastore = ast_channel_datastore_find(old_chan, &fax_datastore, NULL);
640 if (old_details->gateway_id >= 0) {
641 struct ast_fax_session_details *new_details = find_or_create_details(new_chan);
643 ast_framehook_detach(old_chan, old_details->gateway_id);
644 fax_gateway_attach(new_chan, new_details);
645 ao2_cleanup(new_details);
648 if (old_details->faxdetect_id >= 0) {
649 ast_framehook_detach(old_chan, old_details->faxdetect_id);
650 fax_detect_attach(new_chan, old_details->faxdetect_timeout, old_details->faxdetect_flags);
654 ast_channel_datastore_remove(old_chan, datastore);
655 ast_datastore_free(datastore);
659 /*! \brief returns a reference counted pointer to a fax datastore, if it exists */
660 static struct ast_fax_session_details *find_details(struct ast_channel *chan)
662 struct ast_fax_session_details *details;
663 struct ast_datastore *datastore;
665 ast_channel_lock(chan);
666 if (!(datastore = ast_channel_datastore_find(chan, &fax_datastore, NULL))) {
667 ast_channel_unlock(chan);
670 if (!(details = datastore->data)) {
671 ast_log(LOG_WARNING, "Huh? channel '%s' has a FAX datastore without data!\n", ast_channel_name(chan));
672 ast_channel_unlock(chan);
676 ast_channel_unlock(chan);
681 /*! \brief destroy a FAX session details structure */
682 static void destroy_session_details(void *details)
684 struct ast_fax_session_details *d = details;
685 struct ast_fax_document *doc;
687 while ((doc = AST_LIST_REMOVE_HEAD(&d->documents, next))) {
690 ast_string_field_free_memory(d);
693 /*! \brief create a FAX session details structure */
694 static struct ast_fax_session_details *session_details_new(void)
696 struct ast_fax_session_details *d;
697 struct fax_options options;
699 if (!(d = ao2_alloc(sizeof(*d), destroy_session_details))) {
703 if (ast_string_field_init(d, 512)) {
708 get_general_options(&options);
710 AST_LIST_HEAD_INIT_NOLOCK(&d->documents);
712 /* These options need to be set to the configured default and may be overridden by
713 * SendFAX, ReceiveFAX, or FAXOPT */
714 d->option.request_t38 = AST_FAX_OPTFLAG_FALSE;
715 d->option.send_cng = AST_FAX_OPTFLAG_FALSE;
716 d->option.send_ced = AST_FAX_OPTFLAG_FALSE;
717 d->option.ecm = options.ecm;
718 d->option.statusevents = options.statusevents;
719 d->modems = options.modems;
720 d->minrate = options.minrate;
721 d->maxrate = options.maxrate;
722 d->t38timeout = options.t38timeout;
724 d->faxdetect_id = -1;
725 d->gateway_timeout = 0;
730 static struct ast_control_t38_parameters our_t38_parameters = {
733 .rate = AST_T38_RATE_14400,
734 .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
737 static void t38_parameters_ast_to_fax(struct ast_fax_t38_parameters *dst, const struct ast_control_t38_parameters *src)
739 dst->version = src->version;
740 dst->max_ifp = src->max_ifp;
741 dst->rate = src->rate;
742 dst->rate_management = src->rate_management;
743 dst->fill_bit_removal = src->fill_bit_removal;
744 dst->transcoding_mmr = src->transcoding_mmr;
745 dst->transcoding_jbig = src->transcoding_jbig;
748 static void t38_parameters_fax_to_ast(struct ast_control_t38_parameters *dst, const struct ast_fax_t38_parameters *src)
750 dst->version = src->version;
751 dst->max_ifp = src->max_ifp;
752 dst->rate = src->rate;
753 dst->rate_management = src->rate_management;
754 dst->fill_bit_removal = src->fill_bit_removal;
755 dst->transcoding_mmr = src->transcoding_mmr;
756 dst->transcoding_jbig = src->transcoding_jbig;
759 /*! \brief returns a reference counted details structure from the channel's fax datastore. If the datastore
760 * does not exist it will be created */
761 static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan)
763 struct ast_fax_session_details *details;
764 struct ast_datastore *datastore;
766 if ((details = find_details(chan))) {
769 /* channel does not have one so we must create one */
770 if (!(details = session_details_new())) {
771 ast_log(LOG_WARNING, "channel '%s' can't get a FAX details structure for the datastore!\n", ast_channel_name(chan));
774 if (!(datastore = ast_datastore_alloc(&fax_datastore, NULL))) {
775 ao2_ref(details, -1);
776 ast_log(LOG_WARNING, "channel '%s' can't get a datastore!\n", ast_channel_name(chan));
779 /* add the datastore to the channel and increment the refcount */
780 datastore->data = details;
782 /* initialize default T.38 parameters */
783 t38_parameters_ast_to_fax(&details->our_t38_parameters, &our_t38_parameters);
784 t38_parameters_ast_to_fax(&details->their_t38_parameters, &our_t38_parameters);
787 ast_channel_lock(chan);
788 ast_channel_datastore_add(chan, datastore);
789 ast_channel_unlock(chan);
793 unsigned int ast_fax_maxrate(void)
795 struct fax_options options;
796 get_general_options(&options);
798 return options.maxrate;
801 unsigned int ast_fax_minrate(void)
803 struct fax_options options;
804 get_general_options(&options);
806 return options.minrate;
809 static int update_modem_bits(enum ast_fax_modems *bits, const char *value)
811 char *m[5], *tok, *v = (char *)value;
814 if (!strchr(v, ',')) {
818 tok = strtok(v, ", ");
819 while (tok && i < ARRAY_LEN(m) - 1) {
821 tok = strtok(NULL, ", ");
827 for (j = 0; j < i; j++) {
828 if (!strcasecmp(m[j], "v17")) {
829 *bits |= AST_FAX_MODEM_V17;
830 } else if (!strcasecmp(m[j], "v27")) {
831 *bits |= AST_FAX_MODEM_V27;
832 } else if (!strcasecmp(m[j], "v29")) {
833 *bits |= AST_FAX_MODEM_V29;
834 } else if (!strcasecmp(m[j], "v34")) {
835 *bits |= AST_FAX_MODEM_V34;
837 ast_log(LOG_WARNING, "ignoring invalid modem setting: '%s', valid options {v17 | v27 | v29 | v34}\n", m[j]);
843 static char *ast_fax_caps_to_str(enum ast_fax_capabilities caps, char *buf, size_t bufsize)
846 size_t size = bufsize;
849 if (caps & AST_FAX_TECH_SEND) {
851 ast_build_string(&buf, &size, ",");
853 ast_build_string(&buf, &size, "SEND");
856 if (caps & AST_FAX_TECH_RECEIVE) {
858 ast_build_string(&buf, &size, ",");
860 ast_build_string(&buf, &size, "RECEIVE");
863 if (caps & AST_FAX_TECH_AUDIO) {
865 ast_build_string(&buf, &size, ",");
867 ast_build_string(&buf, &size, "AUDIO");
870 if (caps & AST_FAX_TECH_T38) {
872 ast_build_string(&buf, &size, ",");
874 ast_build_string(&buf, &size, "T38");
877 if (caps & AST_FAX_TECH_MULTI_DOC) {
879 ast_build_string(&buf, &size, ",");
881 ast_build_string(&buf, &size, "MULTI_DOC");
884 if (caps & AST_FAX_TECH_GATEWAY) {
886 ast_build_string(&buf, &size, ",");
888 ast_build_string(&buf, &size, "GATEWAY");
891 if (caps & AST_FAX_TECH_V21_DETECT) {
893 ast_build_string(&buf, &size, ",");
895 ast_build_string(&buf, &size, "V21");
902 static int ast_fax_modem_to_str(enum ast_fax_modems bits, char *tbuf, size_t bufsize)
906 if (bits & AST_FAX_MODEM_V17) {
910 if (bits & AST_FAX_MODEM_V27) {
917 if (bits & AST_FAX_MODEM_V29) {
924 if (bits & AST_FAX_MODEM_V34) {
935 static int check_modem_rate(enum ast_fax_modems modems, unsigned int rate)
939 if (!(modems & (AST_FAX_MODEM_V34))) {
944 if (!(modems & (AST_FAX_MODEM_V27 | AST_FAX_MODEM_V34))) {
949 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
954 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34))) {
960 if (!(modems & (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V34))) {
966 if (!(modems & AST_FAX_MODEM_V34)) {
971 /* this should never happen */
978 /*! \brief register a FAX technology module */
979 int ast_fax_tech_register(struct ast_fax_tech *tech)
981 struct fax_module *fax;
983 if (!(fax = ast_calloc(1, sizeof(*fax)))) {
987 AST_RWLIST_WRLOCK(&faxmodules);
988 AST_RWLIST_INSERT_TAIL(&faxmodules, fax, list);
989 AST_RWLIST_UNLOCK(&faxmodules);
990 ast_module_ref(ast_module_info->self);
992 ast_verb(3, "Registered handler for '%s' (%s)\n", fax->tech->type, fax->tech->description);
997 /*! \brief unregister a FAX technology module */
998 void ast_fax_tech_unregister(struct ast_fax_tech *tech)
1000 struct fax_module *fax;
1002 ast_verb(3, "Unregistering FAX module type '%s'\n", tech->type);
1004 AST_RWLIST_WRLOCK(&faxmodules);
1005 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&faxmodules, fax, list) {
1006 if (fax->tech != tech) {
1009 AST_RWLIST_REMOVE_CURRENT(list);
1010 ast_module_unref(ast_module_info->self);
1012 ast_verb(4, "Unregistered FAX module type '%s'\n", tech->type);
1015 AST_RWLIST_TRAVERSE_SAFE_END;
1016 AST_RWLIST_UNLOCK(&faxmodules);
1019 /*! \brief convert a ast_fax_state to a string */
1020 const char *ast_fax_state_to_str(enum ast_fax_state state)
1023 case AST_FAX_STATE_UNINITIALIZED:
1024 return "Uninitialized";
1025 case AST_FAX_STATE_INITIALIZED:
1026 return "Initialized";
1027 case AST_FAX_STATE_OPEN:
1029 case AST_FAX_STATE_ACTIVE:
1031 case AST_FAX_STATE_COMPLETE:
1033 case AST_FAX_STATE_RESERVED:
1035 case AST_FAX_STATE_INACTIVE:
1038 ast_log(LOG_WARNING, "unhandled FAX state: %u\n", state);
1043 void ast_fax_log(int level, const char *file, const int line, const char *function, const char *msg)
1045 if (fax_logger_level != -1) {
1046 ast_log_dynamic_level(fax_logger_level, "%s", msg);
1048 ast_log(level, file, line, function, "%s", msg);
1052 /*! \brief convert a rate string to a rate */
1053 static unsigned int fax_rate_str_to_int(const char *ratestr)
1057 if (sscanf(ratestr, "%d", &rate) != 1) {
1058 ast_log(LOG_ERROR, "failed to sscanf '%s' to rate\n", ratestr);
1072 ast_log(LOG_WARNING, "ignoring invalid rate '%s'. Valid options are {2400 | 4800 | 7200 | 9600 | 12000 | 14400 | 28800 | 33600}\n", ratestr);
1077 /*! \brief Release a session token.
1078 * \param s a session returned from fax_session_reserve()
1079 * \param token a token generated from fax_session_reserve()
1081 * This function releases the given token and marks the given session as no
1082 * longer reserved. It is safe to call on a session that is not actually
1083 * reserved and with a NULL token. This is so that sessions returned by
1084 * technologies that do not support reserved sessions don't require extra logic
1087 * \note This function DOES NOT release the given fax session, only the given
1090 static void fax_session_release(struct ast_fax_session *s, struct ast_fax_tech_token *token)
1093 s->tech->release_token(token);
1096 if (s->state == AST_FAX_STATE_RESERVED) {
1097 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
1098 s->state = AST_FAX_STATE_INACTIVE;
1102 /*! \brief destroy a FAX session structure */
1103 static void destroy_session(void *session)
1105 struct ast_fax_session *s = session;
1108 fax_session_release(s, NULL);
1110 s->tech->destroy_session(s);
1112 ast_module_unref(s->tech->module);
1116 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
1117 s->details->caps &= ~AST_FAX_TECH_GATEWAY;
1119 ao2_ref(s->details, -1);
1122 if (s->debug_info) {
1123 ast_dsp_free(s->debug_info->dsp);
1124 ast_free(s->debug_info);
1128 ast_smoother_free(s->smoother);
1131 if (s->state != AST_FAX_STATE_INACTIVE) {
1132 ast_atomic_fetchadd_int(&faxregistry.active_sessions, -1);
1135 ast_free(s->channame);
1136 ast_free(s->chan_uniqueid);
1139 /*! \brief Reserve a fax session.
1140 * \param details the fax session details
1141 * \param token a pointer to a place to store a token to be passed to fax_session_new() later
1143 * This function reserves a fax session for use later. If the selected fax
1144 * technology does not support reserving sessions a session will still be
1145 * returned but token will not be set.
1147 * \note The reference returned by this function does not get consumed by
1148 * fax_session_new() and must always be dereferenced separately.
1150 * \return NULL or an uninitialized and possibly reserved session
1152 static struct ast_fax_session *fax_session_reserve(struct ast_fax_session_details *details, struct ast_fax_tech_token **token)
1154 struct ast_fax_session *s;
1155 struct fax_module *faxmod;
1157 if (!(s = ao2_alloc(sizeof(*s), destroy_session))) {
1161 s->state = AST_FAX_STATE_INACTIVE;
1162 s->details = details;
1163 ao2_ref(s->details, 1);
1165 /* locate a FAX technology module that can handle said requirements
1166 * Note: the requirements have not yet been finalized as T.38
1167 * negotiation has not yet occured. */
1168 AST_RWLIST_RDLOCK(&faxmodules);
1169 AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
1170 if ((faxmod->tech->caps & details->caps) != details->caps) {
1173 ast_debug(4, "Reserving a FAX session from '%s'.\n", faxmod->tech->description);
1174 ast_module_ref(faxmod->tech->module);
1175 s->tech = faxmod->tech;
1178 AST_RWLIST_UNLOCK(&faxmodules);
1181 char caps[128] = "";
1182 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)));
1187 if (!s->tech->reserve_session) {
1188 ast_debug(1, "Selected FAX technology module (%s) does not support reserving sessions.\n", s->tech->description);
1192 if (!(*token = s->tech->reserve_session(s))) {
1197 s->state = AST_FAX_STATE_RESERVED;
1198 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, 1);
1203 /*! \brief create a FAX session
1205 * \param details details for the session
1206 * \param chan the channel the session will run on
1207 * \param reserved a reserved session to base this session on (can be NULL)
1208 * \param token the token for a reserved session (can be NULL)
1210 * Create a new fax session based on the given details structure.
1212 * \note The given token is always consumed (by tech->new_session() or by
1213 * fax_session_release() in the event of a failure). The given reference to a
1214 * reserved session is never consumed and must be dereferenced separately from
1215 * the reference returned by this function.
1217 * \return NULL or a reference to a new fax session
1219 static struct ast_fax_session *fax_session_new(struct ast_fax_session_details *details, struct ast_channel *chan, struct ast_fax_session *reserved, struct ast_fax_tech_token *token)
1221 struct ast_fax_session *s = NULL;
1222 struct fax_module *faxmod;
1226 ao2_ref(reserved, +1);
1227 ao2_unlink(faxregistry.container, reserved);
1229 /* NOTE: we don't consume the reference to the reserved
1230 * session. The session returned from fax_session_new() is a
1231 * new reference and must be derefed in addition to the
1235 if (s->state == AST_FAX_STATE_RESERVED) {
1236 ast_atomic_fetchadd_int(&faxregistry.reserved_sessions, -1);
1237 s->state = AST_FAX_STATE_UNINITIALIZED;
1241 if (!s && !(s = ao2_alloc(sizeof(*s), destroy_session))) {
1245 ast_atomic_fetchadd_int(&faxregistry.active_sessions, 1);
1246 s->state = AST_FAX_STATE_UNINITIALIZED;
1248 if (details->option.debug && (details->caps & AST_FAX_TECH_AUDIO)) {
1249 if (!(s->debug_info = ast_calloc(1, sizeof(*(s->debug_info))))) {
1250 fax_session_release(s, token);
1254 if (!(s->debug_info->dsp = ast_dsp_new())) {
1255 ast_free(s->debug_info);
1256 s->debug_info = NULL;
1257 fax_session_release(s, token);
1261 ast_dsp_set_threshold(s->debug_info->dsp, 128);
1264 if (!(s->channame = ast_strdup(ast_channel_name(chan)))) {
1265 fax_session_release(s, token);
1270 if (!(s->chan_uniqueid = ast_strdup(ast_channel_uniqueid(chan)))) {
1271 fax_session_release(s, token);
1278 s->details = details;
1279 ao2_ref(s->details, 1);
1282 details->id = s->id = ast_atomic_fetchadd_int(&faxregistry.nextsessionname, 1);
1285 /* locate a FAX technology module that can handle said requirements */
1286 AST_RWLIST_RDLOCK(&faxmodules);
1287 AST_RWLIST_TRAVERSE(&faxmodules, faxmod, list) {
1288 if ((faxmod->tech->caps & details->caps) != details->caps) {
1291 ast_debug(4, "Requesting a new FAX session from '%s'.\n", faxmod->tech->description);
1292 ast_module_ref(faxmod->tech->module);
1294 /* Balance module ref from reserved session */
1295 ast_module_unref(reserved->tech->module);
1297 s->tech = faxmod->tech;
1300 AST_RWLIST_UNLOCK(&faxmodules);
1303 char caps[128] = "";
1304 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)));
1310 if (!(s->tech_pvt = s->tech->new_session(s, token))) {
1311 ast_log(LOG_ERROR, "FAX session failed to initialize.\n");
1315 /* link the session to the session container */
1316 if (!(ao2_link(faxregistry.container, s))) {
1317 ast_log(LOG_ERROR, "failed to add FAX session '%u' to container.\n", s->id);
1321 ast_debug(4, "channel '%s' using FAX session '%u'\n", s->channame, s->id);
1328 * \brief Convert the filenames in a fax session into a JSON array
1329 * \retval NULL on error
1330 * \retval A \ref ast_json array on success
1332 static struct ast_json *generate_filenames_json(struct ast_fax_session_details *details)
1334 RAII_VAR(struct ast_json *, json_array, ast_json_array_create(), ast_json_unref);
1335 struct ast_fax_document *doc;
1337 if (!details || !json_array) {
1341 /* don't process empty lists */
1342 if (AST_LIST_EMPTY(&details->documents)) {
1346 AST_LIST_TRAVERSE(&details->documents, doc, next) {
1347 struct ast_json *entry = ast_json_string_create(doc->filename);
1351 if (ast_json_array_append(json_array, entry)) {
1356 ast_json_ref(json_array);
1361 * \brief Generate a string of filenames using the given prefix and separator.
1362 * \param details the fax session details
1363 * \param prefix the prefix to each filename
1364 * \param separator the separator between filenames
1366 * This function generates a string of filenames from the given details
1367 * structure and using the given prefix and separator.
1369 * \retval NULL there was an error generating the string
1370 * \return the string generated string
1372 static char *generate_filenames_string(struct ast_fax_session_details *details, char *prefix, char *separator)
1374 char *filenames, *c;
1377 struct ast_fax_document *doc;
1379 /* don't process empty lists */
1380 if (AST_LIST_EMPTY(&details->documents)) {
1381 return ast_strdup("");
1384 /* Calculate the total length of all of the file names */
1385 AST_LIST_TRAVERSE(&details->documents, doc, next) {
1386 size += strlen(separator) + strlen(prefix) + strlen(doc->filename);
1388 size += 1; /* add space for the terminating null */
1390 if (!(filenames = ast_malloc(size))) {
1395 ast_build_string(&c, &size, "%s%s", prefix, AST_LIST_FIRST(&details->documents)->filename);
1396 AST_LIST_TRAVERSE(&details->documents, doc, next) {
1402 ast_build_string(&c, &size, "%s%s%s", separator, prefix, doc->filename);
1408 /*! \brief send a FAX status manager event */
1409 static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details, const char *status)
1411 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1412 RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
1413 struct ast_json *json_filenames = NULL;
1415 if (!details->option.statusevents) {
1419 json_filenames = generate_filenames_json(details);
1420 if (!json_filenames) {
1424 json_object = ast_json_pack("{s: s, s: s, s: s, s: s, s: o}",
1426 "operation", (details->caps & AST_FAX_TECH_GATEWAY) ? "gateway" : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
1428 "local_station_id", details->localstationid,
1429 "filenames", json_filenames);
1435 SCOPED_CHANNELLOCK(lock, chan);
1437 message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), ast_channel_fax_type(), json_object);
1441 stasis_publish(ast_channel_topic(chan), message);
1446 /*! \brief Set fax related channel variables. */
1447 static void set_channel_variables(struct ast_channel *chan, struct ast_fax_session_details *details)
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", S_OR(details->remotestationid, NULL));
1454 pbx_builtin_setvar_helper(chan, "LOCALSTATIONID", S_OR(details->localstationid, NULL));
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));
1458 snprintf(buf, sizeof(buf), "%u", details->pages_transferred);
1459 pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
1462 #define GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason) \
1464 if (ast_strlen_zero(fax->details->result)) \
1465 ast_string_field_set(fax->details, result, "FAILED"); \
1466 if (ast_strlen_zero(fax->details->resultstr)) \
1467 ast_string_field_set(fax->details, resultstr, reason); \
1468 if (ast_strlen_zero(fax->details->error)) \
1469 ast_string_field_set(fax->details, error, errorstr); \
1470 set_channel_variables(chan, fax->details); \
1473 #define GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason) \
1475 GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason); \
1478 #define GENERIC_FAX_EXEC_ERROR(fax, chan, errorstr, reason) \
1480 ast_log(LOG_ERROR, "channel '%s' FAX session '%u' failure, reason: '%s' (%s)\n", ast_channel_name(chan), fax->id, reason, errorstr); \
1481 GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason); \
1484 static int set_fax_t38_caps(struct ast_channel *chan, struct ast_fax_session_details *details)
1486 switch (ast_channel_get_t38_state(chan)) {
1487 case T38_STATE_UNKNOWN:
1488 details->caps |= AST_FAX_TECH_T38;
1490 case T38_STATE_REJECTED:
1491 case T38_STATE_UNAVAILABLE:
1492 details->caps |= AST_FAX_TECH_AUDIO;
1494 case T38_STATE_NEGOTIATED:
1495 /* already in T.38 mode? This should not happen. */
1496 case T38_STATE_NEGOTIATING: {
1497 /* the other end already sent us a T.38 reinvite, so we need to prod the channel
1498 * driver into resending their parameters to us if it supports doing so... if
1499 * not, we can't proceed, because we can't create a proper reply without them.
1500 * if it does work, the channel driver will send an AST_CONTROL_T38_PARAMETERS
1501 * with a request of AST_T38_REQUEST_NEGOTIATE, which will be read by the function
1502 * that gets called after this one completes
1504 struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_PARMS, };
1505 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)) != AST_T38_REQUEST_PARMS) {
1506 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", ast_channel_name(chan));
1509 details->caps |= AST_FAX_TECH_T38;
1513 ast_log(LOG_ERROR, "channel '%s' is in an unsupported T.38 negotiation state, cannot continue.\n", ast_channel_name(chan));
1520 static int disable_t38(struct ast_channel *chan)
1523 struct ast_frame *frame = NULL;
1524 struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
1525 struct timeval start;
1528 ast_debug(1, "Shutting down T.38 on %s\n", ast_channel_name(chan));
1529 if (ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0) {
1530 ast_debug(1, "error while disabling T.38 on channel '%s'\n", ast_channel_name(chan));
1534 /* wait up to five seconds for negotiation to complete */
1536 start = ast_tvnow();
1537 while ((ms = ast_remaining_ms(start, timeout_ms))) {
1538 ms = ast_waitfor(chan, ms);
1544 ast_debug(1, "error while disabling T.38 on channel '%s'\n", ast_channel_name(chan));
1548 if (!(frame = ast_read(chan))) {
1551 if ((frame->frametype == AST_FRAME_CONTROL) &&
1552 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1553 (frame->datalen == sizeof(t38_parameters))) {
1554 struct ast_control_t38_parameters *parameters = frame->data.ptr;
1556 switch (parameters->request_response) {
1557 case AST_T38_TERMINATED:
1558 ast_debug(1, "Shut down T.38 on %s\n", ast_channel_name(chan));
1560 case AST_T38_REFUSED:
1561 ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", ast_channel_name(chan));
1565 ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", ast_channel_name(chan));
1575 if (ms == 0) { /* all done, nothing happened */
1576 ast_debug(1, "channel '%s' timed-out during T.38 shutdown\n", ast_channel_name(chan));
1582 /*! \brief this is the generic FAX session handling function */
1583 static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_details *details, struct ast_fax_session *reserved, struct ast_fax_tech_token *token)
1586 int timeout = RES_FAX_TIMEOUT;
1588 unsigned int expected_frametype = -1;
1589 struct ast_frame_subclass expected_framesubclass = { .integer = 0, };
1590 unsigned int t38negotiated = (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED);
1591 struct ast_control_t38_parameters t38_parameters;
1592 const char *tempvar;
1593 struct ast_fax_session *fax = NULL;
1594 struct ast_frame *frame = NULL;
1595 struct ast_channel *c = chan;
1596 RAII_VAR(struct ast_format *, orig_write_format, NULL, ao2_cleanup);
1597 RAII_VAR(struct ast_format *, orig_read_format, NULL, ao2_cleanup);
1599 struct timeval start;
1603 /* create the FAX session */
1604 if (!(fax = fax_session_new(details, chan, reserved, token))) {
1605 ast_log(LOG_ERROR, "Can't create a FAX session, FAX attempt failed.\n");
1606 report_fax_status(chan, details, "No Available Resource");
1610 ast_channel_lock(chan);
1611 /* update session details */
1612 if (ast_strlen_zero(details->headerinfo) && (tempvar = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO"))) {
1613 ast_string_field_set(details, headerinfo, tempvar);
1615 if (ast_strlen_zero(details->localstationid)) {
1616 tempvar = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
1617 ast_string_field_set(details, localstationid, tempvar ? tempvar : "unknown");
1619 ast_channel_unlock(chan);
1621 report_fax_status(chan, details, "Allocating Resources");
1623 if (details->caps & AST_FAX_TECH_AUDIO) {
1624 expected_frametype = AST_FRAME_VOICE;
1625 expected_framesubclass.format = ast_format_slin;
1626 orig_write_format = ao2_bump(ast_channel_writeformat(chan));
1627 if (ast_set_write_format(chan, ast_format_slin) < 0) {
1628 ast_log(LOG_ERROR, "channel '%s' failed to set write format to signed linear'.\n", ast_channel_name(chan));
1629 ao2_unlink(faxregistry.container, fax);
1633 orig_read_format = ao2_bump(ast_channel_readformat(chan));
1634 if (ast_set_read_format(chan, ast_format_slin) < 0) {
1635 ast_log(LOG_ERROR, "channel '%s' failed to set read format to signed linear.\n", ast_channel_name(chan));
1636 ao2_unlink(faxregistry.container, fax);
1640 if (fax->smoother) {
1641 ast_smoother_free(fax->smoother);
1642 fax->smoother = NULL;
1644 if (!(fax->smoother = ast_smoother_new(320))) {
1645 ast_log(LOG_WARNING, "Channel '%s' FAX session '%u' failed to obtain a smoother.\n", ast_channel_name(chan), fax->id);
1648 expected_frametype = AST_FRAME_MODEM;
1649 expected_framesubclass.integer = AST_MODEM_T38;
1652 if (fax->debug_info) {
1653 fax->debug_info->base_tv = ast_tvnow();
1656 /* reset our result fields just in case the fax tech driver wants to
1657 * set custom error messages */
1658 ast_string_field_set(details, result, "");
1659 ast_string_field_set(details, resultstr, "");
1660 ast_string_field_set(details, error, "");
1661 set_channel_variables(chan, details);
1663 if (fax->tech->start_session(fax) < 0) {
1664 GENERIC_FAX_EXEC_ERROR(fax, chan, "INIT_ERROR", "failed to start FAX session");
1667 report_fax_status(chan, details, "FAX Transmission In Progress");
1669 ast_debug(5, "channel %s will wait on FAX fd %d\n", ast_channel_name(chan), fax->fd);
1671 /* handle frames for the session */
1672 remaining_time = timeout;
1673 start = ast_tvnow();
1674 while (remaining_time > 0) {
1675 struct ast_channel *ready_chan;
1680 ready_chan = ast_waitfor_nandfds(&c, chancount, &fax->fd, 1, &exception, &ofd, &ms);
1682 if (!(frame = ast_read(chan))) {
1683 /* the channel is probably gone, so lets stop polling on it and let the
1684 * FAX session complete before we exit the application. if needed,
1685 * send the FAX stack silence so the modems can finish their session without
1687 ast_debug(1, "Channel '%s' did not return a frame; probably hung up.\n", ast_channel_name(chan));
1688 GENERIC_FAX_EXEC_SET_VARS(fax, chan, "HANGUP", "remote channel hungup");
1691 remaining_time = ast_remaining_ms(start, timeout);
1692 fax->tech->cancel_session(fax);
1693 if (fax->tech->generate_silence) {
1694 fax->tech->generate_silence(fax);
1699 if ((frame->frametype == AST_FRAME_CONTROL) &&
1700 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1701 (frame->datalen == sizeof(t38_parameters))) {
1702 unsigned int was_t38 = t38negotiated;
1703 struct ast_control_t38_parameters *parameters = frame->data.ptr;
1705 switch (parameters->request_response) {
1706 case AST_T38_REQUEST_NEGOTIATE:
1707 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1710 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1711 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
1712 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1714 case AST_T38_NEGOTIATED:
1715 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1721 if (t38negotiated && !was_t38) {
1722 if (fax->tech->switch_to_t38(fax)) {
1723 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "T.38 switch failed");
1726 details->caps &= ~AST_FAX_TECH_AUDIO;
1727 expected_frametype = AST_FRAME_MODEM;
1728 expected_framesubclass.integer = AST_MODEM_T38;
1729 if (fax->smoother) {
1730 ast_smoother_free(fax->smoother);
1731 fax->smoother = NULL;
1734 report_fax_status(chan, details, "T.38 Negotiated");
1736 ast_verb(3, "Channel '%s' switched to T.38 FAX session '%u'.\n", ast_channel_name(chan), fax->id);
1738 } else if ((frame->frametype == expected_frametype) && (expected_framesubclass.integer == frame->subclass.integer) &&
1739 ((!frame->subclass.format && !expected_framesubclass.format) ||
1740 (frame->subclass.format && expected_framesubclass.format &&
1741 (ast_format_cmp(frame->subclass.format, expected_framesubclass.format) != AST_FORMAT_CMP_NOT_EQUAL)))) {
1742 struct ast_frame *f;
1744 if (fax->smoother) {
1745 /* push the frame into a smoother */
1746 if (ast_smoother_feed(fax->smoother, frame) < 0) {
1747 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "Failed to feed the smoother");
1749 while ((f = ast_smoother_read(fax->smoother)) && (f->data.ptr)) {
1750 if (fax->debug_info) {
1751 debug_check_frame_for_silence(fax, 1, f);
1753 /* write the frame to the FAX stack */
1754 fax->tech->write(fax, f);
1755 fax->frames_received++;
1761 /* write the frame to the FAX stack */
1762 fax->tech->write(fax, frame);
1763 fax->frames_received++;
1765 start = ast_tvnow();
1768 } else if (ofd == fax->fd) {
1769 /* read a frame from the FAX stack and send it out the channel.
1770 * the FAX stack will return a NULL if the FAX session has already completed */
1771 if (!(frame = fax->tech->read(fax))) {
1775 if (fax->debug_info && (frame->frametype == AST_FRAME_VOICE)) {
1776 debug_check_frame_for_silence(fax, 0, frame);
1779 ast_write(chan, frame);
1782 start = ast_tvnow();
1784 if (ms && (ofd < 0)) {
1785 if ((errno == 0) || (errno == EINTR)) {
1786 remaining_time = ast_remaining_ms(start, timeout);
1787 if (remaining_time <= 0)
1788 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
1791 ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(chan));
1792 GENERIC_FAX_EXEC_ERROR(fax, chan, "UNKNOWN", "error polling data");
1796 /* nothing happened */
1797 remaining_time = ast_remaining_ms(start, timeout);
1798 if (remaining_time <= 0) {
1799 GENERIC_FAX_EXEC_ERROR(fax, chan, "TIMEOUT", "fax session timed-out");
1805 ast_debug(3, "channel '%s' - event loop stopped { timeout: %d, remaining_time: %d }\n", ast_channel_name(chan), timeout, remaining_time);
1807 set_channel_variables(chan, details);
1809 ast_atomic_fetchadd_int(&faxregistry.fax_complete, 1);
1810 if (!strcasecmp(details->result, "FAILED")) {
1811 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
1815 ao2_unlink(faxregistry.container, fax);
1819 /* if the channel is still alive, and we changed its read/write formats,
1823 if (orig_read_format) {
1824 ast_set_read_format(chan, orig_read_format);
1826 if (orig_write_format) {
1827 ast_set_write_format(chan, orig_write_format);
1831 /* return the chancount so the calling function can determine if the channel hungup during this FAX session or not */
1835 static int receivefax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
1838 struct ast_frame *frame = NULL;
1839 struct ast_control_t38_parameters t38_parameters;
1840 struct timeval start;
1843 /* don't send any audio if we've already received a T.38 reinvite */
1844 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
1845 /* generate 3 seconds of CED */
1846 if (ast_playtones_start(chan, 1024, "!2100/3000", 1)) {
1847 ast_log(LOG_ERROR, "error generating CED tone on %s\n", ast_channel_name(chan));
1852 start = ast_tvnow();
1853 while ((ms = ast_remaining_ms(start, timeout_ms))) {
1854 ms = ast_waitfor(chan, ms);
1857 ast_log(LOG_ERROR, "error while generating CED tone on %s\n", ast_channel_name(chan));
1858 ast_playtones_stop(chan);
1862 if (ms == 0) { /* all done, nothing happened */
1866 if (!(frame = ast_read(chan))) {
1867 ast_log(LOG_ERROR, "error reading frame while generating CED tone on %s\n", ast_channel_name(chan));
1868 ast_playtones_stop(chan);
1872 if ((frame->frametype == AST_FRAME_CONTROL) &&
1873 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1874 (frame->datalen == sizeof(t38_parameters))) {
1875 struct ast_control_t38_parameters *parameters = frame->data.ptr;
1877 switch (parameters->request_response) {
1878 case AST_T38_REQUEST_NEGOTIATE:
1879 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
1882 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1883 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
1884 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1885 ast_playtones_stop(chan);
1887 case AST_T38_NEGOTIATED:
1888 ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
1889 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1890 details->caps &= ~AST_FAX_TECH_AUDIO;
1891 report_fax_status(chan, details, "T.38 Negotiated");
1900 ast_playtones_stop(chan);
1903 /* if T.38 was negotiated, we are done initializing */
1904 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1909 ast_debug(1, "Negotiating T.38 for receive on %s\n", ast_channel_name(chan));
1911 /* wait for negotiation to complete */
1912 timeout_ms = details->t38timeout;
1914 /* set parameters based on the session's parameters */
1915 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1916 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
1917 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
1921 start = ast_tvnow();
1922 while ((ms = ast_remaining_ms(start, timeout_ms))) {
1925 ms = ast_waitfor(chan, ms);
1927 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
1930 if (ms == 0) { /* all done, nothing happened */
1931 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(chan));
1932 details->caps &= ~AST_FAX_TECH_T38;
1936 if (!(frame = ast_read(chan))) {
1937 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
1941 if ((frame->frametype == AST_FRAME_CONTROL) &&
1942 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
1943 (frame->datalen == sizeof(t38_parameters))) {
1944 struct ast_control_t38_parameters *parameters = frame->data.ptr;
1946 switch (parameters->request_response) {
1947 case AST_T38_REQUEST_NEGOTIATE:
1948 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
1949 t38_parameters.request_response = AST_T38_NEGOTIATED;
1950 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
1952 case AST_T38_NEGOTIATED:
1953 ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
1954 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
1955 details->caps &= ~AST_FAX_TECH_AUDIO;
1956 report_fax_status(chan, details, "T.38 Negotiated");
1959 case AST_T38_REFUSED:
1960 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(chan));
1961 details->caps &= ~AST_FAX_TECH_T38;
1965 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(chan));
1966 details->caps &= ~AST_FAX_TECH_T38;
1977 /* if T.38 was negotiated, we are done initializing */
1978 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
1982 /* if we made it here, then T.38 failed, check the 'f' flag */
1983 if (details->option.allow_audio != AST_FAX_OPTFLAG_TRUE) {
1984 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", ast_channel_name(chan));
1988 /* ok, audio fallback is allowed */
1989 details->caps |= AST_FAX_TECH_AUDIO;
1994 /*! \brief Report on the final state of a receive fax operation
1995 * \note This will lock the \ref ast_channel
1997 static int report_receive_fax_status(struct ast_channel *chan, const char *filename)
1999 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
2000 RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
2001 RAII_VAR(struct ast_json *, json_array, ast_json_array_create(), ast_json_unref);
2002 struct ast_json *json_filename = ast_json_string_create(filename);
2004 if (!json_array || !json_filename) {
2005 ast_json_unref(json_filename);
2008 ast_json_array_append(json_array, json_filename);
2011 const char *remote_station_id;
2012 const char *local_station_id;
2013 const char *fax_pages;
2014 const char *fax_resolution;
2015 const char *fax_bitrate;
2016 SCOPED_CHANNELLOCK(lock, chan);
2018 remote_station_id = S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), "");
2019 if (!ast_strlen_zero(remote_station_id)) {
2020 remote_station_id = ast_strdupa(remote_station_id);
2022 local_station_id = S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), "");
2023 if (!ast_strlen_zero(local_station_id)) {
2024 local_station_id = ast_strdupa(local_station_id);
2026 fax_pages = S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), "");
2027 if (!ast_strlen_zero(fax_pages)) {
2028 fax_pages = ast_strdupa(fax_pages);
2030 fax_resolution = S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), "");
2031 if (!ast_strlen_zero(fax_resolution)) {
2032 fax_resolution = ast_strdupa(fax_resolution);
2034 fax_bitrate = S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), "");
2035 if (!ast_strlen_zero(fax_bitrate)) {
2036 fax_bitrate = ast_strdupa(fax_bitrate);
2039 json_object = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: O}",
2041 "remote_station_id", S_OR(remote_station_id, ""),
2042 "local_station_id", S_OR(local_station_id, ""),
2043 "fax_pages", S_OR(fax_pages, ""),
2044 "fax_resolution", S_OR(fax_resolution, ""),
2045 "fax_bitrate", S_OR(fax_bitrate, ""),
2046 "filenames", json_array);
2051 message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), ast_channel_fax_type(), json_object);
2055 stasis_publish(ast_channel_topic(chan), message);
2060 /*! \brief initiate a receive FAX session */
2061 static int receivefax_exec(struct ast_channel *chan, const char *data)
2063 char *parse, modems[128] = "";
2065 RAII_VAR(struct ast_fax_session *, s, NULL, ao2_cleanup);
2066 RAII_VAR(struct ast_fax_session_details *, details, NULL, ao2_cleanup);
2067 struct ast_fax_tech_token *token = NULL;
2068 struct ast_fax_document *doc;
2069 AST_DECLARE_APP_ARGS(args,
2070 AST_APP_ARG(filename);
2071 AST_APP_ARG(options);
2073 struct ast_flags opts = { 0, };
2074 enum ast_t38_state t38state;
2076 /* initialize output channel variables */
2077 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
2078 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
2079 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
2080 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
2081 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
2083 /* Get a FAX session details structure from the channel's FAX datastore and create one if
2084 * it does not already exist. */
2085 if (!(details = find_or_create_details(chan))) {
2086 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
2087 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
2088 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2092 ast_string_field_set(details, result, "FAILED");
2093 ast_string_field_set(details, resultstr, "error starting fax session");
2094 ast_string_field_set(details, error, "INIT_ERROR");
2095 set_channel_variables(chan, details);
2097 if (details->gateway_id > 0) {
2098 ast_string_field_set(details, resultstr, "can't receive a fax on a channel with a T.38 gateway");
2099 set_channel_variables(chan, details);
2100 ast_log(LOG_ERROR, "executing ReceiveFAX on a channel with a T.38 Gateway is not supported\n");
2104 if (details->maxrate < details->minrate) {
2105 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2106 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
2107 set_channel_variables(chan, details);
2108 ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", details->maxrate, details->minrate);
2112 if (check_modem_rate(details->modems, details->minrate)) {
2113 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2114 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, details->minrate);
2115 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2116 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
2117 set_channel_variables(chan, details);
2121 if (check_modem_rate(details->modems, details->maxrate)) {
2122 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2123 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, details->maxrate);
2124 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2125 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
2126 set_channel_variables(chan, details);
2130 if (ast_strlen_zero(data)) {
2131 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2132 ast_string_field_set(details, resultstr, "invalid arguments");
2133 set_channel_variables(chan, details);
2134 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
2137 parse = ast_strdupa(data);
2138 AST_STANDARD_APP_ARGS(args, parse);
2140 if (!ast_strlen_zero(args.options) &&
2141 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
2142 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2143 ast_string_field_set(details, resultstr, "invalid arguments");
2144 set_channel_variables(chan, details);
2147 if (ast_strlen_zero(args.filename)) {
2148 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2149 ast_string_field_set(details, resultstr, "invalid arguments");
2150 set_channel_variables(chan, details);
2151 ast_log(LOG_WARNING, "%s requires an argument (filename[,options])\n", app_receivefax);
2155 /* check for unsupported FAX application options */
2156 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
2157 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2158 ast_string_field_set(details, resultstr, "invalid arguments");
2159 set_channel_variables(chan, details);
2160 ast_log(LOG_WARNING, "%s does not support polling\n", app_receivefax);
2164 ast_atomic_fetchadd_int(&faxregistry.fax_rx_attempts, 1);
2166 pbx_builtin_setvar_helper(chan, "FAXERROR", "Channel Problems");
2167 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "Error before FAX transmission started.");
2169 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(args.filename) + 1))) {
2170 ast_string_field_set(details, error, "MEMORY_ERROR");
2171 ast_string_field_set(details, resultstr, "error allocating memory");
2172 set_channel_variables(chan, details);
2173 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2177 strcpy(doc->filename, args.filename);
2178 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
2180 ast_verb(3, "Channel '%s' receiving FAX '%s'\n", ast_channel_name(chan), args.filename);
2182 details->caps = AST_FAX_TECH_RECEIVE;
2183 details->option.send_ced = AST_FAX_OPTFLAG_TRUE;
2185 /* check for debug */
2186 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
2187 details->option.debug = AST_FAX_OPTFLAG_TRUE;
2190 /* check for request for status events */
2191 if (ast_test_flag(&opts, OPT_STATUS)) {
2192 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
2195 t38state = ast_channel_get_t38_state(chan);
2196 if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
2197 ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
2198 ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2199 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
2202 if (!(s = fax_session_reserve(details, &token))) {
2203 ast_string_field_set(details, resultstr, "error reserving fax session");
2204 set_channel_variables(chan, details);
2205 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
2209 /* make sure the channel is up */
2210 if (ast_channel_state(chan) != AST_STATE_UP) {
2211 if (ast_answer(chan)) {
2212 ast_string_field_set(details, resultstr, "error answering channel");
2213 set_channel_variables(chan, details);
2214 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", ast_channel_name(chan));
2215 fax_session_release(s, token);
2220 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2221 if (set_fax_t38_caps(chan, details)) {
2222 ast_string_field_set(details, error, "T38_NEG_ERROR");
2223 ast_string_field_set(details, resultstr, "error negotiating T.38");
2224 set_channel_variables(chan, details);
2225 fax_session_release(s, token);
2229 details->caps |= AST_FAX_TECH_AUDIO;
2232 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
2233 if (receivefax_t38_init(chan, details)) {
2234 ast_string_field_set(details, error, "T38_NEG_ERROR");
2235 ast_string_field_set(details, resultstr, "error negotiating T.38");
2236 set_channel_variables(chan, details);
2237 fax_session_release(s, token);
2238 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", ast_channel_name(chan));
2243 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
2244 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
2247 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2248 if (disable_t38(chan)) {
2249 ast_debug(1, "error disabling T.38 mode on %s\n", ast_channel_name(chan));
2253 if (report_receive_fax_status(chan, args.filename)) {
2254 ast_log(AST_LOG_ERROR, "Error publishing ReceiveFax status message\n");
2257 /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
2258 return (!channel_alive) ? -1 : 0;
2261 static int sendfax_t38_init(struct ast_channel *chan, struct ast_fax_session_details *details)
2264 struct ast_frame *frame = NULL;
2265 struct ast_control_t38_parameters t38_parameters;
2266 struct timeval start;
2269 /* send CNG tone while listening for the receiver to initiate a switch
2270 * to T.38 mode; if they do, stop sending the CNG tone and proceed with
2273 * 10500 is enough time for 3 CNG tones
2277 /* don't send any audio if we've already received a T.38 reinvite */
2278 if (ast_channel_get_t38_state(chan) != T38_STATE_NEGOTIATING) {
2279 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000", 1)) {
2280 ast_log(LOG_ERROR, "error generating CNG tone on %s\n", ast_channel_name(chan));
2285 start = ast_tvnow();
2286 while ((ms = ast_remaining_ms(start, timeout_ms))) {
2288 ms = ast_waitfor(chan, ms);
2291 ast_log(LOG_ERROR, "error while generating CNG tone on %s\n", ast_channel_name(chan));
2292 ast_playtones_stop(chan);
2296 if (ms == 0) { /* all done, nothing happened */
2300 if (!(frame = ast_read(chan))) {
2301 ast_log(LOG_ERROR, "error reading frame while generating CNG tone on %s\n", ast_channel_name(chan));
2302 ast_playtones_stop(chan);
2306 if ((frame->frametype == AST_FRAME_CONTROL) &&
2307 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
2308 (frame->datalen == sizeof(t38_parameters))) {
2309 struct ast_control_t38_parameters *parameters = frame->data.ptr;
2311 switch (parameters->request_response) {
2312 case AST_T38_REQUEST_NEGOTIATE:
2313 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
2316 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2317 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
2318 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2319 ast_playtones_stop(chan);
2321 case AST_T38_NEGOTIATED:
2322 ast_debug(1, "Negotiated T.38 for send on %s\n", ast_channel_name(chan));
2323 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2324 details->caps &= ~AST_FAX_TECH_AUDIO;
2325 report_fax_status(chan, details, "T.38 Negotiated");
2338 ast_playtones_stop(chan);
2340 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2344 /* T.38 negotiation did not happen, initiate a switch if requested */
2345 if (details->option.request_t38 == AST_FAX_OPTFLAG_TRUE) {
2346 ast_debug(1, "Negotiating T.38 for send on %s\n", ast_channel_name(chan));
2348 /* wait up to five seconds for negotiation to complete */
2351 /* set parameters based on the session's parameters */
2352 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2353 t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
2354 if ((ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) != 0)) {
2358 start = ast_tvnow();
2359 while ((ms = ast_remaining_ms(start, timeout_ms))) {
2362 ms = ast_waitfor(chan, ms);
2364 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
2367 if (ms == 0) { /* all done, nothing happened */
2368 ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(chan));
2369 details->caps &= ~AST_FAX_TECH_T38;
2373 if (!(frame = ast_read(chan))) {
2374 ast_log(LOG_WARNING, "error on '%s' while waiting for T.38 negotiation.\n", ast_channel_name(chan));
2378 if ((frame->frametype == AST_FRAME_CONTROL) &&
2379 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
2380 (frame->datalen == sizeof(t38_parameters))) {
2381 struct ast_control_t38_parameters *parameters = frame->data.ptr;
2383 switch (parameters->request_response) {
2384 case AST_T38_REQUEST_NEGOTIATE:
2385 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2386 t38_parameters.request_response = AST_T38_NEGOTIATED;
2387 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2389 case AST_T38_NEGOTIATED:
2390 ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(chan));
2391 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2392 details->caps &= ~AST_FAX_TECH_AUDIO;
2393 report_fax_status(chan, details, "T.38 Negotiated");
2396 case AST_T38_REFUSED:
2397 ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(chan));
2398 details->caps &= ~AST_FAX_TECH_T38;
2402 ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(chan));
2403 details->caps &= ~AST_FAX_TECH_T38;
2414 /* if T.38 was negotiated, we are done initializing */
2415 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2419 /* send one more CNG tone to get audio going again for some
2420 * carriers if we are going to fall back to audio mode */
2421 if (details->option.allow_audio == AST_FAX_OPTFLAG_TRUE) {
2422 if (ast_playtones_start(chan, 1024, "!1100/500,!0/3000", 1)) {
2423 ast_log(LOG_ERROR, "error generating second CNG tone on %s\n", ast_channel_name(chan));
2428 start = ast_tvnow();
2429 while ((ms = ast_remaining_ms(start, timeout_ms))) {
2432 ms = ast_waitfor(chan, ms);
2434 ast_log(LOG_ERROR, "error while generating second CNG tone on %s\n", ast_channel_name(chan));
2435 ast_playtones_stop(chan);
2438 if (ms == 0) { /* all done, nothing happened */
2442 if (!(frame = ast_read(chan))) {
2443 ast_log(LOG_ERROR, "error reading frame while generating second CNG tone on %s\n", ast_channel_name(chan));
2444 ast_playtones_stop(chan);
2448 if ((frame->frametype == AST_FRAME_CONTROL) &&
2449 (frame->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
2450 (frame->datalen == sizeof(t38_parameters))) {
2451 struct ast_control_t38_parameters *parameters = frame->data.ptr;
2453 switch (parameters->request_response) {
2454 case AST_T38_REQUEST_NEGOTIATE:
2455 /* the other end has requested a switch to T.38, so reply that we are willing, if we can
2458 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2459 t38_parameters.request_response = (details->caps & AST_FAX_TECH_T38) ? AST_T38_NEGOTIATED : AST_T38_REFUSED;
2460 ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
2461 ast_playtones_stop(chan);
2463 case AST_T38_NEGOTIATED:
2464 ast_debug(1, "Negotiated T.38 for send on %s\n", ast_channel_name(chan));
2465 t38_parameters_ast_to_fax(&details->their_t38_parameters, parameters);
2466 details->caps &= ~AST_FAX_TECH_AUDIO;
2467 report_fax_status(chan, details, "T.38 Negotiated");
2480 ast_playtones_stop(chan);
2482 /* if T.38 was negotiated, we are done initializing */
2483 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2489 /* if we made it here, then T.38 failed, check the 'f' flag */
2490 if (details->option.allow_audio == AST_FAX_OPTFLAG_FALSE) {
2491 ast_log(LOG_WARNING, "Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting.\n", ast_channel_name(chan));
2495 /* ok, audio fallback is allowed */
2496 details->caps |= AST_FAX_TECH_AUDIO;
2502 * \brief Report on the status of a completed fax send attempt
2503 * \note This will lock the \ref ast_channel
2505 static int report_send_fax_status(struct ast_channel *chan, struct ast_fax_session_details *details)
2507 RAII_VAR(struct ast_json *, json_obj, NULL, ast_json_unref);
2508 RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
2509 struct ast_json *json_filenames;
2511 json_filenames = generate_filenames_json(details);
2512 if (!json_filenames) {
2517 const char *remote_station_id;
2518 const char *local_station_id;
2519 const char *fax_pages;
2520 const char *fax_resolution;
2521 const char *fax_bitrate;
2522 SCOPED_CHANNELLOCK(lock, chan);
2524 remote_station_id = S_OR(pbx_builtin_getvar_helper(chan, "REMOTESTATIONID"), "");
2525 if (!ast_strlen_zero(remote_station_id)) {
2526 remote_station_id = ast_strdupa(remote_station_id);
2528 local_station_id = S_OR(pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"), "");
2529 if (!ast_strlen_zero(local_station_id)) {
2530 local_station_id = ast_strdupa(local_station_id);
2532 fax_pages = S_OR(pbx_builtin_getvar_helper(chan, "FAXPAGES"), "");
2533 if (!ast_strlen_zero(fax_pages)) {
2534 fax_pages = ast_strdupa(fax_pages);
2536 fax_resolution = S_OR(pbx_builtin_getvar_helper(chan, "FAXRESOLUTION"), "");
2537 if (!ast_strlen_zero(fax_resolution)) {
2538 fax_resolution = ast_strdupa(fax_resolution);
2540 fax_bitrate = S_OR(pbx_builtin_getvar_helper(chan, "FAXBITRATE"), "");
2541 if (!ast_strlen_zero(fax_bitrate)) {
2542 fax_bitrate = ast_strdupa(fax_bitrate);
2544 json_obj = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o}",
2546 "remote_station_id", S_OR(remote_station_id, ""),
2547 "local_station_id", S_OR(local_station_id, ""),
2548 "fax_pages", S_OR(fax_pages, ""),
2549 "fax_resolution", S_OR(fax_resolution, ""),
2550 "fax_bitrate", S_OR(fax_bitrate, ""),
2551 "filenames", json_filenames);
2556 message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), ast_channel_fax_type(), json_obj);
2560 stasis_publish(ast_channel_topic(chan), message);
2567 /*! \brief initiate a send FAX session */
2568 static int sendfax_exec(struct ast_channel *chan, const char *data)
2570 char *parse, *filenames, *c, modems[128] = "";
2571 int channel_alive, file_count;
2572 RAII_VAR(struct ast_fax_session_details *, details, NULL, ao2_cleanup);
2573 RAII_VAR(struct ast_fax_session *, s, NULL, ao2_cleanup);
2574 struct ast_fax_tech_token *token = NULL;
2575 struct ast_fax_document *doc;
2576 AST_DECLARE_APP_ARGS(args,
2577 AST_APP_ARG(filenames);
2578 AST_APP_ARG(options);
2580 struct ast_flags opts = { 0, };
2581 enum ast_t38_state t38state;
2583 /* initialize output channel variables */
2584 pbx_builtin_setvar_helper(chan, "FAXSTATUS", "FAILED");
2585 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", NULL);
2586 pbx_builtin_setvar_helper(chan, "FAXPAGES", "0");
2587 pbx_builtin_setvar_helper(chan, "FAXBITRATE", NULL);
2588 pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", NULL);
2590 /* Get a requirement structure and set it. This structure is used
2591 * to tell the FAX technology module about the higher level FAX session */
2592 if (!(details = find_or_create_details(chan))) {
2593 pbx_builtin_setvar_helper(chan, "FAXERROR", "MEMORY_ERROR");
2594 pbx_builtin_setvar_helper(chan, "FAXSTATUSSTRING", "error allocating memory");
2595 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2599 ast_string_field_set(details, result, "FAILED");
2600 ast_string_field_set(details, resultstr, "error starting fax session");
2601 ast_string_field_set(details, error, "INIT_ERROR");
2602 set_channel_variables(chan, details);
2604 if (details->gateway_id > 0) {
2605 ast_string_field_set(details, resultstr, "can't send a fax on a channel with a T.38 gateway");
2606 set_channel_variables(chan, details);
2607 ast_log(LOG_ERROR, "executing SendFAX on a channel with a T.38 Gateway is not supported\n");
2611 if (details->maxrate < details->minrate) {
2612 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2613 ast_string_field_set(details, resultstr, "maxrate is less than minrate");
2614 set_channel_variables(chan, details);
2615 ast_log(LOG_ERROR, "maxrate %u is less than minrate %u\n", details->maxrate, details->minrate);
2619 if (check_modem_rate(details->modems, details->minrate)) {
2620 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2621 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %u\n", modems, details->minrate);
2622 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2623 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'minrate' settings");
2624 set_channel_variables(chan, details);
2628 if (check_modem_rate(details->modems, details->maxrate)) {
2629 ast_fax_modem_to_str(details->modems, modems, sizeof(modems));
2630 ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %u\n", modems, details->maxrate);
2631 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2632 ast_string_field_set(details, resultstr, "incompatible 'modems' and 'maxrate' settings");
2633 set_channel_variables(chan, details);
2637 if (ast_strlen_zero(data)) {
2638 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2639 ast_string_field_set(details, resultstr, "invalid arguments");
2640 set_channel_variables(chan, details);
2641 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]][,options])\n", app_sendfax);
2644 parse = ast_strdupa(data);
2645 AST_STANDARD_APP_ARGS(args, parse);
2648 if (!ast_strlen_zero(args.options) &&
2649 ast_app_parse_options(fax_exec_options, &opts, NULL, args.options)) {
2650 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2651 ast_string_field_set(details, resultstr, "invalid arguments");
2652 set_channel_variables(chan, details);
2655 if (ast_strlen_zero(args.filenames)) {
2656 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2657 ast_string_field_set(details, resultstr, "invalid arguments");
2658 set_channel_variables(chan, details);
2659 ast_log(LOG_WARNING, "%s requires an argument (filename[&filename[&filename]],options])\n", app_sendfax);
2663 /* check for unsupported FAX application options */
2664 if (ast_test_flag(&opts, OPT_CALLERMODE) || ast_test_flag(&opts, OPT_CALLEDMODE)) {
2665 ast_string_field_set(details, error, "INVALID_ARGUMENTS");
2666 ast_string_field_set(details, resultstr, "invalid arguments");
2667 set_channel_variables(chan, details);
2668 ast_log(LOG_WARNING, "%s does not support polling\n", app_sendfax);
2672 ast_atomic_fetchadd_int(&faxregistry.fax_tx_attempts, 1);
2675 filenames = args.filenames;
2676 while ((c = strsep(&filenames, "&"))) {
2677 if (access(c, (F_OK | R_OK)) < 0) {
2678 ast_string_field_set(details, error, "FILE_ERROR");
2679 ast_string_field_set(details, resultstr, "error reading file");
2680 set_channel_variables(chan, details);
2681 ast_log(LOG_ERROR, "access failure. Verify '%s' exists and check permissions.\n", args.filenames);
2685 if (!(doc = ast_calloc(1, sizeof(*doc) + strlen(c) + 1))) {
2686 ast_string_field_set(details, error, "MEMORY_ERROR");
2687 ast_string_field_set(details, resultstr, "error allocating memory");
2688 set_channel_variables(chan, details);
2689 ast_log(LOG_ERROR, "System cannot provide memory for session requirements.\n");
2693 strcpy(doc->filename, c);
2694 AST_LIST_INSERT_TAIL(&details->documents, doc, next);
2698 ast_verb(3, "Channel '%s' sending FAX:\n", ast_channel_name(chan));
2699 AST_LIST_TRAVERSE(&details->documents, doc, next) {
2700 ast_verb(3, " %s\n", doc->filename);
2703 details->caps = AST_FAX_TECH_SEND;
2705 if (file_count > 1) {
2706 details->caps |= AST_FAX_TECH_MULTI_DOC;
2709 /* check for debug */
2710 if (ast_test_flag(&opts, OPT_DEBUG) || global_fax_debug) {
2711 details->option.debug = AST_FAX_OPTFLAG_TRUE;
2714 /* check for request for status events */
2715 if (ast_test_flag(&opts, OPT_STATUS)) {
2716 details->option.statusevents = AST_FAX_OPTFLAG_TRUE;
2719 t38state = ast_channel_get_t38_state(chan);
2720 if ((t38state == T38_STATE_UNAVAILABLE) || (t38state == T38_STATE_REJECTED) ||
2721 ast_test_flag(&opts, OPT_ALLOWAUDIO) ||
2722 ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2723 details->option.allow_audio = AST_FAX_OPTFLAG_TRUE;
2726 if (ast_test_flag(&opts, OPT_REQUEST_T38)) {
2727 details->option.request_t38 = AST_FAX_OPTFLAG_TRUE;
2730 if (!(s = fax_session_reserve(details, &token))) {
2731 ast_string_field_set(details, resultstr, "error reserving fax session");
2732 set_channel_variables(chan, details);
2733 ast_log(LOG_ERROR, "Unable to reserve FAX session.\n");
2737 /* make sure the channel is up */
2738 if (ast_channel_state(chan) != AST_STATE_UP) {
2739 if (ast_answer(chan)) {
2740 ast_string_field_set(details, resultstr, "error answering channel");
2741 set_channel_variables(chan, details);
2742 ast_log(LOG_WARNING, "Channel '%s' failed answer attempt.\n", ast_channel_name(chan));
2743 fax_session_release(s, token);
2748 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO)) {
2749 if (set_fax_t38_caps(chan, details)) {
2750 ast_string_field_set(details, error, "T38_NEG_ERROR");
2751 ast_string_field_set(details, resultstr, "error negotiating T.38");
2752 set_channel_variables(chan, details);
2753 fax_session_release(s, token);
2757 details->caps |= AST_FAX_TECH_AUDIO;
2760 if (!ast_test_flag(&opts, OPT_FORCE_AUDIO) && (details->caps & AST_FAX_TECH_T38)) {
2761 if (sendfax_t38_init(chan, details)) {
2762 ast_string_field_set(details, error, "T38_NEG_ERROR");
2763 ast_string_field_set(details, resultstr, "error negotiating T.38");
2764 set_channel_variables(chan, details);
2765 fax_session_release(s, token);
2766 ast_log(LOG_ERROR, "error initializing channel '%s' in T.38 mode\n", ast_channel_name(chan));
2770 details->option.send_cng = 1;
2773 if ((channel_alive = generic_fax_exec(chan, details, s, token)) < 0) {
2774 ast_atomic_fetchadd_int(&faxregistry.fax_failures, 1);
2777 if (ast_channel_get_t38_state(chan) == T38_STATE_NEGOTIATED) {
2778 if (disable_t38(chan)) {
2779 ast_debug(1, "error disabling T.38 mode on %s\n", ast_channel_name(chan));
2783 if (!(filenames = generate_filenames_string(details, "FileName: ", "\r\n"))) {
2784 ast_log(LOG_ERROR, "Error generating SendFAX manager event\n");
2785 return (!channel_alive) ? -1 : 0;
2788 /* send out the AMI completion event */
2789 if (report_send_fax_status(chan, details)) {
2790 ast_log(AST_LOG_ERROR, "Error publishing SendFAX status message\n");
2793 /* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
2794 return (!channel_alive) ? -1 : 0;
2797 /*! \brief destroy the v21 detection parts of a fax gateway session */
2798 static void destroy_v21_sessions(struct fax_gateway *gateway)
2800 if (gateway->chan_v21_session) {
2801 ao2_unlink(faxregistry.container, gateway->chan_v21_session);
2803 ao2_ref(gateway->chan_v21_session, -1);
2804 gateway->chan_v21_session = NULL;
2807 if (gateway->peer_v21_session) {
2808 ao2_unlink(faxregistry.container, gateway->peer_v21_session);
2810 ao2_ref(gateway->peer_v21_session, -1);
2811 gateway->peer_v21_session = NULL;
2815 /*! \brief destroy a FAX gateway session structure */
2816 static void destroy_gateway(void *data)
2818 struct fax_gateway *gateway = data;
2820 destroy_v21_sessions(gateway);
2823 fax_session_release(gateway->s, gateway->token);
2824 gateway->token = NULL;
2826 ao2_unlink(faxregistry.container, gateway->s);
2828 ao2_ref(gateway->s, -1);
2832 ao2_cleanup(gateway->chan_read_format);
2833 ao2_cleanup(gateway->chan_write_format);
2834 ao2_cleanup(gateway->peer_read_format);
2835 ao2_cleanup(gateway->peer_write_format);
2838 /*! \brief Create a new fax gateway object.
2839 * \param chan the channel the gateway object will be attached to
2840 * \param details the fax session details
2841 * \return NULL or a fax gateway object
2843 static struct fax_gateway *fax_gateway_new(struct ast_channel *chan, struct ast_fax_session_details *details)
2845 struct fax_gateway *gateway = ao2_alloc(sizeof(*gateway), destroy_gateway);
2846 struct ast_fax_session_details *v21_details;
2851 if (!(v21_details = session_details_new())) {
2852 ao2_ref(gateway, -1);
2856 v21_details->caps = AST_FAX_TECH_V21_DETECT;
2857 if (!(gateway->chan_v21_session = fax_session_new(v21_details, chan, NULL, NULL))) {
2858 ao2_ref(v21_details, -1);
2859 ao2_ref(gateway, -1);
2863 if (!(gateway->peer_v21_session = fax_session_new(v21_details, chan, NULL, NULL))) {
2864 ao2_ref(v21_details, -1);
2865 ao2_ref(gateway, -1);
2868 ao2_ref(v21_details, -1);
2870 gateway->framehook = -1;
2872 details->caps = AST_FAX_TECH_GATEWAY;
2873 if (details->gateway_timeout && !(gateway->s = fax_session_reserve(details, &gateway->token))) {
2874 details->caps &= ~AST_FAX_TECH_GATEWAY;
2875 ast_log(LOG_ERROR, "Can't reserve a FAX session, gateway attempt failed.\n");
2876 ao2_ref(gateway, -1);
2883 /*! \brief Create a fax session and start T.30<->T.38 gateway mode
2884 * \param gateway a fax gateway object
2885 * \param details fax session details
2886 * \param chan active channel
2887 * \return 0 on error 1 on success*/
2888 static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session_details *details, struct ast_channel *chan)
2890 struct ast_fax_session *s;
2892 /* create the FAX session */
2893 if (!(s = fax_session_new(details, chan, gateway->s, gateway->token))) {
2894 gateway->token = NULL;
2895 ast_string_field_set(details, result, "FAILED");
2896 ast_string_field_set(details, resultstr, "error starting gateway session");
2897 ast_string_field_set(details, error, "INIT_ERROR");
2898 set_channel_variables(chan, details);
2899 report_fax_status(chan, details, "No Available Resource");
2900 ast_log(LOG_ERROR, "Can't create a FAX session, gateway attempt failed.\n");
2903 /* release the reference for the reserved session and replace it with
2904 * the real session */
2906 ao2_ref(gateway->s, -1);
2909 gateway->token = NULL;
2911 if (gateway->s->tech->start_session(gateway->s) < 0) {
2912 ast_string_field_set(details, result, "FAILED");
2913 ast_string_field_set(details, resultstr, "error starting gateway session");
2914 ast_string_field_set(details, error, "INIT_ERROR");
2915 set_channel_variables(chan, details);
2919 gateway->timeout_start.tv_sec = 0;
2920 gateway->timeout_start.tv_usec = 0;
2922 report_fax_status(chan, details, "FAX Transmission In Progress");
2927 static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_frame *f)
2929 struct ast_frame *fp;
2930 struct ast_control_t38_parameters t38_parameters = {
2931 .request_response = AST_T38_REQUEST_NEGOTIATE,
2933 struct ast_frame control_frame = {
2935 .frametype = AST_FRAME_CONTROL,
2936 .datalen = sizeof(t38_parameters),
2937 .subclass.integer = AST_CONTROL_T38_PARAMETERS,
2938 .data.ptr = &t38_parameters,
2941 struct ast_fax_session_details *details = find_details(chan);
2944 ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
2945 ast_framehook_detach(chan, gateway->framehook);
2949 t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
2950 ao2_ref(details, -1);
2952 if (!(fp = ast_frisolate(&control_frame))) {
2953 ast_log(LOG_ERROR, "error generating T.38 request control frame on chan %s for T.38 gateway session\n", ast_channel_name(chan));
2957 gateway->t38_state = T38_STATE_NEGOTIATING;
2958 gateway->timeout_start = ast_tvnow();
2959 details->gateway_timeout = FAX_GATEWAY_TIMEOUT;
2961 ast_debug(1, "requesting T.38 for gateway session for %s\n", ast_channel_name(chan));
2965 static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *active, struct ast_frame *f)
2967 struct ast_channel *other = (active == chan) ? peer : chan;
2968 struct ast_fax_session *active_v21_session = (active == chan) ? gateway->chan_v21_session : gateway->peer_v21_session;
2970 if (!active_v21_session || gateway->detected_v21) {
2974 if (active_v21_session->tech->write(active_v21_session, f) == 0 &&
2975 active_v21_session->details->option.v21_detected) {
2976 gateway->detected_v21 = 1;
2979 if (gateway->detected_v21) {
2980 destroy_v21_sessions(gateway);
2981 if (ast_channel_get_t38_state(other) == T38_STATE_UNKNOWN) {
2982 ast_debug(1, "detected v21 preamble from %s\n", ast_channel_name(active));
2983 return fax_gateway_request_t38(gateway, chan, f);
2985 ast_debug(1, "detected v21 preamble on %s, but %s does not support T.38 for T.38 gateway session\n", ast_channel_name(active), ast_channel_name(other));
2992 static int fax_gateway_indicate_t38(struct ast_channel *chan, struct ast_channel *active, struct ast_control_t38_parameters *control_params)
2994 if (active == chan) {
2995 return ast_indicate_data(chan, AST_CONTROL_T38_PARAMETERS, control_params, sizeof(*control_params));