diff spandsp-0.0.6pre17/src/spandsp/t38_core.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/t38_core.h	Fri Jun 25 15:50:58 2010 +0200
@@ -0,0 +1,403 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * t38_core.h - An implementation of T.38, less the packet exchange part
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2005 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: t38_core.h,v 1.39 2009/07/14 13:54:22 steveu Exp $
+ */
+
+/*! \file */
+
+#if !defined(_SPANDSP_T38_CORE_H_)
+#define _SPANDSP_T38_CORE_H_
+
+/*! \page t38_core_page T.38 real time FAX over IP message handling
+There are two ITU recommendations which address sending FAXes over IP networks. T.37 specifies a
+method of encapsulating FAX images in e-mails, and transporting them to the recipient (an e-mail
+box, or another FAX machine) in a store-and-forward manner. T.38 defines a protocol for
+transmitting a FAX across an IP network in real time. The core T.38 modules implements the basic
+message handling for the T.38, real time, FAX over IP (FoIP) protocol.
+
+The T.38 protocol can operate between:
+    - Internet-aware FAX terminals, which connect directly to an IP network. The T.38 terminal module
+      extends this module to provide a complete T.38 terminal.
+    - FAX gateways, which allow traditional PSTN FAX terminals to communicate through the Internet.
+      The T.38 gateway module extends this module to provide a T.38 gateway.
+    - A combination of terminals and gateways.
+
+T.38 is the only standardised protocol which exists for real-time FoIP. Reliably transporting a
+FAX between PSTN FAX terminals, through an IP network, requires use of the T.38 protocol at FAX
+gateways. VoIP connections are not robust for modem use, including FAX modem use. Most use low
+bit rate codecs, which cannot convey the modem signals accurately. Even when high bit rate
+codecs are used, VoIP connections suffer dropouts and timing adjustments, which modems cannot
+tolerate. In a LAN environment the dropout rate may be very low, but the timing adjustments which
+occur in VoIP connections still make modem operation unreliable. T.38 FAX gateways deal with the
+delays, timing jitter, and packet loss experienced in packet networks, and isolate the PSTN FAX
+terminals from these as far as possible. In addition, by sending FAXes as image data, rather than
+digitised audio, they reduce the required bandwidth of the IP network.
+
+\section t38_core_page_sec_1 What does it do?
+
+\section t38_core_page_sec_2 How does it work?
+
+Timing differences and jitter between two T.38 entities can be a serious problem, if one of those
+entities is a PSTN gateway.
+
+Flow control for non-ECM image data takes advantage of several features of the T.30 specification.
+First, an unspecified number of 0xFF octets may be sent at the start of transmission. This means we
+can add endless extra 0xFF bytes at this point, without breaking the T.30 spec. In practice, we
+cannot add too many, or we will affect the timing tolerance of the T.30 protocol by delaying the
+response at the end of each image. Secondly, just before an end of line (EOL) marker we can pad
+with zero bits. Again, the number is limited only by need to avoid upsetting the timing of the
+step following the non-ECM data.
+*/
+
+/*! T.38 indicator types */
+enum t30_indicator_types_e
+{
+    T38_IND_NO_SIGNAL = 0,
+    T38_IND_CNG,
+    T38_IND_CED,
+    T38_IND_V21_PREAMBLE,
+    T38_IND_V27TER_2400_TRAINING,
+    T38_IND_V27TER_4800_TRAINING,
+    T38_IND_V29_7200_TRAINING,
+    T38_IND_V29_9600_TRAINING,
+    T38_IND_V17_7200_SHORT_TRAINING,
+    T38_IND_V17_7200_LONG_TRAINING,
+    T38_IND_V17_9600_SHORT_TRAINING,
+    T38_IND_V17_9600_LONG_TRAINING,
+    T38_IND_V17_12000_SHORT_TRAINING,
+    T38_IND_V17_12000_LONG_TRAINING,
+    T38_IND_V17_14400_SHORT_TRAINING,
+    T38_IND_V17_14400_LONG_TRAINING,
+    T38_IND_V8_ANSAM,
+    T38_IND_V8_SIGNAL,
+    T38_IND_V34_CNTL_CHANNEL_1200,
+    T38_IND_V34_PRI_CHANNEL,
+    T38_IND_V34_CC_RETRAIN,
+    T38_IND_V33_12000_TRAINING,
+    T38_IND_V33_14400_TRAINING
+};
+
+/*! T.38 data types */
+enum t38_data_types_e
+{
+    T38_DATA_NONE = -1,
+    T38_DATA_V21 = 0,
+    T38_DATA_V27TER_2400,
+    T38_DATA_V27TER_4800,
+    T38_DATA_V29_7200,
+    T38_DATA_V29_9600,
+    T38_DATA_V17_7200,
+    T38_DATA_V17_9600,
+    T38_DATA_V17_12000,
+    T38_DATA_V17_14400,
+    T38_DATA_V8,
+    T38_DATA_V34_PRI_RATE,
+    T38_DATA_V34_CC_1200,
+    T38_DATA_V34_PRI_CH,
+    T38_DATA_V33_12000,
+    T38_DATA_V33_14400
+};
+
+/*! T.38 data field types */
+enum t38_field_types_e
+{
+    T38_FIELD_HDLC_DATA = 0,
+    T38_FIELD_HDLC_SIG_END,
+    T38_FIELD_HDLC_FCS_OK,
+    T38_FIELD_HDLC_FCS_BAD,
+    T38_FIELD_HDLC_FCS_OK_SIG_END,
+    T38_FIELD_HDLC_FCS_BAD_SIG_END,
+    T38_FIELD_T4_NON_ECM_DATA,
+    T38_FIELD_T4_NON_ECM_SIG_END,
+    T38_FIELD_CM_MESSAGE,
+    T38_FIELD_JM_MESSAGE,
+    T38_FIELD_CI_MESSAGE,
+    T38_FIELD_V34RATE
+};
+
+/*! T.38 field classes */
+enum t38_field_classes_e
+{
+    T38_FIELD_CLASS_NONE = 0,
+    T38_FIELD_CLASS_HDLC,
+    T38_FIELD_CLASS_NON_ECM
+};
+
+/*! T.38 message types */
+enum t38_message_types_e
+{
+    T38_TYPE_OF_MSG_T30_INDICATOR = 0,
+    T38_TYPE_OF_MSG_T30_DATA
+};
+
+/*! T.38 transport types */
+enum t38_transport_types_e
+{
+    T38_TRANSPORT_UDPTL = 0,
+    T38_TRANSPORT_RTP,
+    T38_TRANSPORT_TCP
+};
+
+/*! T.38 TCF management types */
+enum t38_data_rate_management_types_e
+{
+    T38_DATA_RATE_MANAGEMENT_LOCAL_TCF = 1,
+    T38_DATA_RATE_MANAGEMENT_TRANSFERRED_TCF = 2
+};
+
+/*! T.38 Packet categories used for setting the redundancy level and packet repeat
+    counts on a packet by packet basis. */
+enum t38_packet_categories_e
+{
+    /*! \brief Indicator packet */
+    T38_PACKET_CATEGORY_INDICATOR = 0,
+    /*! \brief Control data packet */
+    T38_PACKET_CATEGORY_CONTROL_DATA = 1,
+    /*! \brief Terminating control data packet */
+    T38_PACKET_CATEGORY_CONTROL_DATA_END = 2,
+    /*! \brief Image data packet */
+    T38_PACKET_CATEGORY_IMAGE_DATA = 3,
+    /*! \brief Terminating image data packet */
+    T38_PACKET_CATEGORY_IMAGE_DATA_END = 4
+};
+
+#define T38_RX_BUF_LEN  2048
+#define T38_TX_BUF_LEN  16384
+
+/*! T.38 data field */
+typedef struct
+{
+    /*! Field type */
+    int field_type;
+    /*! Field contents */
+    const uint8_t *field;
+    /*! Field length */
+    int field_len;
+} t38_data_field_t;
+
+/*!
+    Core T.38 state, common to all modes of T.38.
+*/
+typedef struct t38_core_state_s t38_core_state_t;
+
+typedef int (t38_tx_packet_handler_t)(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count);
+
+typedef int (t38_rx_indicator_handler_t)(t38_core_state_t *s, void *user_data, int indicator);
+typedef int (t38_rx_data_handler_t)(t38_core_state_t *s, void *user_data, int data_type, int field_type, const uint8_t *buf, int len);
+typedef int (t38_rx_missing_handler_t)(t38_core_state_t *s, void *user_data, int rx_seq_no, int expected_seq_no);
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/*! \brief Convert the code for an indicator to a short text name.
+    \param indicator The type of indicator.
+    \return A pointer to a short text name for the indicator. */
+SPAN_DECLARE(const char *) t38_indicator_to_str(int indicator);
+
+/*! \brief Convert the code for a type of data to a short text name.
+    \param data_type The data type.
+    \return A pointer to a short text name for the data type. */
+SPAN_DECLARE(const char *) t38_data_type_to_str(int data_type);
+
+/*! \brief Convert the code for a type of data field to a short text name.
+    \param field_type The field type.
+    \return A pointer to a short text name for the field type. */
+SPAN_DECLARE(const char *) t38_field_type_to_str(int field_type);
+
+/*! \brief Convert the code for a CM profile code to text description.
+    \param profile The profile code from a CM message.
+    \return A pointer to a short text description of the profile. */
+SPAN_DECLARE(const char *) t38_cm_profile_to_str(int profile);
+
+/*! \brief Convert a JM message code to text description.
+    \param data The data field of the message.
+    \param len The length of the data field.
+    \return A pointer to a short text description of the profile. */
+SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len);
+
+/*! \brief Convert a V34rate message to an actual bit rate.
+    \param data The data field of the message.
+    \param len The length of the data field.
+    \return The bit rate, or -1 for a bad message. */
+SPAN_DECLARE(int) t38_v34rate_to_bps(const uint8_t *data, int len);
+
+/*! \brief Send an indicator packet
+    \param s The T.38 context.
+    \param indicator The indicator to send.
+    \return The delay to allow after this indicator is sent. */
+SPAN_DECLARE(int) t38_core_send_indicator(t38_core_state_t *s, int indicator);
+
+/*! \brief Find the delay to allow for HDLC flags after sending an indicator
+    \param s The T.38 context.
+    \param indicator The indicator to send.
+    \return The delay to allow for initial HDLC flags after this indicator is sent. */
+SPAN_DECLARE(int) t38_core_send_flags_delay(t38_core_state_t *s, int indicator);
+
+/*! \brief Send a data packet
+    \param s The T.38 context.
+    \param data_type The packet's data type.
+    \param field_type The packet's field type.
+    \param field The message data content for the packet.
+    \param field_len The length of the message data, in bytes.
+    \param category The category of the packet being sent. This should be one of the values defined for t38_packet_categories_e.
+    \return ??? */
+SPAN_DECLARE(int) t38_core_send_data(t38_core_state_t *s, int data_type, int field_type, const uint8_t field[], int field_len, int category);
+
+/*! \brief Send a data packet
+    \param s The T.38 context.
+    \param data_type The packet's data type.
+    \param field The list of fields.
+    \param fields The number of fields in the list.
+    \param category The category of the packet being sent. This should be one of the values defined for t38_packet_categories_e.
+    \return ??? */
+SPAN_DECLARE(int) t38_core_send_data_multi_field(t38_core_state_t *s, int data_type, const t38_data_field_t field[], int fields, int category);
+
+/*! \brief Process a received T.38 IFP packet.
+    \param s The T.38 context.
+    \param buf The packet contents.
+    \param len The length of the packet contents.
+    \param seq_no The packet sequence number.
+    \return 0 for OK, else -1. */
+SPAN_DECLARE(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no);
+
+/*! Set the method to be used for data rate management, as per the T.38 spec.
+    \param s The T.38 context.
+    \param method 1 for pass TCF across the T.38 link, 2 for handle TCF locally.
+*/
+SPAN_DECLARE(void) t38_set_data_rate_management_method(t38_core_state_t *s, int method);
+
+/*! Set the data transport protocol.
+    \param s The T.38 context.
+    \param data_transport_protocol UDPTL, RTP or TPKT.
+*/
+SPAN_DECLARE(void) t38_set_data_transport_protocol(t38_core_state_t *s, int data_transport_protocol);
+
+/*! Set the non-ECM fill bit removal mode.
+    \param s The T.38 context.
+    \param fill_bit_removal TRUE to remove fill bits across the T.38 link, else FALSE.
+*/
+SPAN_DECLARE(void) t38_set_fill_bit_removal(t38_core_state_t *s, int fill_bit_removal);
+
+/*! Set the MMR transcoding mode.
+    \param s The T.38 context.
+    \param mmr_transcoding TRUE to transcode to MMR across the T.38 link, else FALSE.
+*/
+SPAN_DECLARE(void) t38_set_mmr_transcoding(t38_core_state_t *s, int mmr_transcoding);
+
+/*! Set the JBIG transcoding mode.
+    \param s The T.38 context.
+    \param jbig_transcoding TRUE to transcode to JBIG across the T.38 link, else FALSE.
+*/
+SPAN_DECLARE(void) t38_set_jbig_transcoding(t38_core_state_t *s, int jbig_transcoding);
+
+/*! Set the maximum buffer size for received data at the far end.
+    \param s The T.38 context.
+    \param max_buffer_size The maximum buffer size.
+*/
+SPAN_DECLARE(void) t38_set_max_buffer_size(t38_core_state_t *s, int max_buffer_size);
+
+/*! Set the maximum size of an IFP packet that is acceptable by the far end.
+    \param s The T.38 context.
+    \param max_datagram_size The maximum IFP packet length, in bytes.
+*/
+SPAN_DECLARE(void) t38_set_max_datagram_size(t38_core_state_t *s, int max_datagram_size);
+
+/*! \brief Send a data packet
+    \param s The T.38 context.
+    \param category The category of the packet being sent. This should be one of the values defined for t38_packet_categories_e.
+    \param setting The repeat count for the category. This should be at least one for all categories other an indicator packets.
+                   Zero is valid for indicator packets, as it suppresses the sending of indicator packets, as an application using
+                   TCP for the transport would require. As the setting is passed through to the transmission channel, additional
+                   information may be encoded in it, such as the redundancy depth for the particular packet category. */
+SPAN_DECLARE(void) t38_set_redundancy_control(t38_core_state_t *s, int category, int setting);
+
+SPAN_DECLARE(void) t38_set_fastest_image_data_rate(t38_core_state_t *s, int max_rate);
+
+SPAN_DECLARE(int) t38_get_fastest_image_data_rate(t38_core_state_t *s);
+
+/*! Set the T.38 version to be emulated.
+    \param s The T.38 context.
+    \param t38_version Version number, as in the T.38 spec.
+*/
+SPAN_DECLARE(void) t38_set_t38_version(t38_core_state_t *s, int t38_version);
+
+/*! Set the sequence number handling option.
+    \param s The T.38 context.
+    \param check TRUE to check sequence numbers, and handle gaps reasonably. FALSE
+           for no sequence number processing (e.g. for TPKT over TCP transport).
+*/
+SPAN_DECLARE(void) t38_set_sequence_number_handling(t38_core_state_t *s, int check);
+
+/*! Set the TEP handling option.
+    \param s The T.38 context.
+    \param allow_for_tep TRUE to allow for TEP playout, else FALSE.
+*/
+SPAN_DECLARE(void) t38_set_tep_handling(t38_core_state_t *s, int allow_for_tep);
+
+/*! Get a pointer to the logging context associated with a T.38 context.
+    \brief Get a pointer to the logging context associated with a T.38 context.
+    \param s The T.38 context.
+    \return A pointer to the logging context, or NULL.
+*/
+SPAN_DECLARE(logging_state_t *) t38_core_get_logging_state(t38_core_state_t *s);
+
+/*! Initialise a T.38 core context.
+    \brief Initialise a T.38 core context.
+    \param s The T.38 context.
+    \param rx_indicator_handler Receive indicator handling routine.
+    \param rx_data_handler Receive data packet handling routine.
+    \param rx_rx_missing_handler Missing receive packet handling routine.
+    \param rx_packet_user_data An opaque pointer passed to the rx packet handling routines.
+    \param tx_packet_handler Packet transmit handling routine.
+    \param tx_packet_user_data An opaque pointer passed to the tx_packet_handler.
+    \return A pointer to the T.38 context, or NULL if there was a problem. */
+SPAN_DECLARE(t38_core_state_t *) t38_core_init(t38_core_state_t *s,
+                                               t38_rx_indicator_handler_t *rx_indicator_handler,
+                                               t38_rx_data_handler_t *rx_data_handler,
+                                               t38_rx_missing_handler_t *rx_missing_handler,
+                                               void *rx_user_data,
+                                               t38_tx_packet_handler_t *tx_packet_handler,
+                                               void *tx_packet_user_data);
+
+/*! Release a signaling tone transmitter context.
+    \brief Release a signaling tone transmitter context.
+    \param s The T.38 context.
+    \return 0 for OK */
+SPAN_DECLARE(int) t38_core_release(t38_core_state_t *s);
+
+/*! Free a signaling tone transmitter context.
+    \brief Free a signaling tone transmitter context.
+    \param s The T.38 context.
+    \return 0 for OK */
+SPAN_DECLARE(int) t38_core_free(t38_core_state_t *s);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/

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