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 ------------------------------------------------------------*/ |