comparison spandsp-0.0.6pre17/src/t38_core.c @ 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.c - Encode and decode the ASN.1 of a T.38 IFP message
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2005, 2006 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.c,v 1.54 2009/10/09 14:53:57 steveu Exp $
26 */
27
28 /*! \file */
29
30 #if defined(HAVE_CONFIG_H)
31 #include "config.h"
32 #endif
33
34 #include <inttypes.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <fcntl.h>
38 #include <time.h>
39 #include <string.h>
40 #if defined(HAVE_TGMATH_H)
41 #include <tgmath.h>
42 #endif
43 #if defined(HAVE_MATH_H)
44 #include <math.h>
45 #endif
46 #include "floating_fudge.h"
47 #include <assert.h>
48 #include <memory.h>
49 #include <tiffio.h>
50
51 #include "spandsp/telephony.h"
52 #include "spandsp/logging.h"
53 #include "spandsp/bit_operations.h"
54 #include "spandsp/t38_core.h"
55
56 #include "spandsp/private/logging.h"
57 #include "spandsp/private/t38_core.h"
58
59 #define ACCEPTABLE_SEQ_NO_OFFSET 2000
60
61 /* The times for training, the optional TEP, and the HDLC preamble, for all the modem options, in ms.
62 Note that the preamble for V.21 is 1s+-15%, and for the other modems is 200ms+100ms. */
63 static const struct
64 {
65 int tep;
66 int training;
67 int flags;
68 } modem_startup_time[] =
69 {
70 { 0, 75000, 0}, /* T38_IND_NO_SIGNAL */
71 { 0, 0, 0}, /* T38_IND_CNG */
72 { 0, 3000000, 0}, /* T38_IND_CED */
73 { 0, 0, 1000000}, /* T38_IND_V21_PREAMBLE */ /* TODO: 850ms should be OK for this, but it causes trouble with some ATAs. Why? */
74 { 215000, 943000, 200000}, /* T38_IND_V27TER_2400_TRAINING */
75 { 215000, 708000, 200000}, /* T38_IND_V27TER_4800_TRAINING */
76 { 215000, 234000, 200000}, /* T38_IND_V29_7200_TRAINING */
77 { 215000, 234000, 200000}, /* T38_IND_V29_9600_TRAINING */
78 { 215000, 142000, 200000}, /* T38_IND_V17_7200_SHORT_TRAINING */
79 { 215000, 1393000, 200000}, /* T38_IND_V17_7200_LONG_TRAINING */
80 { 215000, 142000, 200000}, /* T38_IND_V17_9600_SHORT_TRAINING */
81 { 215000, 1393000, 200000}, /* T38_IND_V17_9600_LONG_TRAINING */
82 { 215000, 142000, 200000}, /* T38_IND_V17_12000_SHORT_TRAINING */
83 { 215000, 1393000, 200000}, /* T38_IND_V17_12000_LONG_TRAINING */
84 { 215000, 142000, 200000}, /* T38_IND_V17_14400_SHORT_TRAINING */
85 { 215000, 1393000, 200000}, /* T38_IND_V17_14400_LONG_TRAINING */
86 { 215000, 0, 0}, /* T38_IND_V8_ANSAM */
87 { 215000, 0, 0}, /* T38_IND_V8_SIGNAL */
88 { 215000, 0, 0}, /* T38_IND_V34_CNTL_CHANNEL_1200 */
89 { 215000, 0, 0}, /* T38_IND_V34_PRI_CHANNEL */
90 { 215000, 0, 0}, /* T38_IND_V34_CC_RETRAIN */
91 { 215000, 0, 0}, /* T38_IND_V33_12000_TRAINING */
92 { 215000, 0, 0} /* T38_IND_V33_14400_TRAINING */
93 };
94
95 SPAN_DECLARE(const char *) t38_indicator_to_str(int indicator)
96 {
97 switch (indicator)
98 {
99 case T38_IND_NO_SIGNAL:
100 return "no-signal";
101 case T38_IND_CNG:
102 return "cng";
103 case T38_IND_CED:
104 return "ced";
105 case T38_IND_V21_PREAMBLE:
106 return "v21-preamble";
107 case T38_IND_V27TER_2400_TRAINING:
108 return "v27-2400-training";
109 case T38_IND_V27TER_4800_TRAINING:
110 return "v27-4800-training";
111 case T38_IND_V29_7200_TRAINING:
112 return "v29-7200-training";
113 case T38_IND_V29_9600_TRAINING:
114 return "v29-9600-training";
115 case T38_IND_V17_7200_SHORT_TRAINING:
116 return "v17-7200-short-training";
117 case T38_IND_V17_7200_LONG_TRAINING:
118 return "v17-7200-long-training";
119 case T38_IND_V17_9600_SHORT_TRAINING:
120 return "v17-9600-short-training";
121 case T38_IND_V17_9600_LONG_TRAINING:
122 return "v17-9600-long-training";
123 case T38_IND_V17_12000_SHORT_TRAINING:
124 return "v17-12000-short-training";
125 case T38_IND_V17_12000_LONG_TRAINING:
126 return "v17-12000-long-training";
127 case T38_IND_V17_14400_SHORT_TRAINING:
128 return "v17-14400-short-training";
129 case T38_IND_V17_14400_LONG_TRAINING:
130 return "v17-14400-long-training";
131 case T38_IND_V8_ANSAM:
132 return "v8-ansam";
133 case T38_IND_V8_SIGNAL:
134 return "v8-signal";
135 case T38_IND_V34_CNTL_CHANNEL_1200:
136 return "v34-cntl-channel-1200";
137 case T38_IND_V34_PRI_CHANNEL:
138 return "v34-pri-channel";
139 case T38_IND_V34_CC_RETRAIN:
140 return "v34-CC-retrain";
141 case T38_IND_V33_12000_TRAINING:
142 return "v33-12000-training";
143 case T38_IND_V33_14400_TRAINING:
144 return "v33-14400-training";
145 }
146 return "???";
147 }
148 /*- End of function --------------------------------------------------------*/
149
150 SPAN_DECLARE(const char *) t38_data_type_to_str(int data_type)
151 {
152 switch (data_type)
153 {
154 case T38_DATA_V21:
155 return "v21";
156 case T38_DATA_V27TER_2400:
157 return "v27-2400";
158 case T38_DATA_V27TER_4800:
159 return "v27-4800";
160 case T38_DATA_V29_7200:
161 return "v29-7200";
162 case T38_DATA_V29_9600:
163 return "v29-9600";
164 case T38_DATA_V17_7200:
165 return "v17-7200";
166 case T38_DATA_V17_9600:
167 return "v17-9600";
168 case T38_DATA_V17_12000:
169 return "v17-12000";
170 case T38_DATA_V17_14400:
171 return "v17-14400";
172 case T38_DATA_V8:
173 return "v8";
174 case T38_DATA_V34_PRI_RATE:
175 return "v34-pri-rate";
176 case T38_DATA_V34_CC_1200:
177 return "v34-CC-1200";
178 case T38_DATA_V34_PRI_CH:
179 return "v34-pri-vh";
180 case T38_DATA_V33_12000:
181 return "v33-12000";
182 case T38_DATA_V33_14400:
183 return "v33-14400";
184 }
185 return "???";
186 }
187 /*- End of function --------------------------------------------------------*/
188
189 SPAN_DECLARE(const char *) t38_field_type_to_str(int field_type)
190 {
191 switch (field_type)
192 {
193 case T38_FIELD_HDLC_DATA:
194 return "hdlc-data";
195 case T38_FIELD_HDLC_SIG_END:
196 return "hdlc-sig-end";
197 case T38_FIELD_HDLC_FCS_OK:
198 return "hdlc-fcs-OK";
199 case T38_FIELD_HDLC_FCS_BAD:
200 return "hdlc-fcs-BAD";
201 case T38_FIELD_HDLC_FCS_OK_SIG_END:
202 return "hdlc-fcs-OK-sig-end";
203 case T38_FIELD_HDLC_FCS_BAD_SIG_END:
204 return "hdlc-fcs-BAD-sig-end";
205 case T38_FIELD_T4_NON_ECM_DATA:
206 return "t4-non-ecm-data";
207 case T38_FIELD_T4_NON_ECM_SIG_END:
208 return "t4-non-ecm-sig-end";
209 case T38_FIELD_CM_MESSAGE:
210 return "cm-message";
211 case T38_FIELD_JM_MESSAGE:
212 return "jm-message";
213 case T38_FIELD_CI_MESSAGE:
214 return "ci-message";
215 case T38_FIELD_V34RATE:
216 return "v34rate";
217 }
218 return "???";
219 }
220 /*- End of function --------------------------------------------------------*/
221
222 SPAN_DECLARE(const char *) t38_cm_profile_to_str(int profile)
223 {
224 switch (profile)
225 {
226 case '1':
227 return "G3 FAX sending terminal";
228 case '2':
229 return "G3 FAX receiving terminal";
230 case '3':
231 return "V.34 HDX and G3 FAX sending terminal";
232 case '4':
233 return "V.34 HDX and G3 FAX receiving terminal";
234 case '5':
235 return "V.34 HDX-only FAX sending terminal";
236 case '6':
237 return "V.34 HDX-only FAX receiving terminal";
238 }
239 return "???";
240 }
241 /*- End of function --------------------------------------------------------*/
242
243 SPAN_DECLARE(const char *) t38_jm_to_str(const uint8_t *data, int len)
244 {
245 if (len < 2)
246 return "???";
247 switch (data[0])
248 {
249 case 'A':
250 switch (data[1])
251 {
252 case '0':
253 return "ACK";
254 }
255 break;
256 case 'N':
257 switch (data[1])
258 {
259 case '0':
260 return "NACK: No compatible mode available";
261 case '1':
262 /* Response for profiles 1 and 2 */
263 return "NACK: No V.34 FAX, use G3 FAX";
264 case '2':
265 /* Response for profiles 5 and 6 */
266 return "NACK: V.34 only FAX.";
267 }
268 break;
269 }
270 return "???";
271 }
272 /*- End of function --------------------------------------------------------*/
273
274 SPAN_DECLARE(int) t38_v34rate_to_bps(const uint8_t *data, int len)
275 {
276 int i;
277 int rate;
278
279 if (len < 3)
280 return -1;
281 for (i = 0, rate = 0; i < 3; i++)
282 {
283 if (data[i] < '0' || data[i] > '9')
284 return -1;
285 rate = rate*10 + data[i] - '0';
286 }
287 return rate*100;
288 }
289 /*- End of function --------------------------------------------------------*/
290
291 static __inline__ int classify_seq_no_offset(int expected, int actual)
292 {
293 /* Classify the mismatch between expected and actual sequence numbers
294 according to whether the actual is a little in the past (late), a
295 little in the future (some packets have been lost), or a large jump
296 that represents the sequence being lost (possibly when some RTP
297 gets dumped to a UDPTL port). */
298 /* This assumes they are not equal */
299 if (expected > actual)
300 {
301 if (expected > actual + 0x10000 - ACCEPTABLE_SEQ_NO_OFFSET)
302 {
303 /* In the near future */
304 return 1;
305 }
306 if (expected < actual + ACCEPTABLE_SEQ_NO_OFFSET)
307 {
308 /* In the recent past */
309 return -1;
310 }
311 }
312 else
313 {
314 if (expected + ACCEPTABLE_SEQ_NO_OFFSET > actual)
315 {
316 /* In the near future */
317 return 1;
318 }
319 if (expected + 0x10000 - ACCEPTABLE_SEQ_NO_OFFSET < actual)
320 {
321 /* In the recent past */
322 return -1;
323 }
324 }
325 /* There has been a huge step in the sequence */
326 return 0;
327 }
328 /*- End of function --------------------------------------------------------*/
329
330 SPAN_DECLARE(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no)
331 {
332 int i;
333 int t30_indicator;
334 int t30_data;
335 int ptr;
336 int other_half;
337 int numocts;
338 int log_seq_no;
339 const uint8_t *msg;
340 unsigned int count;
341 unsigned int t30_field_type;
342 uint8_t type;
343 uint8_t data_field_present;
344 uint8_t field_data_present;
345 char tag[20];
346
347 log_seq_no = (s->check_sequence_numbers) ? seq_no : s->rx_expected_seq_no;
348
349 if (span_log_test(&s->logging, SPAN_LOG_FLOW))
350 {
351 sprintf(tag, "Rx %5d: IFP", log_seq_no);
352 span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
353 }
354 if (len < 1)
355 {
356 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Bad packet length - %d\n", log_seq_no, len);
357 return -1;
358 }
359 if (s->check_sequence_numbers)
360 {
361 seq_no &= 0xFFFF;
362 if (seq_no != s->rx_expected_seq_no)
363 {
364 /* An expected value of -1 indicates this is the first received packet, and will accept
365 anything for that. We can't assume they will start from zero, even though they should. */
366 if (s->rx_expected_seq_no != -1)
367 {
368 /* We have a packet with a serial number that is not in sequence. The cause could be:
369 - 1. a repeat copy of a recent packet. Many T.38 implementations can preduce quite a lot of these.
370 - 2. a late packet, whose point in the sequence we have already passed.
371 - 3. the result of a hop in the sequence numbers cause by something weird from the other
372 end. Stream switching might cause this
373 - 4. missing packets.
374
375 In cases 1 and 2 we need to drop this packet. In case 2 it might make sense to try to do
376 something with it in the terminal case. Currently we don't. For gateway operation it will be
377 too late to do anything useful.
378 */
379 if (((seq_no + 1) & 0xFFFF) == s->rx_expected_seq_no)
380 {
381 /* Assume this is truly a repeat packet, and don't bother checking its contents. */
382 span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: Repeat packet number\n", log_seq_no);
383 return 0;
384 }
385 /* Distinguish between a little bit out of sequence, and a huge hop. */
386 switch (classify_seq_no_offset(s->rx_expected_seq_no, seq_no))
387 {
388 case -1:
389 /* This packet is in the near past, so its late. */
390 span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: Late packet - expected %d\n", log_seq_no, s->rx_expected_seq_no);
391 return 0;
392 case 1:
393 /* This packet is in the near future, so some packets have been lost */
394 span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: Missing from %d\n", log_seq_no, s->rx_expected_seq_no);
395 s->rx_missing_handler(s, s->rx_user_data, s->rx_expected_seq_no, seq_no);
396 s->missing_packets += (seq_no - s->rx_expected_seq_no);
397 break;
398 default:
399 /* The sequence has jumped wildly */
400 span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: Sequence restart\n", log_seq_no);
401 s->rx_missing_handler(s, s->rx_user_data, -1, -1);
402 s->missing_packets++;
403 break;
404 }
405 }
406 s->rx_expected_seq_no = seq_no;
407 }
408 }
409 /* The sequence numbering is defined as rolling from 0xFFFF to 0x0000. Some implementations
410 of T.38 roll from 0xFFFF to 0x0001. Isn't standardisation a wonderful thing? The T.38
411 document specifies only a small fraction of what it should, yet then they actually nail
412 something properly, people ignore it. Developers in this industry truly deserves the ****
413 **** **** **** **** **** documents they have to live with. Anyway, when the far end has a
414 broken rollover behaviour we will get a hiccup at the rollover point. Don't worry too
415 much. We will just treat the message in progress as one with some missing data. With any
416 luck a retry will ride over the problem. Rollovers don't occur that often. It takes quite
417 a few FAX pages to reach rollover. */
418 s->rx_expected_seq_no = (s->rx_expected_seq_no + 1) & 0xFFFF;
419 data_field_present = (buf[0] >> 7) & 1;
420 type = (buf[0] >> 6) & 1;
421 ptr = 0;
422 switch (type)
423 {
424 case T38_TYPE_OF_MSG_T30_INDICATOR:
425 /* Indicators should never have a data field */
426 if (data_field_present)
427 {
428 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Data field with indicator\n", log_seq_no);
429 return -1;
430 }
431 /* Any received indicator should mean we no longer have a valid concept of "last received data/field type". */
432 s->current_rx_data_type = -1;
433 s->current_rx_field_type = -1;
434 if ((buf[0] & 0x20))
435 {
436 /* Extension */
437 if (len != 2)
438 {
439 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for indicator (A)\n", log_seq_no);
440 return -1;
441 }
442 t30_indicator = T38_IND_V8_ANSAM + (((buf[0] << 2) & 0x3C) | ((buf[1] >> 6) & 0x3));
443 if (t30_indicator > T38_IND_V33_14400_TRAINING)
444 {
445 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown indicator - %d\n", log_seq_no, t30_indicator);
446 return -1;
447 }
448 }
449 else
450 {
451 if (len != 1)
452 {
453 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for indicator (B)\n", log_seq_no);
454 return -1;
455 }
456 t30_indicator = (buf[0] >> 1) & 0xF;
457 }
458 span_log(&s->logging, SPAN_LOG_FLOW, "Rx %5d: indicator %s\n", log_seq_no, t38_indicator_to_str(t30_indicator));
459 s->rx_indicator_handler(s, s->rx_user_data, t30_indicator);
460 /* This must come after the indicator handler, so the handler routine sees the existing state of the
461 indicator. */
462 s->current_rx_indicator = t30_indicator;
463 break;
464 case T38_TYPE_OF_MSG_T30_DATA:
465 if ((buf[0] & 0x20))
466 {
467 /* Extension */
468 if (len < 2)
469 {
470 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (A)\n", log_seq_no);
471 return -1;
472 }
473 t30_data = T38_DATA_V8 + (((buf[0] << 2) & 0x3C) | ((buf[1] >> 6) & 0x3));
474 if (t30_data > T38_DATA_V33_14400)
475 {
476 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown data type - %d\n", log_seq_no, t30_data);
477 return -1;
478 }
479 ptr = 2;
480 }
481 else
482 {
483 t30_data = (buf[0] >> 1) & 0xF;
484 if (t30_data > T38_DATA_V17_14400)
485 {
486 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown data type - %d\n", log_seq_no, t30_data);
487 return -1;
488 }
489 ptr = 1;
490 }
491 if (!data_field_present)
492 {
493 /* This is kinda weird, but I guess if the length checks out we accept it. */
494 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Data type with no data field\n", log_seq_no);
495 if (ptr != len)
496 {
497 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (B)\n", log_seq_no);
498 return -1;
499 }
500 break;
501 }
502 if (ptr >= len)
503 {
504 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (C)\n", log_seq_no);
505 return -1;
506 }
507 count = buf[ptr++];
508 //printf("Count is %d\n", count);
509 other_half = FALSE;
510 t30_field_type = 0;
511 for (i = 0; i < (int) count; i++)
512 {
513 if (ptr >= len)
514 {
515 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (D)\n", log_seq_no);
516 return -1;
517 }
518 if (s->t38_version == 0)
519 {
520 /* The original version of T.38 with a typo in the ASN.1 spec. */
521 if (other_half)
522 {
523 /* The lack of a data field in the previous message means
524 we are currently in the middle of an octet. */
525 field_data_present = (buf[ptr] >> 3) & 1;
526 /* Decode field_type */
527 t30_field_type = buf[ptr] & 0x7;
528 ptr++;
529 other_half = FALSE;
530 }
531 else
532 {
533 field_data_present = (buf[ptr] >> 7) & 1;
534 /* Decode field_type */
535 t30_field_type = (buf[ptr] >> 4) & 0x7;
536 if (field_data_present)
537 ptr++;
538 else
539 other_half = TRUE;
540 }
541 if (t30_field_type > T38_FIELD_T4_NON_ECM_SIG_END)
542 {
543 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown field type - %d\n", log_seq_no, t30_field_type);
544 return -1;
545 }
546 }
547 else
548 {
549 field_data_present = (buf[ptr] >> 7) & 1;
550 /* Decode field_type */
551 if ((buf[ptr] & 0x40))
552 {
553 if (ptr > len - 2)
554 {
555 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (E)\n", log_seq_no);
556 return -1;
557 }
558 t30_field_type = T38_FIELD_CM_MESSAGE + (((buf[ptr] << 2) & 0x3C) | ((buf[ptr + 1] >> 6) & 0x3));
559 if (t30_field_type > T38_FIELD_V34RATE)
560 {
561 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Unknown field type - %d\n", log_seq_no, t30_field_type);
562 return -1;
563 }
564 ptr += 2;
565 }
566 else
567 {
568 t30_field_type = (buf[ptr++] >> 3) & 0x7;
569 }
570 }
571 /* Decode field_data */
572 if (field_data_present)
573 {
574 if (ptr > len - 2)
575 {
576 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (F)\n", log_seq_no);
577 return -1;
578 }
579 numocts = ((buf[ptr] << 8) | buf[ptr + 1]) + 1;
580 msg = buf + ptr + 2;
581 ptr += numocts + 2;
582 }
583 else
584 {
585 numocts = 0;
586 msg = NULL;
587 }
588 if (ptr > len)
589 {
590 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (G)\n", log_seq_no);
591 return -1;
592 }
593 span_log(&s->logging,
594 SPAN_LOG_FLOW,
595 "Rx %5d: (%d) data %s/%s + %d byte(s)\n",
596 log_seq_no,
597 i,
598 t38_data_type_to_str(t30_data),
599 t38_field_type_to_str(t30_field_type),
600 numocts);
601 s->rx_data_handler(s, s->rx_user_data, t30_data, t30_field_type, msg, numocts);
602 s->current_rx_data_type = t30_data;
603 s->current_rx_field_type = t30_field_type;
604 }
605 if (ptr != len)
606 {
607 if (s->t38_version != 0 || ptr != (len - 1) || !other_half)
608 {
609 span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Rx %5d: Invalid length for data (H) - %d %d\n", log_seq_no, ptr, len);
610 return -1;
611 }
612 }
613 break;
614 }
615 return 0;
616 }
617 /*- End of function --------------------------------------------------------*/
618
619 static int t38_encode_indicator(t38_core_state_t *s, uint8_t buf[], int indicator)
620 {
621 int len;
622
623 /* Build the IFP packet */
624 /* Data field not present */
625 /* Indicator packet */
626 /* Type of indicator */
627 if (indicator <= T38_IND_V17_14400_LONG_TRAINING)
628 {
629 buf[0] = (uint8_t) (indicator << 1);
630 len = 1;
631 }
632 else if (s->t38_version != 0 && indicator <= T38_IND_V33_14400_TRAINING)
633 {
634 buf[0] = (uint8_t) (0x20 | (((indicator - T38_IND_V8_ANSAM) & 0xF) >> 2));
635 buf[1] = (uint8_t) (((indicator - T38_IND_V8_ANSAM) << 6) & 0xFF);
636 len = 2;
637 }
638 else
639 {
640 len = -1;
641 }
642 return len;
643 }
644 /*- End of function --------------------------------------------------------*/
645
646 static int t38_encode_data(t38_core_state_t *s, uint8_t buf[], int data_type, const t38_data_field_t field[], int fields)
647 {
648 int len;
649 int i;
650 int enclen;
651 int multiplier;
652 int data_field_no;
653 const t38_data_field_t *q;
654 unsigned int encoded_len;
655 unsigned int fragment_len;
656 unsigned int value;
657 uint8_t data_field_present;
658 uint8_t field_data_present;
659 char tag[20];
660
661 /* Build the IFP packet */
662
663 /* There seems no valid reason why a packet would ever be generated without a data field present */
664 data_field_present = TRUE;
665
666 for (data_field_no = 0; data_field_no < fields; data_field_no++)
667 {
668 span_log(&s->logging,
669 SPAN_LOG_FLOW,
670 "Tx %5d: (%d) data %s/%s + %d byte(s)\n",
671 s->tx_seq_no,
672 data_field_no,
673 t38_data_type_to_str(data_type),
674 t38_field_type_to_str(field[data_field_no].field_type),
675 field[data_field_no].field_len);
676 }
677
678 data_field_no = 0;
679 len = 0;
680 /* Data field present */
681 /* Data packet */
682 /* Type of data */
683 if (data_type <= T38_DATA_V17_14400)
684 {
685 buf[len++] = (uint8_t) ((data_field_present << 7) | 0x40 | (data_type << 1));
686 }
687 else if (s->t38_version != 0 && data_type <= T38_DATA_V33_14400)
688 {
689 buf[len++] = (uint8_t) ((data_field_present << 7) | 0x60 | (((data_type - T38_DATA_V8) & 0xF) >> 2));
690 buf[len++] = (uint8_t) (((data_type - T38_DATA_V8) << 6) & 0xFF);
691 }
692 else
693 {
694 return -1;
695 }
696 if (data_field_present)
697 {
698 encoded_len = 0;
699 data_field_no = 0;
700 do
701 {
702 value = fields - encoded_len;
703 if (value < 0x80)
704 {
705 /* 1 octet case */
706 buf[len++] = (uint8_t) value;
707 enclen = value;
708 }
709 else if (value < 0x4000)
710 {
711 /* 2 octet case */
712 buf[len++] = (uint8_t) (0x80 | ((value >> 8) & 0xFF));
713 buf[len++] = (uint8_t) (value & 0xFF);
714 enclen = value;
715 }
716 else
717 {
718 /* Fragmentation case */
719 multiplier = (value/0x4000 < 4) ? value/0x4000 : 4;
720 buf[len++] = (uint8_t) (0xC0 | multiplier);
721 enclen = 0x4000*multiplier;
722 }
723
724 fragment_len = enclen;
725 encoded_len += fragment_len;
726 /* Encode the elements */
727 for (i = 0; i < (int) encoded_len; i++)
728 {
729 q = &field[data_field_no];
730 field_data_present = (uint8_t) (q->field_len > 0);
731 /* Encode field_type */
732 if (s->t38_version == 0)
733 {
734 /* Original version of T.38 with a typo */
735 if (q->field_type > T38_FIELD_T4_NON_ECM_SIG_END)
736 return -1;
737 buf[len++] = (uint8_t) ((field_data_present << 7) | (q->field_type << 4));
738 }
739 else
740 {
741 if (q->field_type <= T38_FIELD_T4_NON_ECM_SIG_END)
742 {
743 buf[len++] = (uint8_t) ((field_data_present << 7) | (q->field_type << 3));
744 }
745 else if (q->field_type <= T38_FIELD_V34RATE)
746 {
747 buf[len++] = (uint8_t) ((field_data_present << 7) | 0x40 | ((q->field_type - T38_FIELD_CM_MESSAGE) >> 2));
748 buf[len++] = (uint8_t) (((q->field_type - T38_FIELD_CM_MESSAGE) << 6) & 0xC0);
749 }
750 else
751 {
752 return -1;
753 }
754 }
755 /* Encode field_data */
756 if (field_data_present)
757 {
758 if (q->field_len < 1 || q->field_len > 65535)
759 return -1;
760 buf[len++] = (uint8_t) (((q->field_len - 1) >> 8) & 0xFF);
761 buf[len++] = (uint8_t) ((q->field_len - 1) & 0xFF);
762 memcpy(buf + len, q->field, q->field_len);
763 len += q->field_len;
764 }
765 data_field_no++;
766 }
767 }
768 while (fields != (int) encoded_len || fragment_len >= 16384);
769 }
770
771 if (span_log_test(&s->logging, SPAN_LOG_FLOW))
772 {
773 sprintf(tag, "Tx %5d: IFP", s->tx_seq_no);
774 span_log_buf(&s->logging, SPAN_LOG_FLOW, tag, buf, len);
775 }
776 return len;
777 }
778 /*- End of function --------------------------------------------------------*/
779
780 SPAN_DECLARE(int) t38_core_send_indicator(t38_core_state_t *s, int indicator)
781 {
782 uint8_t buf[100];
783 int len;
784 int delay;
785
786 delay = 0;
787 /* Only send an indicator if it represents a change of state. */
788 if (s->current_tx_indicator != indicator)
789 {
790 /* Zero is a valid count, to suppress the transmission of indicators when the
791 transport means they are not needed - e.g. TPKT/TCP. */
792 if (s->category_control[T38_PACKET_CATEGORY_INDICATOR])
793 {
794 if ((len = t38_encode_indicator(s, buf, indicator)) < 0)
795 {
796 span_log(&s->logging, SPAN_LOG_FLOW, "T.38 indicator len is %d\n", len);
797 return len;
798 }
799 span_log(&s->logging, SPAN_LOG_FLOW, "Tx %5d: indicator %s\n", s->tx_seq_no, t38_indicator_to_str(indicator));
800 s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[T38_PACKET_CATEGORY_INDICATOR]);
801 s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
802 delay = modem_startup_time[indicator].training;
803 if (s->allow_for_tep)
804 delay += modem_startup_time[indicator].tep;
805 }
806 s->current_tx_indicator = indicator;
807 }
808 return delay;
809 }
810 /*- End of function --------------------------------------------------------*/
811
812 SPAN_DECLARE(int) t38_core_send_flags_delay(t38_core_state_t *s, int indicator)
813 {
814 return modem_startup_time[indicator].flags;
815 }
816 /*- End of function --------------------------------------------------------*/
817
818 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)
819 {
820 t38_data_field_t field0;
821 uint8_t buf[1000];
822 int len;
823
824 field0.field_type = field_type;
825 field0.field = field;
826 field0.field_len = field_len;
827 if ((len = t38_encode_data(s, buf, data_type, &field0, 1)) < 0)
828 {
829 span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len);
830 return len;
831 }
832 s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]);
833 s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
834 return 0;
835 }
836 /*- End of function --------------------------------------------------------*/
837
838 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)
839 {
840 uint8_t buf[1000];
841 int len;
842
843 if ((len = t38_encode_data(s, buf, data_type, field, fields)) < 0)
844 {
845 span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len);
846 return len;
847 }
848 s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]);
849 s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;
850 return 0;
851 }
852 /*- End of function --------------------------------------------------------*/
853
854 SPAN_DECLARE(void) t38_set_data_rate_management_method(t38_core_state_t *s, int method)
855 {
856 s->data_rate_management_method = method;
857 }
858 /*- End of function --------------------------------------------------------*/
859
860 SPAN_DECLARE(void) t38_set_data_transport_protocol(t38_core_state_t *s, int data_transport_protocol)
861 {
862 s->data_transport_protocol = data_transport_protocol;
863 }
864 /*- End of function --------------------------------------------------------*/
865
866 SPAN_DECLARE(void) t38_set_fill_bit_removal(t38_core_state_t *s, int fill_bit_removal)
867 {
868 s->fill_bit_removal = fill_bit_removal;
869 }
870 /*- End of function --------------------------------------------------------*/
871
872 SPAN_DECLARE(void) t38_set_mmr_transcoding(t38_core_state_t *s, int mmr_transcoding)
873 {
874 s->mmr_transcoding = mmr_transcoding;
875 }
876 /*- End of function --------------------------------------------------------*/
877
878 SPAN_DECLARE(void) t38_set_jbig_transcoding(t38_core_state_t *s, int jbig_transcoding)
879 {
880 s->jbig_transcoding = jbig_transcoding;
881 }
882 /*- End of function --------------------------------------------------------*/
883
884 SPAN_DECLARE(void) t38_set_max_buffer_size(t38_core_state_t *s, int max_buffer_size)
885 {
886 s->max_buffer_size = max_buffer_size;
887 }
888 /*- End of function --------------------------------------------------------*/
889
890 SPAN_DECLARE(void) t38_set_max_datagram_size(t38_core_state_t *s, int max_datagram_size)
891 {
892 s->max_datagram_size = max_datagram_size;
893 }
894 /*- End of function --------------------------------------------------------*/
895
896 SPAN_DECLARE(void) t38_set_t38_version(t38_core_state_t *s, int t38_version)
897 {
898 s->t38_version = t38_version;
899 }
900 /*- End of function --------------------------------------------------------*/
901
902 SPAN_DECLARE(void) t38_set_sequence_number_handling(t38_core_state_t *s, int check)
903 {
904 s->check_sequence_numbers = check;
905 }
906 /*- End of function --------------------------------------------------------*/
907
908 SPAN_DECLARE(void) t38_set_tep_handling(t38_core_state_t *s, int allow_for_tep)
909 {
910 s->allow_for_tep = allow_for_tep;
911 }
912 /*- End of function --------------------------------------------------------*/
913
914 SPAN_DECLARE(void) t38_set_redundancy_control(t38_core_state_t *s, int category, int setting)
915 {
916 s->category_control[category] = setting;
917 }
918 /*- End of function --------------------------------------------------------*/
919
920 SPAN_DECLARE(void) t38_set_fastest_image_data_rate(t38_core_state_t *s, int max_rate)
921 {
922 s->fastest_image_data_rate = max_rate;
923 }
924 /*- End of function --------------------------------------------------------*/
925
926 SPAN_DECLARE(int) t38_get_fastest_image_data_rate(t38_core_state_t *s)
927 {
928 return s->fastest_image_data_rate;
929 }
930 /*- End of function --------------------------------------------------------*/
931
932 SPAN_DECLARE(logging_state_t *) t38_core_get_logging_state(t38_core_state_t *s)
933 {
934 return &s->logging;
935 }
936 /*- End of function --------------------------------------------------------*/
937
938 SPAN_DECLARE(t38_core_state_t *) t38_core_init(t38_core_state_t *s,
939 t38_rx_indicator_handler_t *rx_indicator_handler,
940 t38_rx_data_handler_t *rx_data_handler,
941 t38_rx_missing_handler_t *rx_missing_handler,
942 void *rx_user_data,
943 t38_tx_packet_handler_t *tx_packet_handler,
944 void *tx_packet_user_data)
945 {
946 if (s == NULL)
947 {
948 if ((s = (t38_core_state_t *) malloc(sizeof(*s))) == NULL)
949 return NULL;
950 }
951 memset(s, 0, sizeof(*s));
952 span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
953 span_log_set_protocol(&s->logging, "T.38");
954
955 /* Set some defaults for the parameters configurable from outside the
956 T.38 domain - e.g. from SDP data. */
957 s->data_rate_management_method = T38_DATA_RATE_MANAGEMENT_TRANSFERRED_TCF;
958 s->data_transport_protocol = T38_TRANSPORT_UDPTL;
959 s->fill_bit_removal = FALSE;
960 s->mmr_transcoding = FALSE;
961 s->jbig_transcoding = FALSE;
962 s->max_buffer_size = 400;
963 s->max_datagram_size = 100;
964 s->t38_version = 0;
965 s->check_sequence_numbers = TRUE;
966
967 /* Set some defaults */
968 s->category_control[T38_PACKET_CATEGORY_INDICATOR] = 1;
969 s->category_control[T38_PACKET_CATEGORY_CONTROL_DATA] = 1;
970 s->category_control[T38_PACKET_CATEGORY_CONTROL_DATA_END] = 1;
971 s->category_control[T38_PACKET_CATEGORY_IMAGE_DATA] = 1;
972 s->category_control[T38_PACKET_CATEGORY_IMAGE_DATA_END] = 1;
973
974 /* Set the initial current receive states to something invalid, so the
975 first data received is seen as a change of state. */
976 s->current_rx_indicator = -1;
977 s->current_rx_data_type = -1;
978 s->current_rx_field_type = -1;
979
980 /* Set the initial current indicator state to something invalid, so the
981 first attempt to send an indicator will work. */
982 s->current_tx_indicator = -1;
983
984 s->rx_indicator_handler = rx_indicator_handler;
985 s->rx_data_handler = rx_data_handler;
986 s->rx_missing_handler = rx_missing_handler;
987 s->rx_user_data = rx_user_data;
988 s->tx_packet_handler = tx_packet_handler;
989 s->tx_packet_user_data = tx_packet_user_data;
990
991 /* We have no initial expectation of the received packet sequence number.
992 They most often start at 0 or 1 for a UDPTL transport, but random
993 starting numbers are possible. */
994 s->rx_expected_seq_no = -1;
995 return s;
996 }
997 /*- End of function --------------------------------------------------------*/
998
999 SPAN_DECLARE(int) t38_core_release(t38_core_state_t *s)
1000 {
1001 return 0;
1002 }
1003 /*- End of function --------------------------------------------------------*/
1004
1005 SPAN_DECLARE(int) t38_core_free(t38_core_state_t *s)
1006 {
1007 if (s)
1008 free(s);
1009 return 0;
1010 }
1011 /*- End of function --------------------------------------------------------*/
1012 /*- End of file ------------------------------------------------------------*/

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