diff spandsp-0.0.6pre17/src/spandsp/t30.h @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spandsp-0.0.6pre17/src/spandsp/t30.h	Fri Jun 25 15:50:58 2010 +0200
@@ -0,0 +1,683 @@
+/*
+ * 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 Lesser General Public License version 2.1,
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.126.4.1 2009/12/19 09:47:56 steveu Exp $
+ */
+
+/*! \file */
+
+#if !defined(_SPANDSP_T30_H_)
+#define _SPANDSP_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.
+    - V.27ter, V.29 and V.17 modes (2400bps, to 14,400bps).
+    - T.4 1D (MH), T.4 2D,(MR) and T.6 (MMR) compression.
+    - Error correction mode (ECM).
+    - All standard horizonal resolutions (R8, R16, 300dpi, 600dpi, 800dpi, 1200dpi).
+    - All standard vertical resolutions (standard, fine, superfine, 300dpi, 600dpi, 800dpi, 1200dpi).
+    - All standard page widths (A4, B4, A3).
+    - All standard page lengths (A4, B4, North American letter, North American legal, continuous).
+    - Monitoring and sending identifier strings (CSI, TSI, and CIG).
+    - Monitoring and sending sub-address strings (SUB).
+    - Monitoring and sending polling sub-addresses (SEP).
+    - Monitoring and sending polled sub-addresses (PSA).
+    - Monitoring and sending sender identifications (SID).
+    - Monitoring and sending passwords (PWD).
+    - Monitoring of non-standard facility frames (NSF, NSC, and NSS).
+    - Sending custom non-standard facility frames (NSF, NSC, and NSS).
+    - Analogue modem and T.38 operation.
+
+\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.
+
+\subsection t30_page_sec_2a 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.
+
+\subsection t30_page_sec_2b 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.
+
+\subsection t30_page_sec_2c 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.. 
+
+\subsection t30_page_sec_2d 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. 
+
+\subsection t30_page_sec_2e 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
+*/
+
+/*! The maximum length of a DIS, DTC or DCS frame */
+#define T30_MAX_DIS_DTC_DCS_LEN     22
+/*! The maximum length of the body of an ident string */
+#define T30_MAX_IDENT_LEN           20
+/*! The maximum length of the user string to insert in page headers */
+#define T30_MAX_PAGE_HEADER_INFO    50
+
+typedef struct t30_state_s t30_state_t;
+
+/*!
+    T.30 phase B callback handler. This handler can be used to process addition
+    information available in some FAX calls, such as passwords. The callback handler
+    can access whatever additional information might have been received, using
+    t30_get_received_info().
+    \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.
+    \return The new status. Normally, T30_ERR_OK is returned.
+*/
+typedef int (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.
+    \return The new status. Normally, T30_ERR_OK is returned.
+*/
+typedef int (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 real time frame handler.
+    \brief T.30 real time frame handler.
+    \param s The T.30 context.
+    \param user_data An opaque pointer.
+    \param direction TRUE for incoming, FALSE for outgoing.
+    \param msg The HDLC message.
+    \param len The length of the message.
+*/
+typedef void (t30_real_time_frame_handler_t)(t30_state_t *s,
+                                             void *user_data,
+                                             int direction,
+                                             const uint8_t msg[],
+                                             int len);
+
+/*!
+    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 bit_rate The bit rate of the modem 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 bit_rate, 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 */
+
+    /* Link problems */
+    T30_ERR_CEDTONE,            /*! The CED tone exceeded 5s */
+    T30_ERR_T0_EXPIRED,         /*! Timed out waiting for initial communication */
+    T30_ERR_T1_EXPIRED,         /*! Timed out waiting for the first message */
+    T30_ERR_T3_EXPIRED,         /*! Timed out waiting for procedural interrupt */
+    T30_ERR_HDLC_CARRIER,       /*! The HDLC carrier did not stop in a timely manner */
+    T30_ERR_CANNOT_TRAIN,       /*! Failed to train with any of the compatible modems */
+    T30_ERR_OPER_INT_FAIL,      /*! Operator intervention failed */
+    T30_ERR_INCOMPATIBLE,       /*! Far end is not compatible */
+    T30_ERR_RX_INCAPABLE,       /*! Far end is not able to receive */
+    T30_ERR_TX_INCAPABLE,       /*! Far end is not able to transmit */
+    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 */
+    T30_ERR_UNEXPECTED,         /*! Unexpected message received */
+
+    /* Phase E status values returned to a transmitter */
+    T30_ERR_TX_BADDCS,          /*! Received bad response to DCS or training */
+    T30_ERR_TX_BADPG,           /*! Received a DCN from remote after sending a page */
+    T30_ERR_TX_ECMPHD,          /*! Invalid ECM response received from receiver */
+    T30_ERR_TX_GOTDCN,          /*! Received a DCN while waiting for a DIS */
+    T30_ERR_TX_INVALRSP,        /*! Invalid response after sending a page */
+    T30_ERR_TX_NODIS,           /*! Received other than DIS while waiting for DIS */
+    T30_ERR_TX_PHBDEAD,         /*! Received no response to DCS, training or TCF */
+    T30_ERR_TX_PHDDEAD,         /*! No response after sending a page */
+    T30_ERR_TX_T5EXP,           /*! Timed out waiting for receiver ready (ECM mode) */
+
+    /* Phase E status values returned to a receiver */
+    T30_ERR_RX_ECMPHD,          /*! Invalid ECM response received from transmitter */
+    T30_ERR_RX_GOTDCS,          /*! DCS received while waiting for DTC */
+    T30_ERR_RX_INVALCMD,        /*! Unexpected command after page received */
+    T30_ERR_RX_NOCARRIER,       /*! Carrier lost during fax receive */
+    T30_ERR_RX_NOEOL,           /*! Timed out while waiting for EOL (end Of line) */
+    T30_ERR_RX_NOFAX,           /*! Timed out while waiting for first line */
+    T30_ERR_RX_T2EXPDCN,        /*! Timer T2 expired while waiting for DCN */
+    T30_ERR_RX_T2EXPD,          /*! Timer T2 expired while waiting for phase D */
+    T30_ERR_RX_T2EXPFAX,        /*! Timer T2 expired while waiting for fax page */
+    T30_ERR_RX_T2EXPMPS,        /*! Timer T2 expired while waiting for next fax page */
+    T30_ERR_RX_T2EXPRR,         /*! Timer T2 expired while waiting for RR command */
+    T30_ERR_RX_T2EXP,           /*! Timer T2 expired while waiting for NSS, DCS or MCF */
+    T30_ERR_RX_DCNWHY,          /*! Unexpected DCN while waiting for DCS or DIS */
+    T30_ERR_RX_DCNDATA,         /*! Unexpected DCN while waiting for image data */
+    T30_ERR_RX_DCNFAX,          /*! Unexpected DCN while waiting for EOM, EOP or MPS */
+    T30_ERR_RX_DCNPHD,          /*! Unexpected DCN after EOM or MPS sequence */
+    T30_ERR_RX_DCNRRD,          /*! Unexpected DCN after RR/RNR sequence */
+    T30_ERR_RX_DCNNORTN,        /*! Unexpected DCN after requested retransmission */
+
+    /* TIFF file 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_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_NOMEM,              /*! Cannot allocate memory for more pages */
+    
+    /* General problems */
+    T30_ERR_RETRYDCN,           /*! Disconnected after permitted retries */
+    T30_ERR_CALLDROPPED,        /*! The call dropped prematurely */
+    
+    /* Feature negotiation issues */
+    T30_ERR_NOPOLL,             /*! Poll not accepted */
+    T30_ERR_IDENT_UNACCEPTABLE, /*! Far end's ident is not acceptable */
+    T30_ERR_SUB_UNACCEPTABLE,   /*! Far end's sub-address is not acceptable */
+    T30_ERR_SEP_UNACCEPTABLE,   /*! Far end's selective polling address is not acceptable */
+    T30_ERR_PSA_UNACCEPTABLE,   /*! Far end's polled sub-address is not acceptable */
+    T30_ERR_SID_UNACCEPTABLE,   /*! Far end's sender identification is not acceptable */
+    T30_ERR_PWD_UNACCEPTABLE,   /*! Far end's password is not acceptable */
+    T30_ERR_TSA_UNACCEPTABLE,   /*! Far end's transmitting subscriber internet address is not acceptable */
+    T30_ERR_IRA_UNACCEPTABLE,   /*! Far end's internet routing address is not acceptable */
+    T30_ERR_CIA_UNACCEPTABLE,   /*! Far end's calling subscriber internet address is not acceptable */
+    T30_ERR_ISP_UNACCEPTABLE,   /*! Far end's internet selective polling address is not acceptable */
+    T30_ERR_CSA_UNACCEPTABLE    /*! Far end's called subscriber internet address is not acceptable */
+};
+
+/*!
+    I/O modes for the T.30 protocol.
+    These are allocated such that the lower 4 bits represents the variant of the modem - e.g. the
+    particular bit rate selected.
+*/
+enum
+{
+    T30_MODEM_NONE = 0,
+    T30_MODEM_PAUSE,
+    T30_MODEM_CED,
+    T30_MODEM_CNG,
+    T30_MODEM_V21,
+    T30_MODEM_V27TER,
+    T30_MODEM_V29,
+    T30_MODEM_V17,
+    T30_MODEM_DONE
+};
+
+enum
+{
+    T30_FRONT_END_SEND_STEP_COMPLETE = 0,
+    /*! 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. */
+    T30_FRONT_END_RECEIVE_COMPLETE,
+    T30_FRONT_END_SIGNAL_PRESENT,
+    T30_FRONT_END_SIGNAL_ABSENT,
+    T30_FRONT_END_CED_PRESENT,
+    T30_FRONT_END_CNG_PRESENT
+};
+
+enum
+{
+    /*! Support the V.27ter modem (2400, and 4800bps) for image transfer. */
+    T30_SUPPORT_V27TER = 0x01,
+    /*! Support the V.29 modem (9600, and 7200bps) for image transfer. */
+    T30_SUPPORT_V29 = 0x02,
+    /*! Support the V.17 modem (14400, 12000, 9600 and 7200bps) for image transfer. */
+    T30_SUPPORT_V17 = 0x04,
+    /*! Support the V.34 modem (up to 33,600bps) for image transfer. */
+    T30_SUPPORT_V34 = 0x08,
+    /*! Support the Internet aware FAX mode (no bit rate limit) for image transfer. */
+    T30_SUPPORT_IAF = 0x10
+};
+
+enum
+{
+    /*! No compression */
+    T30_SUPPORT_NO_COMPRESSION = 0x01,
+    /*! T.1 1D compression */
+    T30_SUPPORT_T4_1D_COMPRESSION = 0x02,
+    /*! T.4 2D compression */
+    T30_SUPPORT_T4_2D_COMPRESSION = 0x04,
+    /*! T.6 2D compression */
+    T30_SUPPORT_T6_COMPRESSION = 0x08,
+    /*! T.85 monochrome JBIG compression */
+    T30_SUPPORT_T85_COMPRESSION = 0x10,
+    /*! T.43 colour JBIG compression */
+    T30_SUPPORT_T43_COMPRESSION = 0x20,
+    /*! T.45 run length colour compression */
+    T30_SUPPORT_T45_COMPRESSION = 0x40,
+    /*! T.81 + T.30 Annex E colour JPEG compression */
+    T30_SUPPORT_T81_COMPRESSION = 0x80,
+    /*! T.81 + T.30 Annex K colour sYCC-JPEG compression */
+    T30_SUPPORT_SYCC_T81_COMPRESSION = 0x100,
+    /*! T.88 monochrome JBIG2 compression */
+    T30_SUPPORT_T88_COMPRESSION = 0x200
+};
+
+enum
+{
+    /*! Support standard FAX Y-resolution 98/100dpi */
+    T30_SUPPORT_STANDARD_RESOLUTION = 0x01,
+    /*! Support fine FAX Y-resolution 196/200dpi */
+    T30_SUPPORT_FINE_RESOLUTION = 0x02,
+    /*! Support super-fine FAX Y-resolution 392/400dpi */
+    T30_SUPPORT_SUPERFINE_RESOLUTION = 0x04,
+
+    /*! Support half FAX X-resolution 100/102dpi */
+    T30_SUPPORT_R4_RESOLUTION = 0x10000,
+    /*! Support standard FAX X-resolution 200/204dpi */
+    T30_SUPPORT_R8_RESOLUTION = 0x20000,
+    /*! Support double FAX X-resolution 400dpi */
+    T30_SUPPORT_R16_RESOLUTION = 0x40000,
+
+    /*! Support 300dpi x 300 dpi */
+    T30_SUPPORT_300_300_RESOLUTION = 0x100000,
+    /*! Support 400dpi x 400 dpi */
+    T30_SUPPORT_400_400_RESOLUTION = 0x200000,
+    /*! Support 600dpi x 600 dpi */
+    T30_SUPPORT_600_600_RESOLUTION = 0x400000,
+    /*! Support 1200dpi x 1200 dpi */
+    T30_SUPPORT_1200_1200_RESOLUTION = 0x800000,
+    /*! Support 300dpi x 600 dpi */
+    T30_SUPPORT_300_600_RESOLUTION = 0x1000000,
+    /*! Support 400dpi x 800 dpi */
+    T30_SUPPORT_400_800_RESOLUTION = 0x2000000,
+    /*! Support 600dpi x 1200 dpi */
+    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
+{
+    /*! Enable support of identification, through the SID and/or PWD frames. */
+    T30_SUPPORT_IDENTIFICATION = 0x01,
+    /*! Enable support of selective polling, through the SEP frame. */
+    T30_SUPPORT_SELECTIVE_POLLING = 0x02,
+    /*! Enable support of polling sub-addressing, through the PSA frame. */
+    T30_SUPPORT_POLLED_SUB_ADDRESSING = 0x04,
+    /*! Enable support of multiple selective polling, through repeated used of the SEP and PSA frames. */
+    T30_SUPPORT_MULTIPLE_SELECTIVE_POLLING = 0x08,
+    /*! Enable support of sub-addressing, through the SUB frame. */
+    T30_SUPPORT_SUB_ADDRESSING = 0x10,
+    /*! Enable support of transmitting subscriber internet address, through the TSA frame. */
+    T30_SUPPORT_TRANSMITTING_SUBSCRIBER_INTERNET_ADDRESS = 0x20,
+    /*! Enable support of internet routing address, through the IRA frame. */
+    T30_SUPPORT_INTERNET_ROUTING_ADDRESS = 0x40,
+    /*! Enable support of calling subscriber internet address, through the CIA frame. */
+    T30_SUPPORT_CALLING_SUBSCRIBER_INTERNET_ADDRESS = 0x80,
+    /*! Enable support of internet selective polling address, through the ISP frame. */
+    T30_SUPPORT_INTERNET_SELECTIVE_POLLING_ADDRESS = 0x100,
+    /*! Enable support of called subscriber internet address, through the CSA frame. */
+    T30_SUPPORT_CALLED_SUBSCRIBER_INTERNET_ADDRESS = 0x200,
+    /*! Enable support of the field not valid (FNV) frame. */
+    T30_SUPPORT_FIELD_NOT_VALID = 0x400,
+    /*! Enable support of the command repeat (CRP) frame. */
+    T30_SUPPORT_COMMAND_REPEAT = 0x800
+};
+
+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,
+    /*! No indicators means do not send indicator messages when using T.38. */
+    T30_IAF_MODE_NO_INDICATORS = 0x40,
+    /*! Use relaxed timers for T.38. This is appropriate when using TCP/TPKT for T.38,
+        as there is no point in anything but a long backstop timeout in such a mode. */
+    T30_IAF_MODE_RELAXED_TIMERS = 0x80
+};
+
+typedef struct
+{
+    /*! \brief The identifier string (CSI, TSI, CIG). */
+    char ident[T30_MAX_IDENT_LEN + 1];
+    /*! \brief The sub-address string (SUB). */
+    char sub_address[T30_MAX_IDENT_LEN + 1];
+    /*! \brief The selective polling sub-address (SEP). */
+    char selective_polling_address[T30_MAX_IDENT_LEN + 1];
+    /*! \brief The polled sub-address (PSA). */
+    char polled_sub_address[T30_MAX_IDENT_LEN + 1];
+    /*! \brief The sender identification (SID). */
+    char sender_ident[T30_MAX_IDENT_LEN + 1];
+    /*! \brief The password (PWD). */
+    char password[T30_MAX_IDENT_LEN + 1];
+    /*! \brief Non-standard facilities (NSF). */
+    uint8_t *nsf;
+    size_t nsf_len;
+    /*! \brief Non-standard facilities command (NSC). */
+    uint8_t *nsc;
+    size_t nsc_len;
+    /*! \brief Non-standard facilities set-up (NSS). */
+    uint8_t *nss;
+    size_t nss_len;
+    /*! \brief Transmitting subscriber internet address (TSA). */
+    int tsa_type;
+    char *tsa;
+    size_t tsa_len;
+    /*! \brief Internet routing address (IRA). */
+    int ira_type;
+    char *ira;
+    size_t ira_len;
+    /*! \brief Calling subscriber internet address (CIA). */
+    int cia_type;
+    char *cia;
+    size_t cia_len;
+    /*! \brief Internet selective polling address (ISP). */
+    int isp_type;
+    char *isp;
+    size_t isp_len;
+    /*! \brief Called subscriber internet address (CSA). */
+    int csa_type;
+    char *csa;
+    size_t csa_len;
+} t30_exchanged_info_t;
+
+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 sent so far. */
+    int pages_tx;
+    /*! \brief The number of pages received so far. */
+    int pages_rx;
+    /*! \brief The number of pages in the file (<0 if not known). */
+    int pages_in_file;
+    /*! \brief The horizontal column-to-column resolution of the most recent page, in pixels per metre */
+    int x_resolution;
+    /*! \brief The vertical row-to-row resolution of the most recent page, in pixels per metre */
+    int y_resolution;
+    /*! \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 size of the image, in bytes */
+    int image_size;
+    /*! \brief The type of compression used between the FAX machines */
+    int encoding;
+    /*! \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 number of HDLC frame retries, if error correcting mode is used. */
+    int error_correcting_mode_retries;
+    /*! \brief Current status */
+    int current_status;
+} t30_stats_t;
+
+#if defined(__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.
+    \param set_rx_type_handler
+    \param set_rx_type_user_data
+    \param set_tx_type_handler
+    \param set_tx_type_user_data
+    \param send_hdlc_handler
+    \param send_hdlc_user_data
+    \return A pointer to the context, or NULL if there was a problem. */
+SPAN_DECLARE(t30_state_t *) 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.
+    \return 0 for OK, else -1. */
+SPAN_DECLARE(int) t30_release(t30_state_t *s);
+
+/*! Free a T.30 context.
+    \brief Free a T.30 context.
+    \param s The T.30 context.
+    \return 0 for OK, else -1. */
+SPAN_DECLARE(int) t30_free(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. */
+SPAN_DECLARE(int) t30_restart(t30_state_t *s);
+
+/*! Check if a T.30 call is still active. This may be used to regularly poll
+    if the job has finished.
+    \brief Check if a T.30 call is still active.
+    \param s The T.30 context.
+    \return TRUE for call still active, or FALSE for call completed. */
+SPAN_DECLARE(int) t30_call_active(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. */
+SPAN_DECLARE(void) t30_terminate(t30_state_t *s);
+
+/*! Inform the T.30 engine of a status change in the front end (end of tx, rx signal change, etc.).
+    \brief Inform the T.30 engine of a status change in the front end (end of tx, rx signal change, etc.).
+    \param user_data The T.30 context.
+    \param status The type of status change which occured. */
+SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status);
+
+/*! 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 The next bit to transmit. */
+SPAN_DECLARE_NONSTD(int) t30_non_ecm_get_bit(void *user_data);
+
+/*! Get a byte of received non-ECM image data.
+    \brief Get a byte of received non-ECM image data.
+    \param user_data An opaque pointer, which must point to the T.30 context.
+    \return The next byte to transmit. */
+SPAN_DECLARE(int) t30_non_ecm_get_byte(void *user_data);
+
+/*! Get a chunk 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.
+    \param buf The buffer to contain the data.
+    \param max_len The maximum length of the chunk.
+    \return The actual length of the chunk. */
+SPAN_DECLARE(int) t30_non_ecm_get_chunk(void *user_data, uint8_t buf[], int max_len);
+
+/*! 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. */
+SPAN_DECLARE_NONSTD(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. */
+SPAN_DECLARE(void) t30_non_ecm_put_byte(void *user_data, int byte);
+
+/*! Process a chunk of received non-ECM image data.
+    \brief Process a chunk of received non-ECM image data
+    \param user_data An opaque pointer, which must point to the T.30 context.
+    \param buf The buffer containing the received data.
+    \param len The length of the data in buf. */
+SPAN_DECLARE(void) t30_non_ecm_put_chunk(void *user_data, const uint8_t buf[], int len);
+
+/*! Process a received HDLC frame.
+    \brief Process a received HDLC frame.
+    \param user_data The T.30 context.
+    \param msg The HDLC message.
+    \param len The length of the message, in octets.
+    \param ok TRUE if the frame was received without error. */
+SPAN_DECLARE_NONSTD(void) t30_hdlc_accept(void *user_data, const uint8_t msg[], int len, int ok);
+
+/*! 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. */
+SPAN_DECLARE(void) t30_timer_update(t30_state_t *s, int samples);
+
+/*! 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. */
+SPAN_DECLARE(void) t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t);
+
+/*! 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. */
+SPAN_DECLARE(void) t30_local_interrupt_request(t30_state_t *s, int state);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.