123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710 |
- /*
- * SpanDSP - a series of DSP components for telephony
- *
- * t38_non_ecm_buffer_tests.c - Tests for the T.38 non-ECM image data buffer module.
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2008 Steve Underwood
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /*! \file */
- /*! \page t38_non_ecm_buffer_tests_page T.38 non-ECM buffer tests
- \section t38_non_ecm_buffer_tests_page_sec_1 What does it do?
- These tests exercise the flow controlling non-ECM image data buffer
- module, used for T.38 gateways.
- */
- #if defined(HAVE_CONFIG_H)
- #include "config.h"
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <string.h>
- #include <assert.h>
- #include <errno.h>
- #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
- #include "spandsp.h"
- /* A pattern of widening gaps between ones, until at 11 apart an
- EOL should be registered */
- static const uint8_t spreader[] =
- {
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55, /* 1 apart */
- 0x22, /* 2 and 3 apart */
- 0x10, /* 4 apart */
- 0x40, /* 5 apart */
- 0x80, /* 6 apart */
- 0x80, /* 7 apart */
- 0x40, /* 8 apart */
- 0x10, /* 9 apart */
- 0x02, /* 10 apart */
- 0x00,
- 0x25 /* 11 apart */
- };
- static int bit_no;
- static int xxx(t38_non_ecm_buffer_state_t *s, logging_state_t *l, int log_bits, int n, int expected)
- {
- int i;
- int j;
- int bit;
- t38_non_ecm_buffer_inject(s, &spreader[n], 1);
- if (expected >= 0)
- {
- for (i = 0; i < 128; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) s);
- if (log_bits)
- printf("Rx bit %d - %d\n", bit_no, bit);
- if (bit != expected)
- {
- printf("Tests failed - %d %d %d\n", bit_no, bit, expected);
- exit(2);
- }
- bit_no++;
- }
- }
- else
- {
- j = -1;
- for (i = 0; i < 256; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) s);
- if (log_bits)
- printf("Rx bit %d - %d\n", bit_no, bit);
- if (j < 0)
- {
- if (bit == 1)
- j = 18*8 - 5;
- }
- else
- {
- expected = (spreader[j >> 3] >> (7 - (j & 7))) & 1;
- if (bit != expected)
- {
- printf("Tests failed - %d %d %d\n", bit_no, bit, expected);
- exit(2);
- }
- j++;
- if (j >= 18*8)
- j = 0;
- }
- bit_no++;
- if (j == 17*8)
- return 0;
- }
- }
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- int main(int argc, char *argv[])
- {
- t38_non_ecm_buffer_state_t buffer;
- logging_state_t logging;
- uint8_t buf[1024];
- int bit;
- int n;
- int log_bits;
- int i;
- log_bits = (argc > 1);
- printf("T.38 non-ECM rate adapting buffer tests.\n");
- span_log_init(&logging, SPAN_LOG_FLOW, NULL);
- span_log_set_protocol(&logging, "Buffer");
- printf("1 - Impose no minimum for the bits per row\n");
- t38_non_ecm_buffer_init(&buffer, true, 0);
- n = 0;
- bit_no = 0;
- /* We should get ones until the buffers recognises an EOL */
- printf(" We should get ones here\n");
- for (i = 0; i < 17; i++)
- xxx(&buffer, &logging, log_bits, i, 1);
- printf(" We should change to zeros here\n");
- xxx(&buffer, &logging, log_bits, i, 0);
- for (i = 0; i < 17; i++)
- xxx(&buffer, &logging, log_bits, i, 0);
- printf(" We should get the first row here\n");
- xxx(&buffer, &logging, log_bits, i, -1);
- for (i = 0; i < 17; i++)
- xxx(&buffer, &logging, log_bits, i, 0);
- printf(" We should get the second row here\n");
- xxx(&buffer, &logging, log_bits, i, -1);
- for (i = 0; i < 17; i++)
- xxx(&buffer, &logging, log_bits, i, 0);
- printf(" We should get the third row here\n");
- xxx(&buffer, &logging, log_bits, i, -1);
- printf(" Done\n");
- t38_non_ecm_buffer_report_input_status(&buffer, &logging);
- t38_non_ecm_buffer_report_output_status(&buffer, &logging);
- t38_non_ecm_buffer_release(&buffer);
- printf("2 - Impose no minimum for the bits per row, different alignment\n");
- t38_non_ecm_buffer_init(&buffer, true, 0);
- n = 0;
- memset(buf, 0, sizeof(buf));
- /* The first one in this should be seen as the first EOL */
- memset(buf + 10, 0x55, 10);
- /* EOL 2 */
- buf[25] = 0x20;
- /* EOL 3 */
- memset(buf + 30, 0x55, 10);
- /* EOL 4 */
- buf[45] = 0x10;
- t38_non_ecm_buffer_inject(&buffer, buf, 50);
- t38_non_ecm_buffer_push(&buffer);
- for (;;)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n, bit);
- n++;
- if (bit == SIG_STATUS_END_OF_DATA)
- {
- if (n != 337)
- {
- printf("Tests failed\n");
- exit(2);
- }
- break;
- }
- if (n >= 18 && n <= 96)
- {
- if (bit == (n & 1))
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- else if (n >= 178 && n <= 256)
- {
- if (bit == (n & 1))
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- else if (n == 139 || n == 300)
- {
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- else
- {
- if (bit != 0)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- }
- t38_non_ecm_buffer_report_input_status(&buffer, &logging);
- t38_non_ecm_buffer_report_output_status(&buffer, &logging);
- t38_non_ecm_buffer_release(&buffer);
- printf("3 - Demand a fairly high minimum for the bits per row\n");
- t38_non_ecm_buffer_init(&buffer, true, 400);
- n = 0;
- memset(buf, 0, sizeof(buf));
- /* The first one in this should be seen as the first EOL */
- memset(buf + 10, 0x55, 10);
- /* EOL 2 */
- buf[25] = 0x08;
- /* EOL 3 */
- memset(buf + 30, 0x55, 10);
- /* EOL 4 */
- buf[45] = 0x04;
- t38_non_ecm_buffer_inject(&buffer, buf, 50);
- t38_non_ecm_buffer_push(&buffer);
- for (;;)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n, bit);
- n++;
- if (bit == SIG_STATUS_END_OF_DATA)
- {
- if (n != 1273)
- {
- printf("Tests failed\n");
- exit(2);
- }
- break;
- }
- if (n >= 18 && n <= 96)
- {
- if (bit == (n & 1))
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- else if (n >= 834 && n <= 912)
- {
- if (bit == (n & 1))
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- else if (n == 429 || n == 1238)
- {
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- else
- {
- if (bit != 0)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- }
- t38_non_ecm_buffer_report_input_status(&buffer, &logging);
- t38_non_ecm_buffer_report_output_status(&buffer, &logging);
- t38_non_ecm_buffer_release(&buffer);
- printf("4 - Take some time to get to the first row of the image, output ahead\n");
- t38_non_ecm_buffer_init(&buffer, true, 400);
- n = 0;
- /* Get some initial bits from an empty buffer. These should be ones */
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Initial ones OK\n");
- /* Now put some zeros into the buffer, but no EOL. We should continue
- getting ones out. */
- memset(buf, 0, sizeof(buf));
- t38_non_ecm_buffer_inject(&buffer, buf, 20);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Continuing initial ones OK\n");
- /* Now add a one, to make an EOL. We should see the zeros come out. */
- buf[0] = 0x01;
- t38_non_ecm_buffer_inject(&buffer, buf, 1);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 0)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" First EOL caused zeros to output OK\n");
- /* Now add another line. We should see the first line come out. This means just the
- 23rd bit from now will be a one. */
- buf[0] = 0x00;
- buf[4] = 0x01;
- t38_non_ecm_buffer_inject(&buffer, buf, 5);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if ((i == 23 && bit == 0) || (i != 23 && bit != 0))
- {
- printf("Tests failed (%d)\n", i);
- exit(2);
- }
- }
- printf(" Second EOL caused the first row to output OK\n");
- /* Now inject an RTC - 6 EOLs */
- memset(buf, 0, sizeof(buf));
- /* T.4 1D style */
- for (i = 10; i < 19; i += 3)
- {
- buf[i] = 0x00;
- buf[i + 1] = 0x10;
- buf[i + 2] = 0x01;
- }
- /* T.4 2D style */
- buf[25 + 0] = 0x00;
- buf[25 + 1] = 0x18;
- buf[25 + 2] = 0x00;
- buf[25 + 3] = 0xC0;
- buf[25 + 4] = 0x06;
- buf[25 + 5] = 0x00;
- buf[25 + 6] = 0x30;
- buf[25 + 7] = 0x01;
- buf[25 + 8] = 0x80;
- buf[25 + 9] = 0x0C;
- t38_non_ecm_buffer_inject(&buffer, buf, 50);
- t38_non_ecm_buffer_push(&buffer);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (i == 7
- ||
- i == 400 + 11 + 0*12
- ||
- i == 400 + 11 + 1*12
- ||
- i == 400 + 11 + 2*12
- ||
- i == 400 + 11 + 3*12
- ||
- i == 400 + 11 + 4*12
- ||
- i == 400 + 11 + 5*12
- ||
- i == 400 + 11 + 60 + 400 + 4 + 0*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 0*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 1*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 1*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 2*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 2*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 3*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 3*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 4*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 4*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 5*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 5*13 + 1)
- {
- if (bit == 0)
- {
- printf("Tests failed (%d)\n", i);
- exit(2);
- }
- }
- else
- {
- if (bit == 1)
- {
- printf("Tests failed (%d)\n", i);
- exit(2);
- }
- }
- }
- printf(" RTC output OK\n");
- t38_non_ecm_buffer_report_input_status(&buffer, &logging);
- t38_non_ecm_buffer_report_output_status(&buffer, &logging);
- t38_non_ecm_buffer_release(&buffer);
- printf("5 - Take some time to get to the first row of the image, output behind\n");
- t38_non_ecm_buffer_init(&buffer, true, 400);
- n = 0;
- /* Inject some ones. */
- memset(buf, 0xFF, 100);
- t38_non_ecm_buffer_inject(&buffer, buf, 100);
- /* Inject some zeros */
- memset(buf, 0, sizeof(buf));
- t38_non_ecm_buffer_inject(&buffer, buf, 100);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Initial ones OK\n");
- /* Now add a one, to make an EOL. We should see the zeros come out. */
- buf[0] = 0x01;
- t38_non_ecm_buffer_inject(&buffer, buf, 1);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 0)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" First EOL caused zeros to output OK\n");
- /* Now add another line. We should see the first line come out. This means just the
- 23rd bit from now will be a one. */
- buf[0] = 0x00;
- buf[4] = 0x01;
- t38_non_ecm_buffer_inject(&buffer, buf, 5);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if ((i == 23 && bit == 0) || (i != 23 && bit != 0))
- {
- printf("Tests failed (%d)\n", i);
- exit(2);
- }
- }
- printf(" Second EOL caused the first row to output OK\n");
- /* Now inject an RTC - 6 EOLs */
- memset(buf, 0, sizeof(buf));
- /* T.4 1D style */
- for (i = 10; i < 19; i += 3)
- {
- buf[i] = 0x00;
- buf[i + 1] = 0x10;
- buf[i + 2] = 0x01;
- }
- /* T.4 2D style */
- buf[25 + 0] = 0x00;
- buf[25 + 1] = 0x18;
- buf[25 + 2] = 0x00;
- buf[25 + 3] = 0xC0;
- buf[25 + 4] = 0x06;
- buf[25 + 5] = 0x00;
- buf[25 + 6] = 0x30;
- buf[25 + 7] = 0x01;
- buf[25 + 8] = 0x80;
- buf[25 + 9] = 0x0C;
- t38_non_ecm_buffer_inject(&buffer, buf, 50);
- t38_non_ecm_buffer_push(&buffer);
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (i == 7
- ||
- i == 400 + 11 + 0*12
- ||
- i == 400 + 11 + 1*12
- ||
- i == 400 + 11 + 2*12
- ||
- i == 400 + 11 + 3*12
- ||
- i == 400 + 11 + 4*12
- ||
- i == 400 + 11 + 5*12
- ||
- i == 400 + 11 + 60 + 400 + 4 + 0*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 0*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 1*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 1*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 2*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 2*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 3*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 3*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 4*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 4*13 + 1
- ||
- i == 400 + 11 + 60 + 400 + 4 + 5*13
- ||
- i == 400 + 11 + 60 + 400 + 4 + 5*13 + 1)
- {
- if (bit == 0)
- {
- printf("Tests failed (%d)\n", i);
- exit(2);
- }
- }
- else
- {
- if (bit == 1)
- {
- printf("Tests failed (%d)\n", i);
- exit(2);
- }
- }
- }
- printf(" RTC output OK\n");
- t38_non_ecm_buffer_report_input_status(&buffer, &logging);
- t38_non_ecm_buffer_report_output_status(&buffer, &logging);
- t38_non_ecm_buffer_release(&buffer);
- printf("6 - TCF without leading ones\n");
- t38_non_ecm_buffer_init(&buffer, false, 400);
- n = 0;
- /* Get some initial bits from an empty buffer. These should be ones */
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Initial ones from an empty TCF buffer OK\n");
- /* Now send some TCF through, and see that it comes out */
- memset(buf, 0x00, sizeof(buf));
- t38_non_ecm_buffer_inject(&buffer, buf, 500);
- t38_non_ecm_buffer_push(&buffer);
- for (i = 0; i < 500*8; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 0)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Passthrough of TCF OK\n");
- /* Check the right number of bits was buffered */
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != SIG_STATUS_END_OF_DATA)
- {
- printf("Tests failed\n");
- exit(2);
- }
- printf(" End of data seen OK\n");
- t38_non_ecm_buffer_report_input_status(&buffer, &logging);
- t38_non_ecm_buffer_report_output_status(&buffer, &logging);
- t38_non_ecm_buffer_release(&buffer);
- printf("7 - TCF with leading ones\n");
- t38_non_ecm_buffer_init(&buffer, false, 400);
- n = 0;
- /* Get some initial bits from an empty buffer. These should be ones */
- for (i = 0; i < 1000; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Initial ones from an empty TCF buffer OK\n");
- /* Now send some initial ones, and see that we continue to get all ones
- as the stuffing. */
- memset(buf, 0xFF, 500);
- t38_non_ecm_buffer_inject(&buffer, buf, 500);
- for (i = 0; i < 500*8; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != 1)
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Sustaining ones OK\n");
- /* Now send some initial ones, and some TCF through, and see that only
- the TCF comes out */
- memset(buf, 0x00, sizeof(buf));
- memset(buf, 0xFF, 100);
- /* End the ones mid byte */
- buf[100] = 0xF0;
- t38_non_ecm_buffer_inject(&buffer, buf, 500);
- t38_non_ecm_buffer_push(&buffer);
- for (i = 0; i < 400*8; i++)
- {
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if ((i < 4 && bit == 0) || (i >= 4 && bit != 0))
- {
- printf("Tests failed\n");
- exit(2);
- }
- }
- printf(" Passthrough of TCF OK\n");
- /* Check the right number of bits was buffered */
- bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
- if (log_bits)
- printf("Rx bit %d - %d\n", n++, bit);
- if (bit != SIG_STATUS_END_OF_DATA)
- {
- printf("Tests failed\n");
- exit(2);
- }
- printf(" End of data seen OK\n");
- t38_non_ecm_buffer_report_input_status(&buffer, &logging);
- t38_non_ecm_buffer_report_output_status(&buffer, &logging);
- t38_non_ecm_buffer_release(&buffer);
- printf("Tests passed\n");
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- /*- End of file ------------------------------------------------------------*/
|