Mercurial > hg > audiostuff
comparison 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 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 | 
|---|---|
| 1 /* | |
| 2 * SpanDSP - a series of DSP components for telephony | |
| 3 * | |
| 4 * t38_core.h - An implementation of T.38, less the packet exchange part | |
| 5 * | |
| 6 * Written by Steve Underwood <steveu@coppice.org> | |
| 7 * | |
| 8 * Copyright (C) 2005 Steve Underwood | |
| 9 * | |
| 10 * All rights reserved. | |
| 11 * | |
| 12 * This program is free software; you can redistribute it and/or modify | |
| 13 * it under the terms of the GNU Lesser General Public License version 2.1, | |
| 14 * as published by the Free Software Foundation. | |
| 15 * | |
| 16 * This program is distributed in the hope that it will be useful, | |
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 19 * GNU Lesser General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU Lesser General Public | |
| 22 * License along with this program; if not, write to the Free Software | |
| 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 24 * | |
| 25 * $Id: t38_core.h,v 1.39 2009/07/14 13:54:22 steveu Exp $ | |
| 26 */ | |
| 27 | |
| 28 /*! \file */ | |
| 29 | |
| 30 #if !defined(_SPANDSP_T38_CORE_H_) | |
| 31 #define _SPANDSP_T38_CORE_H_ | |
| 32 | |
| 33 /*! \page t38_core_page T.38 real time FAX over IP message handling | |
| 34 There are two ITU recommendations which address sending FAXes over IP networks. T.37 specifies a | |
| 35 method of encapsulating FAX images in e-mails, and transporting them to the recipient (an e-mail | |
| 36 box, or another FAX machine) in a store-and-forward manner. T.38 defines a protocol for | |
| 37 transmitting a FAX across an IP network in real time. The core T.38 modules implements the basic | |
| 38 message handling for the T.38, real time, FAX over IP (FoIP) protocol. | |
| 39 | |
| 40 The T.38 protocol can operate between: | |
| 41 - Internet-aware FAX terminals, which connect directly to an IP network. The T.38 terminal module | |
| 42 extends this module to provide a complete T.38 terminal. | |
| 43 - FAX gateways, which allow traditional PSTN FAX terminals to communicate through the Internet. | |
| 44 The T.38 gateway module extends this module to provide a T.38 gateway. | |
| 45 - A combination of terminals and gateways. | |
| 46 | |
| 47 T.38 is the only standardised protocol which exists for real-time FoIP. Reliably transporting a | |
| 48 FAX between PSTN FAX terminals, through an IP network, requires use of the T.38 protocol at FAX | |
| 49 gateways. VoIP connections are not robust for modem use, including FAX modem use. Most use low | |
| 50 bit rate codecs, which cannot convey the modem signals accurately. Even when high bit rate | |
| 51 codecs are used, VoIP connections suffer dropouts and timing adjustments, which modems cannot | |
| 52 tolerate. In a LAN environment the dropout rate may be very low, but the timing adjustments which | |
| 53 occur in VoIP connections still make modem operation unreliable. T.38 FAX gateways deal with the | |
| 54 delays, timing jitter, and packet loss experienced in packet networks, and isolate the PSTN FAX | |
| 55 terminals from these as far as possible. In addition, by sending FAXes as image data, rather than | |
| 56 digitised audio, they reduce the required bandwidth of the IP network. | |
| 57 | |
| 58 \section t38_core_page_sec_1 What does it do? | |
| 59 | |
| 60 \section t38_core_page_sec_2 How does it work? | |
| 61 | |
| 62 Timing differences and jitter between two T.38 entities can be a serious problem, if one of those | |
| 63 entities is a PSTN gateway. | |
| 64 | |
| 65 Flow control for non-ECM image data takes advantage of several features of the T.30 specification. | |
| 66 First, an unspecified number of 0xFF octets may be sent at the start of transmission. This means we | |
| 67 can add endless extra 0xFF bytes at this point, without breaking the T.30 spec. In practice, we | |
| 68 cannot add too many, or we will affect the timing tolerance of the T.30 protocol by delaying the | |
| 69 response at the end of each image. Secondly, just before an end of line (EOL) marker we can pad | |
| 70 with zero bits. Again, the number is limited only by need to avoid upsetting the timing of the | |
| 71 step following the non-ECM data. | |
| 72 */ | |
| 73 | |
| 74 /*! T.38 indicator types */ | |
| 75 enum t30_indicator_types_e | |
| 76 { | |
| 77 T38_IND_NO_SIGNAL = 0, | |
| 78 T38_IND_CNG, | |
| 79 T38_IND_CED, | |
| 80 T38_IND_V21_PREAMBLE, | |
| 81 T38_IND_V27TER_2400_TRAINING, | |
| 82 T38_IND_V27TER_4800_TRAINING, | |
| 83 T38_IND_V29_7200_TRAINING, | |
| 84 T38_IND_V29_9600_TRAINING, | |
| 85 T38_IND_V17_7200_SHORT_TRAINING, | |
| 86 T38_IND_V17_7200_LONG_TRAINING, | |
| 87 T38_IND_V17_9600_SHORT_TRAINING, | |
| 88 T38_IND_V17_9600_LONG_TRAINING, | |
| 89 T38_IND_V17_12000_SHORT_TRAINING, | |
| 90 T38_IND_V17_12000_LONG_TRAINING, | |
| 91 T38_IND_V17_14400_SHORT_TRAINING, | |
| 92 T38_IND_V17_14400_LONG_TRAINING, | |
| 93 T38_IND_V8_ANSAM, | |
| 94 T38_IND_V8_SIGNAL, | |
| 95 T38_IND_V34_CNTL_CHANNEL_1200, | |
| 96 T38_IND_V34_PRI_CHANNEL, | |
| 97 T38_IND_V34_CC_RETRAIN, | |
| 98 T38_IND_V33_12000_TRAINING, | |
| 99 T38_IND_V33_14400_TRAINING | |
| 100 }; | |
| 101 | |
| 102 /*! T.38 data types */ | |
| 103 enum t38_data_types_e | |
| 104 { | |
| 105 T38_DATA_NONE = -1, | |
| 106 T38_DATA_V21 = 0, | |
| 107 T38_DATA_V27TER_2400, | |
| 108 T38_DATA_V27TER_4800, | |
| 109 T38_DATA_V29_7200, | |
| 110 T38_DATA_V29_9600, | |
| 111 T38_DATA_V17_7200, | |
| 112 T38_DATA_V17_9600, | |
| 113 T38_DATA_V17_12000, | |
| 114 T38_DATA_V17_14400, | |
| 115 T38_DATA_V8, | |
| 116 T38_DATA_V34_PRI_RATE, | |
| 117 T38_DATA_V34_CC_1200, | |
| 118 T38_DATA_V34_PRI_CH, | |
| 119 T38_DATA_V33_12000, | |
| 120 T38_DATA_V33_14400 | |
| 121 }; | |
| 122 | |
| 123 /*! T.38 data field types */ | |
| 124 enum t38_field_types_e | |
| 125 { | |
| 126 T38_FIELD_HDLC_DATA = 0, | |
| 127 T38_FIELD_HDLC_SIG_END, | |
| 128 T38_FIELD_HDLC_FCS_OK, | |
| 129 T38_FIELD_HDLC_FCS_BAD, | |
| 130 T38_FIELD_HDLC_FCS_OK_SIG_END, | |
| 131 T38_FIELD_HDLC_FCS_BAD_SIG_END, | |
| 132 T38_FIELD_T4_NON_ECM_DATA, | |
| 133 T38_FIELD_T4_NON_ECM_SIG_END, | |
| 134 T38_FIELD_CM_MESSAGE, | |
| 135 T38_FIELD_JM_MESSAGE, | |
| 136 T38_FIELD_CI_MESSAGE, | |
| 137 T38_FIELD_V34RATE | |
| 138 }; | |
| 139 | |
| 140 /*! T.38 field classes */ | |
| 141 enum t38_field_classes_e | |
| 142 { | |
| 143 T38_FIELD_CLASS_NONE = 0, | |
| 144 T38_FIELD_CLASS_HDLC, | |
| 145 T38_FIELD_CLASS_NON_ECM | |
| 146 }; | |
| 147 | |
| 148 /*! T.38 message types */ | |
| 149 enum t38_message_types_e | |
| 150 { | |
| 151 T38_TYPE_OF_MSG_T30_INDICATOR = 0, | |
| 152 T38_TYPE_OF_MSG_T30_DATA | |
| 153 }; | |
| 154 | |
| 155 /*! T.38 transport types */ | |
| 156 enum t38_transport_types_e | |
| 157 { | |
| 158 T38_TRANSPORT_UDPTL = 0, | |
| 159 T38_TRANSPORT_RTP, | |
| 160 T38_TRANSPORT_TCP | |
| 161 }; | |
| 162 | |
| 163 /*! T.38 TCF management types */ | |
| 164 enum t38_data_rate_management_types_e | |
| 165 { | |
| 166 T38_DATA_RATE_MANAGEMENT_LOCAL_TCF = 1, | |
| 167 T38_DATA_RATE_MANAGEMENT_TRANSFERRED_TCF = 2 | |
| 168 }; | |
| 169 | |
| 170 /*! T.38 Packet categories used for setting the redundancy level and packet repeat | |
| 171 counts on a packet by packet basis. */ | |
| 172 enum t38_packet_categories_e | |
| 173 { | |
| 174 /*! \brief Indicator packet */ | |
| 175 T38_PACKET_CATEGORY_INDICATOR = 0, | |
| 176 /*! \brief Control data packet */ | |
| 177 T38_PACKET_CATEGORY_CONTROL_DATA = 1, | |
| 178 /*! \brief Terminating control data packet */ | |
| 179 T38_PACKET_CATEGORY_CONTROL_DATA_END = 2, | |
| 180 /*! \brief Image data packet */ | |
| 181 T38_PACKET_CATEGORY_IMAGE_DATA = 3, | |
| 182 /*! \brief Terminating image data packet */ | |
| 183 T38_PACKET_CATEGORY_IMAGE_DATA_END = 4 | |
| 184 }; | |
| 185 | |
| 186 #define T38_RX_BUF_LEN 2048 | |
| 187 #define T38_TX_BUF_LEN 16384 | |
| 188 | |
| 189 /*! T.38 data field */ | |
| 190 typedef struct | |
| 191 { | |
| 192 /*! Field type */ | |
| 193 int field_type; | |
| 194 /*! Field contents */ | |
| 195 const uint8_t *field; | |
| 196 /*! Field length */ | |
| 197 int field_len; | |
| 198 } t38_data_field_t; | |
| 199 | |
| 200 /*! | |
| 201 Core T.38 state, common to all modes of T.38. | |
| 202 */ | |
| 203 typedef struct t38_core_state_s t38_core_state_t; | |
| 204 | |
| 205 typedef int (t38_tx_packet_handler_t)(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count); | |
| 206 | |
| 207 typedef int (t38_rx_indicator_handler_t)(t38_core_state_t *s, void *user_data, int indicator); | |
| 208 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); | |
| 209 typedef int (t38_rx_missing_handler_t)(t38_core_state_t *s, void *user_data, int rx_seq_no, int expected_seq_no); | |
| 210 | |
| 211 #if defined(__cplusplus) | |
| 212 extern "C" | |
| 213 { | |
| 214 #endif | |
| 215 | |
| 216 /*! \brief Convert the code for an indicator to a short text name. | |
| 217 \param indicator The type of indicator. | |
| 218 \return A pointer to a short text name for the indicator. */ | |
| 219 SPAN_DECLARE(const char *) t38_indicator_to_str(int indicator); | |
| 220 | |
| 221 /*! \brief Convert the code for a type of data to a short text name. | |
| 222 \param data_type The data type. | |
| 223 \return A pointer to a short text name for the data type. */ | |
| 224 SPAN_DECLARE(const char *) t38_data_type_to_str(int data_type); | |
| 225 | |
| 226 /*! \brief Convert the code for a type of data field to a short text name. | |
| 227 \param field_type The field type. | |
| 228 \return A pointer to a short text name for the field type. */ | |
| 229 SPAN_DECLARE(const char *) t38_field_type_to_str(int field_type); | |
| 230 | |
| 231 /*! \brief Convert the code for a CM profile code to text description. | |
| 232 \param profile The profile code from a CM message. | |
| 233 \return A pointer to a short text description of the profile. */ | |
| 234 SPAN_DECLARE(const char *) t38_cm_profile_to_str(int profile); | |
| 235 | |
| 236 /*! \brief Convert a JM message code to text description. | |
| 237 \param data The data field of the message. | |
| 238 \param len The length of the data field. | |
| 239 \return A pointer to a short text description of the profile. */ | |
| 240 SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len); | |
| 241 | |
| 242 /*! \brief Convert a V34rate message to an actual bit rate. | |
| 243 \param data The data field of the message. | |
| 244 \param len The length of the data field. | |
| 245 \return The bit rate, or -1 for a bad message. */ | |
| 246 SPAN_DECLARE(int) t38_v34rate_to_bps(const uint8_t *data, int len); | |
| 247 | |
| 248 /*! \brief Send an indicator packet | |
| 249 \param s The T.38 context. | |
| 250 \param indicator The indicator to send. | |
| 251 \return The delay to allow after this indicator is sent. */ | |
| 252 SPAN_DECLARE(int) t38_core_send_indicator(t38_core_state_t *s, int indicator); | |
| 253 | |
| 254 /*! \brief Find the delay to allow for HDLC flags after sending an indicator | |
| 255 \param s The T.38 context. | |
| 256 \param indicator The indicator to send. | |
| 257 \return The delay to allow for initial HDLC flags after this indicator is sent. */ | |
| 258 SPAN_DECLARE(int) t38_core_send_flags_delay(t38_core_state_t *s, int indicator); | |
| 259 | |
| 260 /*! \brief Send a data packet | |
| 261 \param s The T.38 context. | |
| 262 \param data_type The packet's data type. | |
| 263 \param field_type The packet's field type. | |
| 264 \param field The message data content for the packet. | |
| 265 \param field_len The length of the message data, in bytes. | |
| 266 \param category The category of the packet being sent. This should be one of the values defined for t38_packet_categories_e. | |
| 267 \return ??? */ | |
| 268 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); | |
| 269 | |
| 270 /*! \brief Send a data packet | |
| 271 \param s The T.38 context. | |
| 272 \param data_type The packet's data type. | |
| 273 \param field The list of fields. | |
| 274 \param fields The number of fields in the list. | |
| 275 \param category The category of the packet being sent. This should be one of the values defined for t38_packet_categories_e. | |
| 276 \return ??? */ | |
| 277 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); | |
| 278 | |
| 279 /*! \brief Process a received T.38 IFP packet. | |
| 280 \param s The T.38 context. | |
| 281 \param buf The packet contents. | |
| 282 \param len The length of the packet contents. | |
| 283 \param seq_no The packet sequence number. | |
| 284 \return 0 for OK, else -1. */ | |
| 285 SPAN_DECLARE(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no); | |
| 286 | |
| 287 /*! Set the method to be used for data rate management, as per the T.38 spec. | |
| 288 \param s The T.38 context. | |
| 289 \param method 1 for pass TCF across the T.38 link, 2 for handle TCF locally. | |
| 290 */ | |
| 291 SPAN_DECLARE(void) t38_set_data_rate_management_method(t38_core_state_t *s, int method); | |
| 292 | |
| 293 /*! Set the data transport protocol. | |
| 294 \param s The T.38 context. | |
| 295 \param data_transport_protocol UDPTL, RTP or TPKT. | |
| 296 */ | |
| 297 SPAN_DECLARE(void) t38_set_data_transport_protocol(t38_core_state_t *s, int data_transport_protocol); | |
| 298 | |
| 299 /*! Set the non-ECM fill bit removal mode. | |
| 300 \param s The T.38 context. | |
| 301 \param fill_bit_removal TRUE to remove fill bits across the T.38 link, else FALSE. | |
| 302 */ | |
| 303 SPAN_DECLARE(void) t38_set_fill_bit_removal(t38_core_state_t *s, int fill_bit_removal); | |
| 304 | |
| 305 /*! Set the MMR transcoding mode. | |
| 306 \param s The T.38 context. | |
| 307 \param mmr_transcoding TRUE to transcode to MMR across the T.38 link, else FALSE. | |
| 308 */ | |
| 309 SPAN_DECLARE(void) t38_set_mmr_transcoding(t38_core_state_t *s, int mmr_transcoding); | |
| 310 | |
| 311 /*! Set the JBIG transcoding mode. | |
| 312 \param s The T.38 context. | |
| 313 \param jbig_transcoding TRUE to transcode to JBIG across the T.38 link, else FALSE. | |
| 314 */ | |
| 315 SPAN_DECLARE(void) t38_set_jbig_transcoding(t38_core_state_t *s, int jbig_transcoding); | |
| 316 | |
| 317 /*! Set the maximum buffer size for received data at the far end. | |
| 318 \param s The T.38 context. | |
| 319 \param max_buffer_size The maximum buffer size. | |
| 320 */ | |
| 321 SPAN_DECLARE(void) t38_set_max_buffer_size(t38_core_state_t *s, int max_buffer_size); | |
| 322 | |
| 323 /*! Set the maximum size of an IFP packet that is acceptable by the far end. | |
| 324 \param s The T.38 context. | |
| 325 \param max_datagram_size The maximum IFP packet length, in bytes. | |
| 326 */ | |
| 327 SPAN_DECLARE(void) t38_set_max_datagram_size(t38_core_state_t *s, int max_datagram_size); | |
| 328 | |
| 329 /*! \brief Send a data packet | |
| 330 \param s The T.38 context. | |
| 331 \param category The category of the packet being sent. This should be one of the values defined for t38_packet_categories_e. | |
| 332 \param setting The repeat count for the category. This should be at least one for all categories other an indicator packets. | |
| 333 Zero is valid for indicator packets, as it suppresses the sending of indicator packets, as an application using | |
| 334 TCP for the transport would require. As the setting is passed through to the transmission channel, additional | |
| 335 information may be encoded in it, such as the redundancy depth for the particular packet category. */ | |
| 336 SPAN_DECLARE(void) t38_set_redundancy_control(t38_core_state_t *s, int category, int setting); | |
| 337 | |
| 338 SPAN_DECLARE(void) t38_set_fastest_image_data_rate(t38_core_state_t *s, int max_rate); | |
| 339 | |
| 340 SPAN_DECLARE(int) t38_get_fastest_image_data_rate(t38_core_state_t *s); | |
| 341 | |
| 342 /*! Set the T.38 version to be emulated. | |
| 343 \param s The T.38 context. | |
| 344 \param t38_version Version number, as in the T.38 spec. | |
| 345 */ | |
| 346 SPAN_DECLARE(void) t38_set_t38_version(t38_core_state_t *s, int t38_version); | |
| 347 | |
| 348 /*! Set the sequence number handling option. | |
| 349 \param s The T.38 context. | |
| 350 \param check TRUE to check sequence numbers, and handle gaps reasonably. FALSE | |
| 351 for no sequence number processing (e.g. for TPKT over TCP transport). | |
| 352 */ | |
| 353 SPAN_DECLARE(void) t38_set_sequence_number_handling(t38_core_state_t *s, int check); | |
| 354 | |
| 355 /*! Set the TEP handling option. | |
| 356 \param s The T.38 context. | |
| 357 \param allow_for_tep TRUE to allow for TEP playout, else FALSE. | |
| 358 */ | |
| 359 SPAN_DECLARE(void) t38_set_tep_handling(t38_core_state_t *s, int allow_for_tep); | |
| 360 | |
| 361 /*! Get a pointer to the logging context associated with a T.38 context. | |
| 362 \brief Get a pointer to the logging context associated with a T.38 context. | |
| 363 \param s The T.38 context. | |
| 364 \return A pointer to the logging context, or NULL. | |
| 365 */ | |
| 366 SPAN_DECLARE(logging_state_t *) t38_core_get_logging_state(t38_core_state_t *s); | |
| 367 | |
| 368 /*! Initialise a T.38 core context. | |
| 369 \brief Initialise a T.38 core context. | |
| 370 \param s The T.38 context. | |
| 371 \param rx_indicator_handler Receive indicator handling routine. | |
| 372 \param rx_data_handler Receive data packet handling routine. | |
| 373 \param rx_rx_missing_handler Missing receive packet handling routine. | |
| 374 \param rx_packet_user_data An opaque pointer passed to the rx packet handling routines. | |
| 375 \param tx_packet_handler Packet transmit handling routine. | |
| 376 \param tx_packet_user_data An opaque pointer passed to the tx_packet_handler. | |
| 377 \return A pointer to the T.38 context, or NULL if there was a problem. */ | |
| 378 SPAN_DECLARE(t38_core_state_t *) t38_core_init(t38_core_state_t *s, | |
| 379 t38_rx_indicator_handler_t *rx_indicator_handler, | |
| 380 t38_rx_data_handler_t *rx_data_handler, | |
| 381 t38_rx_missing_handler_t *rx_missing_handler, | |
| 382 void *rx_user_data, | |
| 383 t38_tx_packet_handler_t *tx_packet_handler, | |
| 384 void *tx_packet_user_data); | |
| 385 | |
| 386 /*! Release a signaling tone transmitter context. | |
| 387 \brief Release a signaling tone transmitter context. | |
| 388 \param s The T.38 context. | |
| 389 \return 0 for OK */ | |
| 390 SPAN_DECLARE(int) t38_core_release(t38_core_state_t *s); | |
| 391 | |
| 392 /*! Free a signaling tone transmitter context. | |
| 393 \brief Free a signaling tone transmitter context. | |
| 394 \param s The T.38 context. | |
| 395 \return 0 for OK */ | |
| 396 SPAN_DECLARE(int) t38_core_free(t38_core_state_t *s); | |
| 397 | |
| 398 #if defined(__cplusplus) | |
| 399 } | |
| 400 #endif | |
| 401 | |
| 402 #endif | |
| 403 /*- End of file ------------------------------------------------------------*/ | 
