00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * t38_gateway.h - A T.38, less the packet exchange part 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2005, 2006, 2007 Steve Underwood 00009 * 00010 * All rights reserved. 00011 * 00012 * This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU Lesser General Public License version 2.1, 00014 * as published by the Free Software Foundation. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00024 * 00025 * $Id: t38_gateway.h,v 1.57 2008/09/02 13:56:10 steveu Exp $ 00026 */ 00027 00028 /*! \file */ 00029 00030 #if !defined(_SPANDSP_T38_GATEWAY_H_) 00031 #define _SPANDSP_T38_GATEWAY_H_ 00032 00033 /*! \page t38_gateway_page T.38 real time FAX over IP PSTN gateway 00034 \section t38_gateway_page_sec_1 What does it do? 00035 00036 The T.38 gateway facility provides a robust interface between T.38 IP packet streams and 00037 and 8k samples/second audio streams. It provides the buffering and flow control features needed 00038 to maximum the tolerance of jitter and packet loss on the IP network. 00039 00040 \section t38_gateway_page_sec_2 How does it work? 00041 */ 00042 00043 #define T38_RX_BUF_LEN 2048 00044 #define T38_TX_HDLC_BUFS 256 00045 /* Make sure the HDLC frame buffers are big enough for ECM frames. */ 00046 #define T38_MAX_HDLC_LEN 260 00047 00048 typedef struct t38_gateway_state_s t38_gateway_state_t; 00049 00050 /*! 00051 T.30 real time frame handler. 00052 \brief T.30 real time frame handler. 00053 \param s The T.30 context. 00054 \param user_data An opaque pointer. 00055 \param direction TRUE for incoming, FALSE for outgoing. 00056 \param msg The HDLC message. 00057 \param len The length of the message. 00058 */ 00059 typedef void (t38_gateway_real_time_frame_handler_t)(t38_gateway_state_t *s, 00060 void *user_data, 00061 int direction, 00062 const uint8_t *msg, 00063 int len); 00064 00065 /*! 00066 T.38 gateway T.38 side channel descriptor. 00067 */ 00068 typedef struct 00069 { 00070 /*! Core T.38 IFP support */ 00071 t38_core_state_t t38; 00072 00073 /*! \brief TRUE if the NSF, NSC, and NSS are to be suppressed by altering 00074 their contents to something the far end will not recognise. */ 00075 int suppress_nsx_len[2]; 00076 /*! \brief TRUE if we need to corrupt the HDLC frame in progress, so the receiver cannot 00077 interpret it. The two values are for the two directions. */ 00078 int corrupt_current_frame[2]; 00079 00080 /*! \brief the current class of field being received - i.e. none, non-ECM or HDLC */ 00081 int current_rx_field_class; 00082 /*! \brief The T.38 indicator currently in use */ 00083 int in_progress_rx_indicator; 00084 00085 /*! \brief The current T.38 data type being sent. */ 00086 int current_tx_data_type; 00087 } t38_gateway_t38_state_t; 00088 00089 /*! 00090 T.38 gateway audio side channel descriptor. 00091 */ 00092 typedef struct 00093 { 00094 fax_modems_state_t modems; 00095 /*! \brief The current receive signal handler. Actual receiving hop between this 00096 and a dummy receive routine. */ 00097 span_rx_handler_t *base_rx_handler; 00098 } t38_gateway_audio_state_t; 00099 00100 typedef struct 00101 { 00102 /*! \brief non-ECM and HDLC modem receive data buffer. */ 00103 uint8_t data[T38_RX_BUF_LEN]; 00104 /*! \brief Current pointer into the data buffer. */ 00105 int data_ptr; 00106 /*! \brief The current octet being received as non-ECM data. */ 00107 unsigned int bit_stream; 00108 /*! \brief The number of bits taken from the modem for the current scan row. This 00109 is used during non-ECM transmission will fill bit removal to see that 00110 T.38 packet transmissions do not stretch too far apart. */ 00111 int bits_absorbed; 00112 /*! \brief The current bit number in the current non-ECM octet. */ 00113 int bit_no; 00114 /*! \brief Progressively calculated CRC for HDLC messages received from a modem. */ 00115 uint16_t crc; 00116 /*! \brief TRUE if non-ECM fill bits are to be stripped when sending image data. */ 00117 int fill_bit_removal; 00118 /*! \brief The number of octets to send in each image packet (non-ECM or ECM) at the current 00119 rate and the current specified packet interval. */ 00120 int octets_per_data_packet; 00121 00122 int in_bits; 00123 int out_octets; 00124 } t38_gateway_to_t38_state_t; 00125 00126 typedef struct 00127 { 00128 /*! \brief HDLC message buffers. */ 00129 uint8_t buf[T38_MAX_HDLC_LEN]; 00130 /*! \brief HDLC message lengths. */ 00131 int len; 00132 /*! \brief HDLC message status flags. */ 00133 int flags; 00134 /*! \brief HDLC buffer contents. */ 00135 int contents; 00136 } t38_gateway_hdlc_buf_t; 00137 00138 typedef struct 00139 { 00140 /*! \brief HDLC message buffers. */ 00141 t38_gateway_hdlc_buf_t buf[T38_TX_HDLC_BUFS]; 00142 #if 0 00143 /*! \brief HDLC message buffers. */ 00144 uint8_t buf[T38_TX_HDLC_BUFS][T38_MAX_HDLC_LEN]; 00145 /*! \brief HDLC message lengths. */ 00146 int len[T38_TX_HDLC_BUFS]; 00147 /*! \brief HDLC message status flags. */ 00148 int flags[T38_TX_HDLC_BUFS]; 00149 /*! \brief HDLC buffer contents. */ 00150 int contents[T38_TX_HDLC_BUFS]; 00151 #endif 00152 /*! \brief HDLC buffer number for input. */ 00153 int in; 00154 /*! \brief HDLC buffer number for output. */ 00155 int out; 00156 } t38_gateway_hdlc_state_t; 00157 00158 /*! 00159 T.38 gateway core descriptor. 00160 */ 00161 typedef struct 00162 { 00163 /*! \brief A bit mask of the currently supported modem types. */ 00164 int supported_modems; 00165 /*! \brief TRUE if ECM FAX mode is allowed through the gateway. */ 00166 int ecm_allowed; 00167 00168 /*! \brief TRUE if in image data modem is to use short training. This usually 00169 follows image_data_mode, but in ECM mode T.30 defines recovery 00170 conditions in which long training is used for image data. */ 00171 int short_train; 00172 /*! \brief TRUE if in image data mode, as opposed to TCF mode. */ 00173 int image_data_mode; 00174 /*! \brief The minimum permitted bits per FAX scan line row. */ 00175 int min_row_bits; 00176 00177 /*! \brief TRUE if we should count the next MCF as a page end, else FALSE */ 00178 int count_page_on_mcf; 00179 /*! \brief The number of pages for which a confirm (MCF) message was returned. */ 00180 int pages_confirmed; 00181 00182 /*! \brief TRUE if we are in error correcting (ECM) mode */ 00183 int ecm_mode; 00184 /*! \brief The current bit rate for the fast modem. */ 00185 int fast_bit_rate; 00186 /*! \brief The current fast modem type. */ 00187 int fast_modem; 00188 /*! \brief The type of fast receive modem currently active, which may be T38_NONE */ 00189 int fast_rx_active; 00190 00191 /*! \brief TRUE if between DCS and TCF, and we want the fast image modem to 00192 start in the T.38 data at a predictable time from the end of the 00193 V.21 signal. */ 00194 int tcf_mode_predictable_modem_start; 00195 00196 /*! \brief The number of samples until the next timeout event */ 00197 int samples_to_timeout; 00198 00199 /*! Buffer for HDLC and non-ECM data going to the T.38 channel */ 00200 t38_gateway_to_t38_state_t to_t38; 00201 /*! Buffer for data going to an HDLC modem. */ 00202 t38_gateway_hdlc_state_t hdlc_to_modem; 00203 /*! Buffer for data going to a non-ECM mode modem. */ 00204 t38_non_ecm_buffer_state_t non_ecm_to_modem; 00205 00206 /*! \brief A pointer to a callback routine to be called when frames are 00207 exchanged. */ 00208 t38_gateway_real_time_frame_handler_t *real_time_frame_handler; 00209 /*! \brief An opaque pointer supplied in real time frame callbacks. */ 00210 void *real_time_frame_user_data; 00211 } t38_gateway_core_state_t; 00212 00213 /*! 00214 T.38 gateway state. 00215 */ 00216 struct t38_gateway_state_s 00217 { 00218 t38_gateway_t38_state_t t38x; 00219 t38_gateway_audio_state_t audio; 00220 t38_gateway_core_state_t core; 00221 00222 /*! \brief Error and flow logging control */ 00223 logging_state_t logging; 00224 }; 00225 00226 typedef struct 00227 { 00228 /*! \brief The current bit rate for image transfer. */ 00229 int bit_rate; 00230 /*! \brief TRUE if error correcting mode is used. */ 00231 int error_correcting_mode; 00232 /*! \brief The number of pages transferred so far. */ 00233 int pages_transferred; 00234 } t38_stats_t; 00235 00236 #if defined(__cplusplus) 00237 extern "C" 00238 { 00239 #endif 00240 00241 /*! \brief Initialise a gateway mode T.38 context. 00242 \param s The T.38 context. 00243 \param tx_packet_handler A callback routine to encapsulate and transmit T.38 packets. 00244 \param tx_packet_user_data An opaque pointer passed to the tx_packet_handler routine. 00245 \return A pointer to the termination mode T.38 context, or NULL if there was a problem. */ 00246 t38_gateway_state_t *t38_gateway_init(t38_gateway_state_t *s, 00247 t38_tx_packet_handler_t *tx_packet_handler, 00248 void *tx_packet_user_data); 00249 00250 /*! Free a gateway mode T.38 context. 00251 \brief Free a T.38 context. 00252 \param s The T.38 context. 00253 \return 0 for OK, else -1. */ 00254 int t38_gateway_free(t38_gateway_state_t *s); 00255 00256 /*! Process a block of received FAX audio samples. 00257 \brief Process a block of received FAX audio samples. 00258 \param s The T.38 context. 00259 \param amp The audio sample buffer. 00260 \param len The number of samples in the buffer. 00261 \return The number of samples unprocessed. */ 00262 int t38_gateway_rx(t38_gateway_state_t *s, int16_t amp[], int len); 00263 00264 /*! Generate a block of FAX audio samples. 00265 \brief Generate a block of FAX audio samples. 00266 \param s The T.38 context. 00267 \param amp The audio sample buffer. 00268 \param max_len The number of samples to be generated. 00269 \return The number of samples actually generated. 00270 */ 00271 int t38_gateway_tx(t38_gateway_state_t *s, int16_t amp[], int max_len); 00272 00273 /*! Control whether error correcting mode (ECM) is allowed. 00274 \brief Control whether error correcting mode (ECM) is allowed. 00275 \param s The T.38 context. 00276 \param ecm_allowed TRUE is ECM is to be allowed. 00277 */ 00278 void t38_gateway_set_ecm_capability(t38_gateway_state_t *s, int ecm_allowed); 00279 00280 /*! Select whether silent audio will be sent when transmit is idle. 00281 \brief Select whether silent audio will be sent when transmit is idle. 00282 \param s The T.38 context. 00283 \param transmit_on_idle TRUE if silent audio should be output when the FAX transmitter is 00284 idle. FALSE to transmit zero length audio when the FAX transmitter is idle. The default 00285 behaviour is FALSE. 00286 */ 00287 void t38_gateway_set_transmit_on_idle(t38_gateway_state_t *s, int transmit_on_idle); 00288 00289 /*! Specify which modem types are supported by a T.30 context. 00290 \brief Specify supported modems. 00291 \param s The T.38 context. 00292 \param supported_modems Bit field list of the supported modems. 00293 */ 00294 void t38_gateway_set_supported_modems(t38_gateway_state_t *s, int supported_modems); 00295 00296 /*! Select whether NSC, NSF, and NSS should be suppressed. It selected, the contents of 00297 these messages are forced to zero for all octets beyond the message type. This makes 00298 them look like manufacturer specific messages, from a manufacturer which does not exist. 00299 \brief Select whether NSC, NSF, and NSS should be suppressed. 00300 \param s The T.38 context. 00301 \param from_t38 A string of bytes to overwrite the header of any NSC, NSF, and NSS 00302 frames passing through the gateway from T.38 the the modem. 00303 \param from_t38_len The length of the overwrite string. 00304 \param from_modem A string of bytes to overwrite the header of any NSC, NSF, and NSS 00305 frames passing through the gateway from the modem to T.38. 00306 \param from_modem_len The length of the overwrite string. 00307 */ 00308 void t38_gateway_set_nsx_suppression(t38_gateway_state_t *s, 00309 const uint8_t *from_t38, 00310 int from_t38_len, 00311 const uint8_t *from_modem, 00312 int from_modem_len); 00313 00314 /*! Select whether talker echo protection tone will be sent for the image modems. 00315 \brief Select whether TEP will be sent for the image modems. 00316 \param s The T.38 context. 00317 \param use_tep TRUE if TEP should be sent. 00318 */ 00319 void t38_gateway_set_tep_mode(t38_gateway_state_t *s, int use_tep); 00320 00321 /*! Select whether non-ECM fill bits are to be removed during transmission. 00322 \brief Select whether non-ECM fill bits are to be removed during transmission. 00323 \param s The T.38 context. 00324 \param remove TRUE if fill bits are to be removed. 00325 */ 00326 void t38_gateway_set_fill_bit_removal(t38_gateway_state_t *s, int remove); 00327 00328 /*! Get the current transfer statistics for the current T.38 session. 00329 \brief Get the current transfer statistics. 00330 \param s The T.38 context. 00331 \param t A pointer to a buffer for the statistics. */ 00332 void t38_gateway_get_transfer_statistics(t38_gateway_state_t *s, t38_stats_t *t); 00333 00334 /*! Set a callback function for T.30 frame exchange monitoring. This is called from the heart 00335 of the signal processing, so don't take too long in the handler routine. 00336 \brief Set a callback function for T.30 frame exchange monitoring. 00337 \param s The T.30 context. 00338 \param handler The callback function. 00339 \param user_data An opaque pointer passed to the callback function. */ 00340 void t38_gateway_set_real_time_frame_handler(t38_gateway_state_t *s, 00341 t38_gateway_real_time_frame_handler_t *handler, 00342 void *user_data); 00343 00344 #if defined(__cplusplus) 00345 } 00346 #endif 00347 00348 #endif 00349 /*- End of file ------------------------------------------------------------*/