Mercurial > hg > audiostuff
diff spandsp-0.0.3/spandsp-0.0.3/src/spandsp/t30.h @ 5:f762bf195c4b
import spandsp-0.0.3
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:00:21 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spandsp-0.0.3/spandsp-0.0.3/src/spandsp/t30.h Fri Jun 25 16:00:21 2010 +0200 @@ -0,0 +1,846 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * t30.h - definitions for T.30 fax processing + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2003 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: t30.h,v 1.61 2006/11/01 12:58:21 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_T30_H_) +#define _T30_H_ + +/*! \page t30_page T.30 FAX protocol handling + +\section t30_page_sec_1 What does it do? +The T.30 protocol is the core protocol used for FAX transmission. This module +implements most of its key featrues. It does not interface to the outside work. +Seperate modules do that for T.38, analogue line, and other forms of FAX +communication. + +Current features of this module include: + + - FAXing to and from multi-page TIFF/F files, whose images are one of the standard + FAX sizes. + - T.4 1D (MH), T.4 2D,(MR) and T.6 (MMR) compression. + - Error correction (ECM) + - All standard resolutions and page sizes + +\section t30_page_sec_2 How does it work? + +Some of the following is paraphrased from some notes found a while ago on the Internet. +I cannot remember exactly where they came from, but they are useful. + +The answer (CED) tone + +The T.30 standard says an answering fax device must send CED (a 2100Hz tone) for +approximately 3 seconds before sending the first handshake message. Some machines +send an 1100Hz or 1850Hz tone, and some send no tone at all. In fact, this answer +tone is so unpredictable, it cannot really be used. It should, however, always be +generated according to the specification. + +Common Timing Deviations + +The T.30 spec. specifies a number of time-outs. For example, after dialing a number, +a calling fax system should listen for a response for 35 seconds before giving up. +These time-out periods are as follows: + + * T1 - 35+-5s: the maximum time for which two fax system will attempt to identify each other + * T2 - 6+-1s: a time-out used to start the sequence for changing transmit parameters + * T3 - 10+-5s: a time-out used in handling operator interrupts + * T5 - 60+-5s: a time-out used in error correction mode + +These time-outs are sometimes misinterpreted. In addition, they are routinely +ignored, sometimes with good reason. For example, after placing a call, the +calling fax system is supposed to wait for 35 seconds before giving up. If the +answering unit does not answer on the first ring or if a voice answering machine +is connected to the line, or if there are many delays through the network, +the delay before answer can be much longer than 35 seconds. + +Fax units that support error correction mode (ECM) can respond to a post-image +handshake message with a receiver not ready (RNR) message. The calling unit then +queries the receiving fax unit with a receiver ready (RR) message. If the +answering unit is still busy (printing for example), it will repeat the RNR +message. According to the T.30 standard, this sequence (RR/RNR RR/RNR) can be +repeated for up to the end of T5 (60+-5s). However, many fax systems +ignore the time-out and will continue the sequence indefinitely, unless the user +manually overrides. + +All the time-outs are subject to alteration, and sometimes misuse. Good T.30 +implementations must do the right thing, and tolerate others doing the wrong thing. + +Variations in the inter-carrier gap + +T.30 specifies 75+-20ms of silence between signals using different modulation +schemes. Examples are between the end of a DCS signal and the start of a TCF signal, +and between the end of an image and the start of a post-image signal. Many fax systems +violate this requirement, especially for the silent period between DCS and TCF. +This may be stretched to well over 100ms. If this period is too long, it can interfere with +handshake signal error recovery, should a packet be corrupted on the line. Systems +should ensure they stay within the prescribed T.30 limits, and be tolerant of others +being out of spec.. + +Other timing variations + +Testing is required to determine the ability of a fax system to handle +variations in the duration of pauses between unacknowledged handshake message +repetitions, and also in the pauses between the receipt of a handshake command and +the start of a response to that command. In order to reduce the total +transmission time, many fax systems start sending a response message before the +end of the command has been received. + +Other deviations from the T.30 standard + +There are many other commonly encountered variations between machines, including: + + * frame sequence deviations + * preamble and flag sequence variations + * improper EOM usage + * unusual data rate fallback sequences + * common training pattern detection algorithms + * image transmission deviations + * use of the talker echo protect tone + * image padding and short lines + * RTP/RTN handshake message usage + * long duration lines + * nonstandard disconnect sequences + * DCN usage +*/ + +#define T30_MAX_DIS_DTC_DCS_LEN 22 +#define T30_MAX_IDENT_LEN 21 + +typedef struct t30_state_s t30_state_t; + +/*! + T.30 phase B callback handler. + \brief T.30 phase B callback handler. + \param s The T.30 context. + \param user_data An opaque pointer. + \param result The phase B event code. +*/ +typedef void (t30_phase_b_handler_t)(t30_state_t *s, void *user_data, int result); + +/*! + T.30 phase D callback handler. + \brief T.30 phase D callback handler. + \param s The T.30 context. + \param user_data An opaque pointer. + \param result The phase D event code. +*/ +typedef void (t30_phase_d_handler_t)(t30_state_t *s, void *user_data, int result); + +/*! + T.30 phase E callback handler. + \brief T.30 phase E callback handler. + \param s The T.30 context. + \param user_data An opaque pointer. + \param completion_code The phase E completion code. +*/ +typedef void (t30_phase_e_handler_t)(t30_state_t *s, void *user_data, int completion_code); + +/*! + T.30 document handler. + \brief T.30 document handler. + \param s The T.30 context. + \param user_data An opaque pointer. + \param result The document event code. +*/ +typedef int (t30_document_handler_t)(t30_state_t *s, void *user_data, int status); + +/*! + T.30 set a receive or transmit type handler. + \brief T.30 set a receive or transmit type handler. + \param user_data An opaque pointer. + \param type The modem, tone or silence to be sent or received. + \param short_train TRUE if the short training sequence should be used (where one exists). + \param use_hdlc FALSE for bit stream, TRUE for HDLC framing. +*/ +typedef void (t30_set_handler_t)(void *user_data, int type, int short_train, int use_hdlc); + +/*! + T.30 send HDLC handler. + \brief T.30 send HDLC handler. + \param user_data An opaque pointer. + \param msg The HDLC message. + \param len The length of the message. +*/ +typedef void (t30_send_hdlc_handler_t)(void *user_data, const uint8_t *msg, int len); + +/*! + T.30 protocol completion codes, at phase E. +*/ +enum +{ + T30_ERR_OK = 0, /* OK */ + + /* External problems */ + T30_ERR_CEDTONE, /* The CED tone exceeded 5s */ + T30_ERR_T0EXPIRED, /* Timed out waiting for initial communication */ + T30_ERR_T1EXPIRED, /* Timed out waiting for the first message */ + T30_ERR_T3EXPIRED, /* Timed out waiting for procedural interrupt */ + T30_ERR_HDLCCARR, /* The HDLC carrier did not stop in a timely manner */ + T30_ERR_CANNOTTRAIN, /* Failed to train with any of the compatible modems */ + T30_ERR_OPERINTFAIL, /* Operator intervention failed */ + T30_ERR_INCOMPATIBLE, /* Far end is not compatible */ + T30_ERR_NOTRXCAPABLE, /* Far end is not receive capable */ + T30_ERR_NOTTXCAPABLE, /* Far end is not transmit capable */ + T30_ERR_UNEXPECTED, /* Unexpected message received */ + T30_ERR_NORESSUPPORT, /* Far end cannot receive at the resolution of the image */ + T30_ERR_NOSIZESUPPORT, /* Far end cannot receive at the size of image */ + + /* Internal problems */ + T30_ERR_FILEERROR, /* TIFF/F file cannot be opened */ + T30_ERR_NOPAGE, /* TIFF/F page not found */ + T30_ERR_BADTIFF, /* TIFF/F format is not compatible */ + T30_ERR_UNSUPPORTED, /* Unsupported feature */ + + /* Phase E status values returned to a transmitter */ + T30_ERR_BADDCSTX, /* Received bad response to DCS or training */ + T30_ERR_BADPGTX, /* Received a DCN from remote after sending a page */ + T30_ERR_ECMPHDTX, /* Invalid ECM response received from receiver */ + T30_ERR_ECMRNRTX, /* Timer T5 expired, receiver not ready */ + T30_ERR_GOTDCNTX, /* Received a DCN while waiting for a DIS */ + T30_ERR_INVALRSPTX, /* Invalid response after sending a page */ + T30_ERR_NODISTX, /* Received other than DIS while waiting for DIS */ + T30_ERR_NXTCMDTX, /* Timed out waiting for next send_page command from driver */ + T30_ERR_PHBDEADTX, /* Received no response to DCS, training or TCF */ + T30_ERR_PHDDEADTX, /* No response after sending a page */ + + /* Phase E status values returned to a receiver */ + T30_ERR_ECMPHDRX, /* Invalid ECM response received from transmitter */ + T30_ERR_GOTDCSRX, /* DCS received while waiting for DTC */ + T30_ERR_INVALCMDRX, /* Unexpected command after page received */ + T30_ERR_NOCARRIERRX, /* Carrier lost during fax receive */ + T30_ERR_NOEOLRX, /* Timed out while waiting for EOL (end Of line) */ + T30_ERR_NOFAXRX, /* Timed out while waiting for first line */ + T30_ERR_NXTCMDRX, /* Timed out waiting for next receive page command */ + T30_ERR_T2EXPDCNRX, /* Timer T2 expired while waiting for DCN */ + T30_ERR_T2EXPDRX, /* Timer T2 expired while waiting for phase D */ + T30_ERR_T2EXPFAXRX, /* Timer T2 expired while waiting for fax page */ + T30_ERR_T2EXPMPSRX, /* Timer T2 expired while waiting for next fax page */ + T30_ERR_T2EXPRRRX, /* Timer T2 expired while waiting for RR command */ + T30_ERR_T2EXPRX, /* Timer T2 expired while waiting for NSS, DCS or MCF */ + T30_ERR_DCNWHYRX, /* Unexpected DCN while waiting for DCS or DIS */ + T30_ERR_DCNDATARX, /* Unexpected DCN while waiting for image data */ + T30_ERR_DCNFAXRX, /* Unexpected DCN while waiting for EOM, EOP or MPS */ + T30_ERR_DCNPHDRX, /* Unexpected DCN after EOM or MPS sequence */ + T30_ERR_DCNRRDRX, /* Unexpected DCN after RR/RNR sequence */ + T30_ERR_DCNNORTNRX, /* Unexpected DCN after requested retransmission */ + + T30_ERR_BADPAGE, /* TIFF/F page number tag missing */ + T30_ERR_BADTAG, /* Incorrect values for TIFF/F tags */ + T30_ERR_BADTIFFHDR, /* Bad TIFF/F header - incorrect values in fields */ + T30_ERR_BADPARM, /* Invalid value for fax parameter */ + T30_ERR_BADSTATE, /* Invalid initial state value specified */ + T30_ERR_CMDDATA, /* Last command contained invalid data */ + T30_ERR_DISCONNECT, /* Fax call disconnected by the other station */ + T30_ERR_INVALARG, /* Illegal argument to function */ + T30_ERR_INVALFUNC, /* Illegal call to function */ + T30_ERR_NODATA, /* Data requested is not available (NSF, DIS, DCS) */ + T30_ERR_NOMEM, /* Cannot allocate memory for more pages */ + T30_ERR_NOPOLL, /* Poll not accepted */ + T30_ERR_NOSTATE, /* Initial state value not set */ + T30_ERR_RETRYDCN, /* Disconnected after permitted retries */ + T30_ERR_CALLDROPPED /* The call dropped prematurely */ +}; + +/*! + I/O modes for the T.30 protocol. +*/ +enum +{ + T30_MODEM_NONE = 0, + T30_MODEM_PAUSE, + T30_MODEM_CED, + T30_MODEM_CNG, + T30_MODEM_V21, + T30_MODEM_V27TER_2400, + T30_MODEM_V27TER_4800, + T30_MODEM_V29_7200, + T30_MODEM_V29_9600, + T30_MODEM_V17_7200, + T30_MODEM_V17_9600, + T30_MODEM_V17_12000, + T30_MODEM_V17_14400, + T30_MODEM_DONE +}; + +enum +{ + T30_SUPPORT_V27TER = 0x01, + T30_SUPPORT_V29 = 0x02, + T30_SUPPORT_V17 = 0x04, + T30_SUPPORT_V34 = 0x08, + T30_SUPPORT_IAF = 0x10, +}; + +enum +{ + T30_SUPPORT_NO_COMPRESSION = 0x01, + T30_SUPPORT_T4_1D_COMPRESSION = 0x02, + T30_SUPPORT_T4_2D_COMPRESSION = 0x04, + T30_SUPPORT_T6_COMPRESSION = 0x08, + T30_SUPPORT_T85_COMPRESSION = 0x10, /* Monochrome JBIG */ + T30_SUPPORT_T43_COMPRESSION = 0x20, /* Colour JBIG */ + T30_SUPPORT_T45_COMPRESSION = 0x40 /* Run length colour compression */ +}; + +enum +{ + T30_SUPPORT_STANDARD_RESOLUTION = 0x01, + T30_SUPPORT_FINE_RESOLUTION = 0x02, + T30_SUPPORT_SUPERFINE_RESOLUTION = 0x04, + + T30_SUPPORT_R4_RESOLUTION = 0x10000, + T30_SUPPORT_R8_RESOLUTION = 0x20000, + T30_SUPPORT_R16_RESOLUTION = 0x40000, + + T30_SUPPORT_300_300_RESOLUTION = 0x100000, + T30_SUPPORT_400_400_RESOLUTION = 0x200000, + T30_SUPPORT_600_600_RESOLUTION = 0x400000, + T30_SUPPORT_1200_1200_RESOLUTION = 0x800000, + T30_SUPPORT_300_600_RESOLUTION = 0x1000000, + T30_SUPPORT_400_800_RESOLUTION = 0x2000000, + T30_SUPPORT_600_1200_RESOLUTION = 0x4000000 +}; + +enum +{ + T30_SUPPORT_215MM_WIDTH = 0x01, + T30_SUPPORT_255MM_WIDTH = 0x02, + T30_SUPPORT_303MM_WIDTH = 0x04, + + T30_SUPPORT_UNLIMITED_LENGTH = 0x10000, + T30_SUPPORT_A4_LENGTH = 0x20000, + T30_SUPPORT_B4_LENGTH = 0x40000, + T30_SUPPORT_US_LETTER_LENGTH = 0x80000, + T30_SUPPORT_US_LEGAL_LENGTH = 0x100000 +}; + +enum +{ + T30_SUPPORT_SEP = 0x01, + T30_SUPPORT_PSA = 0x02 +}; + +enum +{ + T30_IAF_MODE_T37 = 0x01, + T30_IAF_MODE_T38 = 0x02, + T30_IAF_MODE_FLOW_CONTROL = 0x04, + /*! Continuous flow mode means data is sent as fast as possible, usually across + the Internet, where speed is not constrained by a PSTN modem. */ + T30_IAF_MODE_CONTINUOUS_FLOW = 0x08, + /*! No TCF means TCF is not exchanged. The end points must sort out usable speed + issues locally. */ + T30_IAF_MODE_NO_TCF = 0x10, + /*! No fill bits means do not insert fill bits, even if the T.30 messages request + them. */ + T30_IAF_MODE_NO_FILL_BITS = 0x20 +}; + +/*! + T.30 FAX channel descriptor. This defines the state of a single working + instance of a T.30 FAX channel. +*/ +struct t30_state_s +{ + /* This must be kept the first thing in the structure, so it can be pointed + to reliably as the structures change over time. */ + t4_state_t t4; + + /*! \brief TRUE is behaving as the calling party */ + int calling_party; + + /*! \brief The local identifier string. */ + char local_ident[T30_MAX_IDENT_LEN]; + /*! \brief The identifier string supplied by the remote FAX machine. */ + char far_ident[T30_MAX_IDENT_LEN]; + /*! \brief The sub-address string to be sent to the remote FAX machine. */ + char local_sub_address[T30_MAX_IDENT_LEN]; + /*! \brief The sub-address string supplied by the remote FAX machine. */ + char far_sub_address[T30_MAX_IDENT_LEN]; + /*! \brief The selective polling sub-address supplied by the remote FAX machine. */ + char sep_address[T30_MAX_IDENT_LEN]; + /*! \brief The polled sub-address supplied by the remote FAX machine. */ + char psa_address[T30_MAX_IDENT_LEN]; + /*! \brief A password to be associated with the T.30 context. */ + char local_password[T30_MAX_IDENT_LEN]; + /*! \brief A password expected from the far end. */ + char far_password[T30_MAX_IDENT_LEN]; + /*! \brief The text which will be used in FAX page header. No text results + in no header line. */ + char header_info[50 + 1]; + /*! \brief The country of origin of the remote machine, if known, else NULL. */ + const char *country; + /*! \brief The vendor of the remote machine, if known, else NULL. */ + const char *vendor; + /*! \brief The model of the remote machine, if known, else NULL. */ + const char *model; + uint8_t local_nsf[100]; + int local_nsf_len; + + /*! \brief A pointer to a callback routine to be called when phase B events + occur. */ + t30_phase_b_handler_t *phase_b_handler; + /*! \brief An opaque pointer supplied in event B callbacks. */ + void *phase_b_user_data; + /*! \brief A pointer to a callback routine to be called when phase D events + occur. */ + t30_phase_d_handler_t *phase_d_handler; + /*! \brief An opaque pointer supplied in event D callbacks. */ + void *phase_d_user_data; + /*! \brief A pointer to a callback routine to be called when phase E events + occur. */ + t30_phase_e_handler_t *phase_e_handler; + /*! \brief An opaque pointer supplied in event E callbacks. */ + void *phase_e_user_data; + + /*! \brief A pointer to a callback routine to be called when document events + (e.g. end of transmitted document) occur. */ + t30_document_handler_t *document_handler; + /*! \brief An opaque pointer supplied in document callbacks. */ + void *document_user_data; + + t30_set_handler_t *set_rx_type_handler; + void *set_rx_type_user_data; + t30_set_handler_t *set_tx_type_handler; + void *set_tx_type_user_data; + + t30_send_hdlc_handler_t *send_hdlc_handler; + void *send_hdlc_user_data; + + int phase; + int next_phase; + int state; + int step; + + uint8_t dcs_frame[T30_MAX_DIS_DTC_DCS_LEN]; + int dcs_len; + uint8_t dis_dtc_frame[T30_MAX_DIS_DTC_DCS_LEN]; + int dis_dtc_len; + /*! \brief TRUE if a valid DIS has been received from the far end. */ + int dis_received; + /*! \brief TRUE if a valid passwrod has been received from the far end. */ + int far_password_ok; + + /*! \brief A flag to indicate a message is in progress. */ + int in_message; + + /*! \brief TRUE if the short training sequence should be used. */ + int short_train; + + /*! \brief A count of the number of bits in the trainability test. */ + int training_test_bits; + int training_current_zeros; + int training_most_zeros; + + /*! \brief The current fallback step for the fast message transfer modem. */ + int current_fallback; + /*! \brief TRUE if a carrier is present. Otherwise FALSE. */ + int rx_signal_present; + /*! \brief TRUE if a modem has trained correctly. */ + int rx_trained; + int current_rx_type; + int current_tx_type; + + /*! \brief T0 is the answer timeout when calling another FAX machine. + Placing calls is handled outside the FAX processing, but this timeout keeps + running until V.21 modulation is sent or received. + T1 is the remote terminal identification timeout (in audio samples). */ + int timer_t0_t1; + /*! \brief T2 is the HDLC command timeout. + T4 is the HDLC response timeout (in audio samples). */ + int timer_t2_t4; + /*! \brief TRUE if the T2/T4 timer is actually timing T4 */ + int timer_is_t4; + /*! \brief Procedural interrupt timeout (in audio samples). */ + int timer_t3; + /*! \brief This is only used in error correcting mode. */ + int timer_t5; + /*! \brief This is only used in full duplex (e.g. ISDN) modes. */ + int timer_t6; + /*! \brief This is only used in full duplex (e.g. ISDN) modes. */ + int timer_t7; + /*! \brief This is only used in full duplex (e.g. ISDN) modes. */ + int timer_t8; + + int far_end_detected; + + int local_interrupt_pending; + int crp_enabled; + int line_encoding; + int min_row_bits; + int x_resolution; + int y_resolution; + int image_width; + int retries; + int error_correcting_mode; + int ppr_count; + int octets_per_ecm_frame; + uint8_t ecm_data[256][260]; + int16_t ecm_len[256]; + uint8_t ecm_frame_map[3 + 32]; + int ecm_page; + int ecm_block; + int ecm_frames; + int ecm_current_frame; + int ecm_at_page_end; + int next_tx_step; + int next_rx_step; + char rx_file[256]; + int rx_stop_page; + char tx_file[256]; + int tx_start_page; + int tx_stop_page; + int current_status; + int iaf; + int supported_modems; + int supported_compressions; + int supported_resolutions; + int supported_image_sizes; + int supported_polling_features; + int ecm_allowed; + /*! \brief Error and flow logging control */ + logging_state_t logging; +}; + +typedef struct +{ + /*! \brief The current bit rate for image transfer. */ + int bit_rate; + /*! \brief TRUE if error correcting mode is used. */ + int error_correcting_mode; + /*! \brief The number of pages transferred so far. */ + int pages_transferred; + /*! \brief The number of horizontal pixels in the most recent page. */ + int width; + /*! \brief The number of vertical pixels in the most recent page. */ + int length; + /*! \brief The number of bad pixel rows in the most recent page. */ + int bad_rows; + /*! \brief The largest number of bad pixel rows in a block in the most recent page. */ + int longest_bad_row_run; + /*! \brief The horizontal column-to-column resolution of the page in pixels per metre */ + int x_resolution; + /*! \brief The vertical row-to-row resolution of the page in pixels per metre */ + int y_resolution; + /*! \brief The type of compression used between the FAX machines */ + int encoding; + /*! \brief The size of the image, in bytes */ + int image_size; + /*! \brief Current status */ + int current_status; +} t30_stats_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/*! Initialise a T.30 context. + \brief Initialise a T.30 context. + \param s The T.30 context. + \param calling_party TRUE if the context is for a calling party. FALSE if the + context is for an answering party. + \return 0 for OK, else -1. */ +int t30_init(t30_state_t *s, + int calling_party, + t30_set_handler_t *set_rx_type_handler, + void *set_rx_type_user_data, + t30_set_handler_t *set_tx_type_handler, + void *set_tx_type_user_data, + t30_send_hdlc_handler_t *send_hdlc_handler, + void *send_hdlc_user_data); + +/*! Release a T.30 context. + \brief Release a T.30 context. + \param s The T.30 context. */ +void t30_release(t30_state_t *s); + +/*! Restart a T.30 context. + \brief Restart a T.30 context. + \param s The T.30 context. + \return 0 for OK, else -1. */ +int t30_restart(t30_state_t *s); + +/*! Create and initialise a T.30 context. + \brief Create and initialise a T.30 context. + \param calling_party TRUE if the context is for a calling party. FALSE if the + context is for an answering party. + \return A pointer to the FAX context, or NULL if one could not be created. +*/ +t30_state_t *t30_create(int calling_party, + t30_set_handler_t *set_rx_type_handler, + void *set_rx_type_user_data, + t30_set_handler_t *set_tx_type_handler, + void *set_tx_type_user_data, + t30_send_hdlc_handler_t *send_hdlc_handler, + void *send_hdlc_user_data); + +/*! Free a T.30 context. + \brief Free a T.30 context. + \param s The T.30 context. */ +void t30_free(t30_state_t *s); + +/*! Cleanup a T.30 context if the call terminates. + \brief Cleanup a T.30 context if the call terminates. + \param s The T.30 context. */ +void t30_terminate(t30_state_t *s); + +/*! Return a text name for a T.30 frame type. + \brief Return a text name for a T.30 frame type. + \param x The frametype octet. + \return A pointer to the text name for the frame type. If the frame type is + not value, the string "???" is returned. */ +const char *t30_frametype(uint8_t x); + +/*! Decode a DIS, DTC or DCS frame, and log the contents. + \brief Decode a DIS, DTC or DCS frame, and log the contents. + \param s The T.30 context. + \param dis A pointer to the frame to be decoded. + \param len The length of the frame. */ +void t30_decode_dis_dtc_dcs(t30_state_t *s, const uint8_t *dis, int len); + +/*! Convert a phase E completion code to a short text description. + \brief Convert a phase E completion code to a short text description. + \param result The result code. + \return A pointer to the description. */ +const char *t30_completion_code_to_str(int result); + +/*! Set Internet aware FAX (IAF) mode. + \brief Set Internet aware FAX (IAF) mode. + \param s The T.30 context. + \param iaf TRUE for IAF, or FALSE for non-IAF. */ +void t30_set_iaf_mode(t30_state_t *s, int iaf); + +/*! Set the sub-address associated with a T.30 context. + \brief Set the sub-address associated with a T.30 context. + \param s The T.30 context. + \param sub_address A pointer to the sub-address. + \return 0 for OK, else -1. */ +int t30_set_local_sub_address(t30_state_t *s, const char *sub_address); + +/*! Set the header information associated with a T.30 context. + \brief Set the header information associated with a T.30 context. + \param s The T.30 context. + \param info A pointer to the information string. + \return 0 for OK, else -1. */ +int t30_set_header_info(t30_state_t *s, const char *info); + +/*! Set the local identifier associated with a T.30 context. + \brief Set the local identifier associated with a T.30 context. + \param s The T.30 context. + \param id A pointer to the identifier. + \return 0 for OK, else -1. */ +int t30_set_local_ident(t30_state_t *s, const char *id); + +int t30_set_local_nsf(t30_state_t *s, const uint8_t *nsf, int len); + +/*! Get the sub-address associated with a T.30 context. + \brief Get the sub-address associated with a T.30 context. + \param s The T.30 context. + \param sub_address A pointer to a buffer for the sub-address. The buffer + should be at least 21 bytes long. + \return the length of the string. */ +size_t t30_get_sub_address(t30_state_t *s, char *sub_address); + +/*! Get the header information associated with a T.30 context. + \brief Get the header information associated with a T.30 context. + \param s The T.30 context. + \param sub_address A pointer to a buffer for the header information. The buffer + should be at least 51 bytes long. + \return the length of the string. */ +size_t t30_get_header_info(t30_state_t *s, char *info); + +/*! Get the local FAX machine identifier associated with a T.30 context. + \brief Get the local identifier associated with a T.30 context. + \param s The T.30 context. + \param id A pointer to a buffer for the identifier. The buffer should + be at least 21 bytes long. + \return the length of the string. */ +size_t t30_get_local_ident(t30_state_t *s, char *id); + +/*! Get the remote FAX machine identifier associated with a T.30 context. + \brief Get the remote identifier associated with a T.30 context. + \param s The T.30 context. + \param id A pointer to a buffer for the identifier. The buffer should + be at least 21 bytes long. + \return the length of the string. */ +size_t t30_get_far_ident(t30_state_t *s, char *id); + +/*! Get the country of origin of the remote FAX machine associated with a T.30 context. + \brief Get the country of origin of the remote FAX machine associated with a T.30 context. + \param s The T.30 context. + \return a pointer to the country name, or NULL if the country is not known. */ +const char *t30_get_far_country(t30_state_t *s); + +/*! Get the name of the vendor of the remote FAX machine associated with a T.30 context. + \brief Get the name of the vendor of the remote FAX machine associated with a T.30 context. + \param s The T.30 context. + \return a pointer to the vendor name, or NULL if the vendor is not known. */ +const char *t30_get_far_vendor(t30_state_t *s); + +/*! Get the name of the model of the remote FAX machine associated with a T.30 context. + \brief Get the name of the model of the remote FAX machine associated with a T.30 context. + \param s The T.30 context. + \return a pointer to the model name, or NULL if the model is not known. */ +const char *t30_get_far_model(t30_state_t *s); + +/*! Get the current transfer statistics for the file being sent or received. + \brief Get the current transfer statistics. + \param s The T.30 context. + \param t A pointer to a buffer for the statistics. */ +void t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t); + +/*! Set a callback function for T.30 phase B handling. + \brief Set a callback function for T.30 phase B handling. + \param s The T.30 context. + \param handler The callback function + \param user_data An opaque pointer passed to the callback function. */ +void t30_set_phase_b_handler(t30_state_t *s, t30_phase_b_handler_t *handler, void *user_data); + +/*! Set a callback function for T.30 phase D handling. + \brief Set a callback function for T.30 phase D handling. + \param s The T.30 context. + \param handler The callback function + \param user_data An opaque pointer passed to the callback function. */ +void t30_set_phase_d_handler(t30_state_t *s, t30_phase_d_handler_t *handler, void *user_data); + +/*! Set a callback function for T.30 phase E handling. + \brief Set a callback function for T.30 phase E handling. + \param s The T.30 context. + \param handler The callback function + \param user_data An opaque pointer passed to the callback function. */ +void t30_set_phase_e_handler(t30_state_t *s, t30_phase_e_handler_t *handler, void *user_data); + +/*! Set a callback function for T.30 end of document handling. + \brief Set a callback function for T.30 end of document handling. + \param s The T.30 context. + \param handler The callback function + \param user_data An opaque pointer passed to the callback function. */ +void t30_set_document_handler(t30_state_t *s, t30_document_handler_t *handler, void *user_data); + +/*! Specify the file name of the next TIFF file to be received by a T.30 + context. + \brief Set next receive file name. + \param s The T.30 context. + \param file The file name + \param stop_page The maximum page to receive. -1 for no restriction. */ +void t30_set_rx_file(t30_state_t *s, const char *file, int stop_page); + +/*! Specify the file name of the next TIFF file to be transmitted by a T.30 + context. + \brief Set next transmit file name. + \param s The T.30 context. + \param file The file name + \param start_page The first page to send. -1 for no restriction. + \param stop_page The last page to send. -1 for no restriction. */ +void t30_set_tx_file(t30_state_t *s, const char *file, int start_page, int stop_page); + +/*! Specify which modem types are supported by a T.30 context. + \brief Specify supported modems. + \param s The T.30 context. + \param supported_modems Bit field list of the supported modems. */ +void t30_set_supported_modems(t30_state_t *s, int supported_modems); + +/*! Specify which compression types are supported by a T.30 context. + \brief Specify supported compression types. + \param s The T.30 context. + \param supported_compressions Bit field list of the supported compression types. */ +void t30_set_supported_compressions(t30_state_t *s, int supported_compressions); + +/*! Specify which resolutions are supported by a T.30 context. + \brief Specify supported resolutions. + \param s The T.30 context. + \param supported_compressions Bit field list of the supported resolutions. */ +void t30_set_supported_resolutions(t30_state_t *s, int supported_resolutions); + +/*! Specify which images sizes are supported by a T.30 context. + \brief Specify supported image sizes. + \param s The T.30 context. + \param supported_image_sizes Bit field list of the supported widths and lengths. */ +void t30_set_supported_image_sizes(t30_state_t *s, int supported_image_sizes); + +/*! Specify if error correction mode (ECM) is allowed by a T.30 context. + \brief Select ECM capability. + \param s The T.30 context. + \param enabled TRUE for ECM capable, FALSE for not ECM capable. */ +void t30_set_ecm_capability(t30_state_t *s, int enabled); + +/*! Request a local interrupt of FAX exchange. + \brief Request a local interrupt of FAX exchange. + \param s The T.30 context. + \param state TRUE to enable interrupt request, else FALSE. */ +void t30_local_interrupt_request(t30_state_t *s, int state); + +/*! Inform the T.30 engine the current transmission has completed. + \brief Inform the T.30 engine the current transmission has completed. + \param s The T.30 context. */ +void t30_send_complete(void *user_data); + +/*! Inform the T.30 engine the current receive has completed. This is + only needed to report an unexpected end of the receive operation, as + might happen with T.38 dying. + \brief Inform the T.30 engine the current receive has completed. + \param s The T.30 context. */ +void t30_receive_complete(void *user_data); + +/*! Get a bit of received non-ECM image data. + \brief Get a bit of received non-ECM image data. + \param user_data An opaque pointer, which must point to the T.30 context. + \return bit The next bit to transmit. */ +int t30_non_ecm_get_bit(void *user_data); + +/*! Process a bit of received non-ECM image data. + \brief Process a bit of received non-ECM image data + \param user_data An opaque pointer, which must point to the T.30 context. + \param bit The received bit. */ +void t30_non_ecm_put_bit(void *user_data, int bit); + +/*! Process a byte of received non-ECM image data. + \brief Process a byte of received non-ECM image data + \param user_data An opaque pointer, which must point to the T.30 context. + \param byte The received byte. */ +void t30_non_ecm_putbyte(void *user_data, int byte); + +/*! Process a received HDLC frame. + \brief Process a received HDLC frame. + \param s The T.30 context. + \param ok TRUE if the frame was received without error. + \param msg The HDLC message. + \param int The length of the message, in octets. */ +void t30_hdlc_accept(void *user_data, int ok, const uint8_t *msg, int len); + +/*! Report the passage of time to the T.30 engine. + \brief Report the passage of time to the T.30 engine. + \param s The T.30 context. + \param samples The time change in 1/8000th second steps. */ +void t30_timer_update(t30_state_t *s, int samples); + +#ifdef __cplusplus +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/