1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * v18_tests.c
5  *
6  * Written by Steve Underwood <steveu@coppice.org>
7  *
8  * Copyright (C) 2004-2009 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 General Public License version 2, as
14  * 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 General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25 
26 /*! \page v18_tests_page V.18 tests
27 \section v18_tests_page_sec_1 What does it do?
28 */
29 
30 #if defined(HAVE_CONFIG_H)
31 #include "config.h"
32 #endif
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <string.h>
39 #include <sndfile.h>
40 
41 #include "spandsp.h"
42 #include "spandsp-sim.h"
43 
44 #define OUTPUT_FILE_NAME    "v18.wav"
45 
46 #define SAMPLES_PER_CHUNK   160
47 
48 #define CHUNKS_PER_SECOND   50
49 
50 #define TESTER              0
51 #define TUT                 1
52 
53 int log_audio = false;
54 SNDFILE *outhandle = NULL;
55 char result[2][1024];
56 int unexpected_echo = false;
57 
58 char *decode_test_file = NULL;
59 
60 int good_message_received;
61 
62 both_ways_line_model_state_t *model;
63 int rbs_pattern = 0;
64 int line_model_no = 0;
65 #if 0
66 float echo_level_cpe1 = -15.0f;
67 float echo_level_co1 = -15.0f;
68 float echo_level_cpe2 = -15.0f;
69 float echo_level_co2 = -15.0f;
70 #else
71 float echo_level_cpe1 = -99.0f;
72 float echo_level_co1 = -99.0f;
73 float echo_level_cpe2 = -99.0f;
74 float echo_level_co2 = -99.0f;
75 #endif
76 float noise_level = -70.0f;
77 int channel_codec = MUNGE_CODEC_NONE;
78 v18_state_t *v18[2];
79 
80 const char *qbf_tx = "The quick Brown Fox Jumps Over The Lazy dog 0123456789!@#$%^&*()'";
81 const char *qbf_rx = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 0123456789!X$$/'+.()'";
82 const char *full_baudot_rx =
83     "\b \n\n\n\r?\n\n\n  !\"$$/+'().+,-./"
84     "0123456789:;(=)?"
85     "XABCDEFGHIJKLMNOPQRSTUVWXYZ(/)' "
86     "'ABCDEFGHIJKLMNOPQRSTUVWXYZ(!) ";
87 
put_text_msg(void * user_data,const uint8_t * msg,int len)88 static void put_text_msg(void *user_data, const uint8_t *msg, int len)
89 {
90     if (strcmp((const char *) msg, qbf_rx))
91     {
92         printf("Result:\n%s\n", msg);
93         printf("Reference result:\n%s\n", qbf_rx);
94     }
95     else
96     {
97         good_message_received = true;
98     }
99 }
100 /*- End of function --------------------------------------------------------*/
101 
basic_tests(int mode)102 static void basic_tests(int mode)
103 {
104     logging_state_t *logging;
105     int16_t amp[2][SAMPLES_PER_CHUNK];
106     int16_t model_amp[2][SAMPLES_PER_CHUNK];
107     int16_t out_amp[2*SAMPLES_PER_CHUNK];
108     int outframes;
109     int samples;
110     int push;
111     int i;
112     int j;
113 
114     printf("Testing %s\n", v18_mode_to_str(mode));
115     v18[TESTER] = v18_init(NULL, true, mode, V18_AUTOMODING_GLOBAL, put_text_msg, NULL);
116     logging = v18_get_logging_state(v18[TESTER]);
117     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
118     span_log_set_tag(logging, "Tester");
119     v18[TUT] = v18_init(NULL, false, mode, V18_AUTOMODING_GLOBAL, put_text_msg, NULL);
120     logging = v18_get_logging_state(v18[TUT]);
121     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
122     span_log_set_tag(logging, "TUT");
123 
124     if ((model = both_ways_line_model_init(line_model_no,
125                                            noise_level,
126                                            echo_level_cpe1,
127                                            echo_level_co1,
128                                            line_model_no,
129                                            noise_level,
130                                            echo_level_cpe2,
131                                            echo_level_co2,
132                                            channel_codec,
133                                            rbs_pattern)) == NULL)
134     {
135         fprintf(stderr, "    Failed to create line model\n");
136         exit(2);
137     }
138 
139     /* Fake an OK condition for the first message test */
140     good_message_received = true;
141     push = 0;
142     if (v18_put(v18[TESTER], qbf_tx, -1) != strlen(qbf_tx))
143     {
144         printf("V.18 put failed\n");
145         exit(2);
146     }
147 
148     result[TESTER][0] =
149     result[TUT][0] = '\0';
150     for (i = 0;  i < 10000;  i++)
151     {
152         if (push == 0)
153         {
154             if ((samples = v18_tx(v18[TESTER], amp[0], SAMPLES_PER_CHUNK)) == 0)
155                 push = 10;
156         }
157         else
158         {
159             samples = 0;
160             /* Push a little silence through, to flush things out */
161             if (--push == 0)
162             {
163                 if (!good_message_received)
164                 {
165                     printf("No message received\n");
166                     exit(2);
167                 }
168                 good_message_received = false;
169                 if (v18_put(v18[TESTER], qbf_tx, -1) != strlen(qbf_tx))
170                 {
171                     printf("V.18 put failed\n");
172                     exit(2);
173                 }
174             }
175         }
176         if (samples < SAMPLES_PER_CHUNK)
177         {
178             vec_zeroi16(&amp[0][samples], SAMPLES_PER_CHUNK - samples);
179             samples = SAMPLES_PER_CHUNK;
180         }
181         if ((samples = v18_tx(v18[TUT], amp[1], SAMPLES_PER_CHUNK)) == 0)
182             push = 10;
183         if (samples < SAMPLES_PER_CHUNK)
184         {
185             vec_zeroi16(&amp[1][samples], SAMPLES_PER_CHUNK - samples);
186             samples = SAMPLES_PER_CHUNK;
187         }
188         if (log_audio)
189         {
190             for (j = 0;  j < samples;  j++)
191             {
192                 out_amp[2*j + 0] = amp[0][j];
193                 out_amp[2*j + 1] = amp[1][j];
194             }
195             outframes = sf_writef_short(outhandle, out_amp, samples);
196             if (outframes != samples)
197             {
198                 fprintf(stderr, "    Error writing audio file\n");
199                 exit(2);
200             }
201         }
202 #if 1
203         both_ways_line_model(model,
204                              model_amp[0],
205                              amp[0],
206                              model_amp[1],
207                              amp[1],
208                              samples);
209 #else
210         vec_copyi16(model_amp[0], amp[0], samples);
211         vec_copyi16(model_amp[1], amp[1], samples);
212 #endif
213         v18_rx(v18[TESTER], model_amp[1], samples);
214         v18_rx(v18[TUT], model_amp[0], samples);
215     }
216     v18_free(v18[TESTER]);
217     v18_free(v18[TUT]);
218 }
219 /*- End of function --------------------------------------------------------*/
220 
misc_01_put_text_msg(void * user_data,const uint8_t * msg,int len)221 static void misc_01_put_text_msg(void *user_data, const uint8_t *msg, int len)
222 {
223 }
224 /*- End of function --------------------------------------------------------*/
225 
test_misc_01(void)226 static int test_misc_01(void)
227 {
228     logging_state_t *logging;
229     int16_t amp[2][SAMPLES_PER_CHUNK];
230     int16_t model_amp[2][SAMPLES_PER_CHUNK];
231     int16_t out_amp[2*SAMPLES_PER_CHUNK];
232     int outframes;
233     int samples;
234     int push;
235     int i;
236     int j;
237 
238     /*
239         III.5.4.1.1     No disconnection test
240         Purpose:        To verify that the DCE does not initiate a disconnection.
241         Preamble:       N/A
242         Method:         A call is made to the TUT from the tester which remains off hook for 10 minutes
243                         without sending any signal.
244         Pass criteria:  The TUT should answer the call and enter the probing state after 3s. The
245                         TUT should continue to probe until the test is terminated.
246         Comments:       This feature should also be verified by observation during the automoding tests.
247      */
248     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_01_put_text_msg, (void *) (intptr_t) 0);
249     logging = v18_get_logging_state(v18[TESTER]);
250     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
251     span_log_set_tag(logging, "Tester");
252     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_01_put_text_msg, (void *) (intptr_t) 1);
253     logging = v18_get_logging_state(v18[TUT]);
254     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
255     span_log_set_tag(logging, "TUT");
256 
257     if ((model = both_ways_line_model_init(line_model_no,
258                                            noise_level,
259                                            echo_level_cpe1,
260                                            echo_level_co1,
261                                            line_model_no,
262                                            noise_level,
263                                            echo_level_cpe2,
264                                            echo_level_co2,
265                                            channel_codec,
266                                            rbs_pattern)) == NULL)
267     {
268         fprintf(stderr, "    Failed to create line model\n");
269         exit(2);
270     }
271 
272     result[TESTER][0] =
273     result[TUT][0] = '\0';
274     for (i = 0;  i < 10000;  i++)
275     {
276         for (j = 0;  j < 2;  j++)
277         {
278             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
279                 push = 10;
280             if (samples < SAMPLES_PER_CHUNK)
281             {
282                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
283                 samples = SAMPLES_PER_CHUNK;
284             }
285         }
286         if (log_audio)
287         {
288             for (j = 0;  j < samples;  j++)
289             {
290                 out_amp[2*j + 0] = amp[0][j];
291                 out_amp[2*j + 1] = amp[1][j];
292             }
293             outframes = sf_writef_short(outhandle, out_amp, samples);
294             if (outframes != samples)
295             {
296                 fprintf(stderr, "    Error writing audio file\n");
297                 exit(2);
298             }
299         }
300 #if 1
301         both_ways_line_model(model,
302                              model_amp[0],
303                              amp[0],
304                              model_amp[1],
305                              amp[1],
306                              samples);
307 #else
308         vec_copyi16(model_amp[0], amp[0], samples);
309         vec_copyi16(model_amp[1], amp[1], samples);
310 #endif
311         v18_rx(v18[TESTER], model_amp[1], samples);
312         v18_rx(v18[TUT], model_amp[0], samples);
313     }
314 
315     v18_free(v18[TESTER]);
316     v18_free(v18[TUT]);
317     printf("Test not yet implemented\n");
318     return 1;
319 }
320 /*- End of function --------------------------------------------------------*/
321 
misc_02_put_text_msg(void * user_data,const uint8_t * msg,int len)322 static void misc_02_put_text_msg(void *user_data, const uint8_t *msg, int len)
323 {
324 }
325 /*- End of function --------------------------------------------------------*/
326 
test_misc_02(void)327 static int test_misc_02(void)
328 {
329     logging_state_t *logging;
330     int16_t amp[2][SAMPLES_PER_CHUNK];
331     int16_t model_amp[2][SAMPLES_PER_CHUNK];
332     int16_t out_amp[2*SAMPLES_PER_CHUNK];
333     int outframes;
334     int samples;
335     int push;
336     int i;
337     int j;
338 
339     /*
340         III.5.4.1.2     Automatic resumption of automoding
341         Purpose:        To ensure that the DCE can be configured to automatically re-assume the automode
342                         calling state after 10s of no valid signal.
343         Preamble:       The TUT should be configured to automatically re-assume the initial automoding
344                         state.
345         Method:         The tester should set up a call to the TUT in V.21 mode and then drop the carrier.
346                         The tester will then transmit silence for 11s followed by a 1300Hz tone for
347                         5s (i.e. V.23).
348         Pass criteria:  1) 10s after dropping the carrier the TUT should return to state Monitor 1.
349                         2) After 2.7+-0.3s the TUT should select V.23 mode and send a 390Hz tone.
350         Comments:       The TUT should indicate that carrier has been lost at some time after the 1650Hz
351                         signal is lost.
352      */
353     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_02_put_text_msg, (void *) (intptr_t) 0);
354     logging = v18_get_logging_state(v18[TESTER]);
355     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
356     span_log_set_tag(logging, "Tester");
357     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_02_put_text_msg, (void *) (intptr_t) 1);
358     logging = v18_get_logging_state(v18[TUT]);
359     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
360     span_log_set_tag(logging, "TUT");
361 
362     if ((model = both_ways_line_model_init(line_model_no,
363                                            noise_level,
364                                            echo_level_cpe1,
365                                            echo_level_co1,
366                                            line_model_no,
367                                            noise_level,
368                                            echo_level_cpe2,
369                                            echo_level_co2,
370                                            channel_codec,
371                                            rbs_pattern)) == NULL)
372     {
373         fprintf(stderr, "    Failed to create line model\n");
374         exit(2);
375     }
376 
377     result[TESTER][0] =
378     result[TUT][0] = '\0';
379     for (i = 0;  i < 10000;  i++)
380     {
381         for (j = 0;  j < 2;  j++)
382         {
383             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
384                 push = 10;
385             if (samples < SAMPLES_PER_CHUNK)
386             {
387                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
388                 samples = SAMPLES_PER_CHUNK;
389             }
390         }
391         if (log_audio)
392         {
393             for (j = 0;  j < samples;  j++)
394             {
395                 out_amp[2*j + 0] = amp[0][j];
396                 out_amp[2*j + 1] = amp[1][j];
397             }
398             outframes = sf_writef_short(outhandle, out_amp, samples);
399             if (outframes != samples)
400             {
401                 fprintf(stderr, "    Error writing audio file\n");
402                 exit(2);
403             }
404         }
405 #if 1
406         both_ways_line_model(model,
407                              model_amp[0],
408                              amp[0],
409                              model_amp[1],
410                              amp[1],
411                              samples);
412 #else
413         vec_copyi16(model_amp[0], amp[0], samples);
414         vec_copyi16(model_amp[1], amp[1], samples);
415 #endif
416         v18_rx(v18[TESTER], model_amp[1], samples);
417         v18_rx(v18[TUT], model_amp[0], samples);
418     }
419 
420     v18_free(v18[TESTER]);
421     v18_free(v18[TUT]);
422     printf("Test not yet implemented\n");
423     return 1;
424 }
425 /*- End of function --------------------------------------------------------*/
426 
misc_03_put_text_msg(void * user_data,const uint8_t * msg,int len)427 static void misc_03_put_text_msg(void *user_data, const uint8_t *msg, int len)
428 {
429 }
430 /*- End of function --------------------------------------------------------*/
431 
test_misc_03(void)432 static int test_misc_03(void)
433 {
434     logging_state_t *logging;
435     int16_t amp[2][SAMPLES_PER_CHUNK];
436     int16_t model_amp[2][SAMPLES_PER_CHUNK];
437     int16_t out_amp[2*SAMPLES_PER_CHUNK];
438     int outframes;
439     int samples;
440     int push;
441     int i;
442     int j;
443 
444     /*
445         III.5.4.1.3     Retention of selected mode on loss of signal
446         Purpose:        To ensure that the DCE stays in the selected transmission mode if it is not
447                         configured to automatically re-assume the initial automoding state.
448         Preamble:       The TUT should be configured to remain in the selected transmission mode when
449                         the carrier is lost.
450         Method:         The tester should set up a call to the TUT in V.21 mode, for example. It will drop
451                         the carrier for 9s and then re-start transmission of the same carrier for
452                         1s followed by a short message.
453         Pass criteria:  The TUT should resume operation in V.21 mode and capture the entire test
454                         message.
455         Comments:       The TUT should indicate that carrier has been lost at some time after the carrier
456                         signal is removed and not disconnect.
457      */
458     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_03_put_text_msg, (void *) (intptr_t) 0);
459     logging = v18_get_logging_state(v18[TESTER]);
460     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
461     span_log_set_tag(logging, "Tester");
462     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_03_put_text_msg, (void *) (intptr_t) 1);
463     logging = v18_get_logging_state(v18[TUT]);
464     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
465     span_log_set_tag(logging, "TUT");
466 
467     if ((model = both_ways_line_model_init(line_model_no,
468                                            noise_level,
469                                            echo_level_cpe1,
470                                            echo_level_co1,
471                                            line_model_no,
472                                            noise_level,
473                                            echo_level_cpe2,
474                                            echo_level_co2,
475                                            channel_codec,
476                                            rbs_pattern)) == NULL)
477     {
478         fprintf(stderr, "    Failed to create line model\n");
479         exit(2);
480     }
481 
482     result[TESTER][0] =
483     result[TUT][0] = '\0';
484     for (i = 0;  i < 10000;  i++)
485     {
486         for (j = 0;  j < 2;  j++)
487         {
488             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
489                 push = 10;
490             if (samples < SAMPLES_PER_CHUNK)
491             {
492                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
493                 samples = SAMPLES_PER_CHUNK;
494             }
495         }
496         if (log_audio)
497         {
498             for (j = 0;  j < samples;  j++)
499             {
500                 out_amp[2*j + 0] = amp[0][j];
501                 out_amp[2*j + 1] = amp[1][j];
502             }
503             outframes = sf_writef_short(outhandle, out_amp, samples);
504             if (outframes != samples)
505             {
506                 fprintf(stderr, "    Error writing audio file\n");
507                 exit(2);
508             }
509         }
510 #if 1
511         both_ways_line_model(model,
512                              model_amp[0],
513                              amp[0],
514                              model_amp[1],
515                              amp[1],
516                              samples);
517 #else
518         vec_copyi16(model_amp[0], amp[0], samples);
519         vec_copyi16(model_amp[1], amp[1], samples);
520 #endif
521         v18_rx(v18[TESTER], model_amp[1], samples);
522         v18_rx(v18[TUT], model_amp[0], samples);
523     }
524 
525     v18_free(v18[TESTER]);
526     v18_free(v18[TUT]);
527     printf("Test not yet implemented\n");
528     return 1;
529 }
530 /*- End of function --------------------------------------------------------*/
531 
misc_04_put_text_msg(void * user_data,const uint8_t * msg,int len)532 static void misc_04_put_text_msg(void *user_data, const uint8_t *msg, int len)
533 {
534 }
535 /*- End of function --------------------------------------------------------*/
536 
test_misc_04(void)537 static int test_misc_04(void)
538 {
539     logging_state_t *logging;
540     int16_t amp[2][SAMPLES_PER_CHUNK];
541     int16_t model_amp[2][SAMPLES_PER_CHUNK];
542     int16_t out_amp[2*SAMPLES_PER_CHUNK];
543     int outframes;
544     int samples;
545     int push;
546     int i;
547     int j;
548 
549     /*
550         III.5.4.1.4     Detection of BUSY tone
551         Purpose:        To ensure that the DCE provides the call progress indication "BUSY" in presence of
552                         the national busy tone.
553         Preamble:       N/A
554         Method:         The TUT should be configured to dial out and then be presented with the
555                         appropriate national busy tone.
556         Pass criteria:  Detection of busy tone should be displayed by the TUT.
557         Comments:       ITU-T V.18 specifies that the DCE should not hang up, but that is intended to apply
558                         to the case where a connection is established and then lost. A terminal may
559                         automatically hang up when busy tone is detected. PABX busy tones may differ in
560                         frequency and cadence from national parameters.
561      */
562     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_04_put_text_msg, (void *) (intptr_t) 0);
563     logging = v18_get_logging_state(v18[TESTER]);
564     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
565     span_log_set_tag(logging, "Tester");
566     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_04_put_text_msg, (void *) (intptr_t) 1);
567     logging = v18_get_logging_state(v18[TUT]);
568     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
569     span_log_set_tag(logging, "TUT");
570 
571     if ((model = both_ways_line_model_init(line_model_no,
572                                            noise_level,
573                                            echo_level_cpe1,
574                                            echo_level_co1,
575                                            line_model_no,
576                                            noise_level,
577                                            echo_level_cpe2,
578                                            echo_level_co2,
579                                            channel_codec,
580                                            rbs_pattern)) == NULL)
581     {
582         fprintf(stderr, "    Failed to create line model\n");
583         exit(2);
584     }
585 
586     result[TESTER][0] =
587     result[TUT][0] = '\0';
588     for (i = 0;  i < 10000;  i++)
589     {
590         for (j = 0;  j < 2;  j++)
591         {
592             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
593                 push = 10;
594             if (samples < SAMPLES_PER_CHUNK)
595             {
596                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
597                 samples = SAMPLES_PER_CHUNK;
598             }
599         }
600         if (log_audio)
601         {
602             for (j = 0;  j < samples;  j++)
603             {
604                 out_amp[2*j + 0] = amp[0][j];
605                 out_amp[2*j + 1] = amp[1][j];
606             }
607             outframes = sf_writef_short(outhandle, out_amp, samples);
608             if (outframes != samples)
609             {
610                 fprintf(stderr, "    Error writing audio file\n");
611                 exit(2);
612             }
613         }
614 #if 1
615         both_ways_line_model(model,
616                              model_amp[0],
617                              amp[0],
618                              model_amp[1],
619                              amp[1],
620                              samples);
621 #else
622         vec_copyi16(model_amp[0], amp[0], samples);
623         vec_copyi16(model_amp[1], amp[1], samples);
624 #endif
625         v18_rx(v18[TESTER], model_amp[1], samples);
626         v18_rx(v18[TUT], model_amp[0], samples);
627     }
628 
629     v18_free(v18[TESTER]);
630     v18_free(v18[TUT]);
631     printf("Test not yet implemented\n");
632     return 1;
633 }
634 /*- End of function --------------------------------------------------------*/
635 
misc_05_put_text_msg(void * user_data,const uint8_t * msg,int len)636 static void misc_05_put_text_msg(void *user_data, const uint8_t *msg, int len)
637 {
638 }
639 /*- End of function --------------------------------------------------------*/
640 
test_misc_05(void)641 static int test_misc_05(void)
642 {
643     logging_state_t *logging;
644     int16_t amp[2][SAMPLES_PER_CHUNK];
645     int16_t model_amp[2][SAMPLES_PER_CHUNK];
646     int16_t out_amp[2*SAMPLES_PER_CHUNK];
647     int outframes;
648     int samples;
649     int push;
650     int i;
651     int j;
652 
653     /*
654         III.5.4.1.5     Detection of RINGING
655         Purpose:        To ensure that the DCE provides the call progress indication "RINGING" in
656                         presence of the national ringing tone.
657         Preamble:       N/A
658         Method:         The tester will make a call to the TUT using the nationally recommended cadence
659                         and the minimum recommended ring voltage/current.
660         Pass criteria:  The RINGING condition should be visually indicated by the TUT.
661         Comments:       This test should be repeated across a range of valid timings and ring voltages.
662      */
663     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_05_put_text_msg, (void *) (intptr_t) 0);
664     logging = v18_get_logging_state(v18[TESTER]);
665     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
666     span_log_set_tag(logging, "Tester");
667     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_05_put_text_msg, (void *) (intptr_t) 1);
668     logging = v18_get_logging_state(v18[TUT]);
669     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
670     span_log_set_tag(logging, "TUT");
671 
672     if ((model = both_ways_line_model_init(line_model_no,
673                                            noise_level,
674                                            echo_level_cpe1,
675                                            echo_level_co1,
676                                            line_model_no,
677                                            noise_level,
678                                            echo_level_cpe2,
679                                            echo_level_co2,
680                                            channel_codec,
681                                            rbs_pattern)) == NULL)
682     {
683         fprintf(stderr, "    Failed to create line model\n");
684         exit(2);
685     }
686 
687     result[TESTER][0] =
688     result[TUT][0] = '\0';
689     for (i = 0;  i < 10000;  i++)
690     {
691         for (j = 0;  j < 2;  j++)
692         {
693             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
694                 push = 10;
695             if (samples < SAMPLES_PER_CHUNK)
696             {
697                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
698                 samples = SAMPLES_PER_CHUNK;
699             }
700         }
701         if (log_audio)
702         {
703             for (j = 0;  j < samples;  j++)
704             {
705                 out_amp[2*j + 0] = amp[0][j];
706                 out_amp[2*j + 1] = amp[1][j];
707             }
708             outframes = sf_writef_short(outhandle, out_amp, samples);
709             if (outframes != samples)
710             {
711                 fprintf(stderr, "    Error writing audio file\n");
712                 exit(2);
713             }
714         }
715 #if 1
716         both_ways_line_model(model,
717                              model_amp[0],
718                              amp[0],
719                              model_amp[1],
720                              amp[1],
721                              samples);
722 #else
723         vec_copyi16(model_amp[0], amp[0], samples);
724         vec_copyi16(model_amp[1], amp[1], samples);
725 #endif
726         v18_rx(v18[TESTER], model_amp[1], samples);
727         v18_rx(v18[TUT], model_amp[0], samples);
728     }
729 
730     v18_free(v18[TESTER]);
731     v18_free(v18[TUT]);
732     printf("Test not yet implemented\n");
733     return 1;
734 }
735 /*- End of function --------------------------------------------------------*/
736 
misc_06_put_text_msg(void * user_data,const uint8_t * msg,int len)737 static void misc_06_put_text_msg(void *user_data, const uint8_t *msg, int len)
738 {
739 }
740 /*- End of function --------------------------------------------------------*/
741 
test_misc_06(void)742 static int test_misc_06(void)
743 {
744     logging_state_t *logging;
745     int16_t amp[2][SAMPLES_PER_CHUNK];
746     int16_t model_amp[2][SAMPLES_PER_CHUNK];
747     int16_t out_amp[2*SAMPLES_PER_CHUNK];
748     int outframes;
749     int samples;
750     int push;
751     int i;
752     int j;
753 
754     /*
755         III.5.4.1.6     "LOSS OF CARRIER" indication
756         Purpose:        To ensure that the DCE provides the call progress indication "LOSS OF CARRIER"
757                         upon a loss of carrier in full duplex modes, i.e. V.21, V.23, Bell 103.
758         Preamble:       N/A
759         Method:         Set up a call in each of the full duplex modes and force a carrier failure to the TUT.
760         Pass criteria:  Loss of carrier should be indicated and disappear when the carrier is restored.
761         Comments:       The V.18 modem should not automatically disconnect when used in a manual
762                         conversation mode. However, a V.18 equipped terminal may disconnect based on
763                         operational decisions, e.g. when it is a terminal in automatic answering machine
764                         mode. There may be other cases, e.g. where the V.18 DCE is used in a gateway,
765                         when automatic disconnection is required.
766      */
767     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_06_put_text_msg, (void *) (intptr_t) 0);
768     logging = v18_get_logging_state(v18[TESTER]);
769     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
770     span_log_set_tag(logging, "Tester");
771     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_06_put_text_msg, (void *) (intptr_t) 1);
772     logging = v18_get_logging_state(v18[TUT]);
773     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
774     span_log_set_tag(logging, "TUT");
775 
776     if ((model = both_ways_line_model_init(line_model_no,
777                                            noise_level,
778                                            echo_level_cpe1,
779                                            echo_level_co1,
780                                            line_model_no,
781                                            noise_level,
782                                            echo_level_cpe2,
783                                            echo_level_co2,
784                                            channel_codec,
785                                            rbs_pattern)) == NULL)
786     {
787         fprintf(stderr, "    Failed to create line model\n");
788         exit(2);
789     }
790 
791     result[TESTER][0] =
792     result[TUT][0] = '\0';
793     for (i = 0;  i < 10000;  i++)
794     {
795         for (j = 0;  j < 2;  j++)
796         {
797             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
798                 push = 10;
799             if (samples < SAMPLES_PER_CHUNK)
800             {
801                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
802                 samples = SAMPLES_PER_CHUNK;
803             }
804         }
805         if (log_audio)
806         {
807             for (j = 0;  j < samples;  j++)
808             {
809                 out_amp[2*j + 0] = amp[0][j];
810                 out_amp[2*j + 1] = amp[1][j];
811             }
812             outframes = sf_writef_short(outhandle, out_amp, samples);
813             if (outframes != samples)
814             {
815                 fprintf(stderr, "    Error writing audio file\n");
816                 exit(2);
817             }
818         }
819 #if 1
820         both_ways_line_model(model,
821                              model_amp[0],
822                              amp[0],
823                              model_amp[1],
824                              amp[1],
825                              samples);
826 #else
827         vec_copyi16(model_amp[0], amp[0], samples);
828         vec_copyi16(model_amp[1], amp[1], samples);
829 #endif
830         v18_rx(v18[TESTER], model_amp[1], samples);
831         v18_rx(v18[TUT], model_amp[0], samples);
832     }
833 
834     v18_free(v18[TESTER]);
835     v18_free(v18[TUT]);
836     printf("Test not yet implemented\n");
837     return 1;
838 }
839 /*- End of function --------------------------------------------------------*/
840 
misc_07_put_text_msg(void * user_data,const uint8_t * msg,int len)841 static void misc_07_put_text_msg(void *user_data, const uint8_t *msg, int len)
842 {
843 }
844 /*- End of function --------------------------------------------------------*/
845 
test_misc_07(void)846 static int test_misc_07(void)
847 {
848     logging_state_t *logging;
849     int16_t amp[2][SAMPLES_PER_CHUNK];
850     int16_t model_amp[2][SAMPLES_PER_CHUNK];
851     int16_t out_amp[2*SAMPLES_PER_CHUNK];
852     int outframes;
853     int samples;
854     int push;
855     int i;
856     int j;
857 
858     /*
859         III.5.4.1.7     Call progress indication
860         Purpose:        To ensure that the DCE provides the call progress indication "CONNECT(x)" upon
861                         a connection.
862         Preamble:       N/A
863         Method:         Correct CONNECT messages should be verified during the Automode tests that
864                         follow.
865         Pass criteria:  The relevant mode should be indicated by the DCE when automoding is complete.
866                         However, this may possibly not be indicated by the DTE.
867         Comments:       The possible modes are: V.21, V.23, Baudot 45, Baudot 50, EDT, Bell 103, DTMF.
868      */
869     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_07_put_text_msg, (void *) (intptr_t) 0);
870     logging = v18_get_logging_state(v18[TESTER]);
871     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
872     span_log_set_tag(logging, "Tester");
873     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_07_put_text_msg, (void *) (intptr_t) 1);
874     logging = v18_get_logging_state(v18[TUT]);
875     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
876     span_log_set_tag(logging, "TUT");
877 
878     if ((model = both_ways_line_model_init(line_model_no,
879                                            noise_level,
880                                            echo_level_cpe1,
881                                            echo_level_co1,
882                                            line_model_no,
883                                            noise_level,
884                                            echo_level_cpe2,
885                                            echo_level_co2,
886                                            channel_codec,
887                                            rbs_pattern)) == NULL)
888     {
889         fprintf(stderr, "    Failed to create line model\n");
890         exit(2);
891     }
892 
893     result[TESTER][0] =
894     result[TUT][0] = '\0';
895     for (i = 0;  i < 10000;  i++)
896     {
897         for (j = 0;  j < 2;  j++)
898         {
899             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
900                 push = 10;
901             if (samples < SAMPLES_PER_CHUNK)
902             {
903                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
904                 samples = SAMPLES_PER_CHUNK;
905             }
906         }
907         if (log_audio)
908         {
909             for (j = 0;  j < samples;  j++)
910             {
911                 out_amp[2*j + 0] = amp[0][j];
912                 out_amp[2*j + 1] = amp[1][j];
913             }
914             outframes = sf_writef_short(outhandle, out_amp, samples);
915             if (outframes != samples)
916             {
917                 fprintf(stderr, "    Error writing audio file\n");
918                 exit(2);
919             }
920         }
921 #if 1
922         both_ways_line_model(model,
923                              model_amp[0],
924                              amp[0],
925                              model_amp[1],
926                              amp[1],
927                              samples);
928 #else
929         vec_copyi16(model_amp[0], amp[0], samples);
930         vec_copyi16(model_amp[1], amp[1], samples);
931 #endif
932         v18_rx(v18[TESTER], model_amp[1], samples);
933         v18_rx(v18[TUT], model_amp[0], samples);
934     }
935 
936     v18_free(v18[TESTER]);
937     v18_free(v18[TUT]);
938     printf("Test not yet implemented\n");
939     return 1;
940 }
941 /*- End of function --------------------------------------------------------*/
942 
misc_08_put_text_msg(void * user_data,const uint8_t * msg,int len)943 static void misc_08_put_text_msg(void *user_data, const uint8_t *msg, int len)
944 {
945 }
946 /*- End of function --------------------------------------------------------*/
947 
test_misc_08(void)948 static int test_misc_08(void)
949 {
950     logging_state_t *logging;
951     int16_t amp[2][SAMPLES_PER_CHUNK];
952     int16_t model_amp[2][SAMPLES_PER_CHUNK];
953     int16_t out_amp[2*SAMPLES_PER_CHUNK];
954     int outframes;
955     int samples;
956     int push;
957     int i;
958     int j;
959 
960     /*
961         III.5.4.1.8     Circuit 135 Test
962         Purpose:        To ensure that the DCE implements circuit 135 or an equivalent way of indicating
963                         presence of a signal.
964         Preamble:       N/A
965         Method:         A call from the TUT should be answered in voice mode after 20s. The tester
966                         will transmit sampled voice messages. V.24 circuit 135 or its equivalent should be
967                         observed.
968         Pass criteria:  The ring tone and speech shall be indicated by circuit 135.
969         Comment:        The response times and signal level thresholds of Circuit 135 are not specified in
970                         ITU-T V.18 or V.24 and therefore the pattern indicated may vary.
971      */
972     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_08_put_text_msg, (void *) (intptr_t) 0);
973     logging = v18_get_logging_state(v18[TESTER]);
974     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
975     span_log_set_tag(logging, "Tester");
976     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_08_put_text_msg, (void *) (intptr_t) 1);
977     logging = v18_get_logging_state(v18[TUT]);
978     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
979     span_log_set_tag(logging, "TUT");
980 
981     if ((model = both_ways_line_model_init(line_model_no,
982                                            noise_level,
983                                            echo_level_cpe1,
984                                            echo_level_co1,
985                                            line_model_no,
986                                            noise_level,
987                                            echo_level_cpe2,
988                                            echo_level_co2,
989                                            channel_codec,
990                                            rbs_pattern)) == NULL)
991     {
992         fprintf(stderr, "    Failed to create line model\n");
993         exit(2);
994     }
995 
996     result[TESTER][0] =
997     result[TUT][0] = '\0';
998     for (i = 0;  i < 10000;  i++)
999     {
1000         for (j = 0;  j < 2;  j++)
1001         {
1002             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1003                 push = 10;
1004             if (samples < SAMPLES_PER_CHUNK)
1005             {
1006                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1007                 samples = SAMPLES_PER_CHUNK;
1008             }
1009         }
1010         if (log_audio)
1011         {
1012             for (j = 0;  j < samples;  j++)
1013             {
1014                 out_amp[2*j + 0] = amp[0][j];
1015                 out_amp[2*j + 1] = amp[1][j];
1016             }
1017             outframes = sf_writef_short(outhandle, out_amp, samples);
1018             if (outframes != samples)
1019             {
1020                 fprintf(stderr, "    Error writing audio file\n");
1021                 exit(2);
1022             }
1023         }
1024 #if 1
1025         both_ways_line_model(model,
1026                              model_amp[0],
1027                              amp[0],
1028                              model_amp[1],
1029                              amp[1],
1030                              samples);
1031 #else
1032         vec_copyi16(model_amp[0], amp[0], samples);
1033         vec_copyi16(model_amp[1], amp[1], samples);
1034 #endif
1035         v18_rx(v18[TESTER], model_amp[1], samples);
1036         v18_rx(v18[TUT], model_amp[0], samples);
1037     }
1038 
1039     v18_free(v18[TESTER]);
1040     v18_free(v18[TUT]);
1041     printf("Test not yet implemented\n");
1042     return 1;
1043 }
1044 /*- End of function --------------------------------------------------------*/
1045 
misc_09_put_text_msg(void * user_data,const uint8_t * msg,int len)1046 static void misc_09_put_text_msg(void *user_data, const uint8_t *msg, int len)
1047 {
1048 }
1049 /*- End of function --------------------------------------------------------*/
1050 
test_misc_09(void)1051 static int test_misc_09(void)
1052 {
1053     logging_state_t *logging;
1054     int16_t amp[2][SAMPLES_PER_CHUNK];
1055     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1056     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1057     int outframes;
1058     int samples;
1059     int push;
1060     int i;
1061     int j;
1062 
1063     /*
1064         III.5.4.1.9     Connection procedures
1065         Purpose:        To ensure that the TUT implements the call connect procedure described in
1066                         clause 6.
1067         Preamble:       N/A
1068         Method:         TBD
1069         Pass criteria:  TBD
1070         Comment:        TBD
1071      */
1072     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_09_put_text_msg, (void *) (intptr_t) 0);
1073     logging = v18_get_logging_state(v18[TESTER]);
1074     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1075     span_log_set_tag(logging, "Tester");
1076     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, misc_09_put_text_msg, (void *) (intptr_t) 1);
1077     logging = v18_get_logging_state(v18[TUT]);
1078     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1079     span_log_set_tag(logging, "TUT");
1080 
1081     if ((model = both_ways_line_model_init(line_model_no,
1082                                            noise_level,
1083                                            echo_level_cpe1,
1084                                            echo_level_co1,
1085                                            line_model_no,
1086                                            noise_level,
1087                                            echo_level_cpe2,
1088                                            echo_level_co2,
1089                                            channel_codec,
1090                                            rbs_pattern)) == NULL)
1091     {
1092         fprintf(stderr, "    Failed to create line model\n");
1093         exit(2);
1094     }
1095 
1096     result[TESTER][0] =
1097     result[TUT][0] = '\0';
1098     for (i = 0;  i < 10000;  i++)
1099     {
1100         for (j = 0;  j < 2;  j++)
1101         {
1102             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1103                 push = 10;
1104             if (samples < SAMPLES_PER_CHUNK)
1105             {
1106                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1107                 samples = SAMPLES_PER_CHUNK;
1108             }
1109         }
1110         if (log_audio)
1111         {
1112             for (j = 0;  j < samples;  j++)
1113             {
1114                 out_amp[2*j + 0] = amp[0][j];
1115                 out_amp[2*j + 1] = amp[1][j];
1116             }
1117             outframes = sf_writef_short(outhandle, out_amp, samples);
1118             if (outframes != samples)
1119             {
1120                 fprintf(stderr, "    Error writing audio file\n");
1121                 exit(2);
1122             }
1123         }
1124 #if 1
1125         both_ways_line_model(model,
1126                              model_amp[0],
1127                              amp[0],
1128                              model_amp[1],
1129                              amp[1],
1130                              samples);
1131 #else
1132         vec_copyi16(model_amp[0], amp[0], samples);
1133         vec_copyi16(model_amp[1], amp[1], samples);
1134 #endif
1135         v18_rx(v18[TESTER], model_amp[1], samples);
1136         v18_rx(v18[TUT], model_amp[0], samples);
1137     }
1138 
1139     v18_free(v18[TESTER]);
1140     v18_free(v18[TUT]);
1141     printf("Test not yet implemented\n");
1142     return 1;
1143 }
1144 /*- End of function --------------------------------------------------------*/
1145 
org_01_put_text_msg(void * user_data,const uint8_t * msg,int len)1146 static void org_01_put_text_msg(void *user_data, const uint8_t *msg, int len)
1147 {
1148 }
1149 /*- End of function --------------------------------------------------------*/
1150 
test_org_01(void)1151 static int test_org_01(void)
1152 {
1153     logging_state_t *logging;
1154     int16_t amp[2][SAMPLES_PER_CHUNK];
1155     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1156     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1157     int outframes;
1158     int samples;
1159     int push;
1160     int i;
1161     int j;
1162 
1163     /*
1164         III.5.4.2.1     CI and XCI signal coding and cadence
1165         Purpose:        To verify that TUT correctly emits the CI and XCI signals with the ON/OFF
1166                         cadence defined in 5.1.1.
1167         Preamble:       N/A
1168         Method:         V.21 demodulator is used to decode the CI sequence and a timer to measure the
1169                         silence intervals between them. The XCI signal is also monitored and decoded to
1170                         check for correct coding and timing of the signal.
1171         Pass criteria:  1) No signal should be transmitted for one second after connecting to the line.
1172                         2) Four CI patterns are transmitted for each repetition.
1173                         3) No signal is transmitted for 2s after the end of each CI.
1174                         4) Each CI must have the correct bit pattern.
1175                         5) The CI patterns followed by 2s of silence must be repeated twice.
1176                         6) One second after every 3 blocks CI an XCI signal must be transmitted.
1177                         7) The XCI should have the structure defined in 3.11.
1178                         8) The whole sequence should be repeated until the call is cleared.
1179                         9) When V.18 to V.18, the XCI must not force V.23 or Minitel mode.
1180      */
1181     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_01_put_text_msg, (void *) (intptr_t) 0);
1182     logging = v18_get_logging_state(v18[TESTER]);
1183     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1184     span_log_set_tag(logging, "Tester");
1185     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_01_put_text_msg, (void *) (intptr_t) 1);
1186     logging = v18_get_logging_state(v18[TUT]);
1187     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1188     span_log_set_tag(logging, "TUT");
1189 
1190     if ((model = both_ways_line_model_init(line_model_no,
1191                                            noise_level,
1192                                            echo_level_cpe1,
1193                                            echo_level_co1,
1194                                            line_model_no,
1195                                            noise_level,
1196                                            echo_level_cpe2,
1197                                            echo_level_co2,
1198                                            channel_codec,
1199                                            rbs_pattern)) == NULL)
1200     {
1201         fprintf(stderr, "    Failed to create line model\n");
1202         exit(2);
1203     }
1204 
1205     result[TESTER][0] =
1206     result[TUT][0] = '\0';
1207     for (i = 0;  i < 10000;  i++)
1208     {
1209         for (j = 0;  j < 2;  j++)
1210         {
1211             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1212                 push = 10;
1213             if (samples < SAMPLES_PER_CHUNK)
1214             {
1215                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1216                 samples = SAMPLES_PER_CHUNK;
1217             }
1218         }
1219         if (log_audio)
1220         {
1221             for (j = 0;  j < samples;  j++)
1222             {
1223                 out_amp[2*j + 0] = amp[0][j];
1224                 out_amp[2*j + 1] = amp[1][j];
1225             }
1226             outframes = sf_writef_short(outhandle, out_amp, samples);
1227             if (outframes != samples)
1228             {
1229                 fprintf(stderr, "    Error writing audio file\n");
1230                 exit(2);
1231             }
1232         }
1233 #if 1
1234         both_ways_line_model(model,
1235                              model_amp[0],
1236                              amp[0],
1237                              model_amp[1],
1238                              amp[1],
1239                              samples);
1240 #else
1241         vec_copyi16(model_amp[0], amp[0], samples);
1242         vec_copyi16(model_amp[1], amp[1], samples);
1243 #endif
1244         v18_rx(v18[TESTER], model_amp[1], samples);
1245         v18_rx(v18[TUT], model_amp[0], samples);
1246     }
1247 
1248     v18_free(v18[TESTER]);
1249     v18_free(v18[TUT]);
1250     printf("Test not yet implemented\n");
1251     return 1;
1252 }
1253 /*- End of function --------------------------------------------------------*/
1254 
org_02_put_text_msg(void * user_data,const uint8_t * msg,int len)1255 static void org_02_put_text_msg(void *user_data, const uint8_t *msg, int len)
1256 {
1257 }
1258 /*- End of function --------------------------------------------------------*/
1259 
test_org_02(void)1260 static int test_org_02(void)
1261 {
1262     logging_state_t *logging;
1263     int16_t amp[2][SAMPLES_PER_CHUNK];
1264     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1265     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1266     int outframes;
1267     int samples;
1268     int push;
1269     int i;
1270     int j;
1271 
1272     /*
1273         III.5.4.2.2     ANS signal detection
1274         Purpose:        To verify that TUT correctly detects the ANS (2100Hz) signal during the
1275                         two-second interval (Toff) between transmission of CI sequences.
1276         Preamble:       Make a V.18 call from the TUT.
1277         Method:         The Test System waits for the TUT to stop transmitting a CI and responds with an
1278                         ANS signal. The V.21 demodulator is used to decode the TXP sequence and a timer
1279                         measures the silence intervals between them. ANS should be transmitted for 2s.
1280         Pass criteria:  1) No signal should be transmitted by TUT for 0.5s from detection of ANS.
1281                         2) The TUT should reply with transmission of TXP as defined in 5.1.2.
1282                         3) Verify that TXP sequence has correct bit pattern.
1283      */
1284     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_02_put_text_msg, (void *) (intptr_t) 0);
1285     logging = v18_get_logging_state(v18[TESTER]);
1286     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1287     span_log_set_tag(logging, "Tester");
1288     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_02_put_text_msg, (void *) (intptr_t) 1);
1289     logging = v18_get_logging_state(v18[TUT]);
1290     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1291     span_log_set_tag(logging, "TUT");
1292 
1293     if ((model = both_ways_line_model_init(line_model_no,
1294                                            noise_level,
1295                                            echo_level_cpe1,
1296                                            echo_level_co1,
1297                                            line_model_no,
1298                                            noise_level,
1299                                            echo_level_cpe2,
1300                                            echo_level_co2,
1301                                            channel_codec,
1302                                            rbs_pattern)) == NULL)
1303     {
1304         fprintf(stderr, "    Failed to create line model\n");
1305         exit(2);
1306     }
1307 
1308     result[TESTER][0] =
1309     result[TUT][0] = '\0';
1310     for (i = 0;  i < 10000;  i++)
1311     {
1312         for (j = 0;  j < 2;  j++)
1313         {
1314             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1315                 push = 10;
1316             if (samples < SAMPLES_PER_CHUNK)
1317             {
1318                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1319                 samples = SAMPLES_PER_CHUNK;
1320             }
1321         }
1322         if (log_audio)
1323         {
1324             for (j = 0;  j < samples;  j++)
1325             {
1326                 out_amp[2*j + 0] = amp[0][j];
1327                 out_amp[2*j + 1] = amp[1][j];
1328             }
1329             outframes = sf_writef_short(outhandle, out_amp, samples);
1330             if (outframes != samples)
1331             {
1332                 fprintf(stderr, "    Error writing audio file\n");
1333                 exit(2);
1334             }
1335         }
1336 #if 1
1337         both_ways_line_model(model,
1338                              model_amp[0],
1339                              amp[0],
1340                              model_amp[1],
1341                              amp[1],
1342                              samples);
1343 #else
1344         vec_copyi16(model_amp[0], amp[0], samples);
1345         vec_copyi16(model_amp[1], amp[1], samples);
1346 #endif
1347         v18_rx(v18[TESTER], model_amp[1], samples);
1348         v18_rx(v18[TUT], model_amp[0], samples);
1349     }
1350 
1351     v18_free(v18[TESTER]);
1352     v18_free(v18[TUT]);
1353     printf("Test not yet implemented\n");
1354     return 1;
1355 }
1356 /*- End of function --------------------------------------------------------*/
1357 
org_03_put_text_msg(void * user_data,const uint8_t * msg,int len)1358 static void org_03_put_text_msg(void *user_data, const uint8_t *msg, int len)
1359 {
1360 }
1361 /*- End of function --------------------------------------------------------*/
1362 
test_org_03(void)1363 static int test_org_03(void)
1364 {
1365     logging_state_t *logging;
1366     int16_t amp[2][SAMPLES_PER_CHUNK];
1367     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1368     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1369     int outframes;
1370     int samples;
1371     int push;
1372     int i;
1373     int j;
1374 
1375     /*
1376         III.5.4.2.3     End of ANS signal detection
1377         Purpose:        The TUT should stop sending TXP at the end of the current sequence when the ANS
1378                         tone ceases.
1379         Preamble:       Test ORG-02 should be successfully completed immediately prior to this test.
1380         Method:         The tester sends ANS for 2s followed by silence. The tester will then
1381                         monitor for cessation of TXP at the end of the answer tone.
1382         Pass criteria:  The TUT should stop sending TXP at the end of the current sequence when ANS
1383                         tone ceases.
1384      */
1385     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_03_put_text_msg, (void *) (intptr_t) 0);
1386     logging = v18_get_logging_state(v18[TESTER]);
1387     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1388     span_log_set_tag(logging, "Tester");
1389     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_03_put_text_msg, (void *) (intptr_t) 1);
1390     logging = v18_get_logging_state(v18[TUT]);
1391     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1392     span_log_set_tag(logging, "TUT");
1393 
1394     if ((model = both_ways_line_model_init(line_model_no,
1395                                            noise_level,
1396                                            echo_level_cpe1,
1397                                            echo_level_co1,
1398                                            line_model_no,
1399                                            noise_level,
1400                                            echo_level_cpe2,
1401                                            echo_level_co2,
1402                                            channel_codec,
1403                                            rbs_pattern)) == NULL)
1404     {
1405         fprintf(stderr, "    Failed to create line model\n");
1406         exit(2);
1407     }
1408 
1409     result[TESTER][0] =
1410     result[TUT][0] = '\0';
1411     for (i = 0;  i < 10000;  i++)
1412     {
1413         for (j = 0;  j < 2;  j++)
1414         {
1415             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1416                 push = 10;
1417             if (samples < SAMPLES_PER_CHUNK)
1418             {
1419                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1420                 samples = SAMPLES_PER_CHUNK;
1421             }
1422         }
1423         if (log_audio)
1424         {
1425             for (j = 0;  j < samples;  j++)
1426             {
1427                 out_amp[2*j + 0] = amp[0][j];
1428                 out_amp[2*j + 1] = amp[1][j];
1429             }
1430             outframes = sf_writef_short(outhandle, out_amp, samples);
1431             if (outframes != samples)
1432             {
1433                 fprintf(stderr, "    Error writing audio file\n");
1434                 exit(2);
1435             }
1436         }
1437 #if 1
1438         both_ways_line_model(model,
1439                              model_amp[0],
1440                              amp[0],
1441                              model_amp[1],
1442                              amp[1],
1443                              samples);
1444 #else
1445         vec_copyi16(model_amp[0], amp[0], samples);
1446         vec_copyi16(model_amp[1], amp[1], samples);
1447 #endif
1448         v18_rx(v18[TESTER], model_amp[1], samples);
1449         v18_rx(v18[TUT], model_amp[0], samples);
1450     }
1451 
1452     v18_free(v18[TESTER]);
1453     v18_free(v18[TUT]);
1454     printf("Test not yet implemented\n");
1455     return 1;
1456 }
1457 /*- End of function --------------------------------------------------------*/
1458 
org_04_put_text_msg(void * user_data,const uint8_t * msg,int len)1459 static void org_04_put_text_msg(void *user_data, const uint8_t *msg, int len)
1460 {
1461 }
1462 /*- End of function --------------------------------------------------------*/
1463 
test_org_04(void)1464 static int test_org_04(void)
1465 {
1466     logging_state_t *logging;
1467     int16_t amp[2][SAMPLES_PER_CHUNK];
1468     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1469     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1470     int outframes;
1471     int samples;
1472     int push;
1473     int i;
1474     int j;
1475 
1476     /*
1477         III.5.4.2.4     ANS tone followed by TXP
1478         Purpose:        To check correct detection of V.18 modem.
1479         Preamble:       Tests ORG-02 and ORG-03 should be successfully completed prior to this test.
1480         Method:         Tester transmits ANS for 2.5s followed by 75ms of no tone then transmits
1481                         3 TXP sequences using V.21 (2) and starts a 1s timer. It will then transmit 1650Hz
1482                         for 5s.
1483         Pass criteria:  1) TUT should initially respond with TXP.
1484                         2) TUT should stop sending TXP within 0.2s of end of ANS.
1485                         3) TUT should respond with 980Hz carrier within 1s of end of 3 TXP sequences.
1486                         4) Data should be transmitted and received according to ITU-T T.140 to comply
1487                            with the V.18 operational requirements.
1488         Comments:       The TUT should indicate that V.18 mode has been selected.
1489      */
1490     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_04_put_text_msg, (void *) (intptr_t) 0);
1491     logging = v18_get_logging_state(v18[TESTER]);
1492     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1493     span_log_set_tag(logging, "Tester");
1494     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_04_put_text_msg, (void *) (intptr_t) 1);
1495     logging = v18_get_logging_state(v18[TUT]);
1496     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1497     span_log_set_tag(logging, "TUT");
1498 
1499     if ((model = both_ways_line_model_init(line_model_no,
1500                                            noise_level,
1501                                            echo_level_cpe1,
1502                                            echo_level_co1,
1503                                            line_model_no,
1504                                            noise_level,
1505                                            echo_level_cpe2,
1506                                            echo_level_co2,
1507                                            channel_codec,
1508                                            rbs_pattern)) == NULL)
1509     {
1510         fprintf(stderr, "    Failed to create line model\n");
1511         exit(2);
1512     }
1513 
1514     result[TESTER][0] =
1515     result[TUT][0] = '\0';
1516     for (i = 0;  i < 10000;  i++)
1517     {
1518         for (j = 0;  j < 2;  j++)
1519         {
1520             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1521                 push = 10;
1522             if (samples < SAMPLES_PER_CHUNK)
1523             {
1524                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1525                 samples = SAMPLES_PER_CHUNK;
1526             }
1527         }
1528         if (log_audio)
1529         {
1530             for (j = 0;  j < samples;  j++)
1531             {
1532                 out_amp[2*j + 0] = amp[0][j];
1533                 out_amp[2*j + 1] = amp[1][j];
1534             }
1535             outframes = sf_writef_short(outhandle, out_amp, samples);
1536             if (outframes != samples)
1537             {
1538                 fprintf(stderr, "    Error writing audio file\n");
1539                 exit(2);
1540             }
1541         }
1542 #if 1
1543         both_ways_line_model(model,
1544                              model_amp[0],
1545                              amp[0],
1546                              model_amp[1],
1547                              amp[1],
1548                              samples);
1549 #else
1550         vec_copyi16(model_amp[0], amp[0], samples);
1551         vec_copyi16(model_amp[1], amp[1], samples);
1552 #endif
1553         v18_rx(v18[TESTER], model_amp[1], samples);
1554         v18_rx(v18[TUT], model_amp[0], samples);
1555     }
1556 
1557     v18_free(v18[TESTER]);
1558     v18_free(v18[TUT]);
1559     printf("Test not yet implemented\n");
1560     return 1;
1561 }
1562 /*- End of function --------------------------------------------------------*/
1563 
org_05_put_text_msg(void * user_data,const uint8_t * msg,int len)1564 static void org_05_put_text_msg(void *user_data, const uint8_t *msg, int len)
1565 {
1566 }
1567 /*- End of function --------------------------------------------------------*/
1568 
test_org_05(void)1569 static int test_org_05(void)
1570 {
1571     logging_state_t *logging;
1572     int16_t amp[2][SAMPLES_PER_CHUNK];
1573     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1574     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1575     int outframes;
1576     int samples;
1577     int push;
1578     int i;
1579     int j;
1580 
1581     /*
1582         III.5.4.2.5     ANS tone followed by 1650Hz
1583         Purpose:        To check correct detection of V.21 modem upper channel when preceded by answer
1584                         tone and to confirm discrimination between V.21 and V.18 modes.
1585         Preamble:       Tests ORG-02 and ORG-03 should be successfully completed prior to this test.
1586         Method:         Tester transmits ANS for 2.5s followed by 75ms of no tone then transmits
1587                         1650Hz and starts a 0.7 second timer.
1588         Pass criteria:  1) TUT should initially respond with TXP.
1589                         2) TUT should stop sending TXP within 0.2s of end of ANS.
1590                         3) TUT should respond with 980Hz at 0.5(+0.2-0.0)s of start of 1650Hz.
1591                         4) Data should be transmitted and received at 300 bit/s complying with Annex F.
1592         Comments:       Selection of ITU-T V.21 as opposed to ITU-T V.18 should be confirmed by
1593                         examination of TUT. If there is no visual indication, verify by use of ITU-T T.50 for
1594                         ITU-T V.21 as opposed to UTF-8 coded ISO 10646 character set for ITU-T V.18.
1595      */
1596     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_05_put_text_msg, (void *) (intptr_t) 0);
1597     logging = v18_get_logging_state(v18[TESTER]);
1598     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1599     span_log_set_tag(logging, "Tester");
1600     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_05_put_text_msg, (void *) (intptr_t) 1);
1601     logging = v18_get_logging_state(v18[TUT]);
1602     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1603     span_log_set_tag(logging, "TUT");
1604 
1605     if ((model = both_ways_line_model_init(line_model_no,
1606                                            noise_level,
1607                                            echo_level_cpe1,
1608                                            echo_level_co1,
1609                                            line_model_no,
1610                                            noise_level,
1611                                            echo_level_cpe2,
1612                                            echo_level_co2,
1613                                            channel_codec,
1614                                            rbs_pattern)) == NULL)
1615     {
1616         fprintf(stderr, "    Failed to create line model\n");
1617         exit(2);
1618     }
1619 
1620     result[TESTER][0] =
1621     result[TUT][0] = '\0';
1622     for (i = 0;  i < 10000;  i++)
1623     {
1624         for (j = 0;  j < 2;  j++)
1625         {
1626             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1627                 push = 10;
1628             if (samples < SAMPLES_PER_CHUNK)
1629             {
1630                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1631                 samples = SAMPLES_PER_CHUNK;
1632             }
1633         }
1634         if (log_audio)
1635         {
1636             for (j = 0;  j < samples;  j++)
1637             {
1638                 out_amp[2*j + 0] = amp[0][j];
1639                 out_amp[2*j + 1] = amp[1][j];
1640             }
1641             outframes = sf_writef_short(outhandle, out_amp, samples);
1642             if (outframes != samples)
1643             {
1644                 fprintf(stderr, "    Error writing audio file\n");
1645                 exit(2);
1646             }
1647         }
1648 #if 1
1649         both_ways_line_model(model,
1650                              model_amp[0],
1651                              amp[0],
1652                              model_amp[1],
1653                              amp[1],
1654                              samples);
1655 #else
1656         vec_copyi16(model_amp[0], amp[0], samples);
1657         vec_copyi16(model_amp[1], amp[1], samples);
1658 #endif
1659         v18_rx(v18[TESTER], model_amp[1], samples);
1660         v18_rx(v18[TUT], model_amp[0], samples);
1661     }
1662 
1663     v18_free(v18[TESTER]);
1664     v18_free(v18[TUT]);
1665     printf("Test not yet implemented\n");
1666     return 1;
1667 }
1668 /*- End of function --------------------------------------------------------*/
1669 
org_06_put_text_msg(void * user_data,const uint8_t * msg,int len)1670 static void org_06_put_text_msg(void *user_data, const uint8_t *msg, int len)
1671 {
1672 }
1673 /*- End of function --------------------------------------------------------*/
1674 
test_org_06(void)1675 static int test_org_06(void)
1676 {
1677     logging_state_t *logging;
1678     int16_t amp[2][SAMPLES_PER_CHUNK];
1679     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1680     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1681     int outframes;
1682     int samples;
1683     int push;
1684     int i;
1685     int j;
1686 
1687     /*
1688         III.5.4.2.6     ANS tone followed by 1300Hz
1689         Purpose:        To check correct detection of V.23 modem upper channel when preceded by answer
1690                         tone.
1691         Preamble:       Tests ORG-02 and ORG-03 should be successfully completed prior to this test.
1692         Method:         Tester transmits ANS for 2.5s followed by 75ms of no tone then transmits
1693                         1300Hz and starts a 2.7s timer.
1694         Pass criteria:  1) TUT should initially respond with TXP.
1695                         2) TUT should stop sending TXP within 0.2s of end of ANS.
1696                         3) TUT should respond with 390Hz after 1.7(+0.2-0.0)s of start of 1300Hz.
1697                         4) Data should be transmitted and received at 75 bit/s and 1200 bit/s respectively
1698                            by the TUT to comply with Annex E.
1699         Comments:       The TUT should indicate that V.23 mode has been selected.
1700      */
1701     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_06_put_text_msg, (void *) (intptr_t) 0);
1702     logging = v18_get_logging_state(v18[TESTER]);
1703     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1704     span_log_set_tag(logging, "Tester");
1705     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_06_put_text_msg, (void *) (intptr_t) 1);
1706     logging = v18_get_logging_state(v18[TUT]);
1707     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1708     span_log_set_tag(logging, "TUT");
1709 
1710     if ((model = both_ways_line_model_init(line_model_no,
1711                                            noise_level,
1712                                            echo_level_cpe1,
1713                                            echo_level_co1,
1714                                            line_model_no,
1715                                            noise_level,
1716                                            echo_level_cpe2,
1717                                            echo_level_co2,
1718                                            channel_codec,
1719                                            rbs_pattern)) == NULL)
1720     {
1721         fprintf(stderr, "    Failed to create line model\n");
1722         exit(2);
1723     }
1724 
1725     result[TESTER][0] =
1726     result[TUT][0] = '\0';
1727     for (i = 0;  i < 10000;  i++)
1728     {
1729         for (j = 0;  j < 2;  j++)
1730         {
1731             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1732                 push = 10;
1733             if (samples < SAMPLES_PER_CHUNK)
1734             {
1735                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1736                 samples = SAMPLES_PER_CHUNK;
1737             }
1738         }
1739         if (log_audio)
1740         {
1741             for (j = 0;  j < samples;  j++)
1742             {
1743                 out_amp[2*j + 0] = amp[0][j];
1744                 out_amp[2*j + 1] = amp[1][j];
1745             }
1746             outframes = sf_writef_short(outhandle, out_amp, samples);
1747             if (outframes != samples)
1748             {
1749                 fprintf(stderr, "    Error writing audio file\n");
1750                 exit(2);
1751             }
1752         }
1753 #if 1
1754         both_ways_line_model(model,
1755                              model_amp[0],
1756                              amp[0],
1757                              model_amp[1],
1758                              amp[1],
1759                              samples);
1760 #else
1761         vec_copyi16(model_amp[0], amp[0], samples);
1762         vec_copyi16(model_amp[1], amp[1], samples);
1763 #endif
1764         v18_rx(v18[TESTER], model_amp[1], samples);
1765         v18_rx(v18[TUT], model_amp[0], samples);
1766     }
1767 
1768     v18_free(v18[TESTER]);
1769     v18_free(v18[TUT]);
1770     printf("Test not yet implemented\n");
1771     return 1;
1772 }
1773 /*- End of function --------------------------------------------------------*/
1774 
org_07_put_text_msg(void * user_data,const uint8_t * msg,int len)1775 static void org_07_put_text_msg(void *user_data, const uint8_t *msg, int len)
1776 {
1777 }
1778 /*- End of function --------------------------------------------------------*/
1779 
test_org_07(void)1780 static int test_org_07(void)
1781 {
1782     logging_state_t *logging;
1783     int16_t amp[2][SAMPLES_PER_CHUNK];
1784     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1785     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1786     int outframes;
1787     int samples;
1788     int push;
1789     int i;
1790     int j;
1791 
1792     /*
1793         III.5.4.2.7     ANS tone followed by no tone
1794         Purpose:        To confirm that TUT does not lock up under this condition.
1795         Preamble:       Tests ORG-02 and ORG-03 should be successfully completed prior to this test.
1796         Method:         Tester transmits ANS for 2.5s followed by no tone for 10 s. It then transmits
1797                         DTMF tones for 2s.
1798         Pass criteria:  1) TUT should initially respond with TXP.
1799                         2) TUT should stop sending TXP within 0.2s of end of ANS.
1800                         3) TUT should return to Monitor 1 state and then connect in DTMF mode within
1801                            12s of the end of ANS tone.
1802         Comments:       This condition would cause the terminal to lock up if the V.18 standard is followed
1803                         literally. It may however, occur when connected to certain Swedish textphones if the
1804                         handset is lifted just after the start of an automatically answered incoming call.
1805      */
1806     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_07_put_text_msg, (void *) (intptr_t) 0);
1807     logging = v18_get_logging_state(v18[TESTER]);
1808     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1809     span_log_set_tag(logging, "Tester");
1810     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_07_put_text_msg, (void *) (intptr_t) 1);
1811     logging = v18_get_logging_state(v18[TUT]);
1812     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1813     span_log_set_tag(logging, "TUT");
1814 
1815     if ((model = both_ways_line_model_init(line_model_no,
1816                                            noise_level,
1817                                            echo_level_cpe1,
1818                                            echo_level_co1,
1819                                            line_model_no,
1820                                            noise_level,
1821                                            echo_level_cpe2,
1822                                            echo_level_co2,
1823                                            channel_codec,
1824                                            rbs_pattern)) == NULL)
1825     {
1826         fprintf(stderr, "    Failed to create line model\n");
1827         exit(2);
1828     }
1829 
1830     result[TESTER][0] =
1831     result[TUT][0] = '\0';
1832     for (i = 0;  i < 10000;  i++)
1833     {
1834         for (j = 0;  j < 2;  j++)
1835         {
1836             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1837                 push = 10;
1838             if (samples < SAMPLES_PER_CHUNK)
1839             {
1840                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1841                 samples = SAMPLES_PER_CHUNK;
1842             }
1843         }
1844         if (log_audio)
1845         {
1846             for (j = 0;  j < samples;  j++)
1847             {
1848                 out_amp[2*j + 0] = amp[0][j];
1849                 out_amp[2*j + 1] = amp[1][j];
1850             }
1851             outframes = sf_writef_short(outhandle, out_amp, samples);
1852             if (outframes != samples)
1853             {
1854                 fprintf(stderr, "    Error writing audio file\n");
1855                 exit(2);
1856             }
1857         }
1858 #if 1
1859         both_ways_line_model(model,
1860                              model_amp[0],
1861                              amp[0],
1862                              model_amp[1],
1863                              amp[1],
1864                              samples);
1865 #else
1866         vec_copyi16(model_amp[0], amp[0], samples);
1867         vec_copyi16(model_amp[1], amp[1], samples);
1868 #endif
1869         v18_rx(v18[TESTER], model_amp[1], samples);
1870         v18_rx(v18[TUT], model_amp[0], samples);
1871     }
1872 
1873     v18_free(v18[TESTER]);
1874     v18_free(v18[TUT]);
1875     printf("Test not yet implemented\n");
1876     return 1;
1877 }
1878 /*- End of function --------------------------------------------------------*/
1879 
org_08_put_text_msg(void * user_data,const uint8_t * msg,int len)1880 static void org_08_put_text_msg(void *user_data, const uint8_t *msg, int len)
1881 {
1882 }
1883 /*- End of function --------------------------------------------------------*/
1884 
test_org_08(void)1885 static int test_org_08(void)
1886 {
1887     logging_state_t *logging;
1888     int16_t amp[2][SAMPLES_PER_CHUNK];
1889     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1890     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1891     int outframes;
1892     int samples;
1893     int push;
1894     int i;
1895     int j;
1896 
1897     /*
1898         III.5.4.2.8     Bell 103 (2225Hz signal) detection
1899         Purpose:        To verify that the TUT correctly detects the Bell 103 upper channel signal during
1900                         the 2-second interval between transmission of CI sequences.
1901         Preamble:       N/A
1902         Method:         The tester waits for a CI and then sends a 2225Hz signal for 5s.
1903         Pass criteria:  1) The TUT should respond with a 1270Hz tone in 0.5+-0.1s.
1904                         2) Data should be transmitted and received at 300 bit/s to comply with Annex D.
1905         Comments:       The TUT should indicate that Bell 103 mode has been selected.
1906      */
1907     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_08_put_text_msg, (void *) (intptr_t) 0);
1908     logging = v18_get_logging_state(v18[TESTER]);
1909     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1910     span_log_set_tag(logging, "Tester");
1911     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_08_put_text_msg, (void *) (intptr_t) 1);
1912     logging = v18_get_logging_state(v18[TUT]);
1913     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1914     span_log_set_tag(logging, "TUT");
1915 
1916     if ((model = both_ways_line_model_init(line_model_no,
1917                                            noise_level,
1918                                            echo_level_cpe1,
1919                                            echo_level_co1,
1920                                            line_model_no,
1921                                            noise_level,
1922                                            echo_level_cpe2,
1923                                            echo_level_co2,
1924                                            channel_codec,
1925                                            rbs_pattern)) == NULL)
1926     {
1927         fprintf(stderr, "    Failed to create line model\n");
1928         exit(2);
1929     }
1930 
1931     result[TESTER][0] =
1932     result[TUT][0] = '\0';
1933     for (i = 0;  i < 10000;  i++)
1934     {
1935         for (j = 0;  j < 2;  j++)
1936         {
1937             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
1938                 push = 10;
1939             if (samples < SAMPLES_PER_CHUNK)
1940             {
1941                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
1942                 samples = SAMPLES_PER_CHUNK;
1943             }
1944         }
1945         if (log_audio)
1946         {
1947             for (j = 0;  j < samples;  j++)
1948             {
1949                 out_amp[2*j + 0] = amp[0][j];
1950                 out_amp[2*j + 1] = amp[1][j];
1951             }
1952             outframes = sf_writef_short(outhandle, out_amp, samples);
1953             if (outframes != samples)
1954             {
1955                 fprintf(stderr, "    Error writing audio file\n");
1956                 exit(2);
1957             }
1958         }
1959 #if 1
1960         both_ways_line_model(model,
1961                              model_amp[0],
1962                              amp[0],
1963                              model_amp[1],
1964                              amp[1],
1965                              samples);
1966 #else
1967         vec_copyi16(model_amp[0], amp[0], samples);
1968         vec_copyi16(model_amp[1], amp[1], samples);
1969 #endif
1970         v18_rx(v18[TESTER], model_amp[1], samples);
1971         v18_rx(v18[TUT], model_amp[0], samples);
1972     }
1973 
1974     v18_free(v18[TESTER]);
1975     v18_free(v18[TUT]);
1976     printf("Test not yet implemented\n");
1977     return 1;
1978 }
1979 /*- End of function --------------------------------------------------------*/
1980 
org_09_put_text_msg(void * user_data,const uint8_t * msg,int len)1981 static void org_09_put_text_msg(void *user_data, const uint8_t *msg, int len)
1982 {
1983 }
1984 /*- End of function --------------------------------------------------------*/
1985 
test_org_09(void)1986 static int test_org_09(void)
1987 {
1988     logging_state_t *logging;
1989     int16_t amp[2][SAMPLES_PER_CHUNK];
1990     int16_t model_amp[2][SAMPLES_PER_CHUNK];
1991     int16_t out_amp[2*SAMPLES_PER_CHUNK];
1992     int outframes;
1993     int samples;
1994     int push;
1995     int i;
1996     int j;
1997 
1998     /*
1999         III.5.4.2.9     V.21 (1650Hz signal) detection
2000         Purpose:        To verify that the TUT correctly detects the V.21 upper channel signal during the
2001                         2-second interval between transmission of CI sequences.
2002         Preamble:       N/A
2003         Method:         The tester waits for a CI and then sends a 1650Hz signal for 5s.
2004         Pass criteria:  1) The TUT should respond with a 980Hz tone in 0.5+-0.1s.
2005                         2) Data should be transmitted and received at 300 bit/s to comply with Annex F.
2006         Comments:       The TUT should indicate that V.21 mode has been selected.
2007      */
2008     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_09_put_text_msg, (void *) (intptr_t) 0);
2009     logging = v18_get_logging_state(v18[TESTER]);
2010     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2011     span_log_set_tag(logging, "Tester");
2012     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_09_put_text_msg, (void *) (intptr_t) 1);
2013     logging = v18_get_logging_state(v18[TUT]);
2014     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2015     span_log_set_tag(logging, "TUT");
2016 
2017     if ((model = both_ways_line_model_init(line_model_no,
2018                                            noise_level,
2019                                            echo_level_cpe1,
2020                                            echo_level_co1,
2021                                            line_model_no,
2022                                            noise_level,
2023                                            echo_level_cpe2,
2024                                            echo_level_co2,
2025                                            channel_codec,
2026                                            rbs_pattern)) == NULL)
2027     {
2028         fprintf(stderr, "    Failed to create line model\n");
2029         exit(2);
2030     }
2031 
2032     result[TESTER][0] =
2033     result[TUT][0] = '\0';
2034     for (i = 0;  i < 10000;  i++)
2035     {
2036         for (j = 0;  j < 2;  j++)
2037         {
2038             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2039                 push = 10;
2040             if (samples < SAMPLES_PER_CHUNK)
2041             {
2042                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2043                 samples = SAMPLES_PER_CHUNK;
2044             }
2045         }
2046         if (log_audio)
2047         {
2048             for (j = 0;  j < samples;  j++)
2049             {
2050                 out_amp[2*j + 0] = amp[0][j];
2051                 out_amp[2*j + 1] = amp[1][j];
2052             }
2053             outframes = sf_writef_short(outhandle, out_amp, samples);
2054             if (outframes != samples)
2055             {
2056                 fprintf(stderr, "    Error writing audio file\n");
2057                 exit(2);
2058             }
2059         }
2060 #if 1
2061         both_ways_line_model(model,
2062                              model_amp[0],
2063                              amp[0],
2064                              model_amp[1],
2065                              amp[1],
2066                              samples);
2067 #else
2068         vec_copyi16(model_amp[0], amp[0], samples);
2069         vec_copyi16(model_amp[1], amp[1], samples);
2070 #endif
2071         v18_rx(v18[TESTER], model_amp[1], samples);
2072         v18_rx(v18[TUT], model_amp[0], samples);
2073     }
2074 
2075     v18_free(v18[TESTER]);
2076     v18_free(v18[TUT]);
2077     printf("Test not yet implemented\n");
2078     return 1;
2079 }
2080 /*- End of function --------------------------------------------------------*/
2081 
org_10_put_text_msg(void * user_data,const uint8_t * msg,int len)2082 static void org_10_put_text_msg(void *user_data, const uint8_t *msg, int len)
2083 {
2084 }
2085 /*- End of function --------------------------------------------------------*/
2086 
test_org_10(void)2087 static int test_org_10(void)
2088 {
2089     logging_state_t *logging;
2090     int16_t amp[2][SAMPLES_PER_CHUNK];
2091     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2092     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2093     int outframes;
2094     int samples;
2095     int push;
2096     int i;
2097     int j;
2098 
2099     /*
2100         III.5.4.2.10    V.23 (1300Hz signal) detection
2101         Purpose:        To verify that the TUT correctly detects the V.23 upper channel signal during the
2102                         2-second interval between transmission of CI sequences.
2103         Preamble:       N/A
2104         Method:         The tester waits for a CI and then sends a 1300Hz signal for 5s.
2105         Pass criteria:  1) The TUT should respond with a 390Hz tone in 1.7+-0.1s.
2106                         2) Data should be transmitted and received at 75 bit/s and 1200 bit/s respectively
2107                            by the TUT to comply with Annex E.
2108         Comments:       The TUT should indicate that V.23 mode has been selected.
2109      */
2110     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_10_put_text_msg, (void *) (intptr_t) 0);
2111     logging = v18_get_logging_state(v18[TESTER]);
2112     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2113     span_log_set_tag(logging, "Tester");
2114     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_10_put_text_msg, (void *) (intptr_t) 1);
2115     logging = v18_get_logging_state(v18[TUT]);
2116     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2117     span_log_set_tag(logging, "TUT");
2118 
2119     if ((model = both_ways_line_model_init(line_model_no,
2120                                            noise_level,
2121                                            echo_level_cpe1,
2122                                            echo_level_co1,
2123                                            line_model_no,
2124                                            noise_level,
2125                                            echo_level_cpe2,
2126                                            echo_level_co2,
2127                                            channel_codec,
2128                                            rbs_pattern)) == NULL)
2129     {
2130         fprintf(stderr, "    Failed to create line model\n");
2131         exit(2);
2132     }
2133 
2134     result[TESTER][0] =
2135     result[TUT][0] = '\0';
2136     for (i = 0;  i < 10000;  i++)
2137     {
2138         for (j = 0;  j < 2;  j++)
2139         {
2140             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2141                 push = 10;
2142             if (samples < SAMPLES_PER_CHUNK)
2143             {
2144                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2145                 samples = SAMPLES_PER_CHUNK;
2146             }
2147         }
2148         if (log_audio)
2149         {
2150             for (j = 0;  j < samples;  j++)
2151             {
2152                 out_amp[2*j + 0] = amp[0][j];
2153                 out_amp[2*j + 1] = amp[1][j];
2154             }
2155             outframes = sf_writef_short(outhandle, out_amp, samples);
2156             if (outframes != samples)
2157             {
2158                 fprintf(stderr, "    Error writing audio file\n");
2159                 exit(2);
2160             }
2161         }
2162 #if 1
2163         both_ways_line_model(model,
2164                              model_amp[0],
2165                              amp[0],
2166                              model_amp[1],
2167                              amp[1],
2168                              samples);
2169 #else
2170         vec_copyi16(model_amp[0], amp[0], samples);
2171         vec_copyi16(model_amp[1], amp[1], samples);
2172 #endif
2173         v18_rx(v18[TESTER], model_amp[1], samples);
2174         v18_rx(v18[TUT], model_amp[0], samples);
2175     }
2176 
2177     v18_free(v18[TESTER]);
2178     v18_free(v18[TUT]);
2179     printf("Test not yet implemented\n");
2180     return 1;
2181 }
2182 /*- End of function --------------------------------------------------------*/
2183 
org_11_put_text_msg(void * user_data,const uint8_t * msg,int len)2184 static void org_11_put_text_msg(void *user_data, const uint8_t *msg, int len)
2185 {
2186 }
2187 /*- End of function --------------------------------------------------------*/
2188 
test_org_11(void)2189 static int test_org_11(void)
2190 {
2191     logging_state_t *logging;
2192     int16_t amp[2][SAMPLES_PER_CHUNK];
2193     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2194     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2195     int outframes;
2196     int samples;
2197     int push;
2198     int i;
2199     int j;
2200 
2201     /*
2202         III.5.4.2.11    V.23 (390Hz signal) detection
2203         Purpose:        To confirm correct selection of V.23 reverse mode during sending of XCI.
2204         Preamble:       N/A
2205         Method:         The tester should wait for the start of the XCI signal and then send 390Hz to TUT
2206                         for 5s.
2207         Pass criteria:  1) The TUT should complete the XCI as normal.
2208                         2) The TUT should then maintain the 1300Hz tone while the 390Hz test tone is
2209                            present.
2210                         3) Data should be transmitted and received at 1200 bit/s and 75 bit/s respectively
2211                            by the TUT to comply with Annex E when connection is indicated.
2212         Comments:       The TUT should indicate that V.23 mode has been selected at least 3s after
2213                         the start of the 390Hz tone.
2214      */
2215     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_11_put_text_msg, (void *) (intptr_t) 0);
2216     logging = v18_get_logging_state(v18[TESTER]);
2217     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2218     span_log_set_tag(logging, "Tester");
2219     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_11_put_text_msg, (void *) (intptr_t) 1);
2220     logging = v18_get_logging_state(v18[TUT]);
2221     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2222     span_log_set_tag(logging, "TUT");
2223 
2224     if ((model = both_ways_line_model_init(line_model_no,
2225                                            noise_level,
2226                                            echo_level_cpe1,
2227                                            echo_level_co1,
2228                                            line_model_no,
2229                                            noise_level,
2230                                            echo_level_cpe2,
2231                                            echo_level_co2,
2232                                            channel_codec,
2233                                            rbs_pattern)) == NULL)
2234     {
2235         fprintf(stderr, "    Failed to create line model\n");
2236         exit(2);
2237     }
2238 
2239     result[TESTER][0] =
2240     result[TUT][0] = '\0';
2241     for (i = 0;  i < 10000;  i++)
2242     {
2243         for (j = 0;  j < 2;  j++)
2244         {
2245             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2246                 push = 10;
2247             if (samples < SAMPLES_PER_CHUNK)
2248             {
2249                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2250                 samples = SAMPLES_PER_CHUNK;
2251             }
2252         }
2253         if (log_audio)
2254         {
2255             for (j = 0;  j < samples;  j++)
2256             {
2257                 out_amp[2*j + 0] = amp[0][j];
2258                 out_amp[2*j + 1] = amp[1][j];
2259             }
2260             outframes = sf_writef_short(outhandle, out_amp, samples);
2261             if (outframes != samples)
2262             {
2263                 fprintf(stderr, "    Error writing audio file\n");
2264                 exit(2);
2265             }
2266         }
2267 #if 1
2268         both_ways_line_model(model,
2269                              model_amp[0],
2270                              amp[0],
2271                              model_amp[1],
2272                              amp[1],
2273                              samples);
2274 #else
2275         vec_copyi16(model_amp[0], amp[0], samples);
2276         vec_copyi16(model_amp[1], amp[1], samples);
2277 #endif
2278         v18_rx(v18[TESTER], model_amp[1], samples);
2279         v18_rx(v18[TUT], model_amp[0], samples);
2280     }
2281 
2282     v18_free(v18[TESTER]);
2283     v18_free(v18[TUT]);
2284     printf("Test not yet implemented\n");
2285     return 1;
2286 }
2287 /*- End of function --------------------------------------------------------*/
2288 
org_12_put_text_msg(void * user_data,const uint8_t * msg,int len)2289 static void org_12_put_text_msg(void *user_data, const uint8_t *msg, int len)
2290 {
2291 }
2292 /*- End of function --------------------------------------------------------*/
2293 
test_org_12(void)2294 static int test_org_12(void)
2295 {
2296     logging_state_t *logging;
2297     int16_t amp[2][SAMPLES_PER_CHUNK];
2298     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2299     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2300     int outframes;
2301     int samples;
2302     int push;
2303     int i;
2304     int j;
2305 
2306     /*
2307         III.5.4.2.12    5 bit mode (Baudot) detection tests
2308         Purpose:        To confirm detection of Baudot modulation at various bit rates that may be
2309                         encountered.
2310         Preamble:       N/A
2311         Method:         The tester transmits the 5-bit coded characters "0" to "9" followed by "abcdef" at
2312                         (a) 45.45, (b) 47.6, (c) 50 and (d) 100 bits per second. When TUT indicates a
2313                         connection, type at least 5 characters back to the tester so that correct selection
2314                         of bit rate can be confirmed.
2315         Pass criteria:  1) TUT should select Baudot mode and the appropriate bit rate.
2316                         2) The tester will analyse the bit rate of received characters, which should be at
2317                            either 45.45 or 50 bits per second as appropriate.
2318         Comments:       45.45 and 50 bit/s are the commonly used Baudot bit rates. However, certain
2319                         textphones can operate at higher rates (e.g. 100 bit/s). Responding at either 45.45 or
2320                         50 bit/s is acceptable to these devices which normally fall back to the selected rate.
2321                         47.6 bit/s may possibly be encountered from another V.18 textphone in the
2322                         automode answer state. The TUT may then select either 45.45 or 50 bit/s for the
2323                         transmission.
2324      */
2325     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_12_put_text_msg, (void *) (intptr_t) 0);
2326     logging = v18_get_logging_state(v18[TESTER]);
2327     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2328     span_log_set_tag(logging, "Tester");
2329     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_12_put_text_msg, (void *) (intptr_t) 1);
2330     logging = v18_get_logging_state(v18[TUT]);
2331     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2332     span_log_set_tag(logging, "TUT");
2333 
2334     if ((model = both_ways_line_model_init(line_model_no,
2335                                            noise_level,
2336                                            echo_level_cpe1,
2337                                            echo_level_co1,
2338                                            line_model_no,
2339                                            noise_level,
2340                                            echo_level_cpe2,
2341                                            echo_level_co2,
2342                                            channel_codec,
2343                                            rbs_pattern)) == NULL)
2344     {
2345         fprintf(stderr, "    Failed to create line model\n");
2346         exit(2);
2347     }
2348 
2349     result[TESTER][0] =
2350     result[TUT][0] = '\0';
2351     for (i = 0;  i < 10000;  i++)
2352     {
2353         for (j = 0;  j < 2;  j++)
2354         {
2355             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2356                 push = 10;
2357             if (samples < SAMPLES_PER_CHUNK)
2358             {
2359                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2360                 samples = SAMPLES_PER_CHUNK;
2361             }
2362         }
2363         if (log_audio)
2364         {
2365             for (j = 0;  j < samples;  j++)
2366             {
2367                 out_amp[2*j + 0] = amp[0][j];
2368                 out_amp[2*j + 1] = amp[1][j];
2369             }
2370             outframes = sf_writef_short(outhandle, out_amp, samples);
2371             if (outframes != samples)
2372             {
2373                 fprintf(stderr, "    Error writing audio file\n");
2374                 exit(2);
2375             }
2376         }
2377 #if 1
2378         both_ways_line_model(model,
2379                              model_amp[0],
2380                              amp[0],
2381                              model_amp[1],
2382                              amp[1],
2383                              samples);
2384 #else
2385         vec_copyi16(model_amp[0], amp[0], samples);
2386         vec_copyi16(model_amp[1], amp[1], samples);
2387 #endif
2388         v18_rx(v18[TESTER], model_amp[1], samples);
2389         v18_rx(v18[TUT], model_amp[0], samples);
2390     }
2391 
2392     v18_free(v18[TESTER]);
2393     v18_free(v18[TUT]);
2394     printf("Test not yet implemented\n");
2395     return 1;
2396 }
2397 /*- End of function --------------------------------------------------------*/
2398 
org_13_put_text_msg(void * user_data,const uint8_t * msg,int len)2399 static void org_13_put_text_msg(void *user_data, const uint8_t *msg, int len)
2400 {
2401 }
2402 /*- End of function --------------------------------------------------------*/
2403 
test_org_13(void)2404 static int test_org_13(void)
2405 {
2406     logging_state_t *logging;
2407     int16_t amp[2][SAMPLES_PER_CHUNK];
2408     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2409     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2410     int outframes;
2411     int samples;
2412     int push;
2413     int i;
2414     int j;
2415 
2416     /*
2417         III.5.4.2.13    DTMF signal detection
2418         Purpose:        To verify whether the TUT correctly recognizes DTMF signals during the 2-second
2419                         interval between transmission of CI.
2420         Preamble:       N/A
2421         Method:         The tester will send a single DTMF tone of 40ms duration to TUT. When TUT
2422                         indicates a connection, type at least 5 characters back to the tester so that correct
2423                         selection of mode can be confirmed.
2424         Pass criteria:  The tester will analyse the received characters to confirm DTMF mode selection.
2425         Comments:       TUT should indicate that it has selected DTMF mode. The DTMF capabilities of the
2426                         TUT should comply with ITU-T Q.24 for the Danish Administration while
2427                         receiving for best possible performance.
2428      */
2429     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_13_put_text_msg, (void *) (intptr_t) 0);
2430     logging = v18_get_logging_state(v18[TESTER]);
2431     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2432     span_log_set_tag(logging, "Tester");
2433     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_13_put_text_msg, (void *) (intptr_t) 1);
2434     logging = v18_get_logging_state(v18[TUT]);
2435     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2436     span_log_set_tag(logging, "TUT");
2437 
2438     if ((model = both_ways_line_model_init(line_model_no,
2439                                            noise_level,
2440                                            echo_level_cpe1,
2441                                            echo_level_co1,
2442                                            line_model_no,
2443                                            noise_level,
2444                                            echo_level_cpe2,
2445                                            echo_level_co2,
2446                                            channel_codec,
2447                                            rbs_pattern)) == NULL)
2448     {
2449         fprintf(stderr, "    Failed to create line model\n");
2450         exit(2);
2451     }
2452 
2453     result[TESTER][0] =
2454     result[TUT][0] = '\0';
2455     for (i = 0;  i < 10000;  i++)
2456     {
2457         for (j = 0;  j < 2;  j++)
2458         {
2459             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2460                 push = 10;
2461             if (samples < SAMPLES_PER_CHUNK)
2462             {
2463                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2464                 samples = SAMPLES_PER_CHUNK;
2465             }
2466         }
2467         if (log_audio)
2468         {
2469             for (j = 0;  j < samples;  j++)
2470             {
2471                 out_amp[2*j + 0] = amp[0][j];
2472                 out_amp[2*j + 1] = amp[1][j];
2473             }
2474             outframes = sf_writef_short(outhandle, out_amp, samples);
2475             if (outframes != samples)
2476             {
2477                 fprintf(stderr, "    Error writing audio file\n");
2478                 exit(2);
2479             }
2480         }
2481 #if 1
2482         both_ways_line_model(model,
2483                              model_amp[0],
2484                              amp[0],
2485                              model_amp[1],
2486                              amp[1],
2487                              samples);
2488 #else
2489         vec_copyi16(model_amp[0], amp[0], samples);
2490         vec_copyi16(model_amp[1], amp[1], samples);
2491 #endif
2492         v18_rx(v18[TESTER], model_amp[1], samples);
2493         v18_rx(v18[TUT], model_amp[0], samples);
2494     }
2495 
2496     v18_free(v18[TESTER]);
2497     v18_free(v18[TUT]);
2498     printf("Test not yet implemented\n");
2499     return 1;
2500 }
2501 /*- End of function --------------------------------------------------------*/
2502 
org_14_put_text_msg(void * user_data,const uint8_t * msg,int len)2503 static void org_14_put_text_msg(void *user_data, const uint8_t *msg, int len)
2504 {
2505 }
2506 /*- End of function --------------------------------------------------------*/
2507 
test_org_14(void)2508 static int test_org_14(void)
2509 {
2510     logging_state_t *logging;
2511     int16_t amp[2][SAMPLES_PER_CHUNK];
2512     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2513     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2514     int outframes;
2515     int samples;
2516     int push;
2517     int i;
2518     int j;
2519 
2520     /*
2521         III.5.4.2.14    EDT rate detection
2522         Purpose:        To confirm detection of EDT modems by detecting the transmission rate of received
2523                         characters.
2524         Preamble:       N/A
2525         Method:         The tester transmits EDT characters "abcdef" to TUT at 110 bit/s. When TUT
2526                         indicates that the connection is established, type characters "abcdef<CR>" back to
2527                         the tester. The same characters will then be transmitted back to the TUT.
2528         Pass criteria:  Ensure correct reception of characters by tester and TUT.
2529         Comments:       The TUT should be able to determine the rate on the six characters given. If it takes
2530                         more than this then performance is probably inadequate as too many characters
2531                         would be lost. Some characters may be lost during the detection process. However,
2532                         the number lost should be minimal. The data bits and parity are specified in
2533                         Annex C.
2534      */
2535     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_14_put_text_msg, (void *) (intptr_t) 0);
2536     logging = v18_get_logging_state(v18[TESTER]);
2537     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2538     span_log_set_tag(logging, "Tester");
2539     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_14_put_text_msg, (void *) (intptr_t) 1);
2540     logging = v18_get_logging_state(v18[TUT]);
2541     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2542     span_log_set_tag(logging, "TUT");
2543 
2544     if ((model = both_ways_line_model_init(line_model_no,
2545                                            noise_level,
2546                                            echo_level_cpe1,
2547                                            echo_level_co1,
2548                                            line_model_no,
2549                                            noise_level,
2550                                            echo_level_cpe2,
2551                                            echo_level_co2,
2552                                            channel_codec,
2553                                            rbs_pattern)) == NULL)
2554     {
2555         fprintf(stderr, "    Failed to create line model\n");
2556         exit(2);
2557     }
2558 
2559     result[TESTER][0] =
2560     result[TUT][0] = '\0';
2561     for (i = 0;  i < 10000;  i++)
2562     {
2563         for (j = 0;  j < 2;  j++)
2564         {
2565             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2566                 push = 10;
2567             if (samples < SAMPLES_PER_CHUNK)
2568             {
2569                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2570                 samples = SAMPLES_PER_CHUNK;
2571             }
2572         }
2573         if (log_audio)
2574         {
2575             for (j = 0;  j < samples;  j++)
2576             {
2577                 out_amp[2*j + 0] = amp[0][j];
2578                 out_amp[2*j + 1] = amp[1][j];
2579             }
2580             outframes = sf_writef_short(outhandle, out_amp, samples);
2581             if (outframes != samples)
2582             {
2583                 fprintf(stderr, "    Error writing audio file\n");
2584                 exit(2);
2585             }
2586         }
2587 #if 1
2588         both_ways_line_model(model,
2589                              model_amp[0],
2590                              amp[0],
2591                              model_amp[1],
2592                              amp[1],
2593                              samples);
2594 #else
2595         vec_copyi16(model_amp[0], amp[0], samples);
2596         vec_copyi16(model_amp[1], amp[1], samples);
2597 #endif
2598         v18_rx(v18[TESTER], model_amp[1], samples);
2599         v18_rx(v18[TUT], model_amp[0], samples);
2600     }
2601 
2602     v18_free(v18[TESTER]);
2603     v18_free(v18[TUT]);
2604     printf("Test not yet implemented\n");
2605     return 1;
2606 }
2607 /*- End of function --------------------------------------------------------*/
2608 
org_15_put_text_msg(void * user_data,const uint8_t * msg,int len)2609 static void org_15_put_text_msg(void *user_data, const uint8_t *msg, int len)
2610 {
2611 }
2612 /*- End of function --------------------------------------------------------*/
2613 
test_org_15(void)2614 static int test_org_15(void)
2615 {
2616     logging_state_t *logging;
2617     int16_t amp[2][SAMPLES_PER_CHUNK];
2618     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2619     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2620     int outframes;
2621     int samples;
2622     int push;
2623     int i;
2624     int j;
2625 
2626     /*
2627         III.5.4.2.15    Rate detection test
2628         Purpose:        To verify the presence of 980/1180Hz at a different signalling rate than 110 bit/s
2629                         returns the TUT modem to the "monitor A" state.
2630         Preamble:       N/A
2631         Method:         The tester transmits 980/1180Hz signals at 300 bit/s for 2s.
2632         Pass criteria:  The TUT should not select EDT or any other mode and should continue to transmit
2633                         the CI signal.
2634         Comments:       Echoes of the CI sequences may be detected at 300 bit/s.
2635      */
2636     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_15_put_text_msg, (void *) (intptr_t) 0);
2637     logging = v18_get_logging_state(v18[TESTER]);
2638     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2639     span_log_set_tag(logging, "Tester");
2640     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_15_put_text_msg, (void *) (intptr_t) 1);
2641     logging = v18_get_logging_state(v18[TUT]);
2642     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2643     span_log_set_tag(logging, "TUT");
2644 
2645     if ((model = both_ways_line_model_init(line_model_no,
2646                                            noise_level,
2647                                            echo_level_cpe1,
2648                                            echo_level_co1,
2649                                            line_model_no,
2650                                            noise_level,
2651                                            echo_level_cpe2,
2652                                            echo_level_co2,
2653                                            channel_codec,
2654                                            rbs_pattern)) == NULL)
2655     {
2656         fprintf(stderr, "    Failed to create line model\n");
2657         exit(2);
2658     }
2659 
2660     result[TESTER][0] =
2661     result[TUT][0] = '\0';
2662     for (i = 0;  i < 10000;  i++)
2663     {
2664         for (j = 0;  j < 2;  j++)
2665         {
2666             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2667                 push = 10;
2668             if (samples < SAMPLES_PER_CHUNK)
2669             {
2670                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2671                 samples = SAMPLES_PER_CHUNK;
2672             }
2673         }
2674         if (log_audio)
2675         {
2676             for (j = 0;  j < samples;  j++)
2677             {
2678                 out_amp[2*j + 0] = amp[0][j];
2679                 out_amp[2*j + 1] = amp[1][j];
2680             }
2681             outframes = sf_writef_short(outhandle, out_amp, samples);
2682             if (outframes != samples)
2683             {
2684                 fprintf(stderr, "    Error writing audio file\n");
2685                 exit(2);
2686             }
2687         }
2688 #if 1
2689         both_ways_line_model(model,
2690                              model_amp[0],
2691                              amp[0],
2692                              model_amp[1],
2693                              amp[1],
2694                              samples);
2695 #else
2696         vec_copyi16(model_amp[0], amp[0], samples);
2697         vec_copyi16(model_amp[1], amp[1], samples);
2698 #endif
2699         v18_rx(v18[TESTER], model_amp[1], samples);
2700         v18_rx(v18[TUT], model_amp[0], samples);
2701     }
2702 
2703     v18_free(v18[TESTER]);
2704     v18_free(v18[TUT]);
2705     printf("Test not yet implemented\n");
2706     return 1;
2707 }
2708 /*- End of function --------------------------------------------------------*/
2709 
org_16_put_text_msg(void * user_data,const uint8_t * msg,int len)2710 static void org_16_put_text_msg(void *user_data, const uint8_t *msg, int len)
2711 {
2712 }
2713 /*- End of function --------------------------------------------------------*/
2714 
test_org_16(void)2715 static int test_org_16(void)
2716 {
2717     logging_state_t *logging;
2718     int16_t amp[2][SAMPLES_PER_CHUNK];
2719     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2720     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2721     int outframes;
2722     int samples;
2723     int push;
2724     int i;
2725     int j;
2726 
2727     /*
2728         III.5.4.2.16    980Hz detection
2729         Purpose:        To confirm correct selection of V.21 reverse mode.
2730         Preamble:       N/A
2731         Method:         The tester sends 980Hz to TUT for 5s.
2732         Pass criteria:  1) TUT should respond with 1650Hz tone after 1.5+-0.1s after start of
2733                            980Hz tone.
2734                         2) Data should be transmitted and received at 300 bit/s complying with Annex F.
2735         Comments:       The TUT should indicate that V.21 mode has been selected.
2736      */
2737     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_16_put_text_msg, (void *) (intptr_t) 0);
2738     logging = v18_get_logging_state(v18[TESTER]);
2739     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2740     span_log_set_tag(logging, "Tester");
2741     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_16_put_text_msg, (void *) (intptr_t) 1);
2742     logging = v18_get_logging_state(v18[TUT]);
2743     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2744     span_log_set_tag(logging, "TUT");
2745 
2746     if ((model = both_ways_line_model_init(line_model_no,
2747                                            noise_level,
2748                                            echo_level_cpe1,
2749                                            echo_level_co1,
2750                                            line_model_no,
2751                                            noise_level,
2752                                            echo_level_cpe2,
2753                                            echo_level_co2,
2754                                            channel_codec,
2755                                            rbs_pattern)) == NULL)
2756     {
2757         fprintf(stderr, "    Failed to create line model\n");
2758         exit(2);
2759     }
2760 
2761     result[TESTER][0] =
2762     result[TUT][0] = '\0';
2763     for (i = 0;  i < 10000;  i++)
2764     {
2765         for (j = 0;  j < 2;  j++)
2766         {
2767             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2768                 push = 10;
2769             if (samples < SAMPLES_PER_CHUNK)
2770             {
2771                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2772                 samples = SAMPLES_PER_CHUNK;
2773             }
2774         }
2775         if (log_audio)
2776         {
2777             for (j = 0;  j < samples;  j++)
2778             {
2779                 out_amp[2*j + 0] = amp[0][j];
2780                 out_amp[2*j + 1] = amp[1][j];
2781             }
2782             outframes = sf_writef_short(outhandle, out_amp, samples);
2783             if (outframes != samples)
2784             {
2785                 fprintf(stderr, "    Error writing audio file\n");
2786                 exit(2);
2787             }
2788         }
2789 #if 1
2790         both_ways_line_model(model,
2791                              model_amp[0],
2792                              amp[0],
2793                              model_amp[1],
2794                              amp[1],
2795                              samples);
2796 #else
2797         vec_copyi16(model_amp[0], amp[0], samples);
2798         vec_copyi16(model_amp[1], amp[1], samples);
2799 #endif
2800         v18_rx(v18[TESTER], model_amp[1], samples);
2801         v18_rx(v18[TUT], model_amp[0], samples);
2802     }
2803 
2804     v18_free(v18[TESTER]);
2805     v18_free(v18[TUT]);
2806     printf("Test not yet implemented\n");
2807     return 1;
2808 }
2809 /*- End of function --------------------------------------------------------*/
2810 
org_17_put_text_msg(void * user_data,const uint8_t * msg,int len)2811 static void org_17_put_text_msg(void *user_data, const uint8_t *msg, int len)
2812 {
2813 }
2814 /*- End of function --------------------------------------------------------*/
2815 
test_org_17(void)2816 static int test_org_17(void)
2817 {
2818     logging_state_t *logging;
2819     int16_t amp[2][SAMPLES_PER_CHUNK];
2820     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2821     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2822     int outframes;
2823     int samples;
2824     int push;
2825     int i;
2826     int j;
2827 
2828     /*
2829         III.5.4.2.17    Loss of signal after 980Hz
2830         Purpose:        To confirm that TUT returns to the Monitor 1 state if 980Hz signal disappears.
2831         Preamble:       N/A
2832         Method:         The tester sends 980Hz to TUT for 1.2s followed by silence for 5s.
2833         Pass criteria:  TUT should not respond to the 980Hz tone and resume sending CI signals after a
2834                         maximum of 2.4s from the end of the 980Hz tone.
2835      */
2836     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_17_put_text_msg, (void *) (intptr_t) 0);
2837     logging = v18_get_logging_state(v18[TESTER]);
2838     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2839     span_log_set_tag(logging, "Tester");
2840     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_17_put_text_msg, (void *) (intptr_t) 1);
2841     logging = v18_get_logging_state(v18[TUT]);
2842     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2843     span_log_set_tag(logging, "TUT");
2844 
2845     if ((model = both_ways_line_model_init(line_model_no,
2846                                            noise_level,
2847                                            echo_level_cpe1,
2848                                            echo_level_co1,
2849                                            line_model_no,
2850                                            noise_level,
2851                                            echo_level_cpe2,
2852                                            echo_level_co2,
2853                                            channel_codec,
2854                                            rbs_pattern)) == NULL)
2855     {
2856         fprintf(stderr, "    Failed to create line model\n");
2857         exit(2);
2858     }
2859 
2860     result[TESTER][0] =
2861     result[TUT][0] = '\0';
2862     for (i = 0;  i < 10000;  i++)
2863     {
2864         for (j = 0;  j < 2;  j++)
2865         {
2866             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2867                 push = 10;
2868             if (samples < SAMPLES_PER_CHUNK)
2869             {
2870                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2871                 samples = SAMPLES_PER_CHUNK;
2872             }
2873         }
2874         if (log_audio)
2875         {
2876             for (j = 0;  j < samples;  j++)
2877             {
2878                 out_amp[2*j + 0] = amp[0][j];
2879                 out_amp[2*j + 1] = amp[1][j];
2880             }
2881             outframes = sf_writef_short(outhandle, out_amp, samples);
2882             if (outframes != samples)
2883             {
2884                 fprintf(stderr, "    Error writing audio file\n");
2885                 exit(2);
2886             }
2887         }
2888 #if 1
2889         both_ways_line_model(model,
2890                              model_amp[0],
2891                              amp[0],
2892                              model_amp[1],
2893                              amp[1],
2894                              samples);
2895 #else
2896         vec_copyi16(model_amp[0], amp[0], samples);
2897         vec_copyi16(model_amp[1], amp[1], samples);
2898 #endif
2899         v18_rx(v18[TESTER], model_amp[1], samples);
2900         v18_rx(v18[TUT], model_amp[0], samples);
2901     }
2902 
2903     v18_free(v18[TESTER]);
2904     v18_free(v18[TUT]);
2905     printf("Test not yet implemented\n");
2906     return 1;
2907 }
2908 /*- End of function --------------------------------------------------------*/
2909 
org_18_put_text_msg(void * user_data,const uint8_t * msg,int len)2910 static void org_18_put_text_msg(void *user_data, const uint8_t *msg, int len)
2911 {
2912 }
2913 /*- End of function --------------------------------------------------------*/
2914 
test_org_18(void)2915 static int test_org_18(void)
2916 {
2917     logging_state_t *logging;
2918     int16_t amp[2][SAMPLES_PER_CHUNK];
2919     int16_t model_amp[2][SAMPLES_PER_CHUNK];
2920     int16_t out_amp[2*SAMPLES_PER_CHUNK];
2921     int outframes;
2922     int samples;
2923     int push;
2924     int i;
2925     int j;
2926 
2927     /*
2928         III.5.4.2.18    Tr timer
2929         Purpose:        To confirm that TUT returns to the Monitor 1 state if Timer Tr expires.
2930         Preamble:       N/A
2931         Method:         The tester sends 980Hz to TUT for 1.2s followed by 1650Hz for 5s
2932                         with no pause.
2933         Pass criteria:  TUT should respond with 980Hz after 1.3+-0.1s of 1650Hz.
2934         Comments:       This implies timer Tr has expired 2s after the start of the 980Hz tone and
2935                         then 1650Hz has been detected for 0.5s.
2936      */
2937     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_18_put_text_msg, (void *) (intptr_t) 0);
2938     logging = v18_get_logging_state(v18[TESTER]);
2939     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2940     span_log_set_tag(logging, "Tester");
2941     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_18_put_text_msg, (void *) (intptr_t) 1);
2942     logging = v18_get_logging_state(v18[TUT]);
2943     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
2944     span_log_set_tag(logging, "TUT");
2945 
2946     if ((model = both_ways_line_model_init(line_model_no,
2947                                            noise_level,
2948                                            echo_level_cpe1,
2949                                            echo_level_co1,
2950                                            line_model_no,
2951                                            noise_level,
2952                                            echo_level_cpe2,
2953                                            echo_level_co2,
2954                                            channel_codec,
2955                                            rbs_pattern)) == NULL)
2956     {
2957         fprintf(stderr, "    Failed to create line model\n");
2958         exit(2);
2959     }
2960 
2961     result[TESTER][0] =
2962     result[TUT][0] = '\0';
2963     for (i = 0;  i < 10000;  i++)
2964     {
2965         for (j = 0;  j < 2;  j++)
2966         {
2967             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
2968                 push = 10;
2969             if (samples < SAMPLES_PER_CHUNK)
2970             {
2971                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
2972                 samples = SAMPLES_PER_CHUNK;
2973             }
2974         }
2975         if (log_audio)
2976         {
2977             for (j = 0;  j < samples;  j++)
2978             {
2979                 out_amp[2*j + 0] = amp[0][j];
2980                 out_amp[2*j + 1] = amp[1][j];
2981             }
2982             outframes = sf_writef_short(outhandle, out_amp, samples);
2983             if (outframes != samples)
2984             {
2985                 fprintf(stderr, "    Error writing audio file\n");
2986                 exit(2);
2987             }
2988         }
2989 #if 1
2990         both_ways_line_model(model,
2991                              model_amp[0],
2992                              amp[0],
2993                              model_amp[1],
2994                              amp[1],
2995                              samples);
2996 #else
2997         vec_copyi16(model_amp[0], amp[0], samples);
2998         vec_copyi16(model_amp[1], amp[1], samples);
2999 #endif
3000         v18_rx(v18[TESTER], model_amp[1], samples);
3001         v18_rx(v18[TUT], model_amp[0], samples);
3002     }
3003 
3004     v18_free(v18[TESTER]);
3005     v18_free(v18[TUT]);
3006     printf("Test not yet implemented\n");
3007     return 1;
3008 }
3009 /*- End of function --------------------------------------------------------*/
3010 
org_19_put_text_msg(void * user_data,const uint8_t * msg,int len)3011 static void org_19_put_text_msg(void *user_data, const uint8_t *msg, int len)
3012 {
3013 }
3014 /*- End of function --------------------------------------------------------*/
3015 
test_org_19(void)3016 static int test_org_19(void)
3017 {
3018     logging_state_t *logging;
3019     int16_t amp[2][SAMPLES_PER_CHUNK];
3020     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3021     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3022     int outframes;
3023     int samples;
3024     int push;
3025     int i;
3026     int j;
3027 
3028     /*
3029         III.5.4.2.19    Bell 103 (1270Hz signal) detection
3030         Purpose:        To confirm correct selection of Bell 103 reverse mode.
3031         Preamble:       N/A
3032         Method:         The tester sends 1270Hz to TUT for 5s.
3033         Pass criteria:  1) TUT should respond with 2225Hz tone after 0.7+-0.1 s.
3034                         2) Data should be transmitted and received at 300 bit/s complying with Annex D.
3035         Comments:       The TUT should indicate that Bell 103 mode has been selected.
3036      */
3037     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_19_put_text_msg, (void *) (intptr_t) 0);
3038     logging = v18_get_logging_state(v18[TESTER]);
3039     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3040     span_log_set_tag(logging, "Tester");
3041     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_19_put_text_msg, (void *) (intptr_t) 1);
3042     logging = v18_get_logging_state(v18[TUT]);
3043     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3044     span_log_set_tag(logging, "TUT");
3045 
3046     if ((model = both_ways_line_model_init(line_model_no,
3047                                            noise_level,
3048                                            echo_level_cpe1,
3049                                            echo_level_co1,
3050                                            line_model_no,
3051                                            noise_level,
3052                                            echo_level_cpe2,
3053                                            echo_level_co2,
3054                                            channel_codec,
3055                                            rbs_pattern)) == NULL)
3056     {
3057         fprintf(stderr, "    Failed to create line model\n");
3058         exit(2);
3059     }
3060 
3061     result[TESTER][0] =
3062     result[TUT][0] = '\0';
3063     for (i = 0;  i < 10000;  i++)
3064     {
3065         for (j = 0;  j < 2;  j++)
3066         {
3067             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3068                 push = 10;
3069             if (samples < SAMPLES_PER_CHUNK)
3070             {
3071                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3072                 samples = SAMPLES_PER_CHUNK;
3073             }
3074         }
3075         if (log_audio)
3076         {
3077             for (j = 0;  j < samples;  j++)
3078             {
3079                 out_amp[2*j + 0] = amp[0][j];
3080                 out_amp[2*j + 1] = amp[1][j];
3081             }
3082             outframes = sf_writef_short(outhandle, out_amp, samples);
3083             if (outframes != samples)
3084             {
3085                 fprintf(stderr, "    Error writing audio file\n");
3086                 exit(2);
3087             }
3088         }
3089 #if 1
3090         both_ways_line_model(model,
3091                              model_amp[0],
3092                              amp[0],
3093                              model_amp[1],
3094                              amp[1],
3095                              samples);
3096 #else
3097         vec_copyi16(model_amp[0], amp[0], samples);
3098         vec_copyi16(model_amp[1], amp[1], samples);
3099 #endif
3100         v18_rx(v18[TESTER], model_amp[1], samples);
3101         v18_rx(v18[TUT], model_amp[0], samples);
3102     }
3103 
3104     v18_free(v18[TESTER]);
3105     v18_free(v18[TUT]);
3106     printf("Test not yet implemented\n");
3107     return 1;
3108 }
3109 /*- End of function --------------------------------------------------------*/
3110 
org_20_put_text_msg(void * user_data,const uint8_t * msg,int len)3111 static void org_20_put_text_msg(void *user_data, const uint8_t *msg, int len)
3112 {
3113 }
3114 /*- End of function --------------------------------------------------------*/
3115 
test_org_20(void)3116 static int test_org_20(void)
3117 {
3118     logging_state_t *logging;
3119     int16_t amp[2][SAMPLES_PER_CHUNK];
3120     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3121     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3122     int outframes;
3123     int samples;
3124     int push;
3125     int i;
3126     int j;
3127 
3128     /*
3129         III.5.4.2.20    Immunity to network tones
3130         Purpose:        To ensure that the TUT does not interpret network tones as valid signals.
3131         Preamble:       N/A
3132         Method:         The tester will first send a dial tone to the TUT, this will be followed by a ringing
3133                         tone and a network congestion tone. The frequencies and cadences of the tones will
3134                         vary according to the country setting. The tester must be configured for the same
3135                         country as the TUT.
3136         Pass criteria:  The countries supported by the TUT should be noted along with the response to
3137                         each tone. The tones should either be ignored or reported as the relevant network
3138                         tone to the user.
3139         Comments:       V.18 is required to recognize and report RINGING and BUSY tones. Other network
3140                         tones may be ignored. Some devices may only provide a visual indication of the
3141                         presence and cadence of the tones for instance by a flashing light. The TUT may
3142                         disconnect on reception of tones indicating a failed call attempt.
3143      */
3144     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_20_put_text_msg, (void *) (intptr_t) 0);
3145     logging = v18_get_logging_state(v18[TESTER]);
3146     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3147     span_log_set_tag(logging, "Tester");
3148     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_20_put_text_msg, (void *) (intptr_t) 1);
3149     logging = v18_get_logging_state(v18[TUT]);
3150     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3151     span_log_set_tag(logging, "TUT");
3152 
3153     if ((model = both_ways_line_model_init(line_model_no,
3154                                            noise_level,
3155                                            echo_level_cpe1,
3156                                            echo_level_co1,
3157                                            line_model_no,
3158                                            noise_level,
3159                                            echo_level_cpe2,
3160                                            echo_level_co2,
3161                                            channel_codec,
3162                                            rbs_pattern)) == NULL)
3163     {
3164         fprintf(stderr, "    Failed to create line model\n");
3165         exit(2);
3166     }
3167 
3168     result[TESTER][0] =
3169     result[TUT][0] = '\0';
3170     for (i = 0;  i < 10000;  i++)
3171     {
3172         for (j = 0;  j < 2;  j++)
3173         {
3174             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3175                 push = 10;
3176             if (samples < SAMPLES_PER_CHUNK)
3177             {
3178                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3179                 samples = SAMPLES_PER_CHUNK;
3180             }
3181         }
3182         if (log_audio)
3183         {
3184             for (j = 0;  j < samples;  j++)
3185             {
3186                 out_amp[2*j + 0] = amp[0][j];
3187                 out_amp[2*j + 1] = amp[1][j];
3188             }
3189             outframes = sf_writef_short(outhandle, out_amp, samples);
3190             if (outframes != samples)
3191             {
3192                 fprintf(stderr, "    Error writing audio file\n");
3193                 exit(2);
3194             }
3195         }
3196 #if 1
3197         both_ways_line_model(model,
3198                              model_amp[0],
3199                              amp[0],
3200                              model_amp[1],
3201                              amp[1],
3202                              samples);
3203 #else
3204         vec_copyi16(model_amp[0], amp[0], samples);
3205         vec_copyi16(model_amp[1], amp[1], samples);
3206 #endif
3207         v18_rx(v18[TESTER], model_amp[1], samples);
3208         v18_rx(v18[TUT], model_amp[0], samples);
3209     }
3210 
3211     v18_free(v18[TESTER]);
3212     v18_free(v18[TUT]);
3213     printf("Test not yet implemented\n");
3214     return 1;
3215 }
3216 /*- End of function --------------------------------------------------------*/
3217 
org_21_put_text_msg(void * user_data,const uint8_t * msg,int len)3218 static void org_21_put_text_msg(void *user_data, const uint8_t *msg, int len)
3219 {
3220 }
3221 /*- End of function --------------------------------------------------------*/
3222 
test_org_21(void)3223 static int test_org_21(void)
3224 {
3225     logging_state_t *logging;
3226     int16_t amp[2][SAMPLES_PER_CHUNK];
3227     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3228     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3229     int outframes;
3230     int samples;
3231     int push;
3232     int i;
3233     int j;
3234 
3235     /*
3236         III.5.4.2.21    Immunity to non-textphone modems
3237         Purpose:        To ensure that the TUT does not interpret modem tones not supported by V.18 as
3238                         valid text telephone tones.
3239         Preamble:       N/A
3240         Method:         The tester will respond with an ANS tone (2100Hz) followed by simulated (a)
3241                         V.32 bis and (b) V.34 modem training sequences.
3242         Pass criteria:  The tones should either be ignored or reported back to the user. No textphone
3243                         modem should be selected.
3244         Comments:       Some high speed modems may fall back to a compatibility mode, e.g. V.21 or V.23
3245                         that should be correctly detected by the TUT.
3246      */
3247     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_21_put_text_msg, (void *) (intptr_t) 0);
3248     logging = v18_get_logging_state(v18[TESTER]);
3249     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3250     span_log_set_tag(logging, "Tester");
3251     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_21_put_text_msg, (void *) (intptr_t) 1);
3252     logging = v18_get_logging_state(v18[TUT]);
3253     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3254     span_log_set_tag(logging, "TUT");
3255 
3256     if ((model = both_ways_line_model_init(line_model_no,
3257                                            noise_level,
3258                                            echo_level_cpe1,
3259                                            echo_level_co1,
3260                                            line_model_no,
3261                                            noise_level,
3262                                            echo_level_cpe2,
3263                                            echo_level_co2,
3264                                            channel_codec,
3265                                            rbs_pattern)) == NULL)
3266     {
3267         fprintf(stderr, "    Failed to create line model\n");
3268         exit(2);
3269     }
3270 
3271     result[TESTER][0] =
3272     result[TUT][0] = '\0';
3273     for (i = 0;  i < 10000;  i++)
3274     {
3275         for (j = 0;  j < 2;  j++)
3276         {
3277             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3278                 push = 10;
3279             if (samples < SAMPLES_PER_CHUNK)
3280             {
3281                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3282                 samples = SAMPLES_PER_CHUNK;
3283             }
3284         }
3285         if (log_audio)
3286         {
3287             for (j = 0;  j < samples;  j++)
3288             {
3289                 out_amp[2*j + 0] = amp[0][j];
3290                 out_amp[2*j + 1] = amp[1][j];
3291             }
3292             outframes = sf_writef_short(outhandle, out_amp, samples);
3293             if (outframes != samples)
3294             {
3295                 fprintf(stderr, "    Error writing audio file\n");
3296                 exit(2);
3297             }
3298         }
3299 #if 1
3300         both_ways_line_model(model,
3301                              model_amp[0],
3302                              amp[0],
3303                              model_amp[1],
3304                              amp[1],
3305                              samples);
3306 #else
3307         vec_copyi16(model_amp[0], amp[0], samples);
3308         vec_copyi16(model_amp[1], amp[1], samples);
3309 #endif
3310         v18_rx(v18[TESTER], model_amp[1], samples);
3311         v18_rx(v18[TUT], model_amp[0], samples);
3312     }
3313 
3314     v18_free(v18[TESTER]);
3315     v18_free(v18[TUT]);
3316     printf("Test not yet implemented\n");
3317     return 1;
3318 }
3319 /*- End of function --------------------------------------------------------*/
3320 
org_22_put_text_msg(void * user_data,const uint8_t * msg,int len)3321 static void org_22_put_text_msg(void *user_data, const uint8_t *msg, int len)
3322 {
3323 }
3324 /*- End of function --------------------------------------------------------*/
3325 
test_org_22(void)3326 static int test_org_22(void)
3327 {
3328     logging_state_t *logging;
3329     int16_t amp[2][SAMPLES_PER_CHUNK];
3330     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3331     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3332     int outframes;
3333     int samples;
3334     int push;
3335     int i;
3336     int j;
3337 
3338     /*
3339         III.5.4.2.22    Immunity to fax tones
3340         Purpose:        To ensure that the TUT will not interpret a called fax machine as being a textphone.
3341         Preamble:       N/A
3342         Method:         The tester will respond as if it were a typical group 3 fax machine in automatic
3343                         answer mode. It should send a CED tone (2100Hz) plus Digital Identification
3344                         Signal (DIS) as defined in ITU-T T.30.
3345         Pass criteria:  The TUT should ignore the received tones.
3346         Comments:       Ideally the TUT should detect the presence of a fax machine and report it back to
3347                         the user.
3348      */
3349     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_22_put_text_msg, (void *) (intptr_t) 0);
3350     logging = v18_get_logging_state(v18[TESTER]);
3351     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3352     span_log_set_tag(logging, "Tester");
3353     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_22_put_text_msg, (void *) (intptr_t) 1);
3354     logging = v18_get_logging_state(v18[TUT]);
3355     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3356     span_log_set_tag(logging, "TUT");
3357 
3358     if ((model = both_ways_line_model_init(line_model_no,
3359                                            noise_level,
3360                                            echo_level_cpe1,
3361                                            echo_level_co1,
3362                                            line_model_no,
3363                                            noise_level,
3364                                            echo_level_cpe2,
3365                                            echo_level_co2,
3366                                            channel_codec,
3367                                            rbs_pattern)) == NULL)
3368     {
3369         fprintf(stderr, "    Failed to create line model\n");
3370         exit(2);
3371     }
3372 
3373     result[TESTER][0] =
3374     result[TUT][0] = '\0';
3375     for (i = 0;  i < 10000;  i++)
3376     {
3377         for (j = 0;  j < 2;  j++)
3378         {
3379             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3380                 push = 10;
3381             if (samples < SAMPLES_PER_CHUNK)
3382             {
3383                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3384                 samples = SAMPLES_PER_CHUNK;
3385             }
3386         }
3387         if (log_audio)
3388         {
3389             for (j = 0;  j < samples;  j++)
3390             {
3391                 out_amp[2*j + 0] = amp[0][j];
3392                 out_amp[2*j + 1] = amp[1][j];
3393             }
3394             outframes = sf_writef_short(outhandle, out_amp, samples);
3395             if (outframes != samples)
3396             {
3397                 fprintf(stderr, "    Error writing audio file\n");
3398                 exit(2);
3399             }
3400         }
3401 #if 1
3402         both_ways_line_model(model,
3403                              model_amp[0],
3404                              amp[0],
3405                              model_amp[1],
3406                              amp[1],
3407                              samples);
3408 #else
3409         vec_copyi16(model_amp[0], amp[0], samples);
3410         vec_copyi16(model_amp[1], amp[1], samples);
3411 #endif
3412         v18_rx(v18[TESTER], model_amp[1], samples);
3413         v18_rx(v18[TUT], model_amp[0], samples);
3414     }
3415 
3416     v18_free(v18[TESTER]);
3417     v18_free(v18[TUT]);
3418     printf("Test not yet implemented\n");
3419     return 1;
3420 }
3421 /*- End of function --------------------------------------------------------*/
3422 
org_23_put_text_msg(void * user_data,const uint8_t * msg,int len)3423 static void org_23_put_text_msg(void *user_data, const uint8_t *msg, int len)
3424 {
3425 }
3426 /*- End of function --------------------------------------------------------*/
3427 
test_org_23(void)3428 static int test_org_23(void)
3429 {
3430     logging_state_t *logging;
3431     int16_t amp[2][SAMPLES_PER_CHUNK];
3432     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3433     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3434     int outframes;
3435     int samples;
3436     int push;
3437     int i;
3438     int j;
3439 
3440     /*
3441         III.5.4.2.23    Immunity to voice
3442         Purpose:        To ensure that the TUT does not misinterpret speech as a valid textphone signal.
3443         Preamble:       N/A
3444         Method:         The tester will respond with sampled speech. A number of phrases recorded from
3445                         typical male and female speakers will be transmitted. This will include a typical
3446                         network announcement.
3447         Pass criteria:  The TUT should ignore the speech.
3448         Comments:       Ideally the TUT should report the presence of speech back to the user, e.g. via
3449                         circuit 135.
3450      */
3451     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_23_put_text_msg, (void *) (intptr_t) 0);
3452     logging = v18_get_logging_state(v18[TESTER]);
3453     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3454     span_log_set_tag(logging, "Tester");
3455     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_23_put_text_msg, (void *) (intptr_t) 1);
3456     logging = v18_get_logging_state(v18[TUT]);
3457     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3458     span_log_set_tag(logging, "TUT");
3459 
3460     if ((model = both_ways_line_model_init(line_model_no,
3461                                            noise_level,
3462                                            echo_level_cpe1,
3463                                            echo_level_co1,
3464                                            line_model_no,
3465                                            noise_level,
3466                                            echo_level_cpe2,
3467                                            echo_level_co2,
3468                                            channel_codec,
3469                                            rbs_pattern)) == NULL)
3470     {
3471         fprintf(stderr, "    Failed to create line model\n");
3472         exit(2);
3473     }
3474 
3475     result[TESTER][0] =
3476     result[TUT][0] = '\0';
3477     for (i = 0;  i < 10000;  i++)
3478     {
3479         for (j = 0;  j < 2;  j++)
3480         {
3481             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3482                 push = 10;
3483             if (samples < SAMPLES_PER_CHUNK)
3484             {
3485                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3486                 samples = SAMPLES_PER_CHUNK;
3487             }
3488         }
3489         if (log_audio)
3490         {
3491             for (j = 0;  j < samples;  j++)
3492             {
3493                 out_amp[2*j + 0] = amp[0][j];
3494                 out_amp[2*j + 1] = amp[1][j];
3495             }
3496             outframes = sf_writef_short(outhandle, out_amp, samples);
3497             if (outframes != samples)
3498             {
3499                 fprintf(stderr, "    Error writing audio file\n");
3500                 exit(2);
3501             }
3502         }
3503 #if 1
3504         both_ways_line_model(model,
3505                              model_amp[0],
3506                              amp[0],
3507                              model_amp[1],
3508                              amp[1],
3509                              samples);
3510 #else
3511         vec_copyi16(model_amp[0], amp[0], samples);
3512         vec_copyi16(model_amp[1], amp[1], samples);
3513 #endif
3514         v18_rx(v18[TESTER], model_amp[1], samples);
3515         v18_rx(v18[TUT], model_amp[0], samples);
3516     }
3517 
3518     v18_free(v18[TESTER]);
3519     v18_free(v18[TUT]);
3520     printf("Test not yet implemented\n");
3521     return 1;
3522 }
3523 /*- End of function --------------------------------------------------------*/
3524 
org_24_put_text_msg(void * user_data,const uint8_t * msg,int len)3525 static void org_24_put_text_msg(void *user_data, const uint8_t *msg, int len)
3526 {
3527 }
3528 /*- End of function --------------------------------------------------------*/
3529 
test_org_24(void)3530 static int test_org_24(void)
3531 {
3532     logging_state_t *logging;
3533     int16_t amp[2][SAMPLES_PER_CHUNK];
3534     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3535     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3536     int outframes;
3537     int samples;
3538     int push;
3539     int i;
3540     int j;
3541 
3542     /*
3543         III.5.4.2.24    ANSam signal detection
3544         Purpose:        To verify that TUT correctly detects the ANSam (2100Hz modulated) signal during
3545                         the two-second interval (Toff) between transmission of CI sequences.
3546         Preamble:       Make a V.18 call from the TUT.
3547         Method:         The Test System waits for the TUT to stop transmitting a CI and responds with an
3548                         ANSam signal. The V.21 demodulator is used to decode the CM sequence. ANSam
3549                         should be transmitted for 2s.
3550         Pass criteria:  1) No signal should be transmitted by TUT for 0.5s from detection of
3551                            ANSam.
3552                         2) The TUT should reply with transmission of CM as defined in 5.2.13.
3553                         3) Verify that CM sequence has correct bit pattern.
3554      */
3555     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_24_put_text_msg, (void *) (intptr_t) 0);
3556     logging = v18_get_logging_state(v18[TESTER]);
3557     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3558     span_log_set_tag(logging, "Tester");
3559     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_24_put_text_msg, (void *) (intptr_t) 1);
3560     logging = v18_get_logging_state(v18[TUT]);
3561     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3562     span_log_set_tag(logging, "TUT");
3563 
3564     if ((model = both_ways_line_model_init(line_model_no,
3565                                            noise_level,
3566                                            echo_level_cpe1,
3567                                            echo_level_co1,
3568                                            line_model_no,
3569                                            noise_level,
3570                                            echo_level_cpe2,
3571                                            echo_level_co2,
3572                                            channel_codec,
3573                                            rbs_pattern)) == NULL)
3574     {
3575         fprintf(stderr, "    Failed to create line model\n");
3576         exit(2);
3577     }
3578 
3579     result[TESTER][0] =
3580     result[TUT][0] = '\0';
3581     for (i = 0;  i < 10000;  i++)
3582     {
3583         for (j = 0;  j < 2;  j++)
3584         {
3585             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3586                 push = 10;
3587             if (samples < SAMPLES_PER_CHUNK)
3588             {
3589                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3590                 samples = SAMPLES_PER_CHUNK;
3591             }
3592         }
3593         if (log_audio)
3594         {
3595             for (j = 0;  j < samples;  j++)
3596             {
3597                 out_amp[2*j + 0] = amp[0][j];
3598                 out_amp[2*j + 1] = amp[1][j];
3599             }
3600             outframes = sf_writef_short(outhandle, out_amp, samples);
3601             if (outframes != samples)
3602             {
3603                 fprintf(stderr, "    Error writing audio file\n");
3604                 exit(2);
3605             }
3606         }
3607 #if 1
3608         both_ways_line_model(model,
3609                              model_amp[0],
3610                              amp[0],
3611                              model_amp[1],
3612                              amp[1],
3613                              samples);
3614 #else
3615         vec_copyi16(model_amp[0], amp[0], samples);
3616         vec_copyi16(model_amp[1], amp[1], samples);
3617 #endif
3618         v18_rx(v18[TESTER], model_amp[1], samples);
3619         v18_rx(v18[TUT], model_amp[0], samples);
3620     }
3621 
3622     v18_free(v18[TESTER]);
3623     v18_free(v18[TUT]);
3624     printf("Test not yet implemented\n");
3625     return 1;
3626 }
3627 /*- End of function --------------------------------------------------------*/
3628 
org_25_put_text_msg(void * user_data,const uint8_t * msg,int len)3629 static void org_25_put_text_msg(void *user_data, const uint8_t *msg, int len)
3630 {
3631 }
3632 /*- End of function --------------------------------------------------------*/
3633 
test_org_25(void)3634 static int test_org_25(void)
3635 {
3636     logging_state_t *logging;
3637     int16_t amp[2][SAMPLES_PER_CHUNK];
3638     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3639     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3640     int outframes;
3641     int samples;
3642     int push;
3643     int i;
3644     int j;
3645 
3646     /*
3647         III.5.4.2.25    V.8 calling procedure
3648         Purpose:        To verify that TUT correctly performs a V.8 call negotiation.
3649         Preamble:       Make a V.18 call from the TUT. Answer with ANSam from the Tester and with JM
3650                         for V.21 on the CM.
3651         Method:         The Test System waits for the TUT to start transmitting V.21 carrier (1).
3652         Pass criteria:  The TUT should connect by sending V.21 carrier (1).
3653      */
3654     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_25_put_text_msg, (void *) (intptr_t) 0);
3655     logging = v18_get_logging_state(v18[TESTER]);
3656     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3657     span_log_set_tag(logging, "Tester");
3658     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, org_25_put_text_msg, (void *) (intptr_t) 1);
3659     logging = v18_get_logging_state(v18[TUT]);
3660     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3661     span_log_set_tag(logging, "TUT");
3662 
3663     if ((model = both_ways_line_model_init(line_model_no,
3664                                            noise_level,
3665                                            echo_level_cpe1,
3666                                            echo_level_co1,
3667                                            line_model_no,
3668                                            noise_level,
3669                                            echo_level_cpe2,
3670                                            echo_level_co2,
3671                                            channel_codec,
3672                                            rbs_pattern)) == NULL)
3673     {
3674         fprintf(stderr, "    Failed to create line model\n");
3675         exit(2);
3676     }
3677 
3678     result[TESTER][0] =
3679     result[TUT][0] = '\0';
3680     for (i = 0;  i < 10000;  i++)
3681     {
3682         for (j = 0;  j < 2;  j++)
3683         {
3684             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3685                 push = 10;
3686             if (samples < SAMPLES_PER_CHUNK)
3687             {
3688                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3689                 samples = SAMPLES_PER_CHUNK;
3690             }
3691         }
3692         if (log_audio)
3693         {
3694             for (j = 0;  j < samples;  j++)
3695             {
3696                 out_amp[2*j + 0] = amp[0][j];
3697                 out_amp[2*j + 1] = amp[1][j];
3698             }
3699             outframes = sf_writef_short(outhandle, out_amp, samples);
3700             if (outframes != samples)
3701             {
3702                 fprintf(stderr, "    Error writing audio file\n");
3703                 exit(2);
3704             }
3705         }
3706 #if 1
3707         both_ways_line_model(model,
3708                              model_amp[0],
3709                              amp[0],
3710                              model_amp[1],
3711                              amp[1],
3712                              samples);
3713 #else
3714         vec_copyi16(model_amp[0], amp[0], samples);
3715         vec_copyi16(model_amp[1], amp[1], samples);
3716 #endif
3717         v18_rx(v18[TESTER], model_amp[1], samples);
3718         v18_rx(v18[TUT], model_amp[0], samples);
3719     }
3720 
3721     v18_free(v18[TESTER]);
3722     v18_free(v18[TUT]);
3723     printf("Test not yet implemented\n");
3724     return 1;
3725 }
3726 /*- End of function --------------------------------------------------------*/
3727 
ans_01_put_text_msg(void * user_data,const uint8_t * msg,int len)3728 static void ans_01_put_text_msg(void *user_data, const uint8_t *msg, int len)
3729 {
3730 }
3731 /*- End of function --------------------------------------------------------*/
3732 
test_ans_01(void)3733 static int test_ans_01(void)
3734 {
3735     logging_state_t *logging;
3736     int16_t amp[2][SAMPLES_PER_CHUNK];
3737     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3738     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3739     int outframes;
3740     int samples;
3741     int push;
3742     int i;
3743     int j;
3744 
3745     /*
3746         III.5.4.3.1     Ta timer
3747         Purpose:        To ensure that on connecting the call, the DCE starts timer Ta (3s) and on
3748                         expiry begins probing.
3749         Preamble:       N/A
3750         Method:         The tester makes a call to the TUT and attempts to determine when the TUT
3751                         answers the call. It will then monitor for any signal.
3752         Pass criteria:  The TUT should start probing 3s after answering the call.
3753      */
3754     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_01_put_text_msg, (void *) (intptr_t) 0);
3755     logging = v18_get_logging_state(v18[TESTER]);
3756     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3757     span_log_set_tag(logging, "Tester");
3758     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_01_put_text_msg, (void *) (intptr_t) 1);
3759     logging = v18_get_logging_state(v18[TUT]);
3760     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3761     span_log_set_tag(logging, "TUT");
3762 
3763     if ((model = both_ways_line_model_init(line_model_no,
3764                                            noise_level,
3765                                            echo_level_cpe1,
3766                                            echo_level_co1,
3767                                            line_model_no,
3768                                            noise_level,
3769                                            echo_level_cpe2,
3770                                            echo_level_co2,
3771                                            channel_codec,
3772                                            rbs_pattern)) == NULL)
3773     {
3774         fprintf(stderr, "    Failed to create line model\n");
3775         exit(2);
3776     }
3777 
3778     result[TESTER][0] =
3779     result[TUT][0] = '\0';
3780     for (i = 0;  i < 10000;  i++)
3781     {
3782         for (j = 0;  j < 2;  j++)
3783         {
3784             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3785                 push = 10;
3786             if (samples < SAMPLES_PER_CHUNK)
3787             {
3788                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3789                 samples = SAMPLES_PER_CHUNK;
3790             }
3791         }
3792         if (log_audio)
3793         {
3794             for (j = 0;  j < samples;  j++)
3795             {
3796                 out_amp[2*j + 0] = amp[0][j];
3797                 out_amp[2*j + 1] = amp[1][j];
3798             }
3799             outframes = sf_writef_short(outhandle, out_amp, samples);
3800             if (outframes != samples)
3801             {
3802                 fprintf(stderr, "    Error writing audio file\n");
3803                 exit(2);
3804             }
3805         }
3806 #if 1
3807         both_ways_line_model(model,
3808                              model_amp[0],
3809                              amp[0],
3810                              model_amp[1],
3811                              amp[1],
3812                              samples);
3813 #else
3814         vec_copyi16(model_amp[0], amp[0], samples);
3815         vec_copyi16(model_amp[1], amp[1], samples);
3816 #endif
3817         v18_rx(v18[TESTER], model_amp[1], samples);
3818         v18_rx(v18[TUT], model_amp[0], samples);
3819     }
3820 
3821     v18_free(v18[TESTER]);
3822     v18_free(v18[TUT]);
3823     printf("Test not yet implemented\n");
3824     return 1;
3825 }
3826 /*- End of function --------------------------------------------------------*/
3827 
ans_02_put_text_msg(void * user_data,const uint8_t * msg,int len)3828 static void ans_02_put_text_msg(void *user_data, const uint8_t *msg, int len)
3829 {
3830 }
3831 /*- End of function --------------------------------------------------------*/
3832 
test_ans_02(void)3833 static int test_ans_02(void)
3834 {
3835     logging_state_t *logging;
3836     int16_t amp[2][SAMPLES_PER_CHUNK];
3837     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3838     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3839     int outframes;
3840     int samples;
3841     int push;
3842     int i;
3843     int j;
3844 
3845     /*
3846         III.5.4.3.2     CI signal detection
3847         Purpose:        To confirm the correct detection and response to the V.18 CI signal.
3848         Preamble:       N/A
3849         Method:         The tester will transmit 2 sequences of 4 CI patterns separated by 2s. It will
3850                         monitor for ANS and measure duration.
3851         Pass criteria:  1) The TUT should respond after either the first or second CI with ANSam tone.
3852                         2) ANSam tone should remain for 3s+-0.5s followed by silence.
3853         Comments:       The ANSam tone is a modulated 2100Hz tone. It may have phase reversals. The
3854                         XCI signal is tested in a separate test.
3855      */
3856     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_02_put_text_msg, (void *) (intptr_t) 0);
3857     logging = v18_get_logging_state(v18[TESTER]);
3858     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3859     span_log_set_tag(logging, "Tester");
3860     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_02_put_text_msg, (void *) (intptr_t) 1);
3861     logging = v18_get_logging_state(v18[TUT]);
3862     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3863     span_log_set_tag(logging, "TUT");
3864 
3865     if ((model = both_ways_line_model_init(line_model_no,
3866                                            noise_level,
3867                                            echo_level_cpe1,
3868                                            echo_level_co1,
3869                                            line_model_no,
3870                                            noise_level,
3871                                            echo_level_cpe2,
3872                                            echo_level_co2,
3873                                            channel_codec,
3874                                            rbs_pattern)) == NULL)
3875     {
3876         fprintf(stderr, "    Failed to create line model\n");
3877         exit(2);
3878     }
3879 
3880     result[TESTER][0] =
3881     result[TUT][0] = '\0';
3882     for (i = 0;  i < 10000;  i++)
3883     {
3884         for (j = 0;  j < 2;  j++)
3885         {
3886             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3887                 push = 10;
3888             if (samples < SAMPLES_PER_CHUNK)
3889             {
3890                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3891                 samples = SAMPLES_PER_CHUNK;
3892             }
3893         }
3894         if (log_audio)
3895         {
3896             for (j = 0;  j < samples;  j++)
3897             {
3898                 out_amp[2*j + 0] = amp[0][j];
3899                 out_amp[2*j + 1] = amp[1][j];
3900             }
3901             outframes = sf_writef_short(outhandle, out_amp, samples);
3902             if (outframes != samples)
3903             {
3904                 fprintf(stderr, "    Error writing audio file\n");
3905                 exit(2);
3906             }
3907         }
3908 #if 1
3909         both_ways_line_model(model,
3910                              model_amp[0],
3911                              amp[0],
3912                              model_amp[1],
3913                              amp[1],
3914                              samples);
3915 #else
3916         vec_copyi16(model_amp[0], amp[0], samples);
3917         vec_copyi16(model_amp[1], amp[1], samples);
3918 #endif
3919         v18_rx(v18[TESTER], model_amp[1], samples);
3920         v18_rx(v18[TUT], model_amp[0], samples);
3921     }
3922 
3923     v18_free(v18[TESTER]);
3924     v18_free(v18[TUT]);
3925     printf("Test not yet implemented\n");
3926     return 1;
3927 }
3928 /*- End of function --------------------------------------------------------*/
3929 
ans_03_put_text_msg(void * user_data,const uint8_t * msg,int len)3930 static void ans_03_put_text_msg(void *user_data, const uint8_t *msg, int len)
3931 {
3932 }
3933 /*- End of function --------------------------------------------------------*/
3934 
test_ans_03(void)3935 static int test_ans_03(void)
3936 {
3937     logging_state_t *logging;
3938     int16_t amp[2][SAMPLES_PER_CHUNK];
3939     int16_t model_amp[2][SAMPLES_PER_CHUNK];
3940     int16_t out_amp[2*SAMPLES_PER_CHUNK];
3941     int outframes;
3942     int samples;
3943     int push;
3944     int i;
3945     int j;
3946 
3947     /*
3948         III.5.4.3.3     Early termination of ANSam tone
3949         Purpose:        To confirm that the TUT will respond correctly to TXP signals, i.e. by stopping
3950                         ANSam tone on reception of TXP signal.
3951         Preamble:       N/A
3952         Method:         The tester will transmit 2 sequences of 4 CI patterns separated by 2s. On
3953                         reception of the ANSam tone the tester will wait 0.5s and then begin
3954                         transmitting the TXP signal in V.21 (1) mode.
3955         Pass criteria:  1) On reception of the TXP signal, the TUT should remain silent for 75+-5ms.
3956                         2) The TUT should then transmit 3 TXP sequences in V.21(2) mode.
3957                         3) The 3 TXPs should be followed by continuous 1650Hz.
3958                         4) Correct transmission and reception of T.140 data should be verified after the
3959                            V.18 mode connection is completed.
3960         Comments:       The TUT should indicate V.18 mode.
3961      */
3962     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_03_put_text_msg, (void *) (intptr_t) 0);
3963     logging = v18_get_logging_state(v18[TESTER]);
3964     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3965     span_log_set_tag(logging, "Tester");
3966     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_03_put_text_msg, (void *) (intptr_t) 1);
3967     logging = v18_get_logging_state(v18[TUT]);
3968     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
3969     span_log_set_tag(logging, "TUT");
3970 
3971     if ((model = both_ways_line_model_init(line_model_no,
3972                                            noise_level,
3973                                            echo_level_cpe1,
3974                                            echo_level_co1,
3975                                            line_model_no,
3976                                            noise_level,
3977                                            echo_level_cpe2,
3978                                            echo_level_co2,
3979                                            channel_codec,
3980                                            rbs_pattern)) == NULL)
3981     {
3982         fprintf(stderr, "    Failed to create line model\n");
3983         exit(2);
3984     }
3985 
3986     result[TESTER][0] =
3987     result[TUT][0] = '\0';
3988     for (i = 0;  i < 10000;  i++)
3989     {
3990         for (j = 0;  j < 2;  j++)
3991         {
3992             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
3993                 push = 10;
3994             if (samples < SAMPLES_PER_CHUNK)
3995             {
3996                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
3997                 samples = SAMPLES_PER_CHUNK;
3998             }
3999         }
4000         if (log_audio)
4001         {
4002             for (j = 0;  j < samples;  j++)
4003             {
4004                 out_amp[2*j + 0] = amp[0][j];
4005                 out_amp[2*j + 1] = amp[1][j];
4006             }
4007             outframes = sf_writef_short(outhandle, out_amp, samples);
4008             if (outframes != samples)
4009             {
4010                 fprintf(stderr, "    Error writing audio file\n");
4011                 exit(2);
4012             }
4013         }
4014 #if 1
4015         both_ways_line_model(model,
4016                              model_amp[0],
4017                              amp[0],
4018                              model_amp[1],
4019                              amp[1],
4020                              samples);
4021 #else
4022         vec_copyi16(model_amp[0], amp[0], samples);
4023         vec_copyi16(model_amp[1], amp[1], samples);
4024 #endif
4025         v18_rx(v18[TESTER], model_amp[1], samples);
4026         v18_rx(v18[TUT], model_amp[0], samples);
4027     }
4028 
4029     v18_free(v18[TESTER]);
4030     v18_free(v18[TUT]);
4031     printf("Test not yet implemented\n");
4032     return 1;
4033 }
4034 /*- End of function --------------------------------------------------------*/
4035 
ans_04_put_text_msg(void * user_data,const uint8_t * msg,int len)4036 static void ans_04_put_text_msg(void *user_data, const uint8_t *msg, int len)
4037 {
4038 }
4039 /*- End of function --------------------------------------------------------*/
4040 
test_ans_04(void)4041 static int test_ans_04(void)
4042 {
4043     logging_state_t *logging;
4044     int16_t amp[2][SAMPLES_PER_CHUNK];
4045     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4046     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4047     int outframes;
4048     int samples;
4049     int push;
4050     int i;
4051     int j;
4052 
4053     /*
4054         III.5.4.3.4     Tt timer
4055         Purpose:        To ensure that after detection of ANSam the TUT will return to Monitor A after
4056                         timer Tt expires.
4057         Preamble:       Successful completion of test ANS-03.
4058         Method:         After completion of test ANS-03 the tester will continue to monitor for signals.
4059         Pass criteria:  The TUT should start probing 3s after ANSam disappears.
4060         Comments:       It is assumed that timer Ta is restarted on return to Monitor A.
4061      */
4062     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_04_put_text_msg, (void *) (intptr_t) 0);
4063     logging = v18_get_logging_state(v18[TESTER]);
4064     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4065     span_log_set_tag(logging, "Tester");
4066     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_04_put_text_msg, (void *) (intptr_t) 1);
4067     logging = v18_get_logging_state(v18[TUT]);
4068     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4069     span_log_set_tag(logging, "TUT");
4070 
4071     if ((model = both_ways_line_model_init(line_model_no,
4072                                            noise_level,
4073                                            echo_level_cpe1,
4074                                            echo_level_co1,
4075                                            line_model_no,
4076                                            noise_level,
4077                                            echo_level_cpe2,
4078                                            echo_level_co2,
4079                                            channel_codec,
4080                                            rbs_pattern)) == NULL)
4081     {
4082         fprintf(stderr, "    Failed to create line model\n");
4083         exit(2);
4084     }
4085 
4086     result[TESTER][0] =
4087     result[TUT][0] = '\0';
4088     for (i = 0;  i < 10000;  i++)
4089     {
4090         for (j = 0;  j < 2;  j++)
4091         {
4092             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4093                 push = 10;
4094             if (samples < SAMPLES_PER_CHUNK)
4095             {
4096                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4097                 samples = SAMPLES_PER_CHUNK;
4098             }
4099         }
4100         if (log_audio)
4101         {
4102             for (j = 0;  j < samples;  j++)
4103             {
4104                 out_amp[2*j + 0] = amp[0][j];
4105                 out_amp[2*j + 1] = amp[1][j];
4106             }
4107             outframes = sf_writef_short(outhandle, out_amp, samples);
4108             if (outframes != samples)
4109             {
4110                 fprintf(stderr, "    Error writing audio file\n");
4111                 exit(2);
4112             }
4113         }
4114 #if 1
4115         both_ways_line_model(model,
4116                              model_amp[0],
4117                              amp[0],
4118                              model_amp[1],
4119                              amp[1],
4120                              samples);
4121 #else
4122         vec_copyi16(model_amp[0], amp[0], samples);
4123         vec_copyi16(model_amp[1], amp[1], samples);
4124 #endif
4125         v18_rx(v18[TESTER], model_amp[1], samples);
4126         v18_rx(v18[TUT], model_amp[0], samples);
4127     }
4128 
4129     v18_free(v18[TESTER]);
4130     v18_free(v18[TUT]);
4131     printf("Test not yet implemented\n");
4132     return 1;
4133 }
4134 /*- End of function --------------------------------------------------------*/
4135 
ans_05_put_text_msg(void * user_data,const uint8_t * msg,int len)4136 static void ans_05_put_text_msg(void *user_data, const uint8_t *msg, int len)
4137 {
4138 }
4139 /*- End of function --------------------------------------------------------*/
4140 
test_ans_05(void)4141 static int test_ans_05(void)
4142 {
4143     logging_state_t *logging;
4144     int16_t amp[2][SAMPLES_PER_CHUNK];
4145     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4146     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4147     int outframes;
4148     int samples;
4149     int push;
4150     int i;
4151     int j;
4152 
4153     /*
4154         III.5.4.3.5     ANS tone followed by 980Hz
4155         Purpose:        To check correct detection of V.21 modem lower channel when preceded by answer
4156                         tone.
4157         Preamble:       N/A
4158         Method:         Tester transmits ANS for 2.5s followed by 75ms of no tone then transmits
4159                         980Hz and starts a 1s timer.
4160         Pass criteria:  TUT should respond with 1650Hz within 400+-100ms of start of 980Hz.
4161         Comments:       The TUT should indicate that V.21 mode has been selected.
4162      */
4163     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_05_put_text_msg, (void *) (intptr_t) 0);
4164     logging = v18_get_logging_state(v18[TESTER]);
4165     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4166     span_log_set_tag(logging, "Tester");
4167     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_05_put_text_msg, (void *) (intptr_t) 1);
4168     logging = v18_get_logging_state(v18[TUT]);
4169     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4170     span_log_set_tag(logging, "TUT");
4171 
4172     if ((model = both_ways_line_model_init(line_model_no,
4173                                            noise_level,
4174                                            echo_level_cpe1,
4175                                            echo_level_co1,
4176                                            line_model_no,
4177                                            noise_level,
4178                                            echo_level_cpe2,
4179                                            echo_level_co2,
4180                                            channel_codec,
4181                                            rbs_pattern)) == NULL)
4182     {
4183         fprintf(stderr, "    Failed to create line model\n");
4184         exit(2);
4185     }
4186 
4187     result[TESTER][0] =
4188     result[TUT][0] = '\0';
4189     for (i = 0;  i < 10000;  i++)
4190     {
4191         for (j = 0;  j < 2;  j++)
4192         {
4193             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4194                 push = 10;
4195             if (samples < SAMPLES_PER_CHUNK)
4196             {
4197                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4198                 samples = SAMPLES_PER_CHUNK;
4199             }
4200         }
4201         if (log_audio)
4202         {
4203             for (j = 0;  j < samples;  j++)
4204             {
4205                 out_amp[2*j + 0] = amp[0][j];
4206                 out_amp[2*j + 1] = amp[1][j];
4207             }
4208             outframes = sf_writef_short(outhandle, out_amp, samples);
4209             if (outframes != samples)
4210             {
4211                 fprintf(stderr, "    Error writing audio file\n");
4212                 exit(2);
4213             }
4214         }
4215 #if 1
4216         both_ways_line_model(model,
4217                              model_amp[0],
4218                              amp[0],
4219                              model_amp[1],
4220                              amp[1],
4221                              samples);
4222 #else
4223         vec_copyi16(model_amp[0], amp[0], samples);
4224         vec_copyi16(model_amp[1], amp[1], samples);
4225 #endif
4226         v18_rx(v18[TESTER], model_amp[1], samples);
4227         v18_rx(v18[TUT], model_amp[0], samples);
4228     }
4229 
4230     v18_free(v18[TESTER]);
4231     v18_free(v18[TUT]);
4232     printf("Test not yet implemented\n");
4233     return 1;
4234 }
4235 /*- End of function --------------------------------------------------------*/
4236 
ans_06_put_text_msg(void * user_data,const uint8_t * msg,int len)4237 static void ans_06_put_text_msg(void *user_data, const uint8_t *msg, int len)
4238 {
4239 }
4240 /*- End of function --------------------------------------------------------*/
4241 
test_ans_06(void)4242 static int test_ans_06(void)
4243 {
4244     logging_state_t *logging;
4245     int16_t amp[2][SAMPLES_PER_CHUNK];
4246     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4247     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4248     int outframes;
4249     int samples;
4250     int push;
4251     int i;
4252     int j;
4253 
4254     /*
4255         III.5.4.3.6     ANS tone followed by 1300Hz
4256         Purpose:        To check correct detection of V.23 modem upper channel when preceded by answer
4257                         tone.
4258         Preamble:       N/A
4259         Method:         Tester transmits ANS for 2.5s followed by 75ms of no tone then transmits
4260                         1300Hz and starts a 2-s timer.
4261         Pass criteria:  TUT should respond with 390Hz after 1.7(+0.2-0.0)s of start of 1300Hz.
4262         Comments:       The TUT should indicate that V.23 mode has been selected.
4263      */
4264     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_06_put_text_msg, (void *) (intptr_t) 0);
4265     logging = v18_get_logging_state(v18[TESTER]);
4266     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4267     span_log_set_tag(logging, "Tester");
4268     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_06_put_text_msg, (void *) (intptr_t) 1);
4269     logging = v18_get_logging_state(v18[TUT]);
4270     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4271     span_log_set_tag(logging, "TUT");
4272 
4273     if ((model = both_ways_line_model_init(line_model_no,
4274                                            noise_level,
4275                                            echo_level_cpe1,
4276                                            echo_level_co1,
4277                                            line_model_no,
4278                                            noise_level,
4279                                            echo_level_cpe2,
4280                                            echo_level_co2,
4281                                            channel_codec,
4282                                            rbs_pattern)) == NULL)
4283     {
4284         fprintf(stderr, "    Failed to create line model\n");
4285         exit(2);
4286     }
4287 
4288     result[TESTER][0] =
4289     result[TUT][0] = '\0';
4290     for (i = 0;  i < 10000;  i++)
4291     {
4292         for (j = 0;  j < 2;  j++)
4293         {
4294             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4295                 push = 10;
4296             if (samples < SAMPLES_PER_CHUNK)
4297             {
4298                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4299                 samples = SAMPLES_PER_CHUNK;
4300             }
4301         }
4302         if (log_audio)
4303         {
4304             for (j = 0;  j < samples;  j++)
4305             {
4306                 out_amp[2*j + 0] = amp[0][j];
4307                 out_amp[2*j + 1] = amp[1][j];
4308             }
4309             outframes = sf_writef_short(outhandle, out_amp, samples);
4310             if (outframes != samples)
4311             {
4312                 fprintf(stderr, "    Error writing audio file\n");
4313                 exit(2);
4314             }
4315         }
4316 #if 1
4317         both_ways_line_model(model,
4318                              model_amp[0],
4319                              amp[0],
4320                              model_amp[1],
4321                              amp[1],
4322                              samples);
4323 #else
4324         vec_copyi16(model_amp[0], amp[0], samples);
4325         vec_copyi16(model_amp[1], amp[1], samples);
4326 #endif
4327         v18_rx(v18[TESTER], model_amp[1], samples);
4328         v18_rx(v18[TUT], model_amp[0], samples);
4329     }
4330 
4331     v18_free(v18[TESTER]);
4332     v18_free(v18[TUT]);
4333     printf("Test not yet implemented\n");
4334     return 1;
4335 }
4336 /*- End of function --------------------------------------------------------*/
4337 
ans_07_put_text_msg(void * user_data,const uint8_t * msg,int len)4338 static void ans_07_put_text_msg(void *user_data, const uint8_t *msg, int len)
4339 {
4340 }
4341 /*- End of function --------------------------------------------------------*/
4342 
test_ans_07(void)4343 static int test_ans_07(void)
4344 {
4345     logging_state_t *logging;
4346     int16_t amp[2][SAMPLES_PER_CHUNK];
4347     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4348     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4349     int outframes;
4350     int samples;
4351     int push;
4352     int i;
4353     int j;
4354 
4355     /*
4356         III.5.4.3.7     ANS tone followed by 1650Hz
4357         Purpose:        To check correct detection of V.21 modem upper channel when preceded by answer
4358                         tone and to confirm discrimination between V.21 and V.18 modes.
4359         Preamble:       N/A
4360         Method:         Tester transmits ANS for 2.5s followed by 75ms of no tone then transmits
4361                         1650Hz and starts a 1-second timer.
4362         Pass criteria:  TUT should respond with 980Hz within 400+-100ms of start of 1650Hz.
4363         Comments:       The TUT should indicate that V.21 mode has been selected.
4364      */
4365     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_07_put_text_msg, (void *) (intptr_t) 0);
4366     logging = v18_get_logging_state(v18[TESTER]);
4367     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4368     span_log_set_tag(logging, "Tester");
4369     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_07_put_text_msg, (void *) (intptr_t) 1);
4370     logging = v18_get_logging_state(v18[TUT]);
4371     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4372     span_log_set_tag(logging, "TUT");
4373 
4374     if ((model = both_ways_line_model_init(line_model_no,
4375                                            noise_level,
4376                                            echo_level_cpe1,
4377                                            echo_level_co1,
4378                                            line_model_no,
4379                                            noise_level,
4380                                            echo_level_cpe2,
4381                                            echo_level_co2,
4382                                            channel_codec,
4383                                            rbs_pattern)) == NULL)
4384     {
4385         fprintf(stderr, "    Failed to create line model\n");
4386         exit(2);
4387     }
4388 
4389     result[TESTER][0] =
4390     result[TUT][0] = '\0';
4391     for (i = 0;  i < 10000;  i++)
4392     {
4393         for (j = 0;  j < 2;  j++)
4394         {
4395             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4396                 push = 10;
4397             if (samples < SAMPLES_PER_CHUNK)
4398             {
4399                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4400                 samples = SAMPLES_PER_CHUNK;
4401             }
4402         }
4403         if (log_audio)
4404         {
4405             for (j = 0;  j < samples;  j++)
4406             {
4407                 out_amp[2*j + 0] = amp[0][j];
4408                 out_amp[2*j + 1] = amp[1][j];
4409             }
4410             outframes = sf_writef_short(outhandle, out_amp, samples);
4411             if (outframes != samples)
4412             {
4413                 fprintf(stderr, "    Error writing audio file\n");
4414                 exit(2);
4415             }
4416         }
4417 #if 1
4418         both_ways_line_model(model,
4419                              model_amp[0],
4420                              amp[0],
4421                              model_amp[1],
4422                              amp[1],
4423                              samples);
4424 #else
4425         vec_copyi16(model_amp[0], amp[0], samples);
4426         vec_copyi16(model_amp[1], amp[1], samples);
4427 #endif
4428         v18_rx(v18[TESTER], model_amp[1], samples);
4429         v18_rx(v18[TUT], model_amp[0], samples);
4430     }
4431 
4432     v18_free(v18[TESTER]);
4433     v18_free(v18[TUT]);
4434     printf("Test not yet implemented\n");
4435     return 1;
4436 }
4437 /*- End of function --------------------------------------------------------*/
4438 
ans_08_put_text_msg(void * user_data,const uint8_t * msg,int len)4439 static void ans_08_put_text_msg(void *user_data, const uint8_t *msg, int len)
4440 {
4441 }
4442 /*- End of function --------------------------------------------------------*/
4443 
test_ans_08(void)4444 static int test_ans_08(void)
4445 {
4446     logging_state_t *logging;
4447     int16_t amp[2][SAMPLES_PER_CHUNK];
4448     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4449     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4450     int outframes;
4451     int samples;
4452     int push;
4453     int i;
4454     int j;
4455 
4456     /*
4457         III.5.4.3.8     980Hz followed by 1650Hz
4458         Purpose:        To ensure the correct selection of V.21 modem channel when certain types of
4459                         Swedish textphones are encountered.
4460         Preamble:       N/A
4461         Method:         The tester will simulate a call from a Diatext2 textphone that alternates between
4462                         980Hz and 1650Hz until a connection is made.
4463         Pass criteria:  The TUT should respond with the appropriate carrier depending on when it
4464                         connects.
4465         Comments:       The TUT should indicate a V.21 connection. The time for which each frequency is
4466                         transmitted is random and varies between 0.64 and 2.56s.
4467      */
4468     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_08_put_text_msg, (void *) (intptr_t) 0);
4469     logging = v18_get_logging_state(v18[TESTER]);
4470     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4471     span_log_set_tag(logging, "Tester");
4472     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_08_put_text_msg, (void *) (intptr_t) 1);
4473     logging = v18_get_logging_state(v18[TUT]);
4474     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4475     span_log_set_tag(logging, "TUT");
4476 
4477     if ((model = both_ways_line_model_init(line_model_no,
4478                                            noise_level,
4479                                            echo_level_cpe1,
4480                                            echo_level_co1,
4481                                            line_model_no,
4482                                            noise_level,
4483                                            echo_level_cpe2,
4484                                            echo_level_co2,
4485                                            channel_codec,
4486                                            rbs_pattern)) == NULL)
4487     {
4488         fprintf(stderr, "    Failed to create line model\n");
4489         exit(2);
4490     }
4491 
4492     result[TESTER][0] =
4493     result[TUT][0] = '\0';
4494     for (i = 0;  i < 10000;  i++)
4495     {
4496         for (j = 0;  j < 2;  j++)
4497         {
4498             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4499                 push = 10;
4500             if (samples < SAMPLES_PER_CHUNK)
4501             {
4502                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4503                 samples = SAMPLES_PER_CHUNK;
4504             }
4505         }
4506         if (log_audio)
4507         {
4508             for (j = 0;  j < samples;  j++)
4509             {
4510                 out_amp[2*j + 0] = amp[0][j];
4511                 out_amp[2*j + 1] = amp[1][j];
4512             }
4513             outframes = sf_writef_short(outhandle, out_amp, samples);
4514             if (outframes != samples)
4515             {
4516                 fprintf(stderr, "    Error writing audio file\n");
4517                 exit(2);
4518             }
4519         }
4520 #if 1
4521         both_ways_line_model(model,
4522                              model_amp[0],
4523                              amp[0],
4524                              model_amp[1],
4525                              amp[1],
4526                              samples);
4527 #else
4528         vec_copyi16(model_amp[0], amp[0], samples);
4529         vec_copyi16(model_amp[1], amp[1], samples);
4530 #endif
4531         v18_rx(v18[TESTER], model_amp[1], samples);
4532         v18_rx(v18[TUT], model_amp[0], samples);
4533     }
4534 
4535     v18_free(v18[TESTER]);
4536     v18_free(v18[TUT]);
4537     printf("Test not yet implemented\n");
4538     return 1;
4539 }
4540 /*- End of function --------------------------------------------------------*/
4541 
ans_09_put_text_msg(void * user_data,const uint8_t * msg,int len)4542 static void ans_09_put_text_msg(void *user_data, const uint8_t *msg, int len)
4543 {
4544 }
4545 /*- End of function --------------------------------------------------------*/
4546 
test_ans_09(void)4547 static int test_ans_09(void)
4548 {
4549     logging_state_t *logging;
4550     int16_t amp[2][SAMPLES_PER_CHUNK];
4551     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4552     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4553     int outframes;
4554     int samples;
4555     int push;
4556     int i;
4557     int j;
4558 
4559     /*
4560         III.5.4.3.9     980Hz calling tone detection
4561         Purpose:        To confirm correct detection of 980Hz calling tones as defined in V.25.
4562         Preamble:       N/A
4563         Method:         The tester will send bursts of 980Hz signals (a) 400ms, (b) 500ms, (c) 700ms and
4564                         (d) 800ms followed by 1s of silence.
4565         Pass criteria:  1) The TUT should not respond to bursts of 400ms or 800ms.
4566                         2) The TUT should immediately begin probing after a burst of 980Hz for 500ms or
4567                            700ms followed by 1s of silence.
4568         Comments:       The probe sent by the TUT will depend on the country setting.
4569      */
4570     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_09_put_text_msg, (void *) (intptr_t) 0);
4571     logging = v18_get_logging_state(v18[TESTER]);
4572     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4573     span_log_set_tag(logging, "Tester");
4574     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_09_put_text_msg, (void *) (intptr_t) 1);
4575     logging = v18_get_logging_state(v18[TUT]);
4576     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4577     span_log_set_tag(logging, "TUT");
4578 
4579     if ((model = both_ways_line_model_init(line_model_no,
4580                                            noise_level,
4581                                            echo_level_cpe1,
4582                                            echo_level_co1,
4583                                            line_model_no,
4584                                            noise_level,
4585                                            echo_level_cpe2,
4586                                            echo_level_co2,
4587                                            channel_codec,
4588                                            rbs_pattern)) == NULL)
4589     {
4590         fprintf(stderr, "    Failed to create line model\n");
4591         exit(2);
4592     }
4593 
4594     result[TESTER][0] =
4595     result[TUT][0] = '\0';
4596     for (i = 0;  i < 10000;  i++)
4597     {
4598         for (j = 0;  j < 2;  j++)
4599         {
4600             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4601                 push = 10;
4602             if (samples < SAMPLES_PER_CHUNK)
4603             {
4604                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4605                 samples = SAMPLES_PER_CHUNK;
4606             }
4607         }
4608         if (log_audio)
4609         {
4610             for (j = 0;  j < samples;  j++)
4611             {
4612                 out_amp[2*j + 0] = amp[0][j];
4613                 out_amp[2*j + 1] = amp[1][j];
4614             }
4615             outframes = sf_writef_short(outhandle, out_amp, samples);
4616             if (outframes != samples)
4617             {
4618                 fprintf(stderr, "    Error writing audio file\n");
4619                 exit(2);
4620             }
4621         }
4622 #if 1
4623         both_ways_line_model(model,
4624                              model_amp[0],
4625                              amp[0],
4626                              model_amp[1],
4627                              amp[1],
4628                              samples);
4629 #else
4630         vec_copyi16(model_amp[0], amp[0], samples);
4631         vec_copyi16(model_amp[1], amp[1], samples);
4632 #endif
4633         v18_rx(v18[TESTER], model_amp[1], samples);
4634         v18_rx(v18[TUT], model_amp[0], samples);
4635     }
4636 
4637     v18_free(v18[TESTER]);
4638     v18_free(v18[TUT]);
4639     printf("Test not yet implemented\n");
4640     return 1;
4641 }
4642 /*- End of function --------------------------------------------------------*/
4643 
ans_10_put_text_msg(void * user_data,const uint8_t * msg,int len)4644 static void ans_10_put_text_msg(void *user_data, const uint8_t *msg, int len)
4645 {
4646 }
4647 /*- End of function --------------------------------------------------------*/
4648 
test_ans_10(void)4649 static int test_ans_10(void)
4650 {
4651     logging_state_t *logging;
4652     int16_t amp[2][SAMPLES_PER_CHUNK];
4653     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4654     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4655     int outframes;
4656     int samples;
4657     int push;
4658     int i;
4659     int j;
4660 
4661     /*
4662         III.5.4.3.10    V.21 detection by timer
4663         Purpose:        To confirm correct selection of V.21 calling modem when the received signal is not
4664                         modulated, i.e. there is no 1180Hz.
4665         Preamble:       N/A
4666         Method:         The tester sends 980Hz to TUT for 2s.
4667         Pass criteria:  The TUT should respond with a 1650Hz tone in 1.5+-0.1s.
4668         Comments:       The TUT should indicate that V.21 mode has been selected.
4669      */
4670     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_10_put_text_msg, (void *) (intptr_t) 0);
4671     logging = v18_get_logging_state(v18[TESTER]);
4672     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4673     span_log_set_tag(logging, "Tester");
4674     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_10_put_text_msg, (void *) (intptr_t) 1);
4675     logging = v18_get_logging_state(v18[TUT]);
4676     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4677     span_log_set_tag(logging, "TUT");
4678 
4679     if ((model = both_ways_line_model_init(line_model_no,
4680                                            noise_level,
4681                                            echo_level_cpe1,
4682                                            echo_level_co1,
4683                                            line_model_no,
4684                                            noise_level,
4685                                            echo_level_cpe2,
4686                                            echo_level_co2,
4687                                            channel_codec,
4688                                            rbs_pattern)) == NULL)
4689     {
4690         fprintf(stderr, "    Failed to create line model\n");
4691         exit(2);
4692     }
4693 
4694     result[TESTER][0] =
4695     result[TUT][0] = '\0';
4696     for (i = 0;  i < 10000;  i++)
4697     {
4698         for (j = 0;  j < 2;  j++)
4699         {
4700             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4701                 push = 10;
4702             if (samples < SAMPLES_PER_CHUNK)
4703             {
4704                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4705                 samples = SAMPLES_PER_CHUNK;
4706             }
4707         }
4708         if (log_audio)
4709         {
4710             for (j = 0;  j < samples;  j++)
4711             {
4712                 out_amp[2*j + 0] = amp[0][j];
4713                 out_amp[2*j + 1] = amp[1][j];
4714             }
4715             outframes = sf_writef_short(outhandle, out_amp, samples);
4716             if (outframes != samples)
4717             {
4718                 fprintf(stderr, "    Error writing audio file\n");
4719                 exit(2);
4720             }
4721         }
4722 #if 1
4723         both_ways_line_model(model,
4724                              model_amp[0],
4725                              amp[0],
4726                              model_amp[1],
4727                              amp[1],
4728                              samples);
4729 #else
4730         vec_copyi16(model_amp[0], amp[0], samples);
4731         vec_copyi16(model_amp[1], amp[1], samples);
4732 #endif
4733         v18_rx(v18[TESTER], model_amp[1], samples);
4734         v18_rx(v18[TUT], model_amp[0], samples);
4735     }
4736 
4737     v18_free(v18[TESTER]);
4738     v18_free(v18[TUT]);
4739     printf("Test not yet implemented\n");
4740     return 1;
4741 }
4742 /*- End of function --------------------------------------------------------*/
4743 
ans_11_put_text_msg(void * user_data,const uint8_t * msg,int len)4744 static void ans_11_put_text_msg(void *user_data, const uint8_t *msg, int len)
4745 {
4746 }
4747 /*- End of function --------------------------------------------------------*/
4748 
test_ans_11(void)4749 static int test_ans_11(void)
4750 {
4751     logging_state_t *logging;
4752     int16_t amp[2][SAMPLES_PER_CHUNK];
4753     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4754     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4755     int outframes;
4756     int samples;
4757     int push;
4758     int i;
4759     int j;
4760 
4761     /*
4762         III.5.4.3.11    EDT detection by rate
4763         Purpose:        To confirm detection of EDT modems by detecting the transmission rate of received
4764                         characters.
4765         Preamble:       N/A
4766         Method:         The tester transmits EDT characters "abcdef" to TUT at 110 bit/s. When TUT
4767                         indicates that the connection is established, type characters "abcdef<CR>" back to
4768                         the tester. The same characters will then be transmitted back to the TUT.
4769         Pass criteria:  Ensure correct reception of characters by tester and TUT.
4770         Comments:       The TUT should indicate that EDT mode has been selected. Some characters may
4771                         be lost during the detection process. However, the number lost should be minimal.
4772                         The data bits and parity are specified in Annex C.
4773      */
4774     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_11_put_text_msg, (void *) (intptr_t) 0);
4775     logging = v18_get_logging_state(v18[TESTER]);
4776     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4777     span_log_set_tag(logging, "Tester");
4778     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_11_put_text_msg, (void *) (intptr_t) 1);
4779     logging = v18_get_logging_state(v18[TUT]);
4780     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4781     span_log_set_tag(logging, "TUT");
4782 
4783     if ((model = both_ways_line_model_init(line_model_no,
4784                                            noise_level,
4785                                            echo_level_cpe1,
4786                                            echo_level_co1,
4787                                            line_model_no,
4788                                            noise_level,
4789                                            echo_level_cpe2,
4790                                            echo_level_co2,
4791                                            channel_codec,
4792                                            rbs_pattern)) == NULL)
4793     {
4794         fprintf(stderr, "    Failed to create line model\n");
4795         exit(2);
4796     }
4797 
4798     result[TESTER][0] =
4799     result[TUT][0] = '\0';
4800     for (i = 0;  i < 10000;  i++)
4801     {
4802         for (j = 0;  j < 2;  j++)
4803         {
4804             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4805                 push = 10;
4806             if (samples < SAMPLES_PER_CHUNK)
4807             {
4808                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4809                 samples = SAMPLES_PER_CHUNK;
4810             }
4811         }
4812         if (log_audio)
4813         {
4814             for (j = 0;  j < samples;  j++)
4815             {
4816                 out_amp[2*j + 0] = amp[0][j];
4817                 out_amp[2*j + 1] = amp[1][j];
4818             }
4819             outframes = sf_writef_short(outhandle, out_amp, samples);
4820             if (outframes != samples)
4821             {
4822                 fprintf(stderr, "    Error writing audio file\n");
4823                 exit(2);
4824             }
4825         }
4826 #if 1
4827         both_ways_line_model(model,
4828                              model_amp[0],
4829                              amp[0],
4830                              model_amp[1],
4831                              amp[1],
4832                              samples);
4833 #else
4834         vec_copyi16(model_amp[0], amp[0], samples);
4835         vec_copyi16(model_amp[1], amp[1], samples);
4836 #endif
4837         v18_rx(v18[TESTER], model_amp[1], samples);
4838         v18_rx(v18[TUT], model_amp[0], samples);
4839     }
4840 
4841     v18_free(v18[TESTER]);
4842     v18_free(v18[TUT]);
4843     printf("Test not yet implemented\n");
4844     return 1;
4845 }
4846 /*- End of function --------------------------------------------------------*/
4847 
ans_12_put_text_msg(void * user_data,const uint8_t * msg,int len)4848 static void ans_12_put_text_msg(void *user_data, const uint8_t *msg, int len)
4849 {
4850 }
4851 /*- End of function --------------------------------------------------------*/
4852 
test_ans_12(void)4853 static int test_ans_12(void)
4854 {
4855     logging_state_t *logging;
4856     int16_t amp[2][SAMPLES_PER_CHUNK];
4857     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4858     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4859     int outframes;
4860     int samples;
4861     int push;
4862     int i;
4863     int j;
4864 
4865     /*
4866         III.5.4.3.12    V.21 Detection by rate
4867         Purpose:        To confirm detection of V.21 modem low channel by detecting the transmission rate
4868                         of received characters and to ensure correct discrimination between V.18 and V.21
4869                         modes.
4870         Preamble:       N/A
4871         Method:         The tester transmits characters "abcdef" to TUT using V.21 (1) at 300 bit/s. When
4872                         TUT indicates that the connection is established, type characters "abcdef<CR>"
4873                         back to the tester. The same characters will then be transmitted back to the TUT.
4874         Pass criteria:  Ensure correct reception of characters by tester and TUT.
4875         Comments:       This situation is unlikely to occur in practice unless the DCE is sending a V.21
4876                         (1650Hz) probe. However, it is catered for in V.18. It is more likely that this is
4877                         where CI or TXP characters would be detected (see test ANS-02).
4878      */
4879     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_12_put_text_msg, (void *) (intptr_t) 0);
4880     logging = v18_get_logging_state(v18[TESTER]);
4881     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4882     span_log_set_tag(logging, "Tester");
4883     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_12_put_text_msg, (void *) (intptr_t) 1);
4884     logging = v18_get_logging_state(v18[TUT]);
4885     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4886     span_log_set_tag(logging, "TUT");
4887 
4888     if ((model = both_ways_line_model_init(line_model_no,
4889                                            noise_level,
4890                                            echo_level_cpe1,
4891                                            echo_level_co1,
4892                                            line_model_no,
4893                                            noise_level,
4894                                            echo_level_cpe2,
4895                                            echo_level_co2,
4896                                            channel_codec,
4897                                            rbs_pattern)) == NULL)
4898     {
4899         fprintf(stderr, "    Failed to create line model\n");
4900         exit(2);
4901     }
4902 
4903     result[TESTER][0] =
4904     result[TUT][0] = '\0';
4905     for (i = 0;  i < 10000;  i++)
4906     {
4907         for (j = 0;  j < 2;  j++)
4908         {
4909             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
4910                 push = 10;
4911             if (samples < SAMPLES_PER_CHUNK)
4912             {
4913                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
4914                 samples = SAMPLES_PER_CHUNK;
4915             }
4916         }
4917         if (log_audio)
4918         {
4919             for (j = 0;  j < samples;  j++)
4920             {
4921                 out_amp[2*j + 0] = amp[0][j];
4922                 out_amp[2*j + 1] = amp[1][j];
4923             }
4924             outframes = sf_writef_short(outhandle, out_amp, samples);
4925             if (outframes != samples)
4926             {
4927                 fprintf(stderr, "    Error writing audio file\n");
4928                 exit(2);
4929             }
4930         }
4931 #if 1
4932         both_ways_line_model(model,
4933                              model_amp[0],
4934                              amp[0],
4935                              model_amp[1],
4936                              amp[1],
4937                              samples);
4938 #else
4939         vec_copyi16(model_amp[0], amp[0], samples);
4940         vec_copyi16(model_amp[1], amp[1], samples);
4941 #endif
4942         v18_rx(v18[TESTER], model_amp[1], samples);
4943         v18_rx(v18[TUT], model_amp[0], samples);
4944     }
4945 
4946     v18_free(v18[TESTER]);
4947     v18_free(v18[TUT]);
4948     printf("Test not yet implemented\n");
4949     return 1;
4950 }
4951 /*- End of function --------------------------------------------------------*/
4952 
ans_13_put_text_msg(void * user_data,const uint8_t * msg,int len)4953 static void ans_13_put_text_msg(void *user_data, const uint8_t *msg, int len)
4954 {
4955 }
4956 /*- End of function --------------------------------------------------------*/
4957 
test_ans_13(void)4958 static int test_ans_13(void)
4959 {
4960     logging_state_t *logging;
4961     int16_t amp[2][SAMPLES_PER_CHUNK];
4962     int16_t model_amp[2][SAMPLES_PER_CHUNK];
4963     int16_t out_amp[2*SAMPLES_PER_CHUNK];
4964     int outframes;
4965     int samples;
4966     int push;
4967     int i;
4968     int j;
4969 
4970     /*
4971         III.5.4.3.13    Tr timer
4972         Purpose:        To ensure that the TUT returns to the Monitor A state on expiry of timer Tr
4973                         (2s). Timer Tr is started when a modulated V.21 (1) signal is detected.
4974         Preamble:       N/A
4975         Method:         The tester will transmit 980Hz for 200ms followed by alternating 980Hz/1180Hz
4976                         at 110 bit/s for 100ms followed by 980Hz for 1s.
4977         Pass criteria:  The TUT should begin probing 4+-0.5s after the 980Hz signal is removed.
4978         Comments:       It is not possible to be precise on timings for this test since the definition of a
4979                         "modulated signal" as in 5.2.4.4 is not specified. Therefore it is not known exactly
4980                         when timer Tr will start. It is assumed that timer Ta is restarted on re-entering the
4981                         Monitor A state.
4982      */
4983     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_13_put_text_msg, (void *) (intptr_t) 0);
4984     logging = v18_get_logging_state(v18[TESTER]);
4985     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4986     span_log_set_tag(logging, "Tester");
4987     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_13_put_text_msg, (void *) (intptr_t) 1);
4988     logging = v18_get_logging_state(v18[TUT]);
4989     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
4990     span_log_set_tag(logging, "TUT");
4991 
4992     if ((model = both_ways_line_model_init(line_model_no,
4993                                            noise_level,
4994                                            echo_level_cpe1,
4995                                            echo_level_co1,
4996                                            line_model_no,
4997                                            noise_level,
4998                                            echo_level_cpe2,
4999                                            echo_level_co2,
5000                                            channel_codec,
5001                                            rbs_pattern)) == NULL)
5002     {
5003         fprintf(stderr, "    Failed to create line model\n");
5004         exit(2);
5005     }
5006 
5007     result[TESTER][0] =
5008     result[TUT][0] = '\0';
5009     for (i = 0;  i < 10000;  i++)
5010     {
5011         for (j = 0;  j < 2;  j++)
5012         {
5013             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5014                 push = 10;
5015             if (samples < SAMPLES_PER_CHUNK)
5016             {
5017                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5018                 samples = SAMPLES_PER_CHUNK;
5019             }
5020         }
5021         if (log_audio)
5022         {
5023             for (j = 0;  j < samples;  j++)
5024             {
5025                 out_amp[2*j + 0] = amp[0][j];
5026                 out_amp[2*j + 1] = amp[1][j];
5027             }
5028             outframes = sf_writef_short(outhandle, out_amp, samples);
5029             if (outframes != samples)
5030             {
5031                 fprintf(stderr, "    Error writing audio file\n");
5032                 exit(2);
5033             }
5034         }
5035 #if 1
5036         both_ways_line_model(model,
5037                              model_amp[0],
5038                              amp[0],
5039                              model_amp[1],
5040                              amp[1],
5041                              samples);
5042 #else
5043         vec_copyi16(model_amp[0], amp[0], samples);
5044         vec_copyi16(model_amp[1], amp[1], samples);
5045 #endif
5046         v18_rx(v18[TESTER], model_amp[1], samples);
5047         v18_rx(v18[TUT], model_amp[0], samples);
5048     }
5049 
5050     v18_free(v18[TESTER]);
5051     v18_free(v18[TUT]);
5052     printf("Test not yet implemented\n");
5053     return 1;
5054 }
5055 /*- End of function --------------------------------------------------------*/
5056 
ans_14_put_text_msg(void * user_data,const uint8_t * msg,int len)5057 static void ans_14_put_text_msg(void *user_data, const uint8_t *msg, int len)
5058 {
5059 }
5060 /*- End of function --------------------------------------------------------*/
5061 
test_ans_14(void)5062 static int test_ans_14(void)
5063 {
5064     logging_state_t *logging;
5065     int16_t amp[2][SAMPLES_PER_CHUNK];
5066     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5067     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5068     int outframes;
5069     int samples;
5070     int push;
5071     int i;
5072     int j;
5073 
5074     /*
5075         III.5.4.3.14    Te timer
5076         Purpose:        To ensure that the TUT returns to the Monitor A on expiry of timer Te
5077                         (2.7s). Timer Te is started when a 980Hz signal is detected.
5078         Preamble:       N/A
5079         Method:         The tester will transmit 980Hz for 200ms followed silence for 7 s.
5080         Pass criteria:  The TUT should begin probing 5.5+-0.5s after the 980Hz signal is removed.
5081         Comments:       It is assumed that timer Ta (3s) is restarted on re-entering the Monitor A
5082                         state.
5083      */
5084     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_14_put_text_msg, (void *) (intptr_t) 0);
5085     logging = v18_get_logging_state(v18[TESTER]);
5086     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5087     span_log_set_tag(logging, "Tester");
5088     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_14_put_text_msg, (void *) (intptr_t) 1);
5089     logging = v18_get_logging_state(v18[TUT]);
5090     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5091     span_log_set_tag(logging, "TUT");
5092 
5093     if ((model = both_ways_line_model_init(line_model_no,
5094                                            noise_level,
5095                                            echo_level_cpe1,
5096                                            echo_level_co1,
5097                                            line_model_no,
5098                                            noise_level,
5099                                            echo_level_cpe2,
5100                                            echo_level_co2,
5101                                            channel_codec,
5102                                            rbs_pattern)) == NULL)
5103     {
5104         fprintf(stderr, "    Failed to create line model\n");
5105         exit(2);
5106     }
5107 
5108     result[TESTER][0] =
5109     result[TUT][0] = '\0';
5110     for (i = 0;  i < 10000;  i++)
5111     {
5112         for (j = 0;  j < 2;  j++)
5113         {
5114             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5115                 push = 10;
5116             if (samples < SAMPLES_PER_CHUNK)
5117             {
5118                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5119                 samples = SAMPLES_PER_CHUNK;
5120             }
5121         }
5122         if (log_audio)
5123         {
5124             for (j = 0;  j < samples;  j++)
5125             {
5126                 out_amp[2*j + 0] = amp[0][j];
5127                 out_amp[2*j + 1] = amp[1][j];
5128             }
5129             outframes = sf_writef_short(outhandle, out_amp, samples);
5130             if (outframes != samples)
5131             {
5132                 fprintf(stderr, "    Error writing audio file\n");
5133                 exit(2);
5134             }
5135         }
5136 #if 1
5137         both_ways_line_model(model,
5138                              model_amp[0],
5139                              amp[0],
5140                              model_amp[1],
5141                              amp[1],
5142                              samples);
5143 #else
5144         vec_copyi16(model_amp[0], amp[0], samples);
5145         vec_copyi16(model_amp[1], amp[1], samples);
5146 #endif
5147         v18_rx(v18[TESTER], model_amp[1], samples);
5148         v18_rx(v18[TUT], model_amp[0], samples);
5149     }
5150 
5151     v18_free(v18[TESTER]);
5152     v18_free(v18[TUT]);
5153     printf("Test not yet implemented\n");
5154     return 1;
5155 }
5156 /*- End of function --------------------------------------------------------*/
5157 
ans_15_put_text_msg(void * user_data,const uint8_t * msg,int len)5158 static void ans_15_put_text_msg(void *user_data, const uint8_t *msg, int len)
5159 {
5160 }
5161 /*- End of function --------------------------------------------------------*/
5162 
test_ans_15(void)5163 static int test_ans_15(void)
5164 {
5165     logging_state_t *logging;
5166     int16_t amp[2][SAMPLES_PER_CHUNK];
5167     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5168     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5169     int outframes;
5170     int samples;
5171     int push;
5172     int i;
5173     int j;
5174 
5175     /*
5176         III.5.4.3.15 5  Bit mode (Baudot) detection tests
5177         Purpose:        To confirm detection of Baudot modulation at various bit rates that may be
5178                         encountered.
5179         Preamble:       N/A
5180         Method:         The tester transmits the 5-bit coded characters "0" to "9" followed by "abcdef" at
5181                         (a) 45.45, (b) 47.6, (c) 50 and (d) 100 bits per second. When TUT indicates a
5182                         connection, type at least 5 characters back to the tester so that correct selection of bit
5183                         rate can be confirmed.
5184         Pass criteria:  1) The TUT should select Baudot mode and the appropriate bit rate.
5185                         2) The tester will analyse the bit rate of received characters, which should be at an
5186                            appropriate rate, and confirm the carrier on/off times before and after the
5187                            characters.
5188         Comments:       45.45 and 50 bit/s are the commonly used Baudot bit rates. However, some
5189                         textphones can transmit at higher rates, e.g. 100 bit/s. Responding at either 45.45 or
5190                         50 bit/s is acceptable to these devices which then fall back to the selected rate.
5191                         A rate of 47.6 bit/s may be encountered from another V.18 textphone in the
5192                         automode answer state. The TUT may then select either 45.45 or 50 bit/s for the
5193                         transmission.
5194      */
5195     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_15_put_text_msg, (void *) (intptr_t) 0);
5196     logging = v18_get_logging_state(v18[TESTER]);
5197     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5198     span_log_set_tag(logging, "Tester");
5199     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_15_put_text_msg, (void *) (intptr_t) 1);
5200     logging = v18_get_logging_state(v18[TUT]);
5201     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5202     span_log_set_tag(logging, "TUT");
5203 
5204     if ((model = both_ways_line_model_init(line_model_no,
5205                                            noise_level,
5206                                            echo_level_cpe1,
5207                                            echo_level_co1,
5208                                            line_model_no,
5209                                            noise_level,
5210                                            echo_level_cpe2,
5211                                            echo_level_co2,
5212                                            channel_codec,
5213                                            rbs_pattern)) == NULL)
5214     {
5215         fprintf(stderr, "    Failed to create line model\n");
5216         exit(2);
5217     }
5218 
5219     result[TESTER][0] =
5220     result[TUT][0] = '\0';
5221     for (i = 0;  i < 10000;  i++)
5222     {
5223         for (j = 0;  j < 2;  j++)
5224         {
5225             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5226                 push = 10;
5227             if (samples < SAMPLES_PER_CHUNK)
5228             {
5229                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5230                 samples = SAMPLES_PER_CHUNK;
5231             }
5232         }
5233         if (log_audio)
5234         {
5235             for (j = 0;  j < samples;  j++)
5236             {
5237                 out_amp[2*j + 0] = amp[0][j];
5238                 out_amp[2*j + 1] = amp[1][j];
5239             }
5240             outframes = sf_writef_short(outhandle, out_amp, samples);
5241             if (outframes != samples)
5242             {
5243                 fprintf(stderr, "    Error writing audio file\n");
5244                 exit(2);
5245             }
5246         }
5247 #if 1
5248         both_ways_line_model(model,
5249                              model_amp[0],
5250                              amp[0],
5251                              model_amp[1],
5252                              amp[1],
5253                              samples);
5254 #else
5255         vec_copyi16(model_amp[0], amp[0], samples);
5256         vec_copyi16(model_amp[1], amp[1], samples);
5257 #endif
5258         v18_rx(v18[TESTER], model_amp[1], samples);
5259         v18_rx(v18[TUT], model_amp[0], samples);
5260     }
5261 
5262     v18_free(v18[TESTER]);
5263     v18_free(v18[TUT]);
5264     printf("Test not yet implemented\n");
5265     return 1;
5266 }
5267 /*- End of function --------------------------------------------------------*/
5268 
ans_16_put_text_msg(void * user_data,const uint8_t * msg,int len)5269 static void ans_16_put_text_msg(void *user_data, const uint8_t *msg, int len)
5270 {
5271 }
5272 /*- End of function --------------------------------------------------------*/
5273 
test_ans_16(void)5274 static int test_ans_16(void)
5275 {
5276     logging_state_t *logging;
5277     int16_t amp[2][SAMPLES_PER_CHUNK];
5278     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5279     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5280     int outframes;
5281     int samples;
5282     int push;
5283     int i;
5284     int j;
5285 
5286     /*
5287         III.5.4.3.16    DTMF signal detection
5288         Purpose:        To verify whether the TUT correctly recognizes DTMF signals.
5289         Preamble:       N/A
5290         Method:         The tester will send a single DTMF tone of 40ms duration to TUT. When TUT
5291                         indicates a connection, type at least 5 characters back to the tester so that correct
5292                         selection of mode can be confirmed.
5293         Pass criteria:  Tester will analyse the received characters to confirm DTMF mode selection.
5294         Comments:       The TUT should indicate that it has selected DTMF mode. The DTMF capabilities
5295                         of the TUT should comply with ITU-T Q.24 for the Danish Administration.
5296      */
5297     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_16_put_text_msg, (void *) (intptr_t) 0);
5298     logging = v18_get_logging_state(v18[TESTER]);
5299     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5300     span_log_set_tag(logging, "Tester");
5301     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_16_put_text_msg, (void *) (intptr_t) 1);
5302     logging = v18_get_logging_state(v18[TUT]);
5303     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5304     span_log_set_tag(logging, "TUT");
5305 
5306     if ((model = both_ways_line_model_init(line_model_no,
5307                                            noise_level,
5308                                            echo_level_cpe1,
5309                                            echo_level_co1,
5310                                            line_model_no,
5311                                            noise_level,
5312                                            echo_level_cpe2,
5313                                            echo_level_co2,
5314                                            channel_codec,
5315                                            rbs_pattern)) == NULL)
5316     {
5317         fprintf(stderr, "    Failed to create line model\n");
5318         exit(2);
5319     }
5320 
5321     result[TESTER][0] =
5322     result[TUT][0] = '\0';
5323     for (i = 0;  i < 10000;  i++)
5324     {
5325         for (j = 0;  j < 2;  j++)
5326         {
5327             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5328                 push = 10;
5329             if (samples < SAMPLES_PER_CHUNK)
5330             {
5331                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5332                 samples = SAMPLES_PER_CHUNK;
5333             }
5334         }
5335         if (log_audio)
5336         {
5337             for (j = 0;  j < samples;  j++)
5338             {
5339                 out_amp[2*j + 0] = amp[0][j];
5340                 out_amp[2*j + 1] = amp[1][j];
5341             }
5342             outframes = sf_writef_short(outhandle, out_amp, samples);
5343             if (outframes != samples)
5344             {
5345                 fprintf(stderr, "    Error writing audio file\n");
5346                 exit(2);
5347             }
5348         }
5349 #if 1
5350         both_ways_line_model(model,
5351                              model_amp[0],
5352                              amp[0],
5353                              model_amp[1],
5354                              amp[1],
5355                              samples);
5356 #else
5357         vec_copyi16(model_amp[0], amp[0], samples);
5358         vec_copyi16(model_amp[1], amp[1], samples);
5359 #endif
5360         v18_rx(v18[TESTER], model_amp[1], samples);
5361         v18_rx(v18[TUT], model_amp[0], samples);
5362     }
5363 
5364     v18_free(v18[TESTER]);
5365     v18_free(v18[TUT]);
5366     printf("Test not yet implemented\n");
5367     return 1;
5368 }
5369 /*- End of function --------------------------------------------------------*/
5370 
ans_17_put_text_msg(void * user_data,const uint8_t * msg,int len)5371 static void ans_17_put_text_msg(void *user_data, const uint8_t *msg, int len)
5372 {
5373 }
5374 /*- End of function --------------------------------------------------------*/
5375 
test_ans_17(void)5376 static int test_ans_17(void)
5377 {
5378     logging_state_t *logging;
5379     int16_t amp[2][SAMPLES_PER_CHUNK];
5380     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5381     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5382     int outframes;
5383     int samples;
5384     int push;
5385     int i;
5386     int j;
5387 
5388     /*
5389         III.5.4.3.17    Bell 103 (1270Hz signal) detection
5390         Purpose:        To ensure correct detection and selection of Bell 103 modems.
5391         Preamble:       N/A
5392         Method:         The tester sends 1270Hz to TUT for 5s.
5393         Pass criteria:  TUT should respond with 2225Hz tone after 0.7+-0.1s.
5394         Comments:       The TUT should indicate that Bell 103 mode has been selected.
5395      */
5396     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_17_put_text_msg, (void *) (intptr_t) 0);
5397     logging = v18_get_logging_state(v18[TESTER]);
5398     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5399     span_log_set_tag(logging, "Tester");
5400     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_17_put_text_msg, (void *) (intptr_t) 1);
5401     logging = v18_get_logging_state(v18[TUT]);
5402     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5403     span_log_set_tag(logging, "TUT");
5404 
5405     if ((model = both_ways_line_model_init(line_model_no,
5406                                            noise_level,
5407                                            echo_level_cpe1,
5408                                            echo_level_co1,
5409                                            line_model_no,
5410                                            noise_level,
5411                                            echo_level_cpe2,
5412                                            echo_level_co2,
5413                                            channel_codec,
5414                                            rbs_pattern)) == NULL)
5415     {
5416         fprintf(stderr, "    Failed to create line model\n");
5417         exit(2);
5418     }
5419 
5420     result[TESTER][0] =
5421     result[TUT][0] = '\0';
5422     for (i = 0;  i < 10000;  i++)
5423     {
5424         for (j = 0;  j < 2;  j++)
5425         {
5426             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5427                 push = 10;
5428             if (samples < SAMPLES_PER_CHUNK)
5429             {
5430                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5431                 samples = SAMPLES_PER_CHUNK;
5432             }
5433         }
5434         if (log_audio)
5435         {
5436             for (j = 0;  j < samples;  j++)
5437             {
5438                 out_amp[2*j + 0] = amp[0][j];
5439                 out_amp[2*j + 1] = amp[1][j];
5440             }
5441             outframes = sf_writef_short(outhandle, out_amp, samples);
5442             if (outframes != samples)
5443             {
5444                 fprintf(stderr, "    Error writing audio file\n");
5445                 exit(2);
5446             }
5447         }
5448 #if 1
5449         both_ways_line_model(model,
5450                              model_amp[0],
5451                              amp[0],
5452                              model_amp[1],
5453                              amp[1],
5454                              samples);
5455 #else
5456         vec_copyi16(model_amp[0], amp[0], samples);
5457         vec_copyi16(model_amp[1], amp[1], samples);
5458 #endif
5459         v18_rx(v18[TESTER], model_amp[1], samples);
5460         v18_rx(v18[TUT], model_amp[0], samples);
5461     }
5462 
5463     v18_free(v18[TESTER]);
5464     v18_free(v18[TUT]);
5465     printf("Test not yet implemented\n");
5466     return 1;
5467 }
5468 /*- End of function --------------------------------------------------------*/
5469 
ans_18_put_text_msg(void * user_data,const uint8_t * msg,int len)5470 static void ans_18_put_text_msg(void *user_data, const uint8_t *msg, int len)
5471 {
5472 }
5473 /*- End of function --------------------------------------------------------*/
5474 
test_ans_18(void)5475 static int test_ans_18(void)
5476 {
5477     logging_state_t *logging;
5478     int16_t amp[2][SAMPLES_PER_CHUNK];
5479     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5480     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5481     int outframes;
5482     int samples;
5483     int push;
5484     int i;
5485     int j;
5486 
5487     /*
5488         III.5.4.3.18    Bell 103 (2225Hz signal) detection
5489         Purpose:        To ensure correct detection and selection of Bell 103 modems in reverse mode.
5490         Preamble:       N/A
5491         Method:         The tester sends 2225Hz to TUT for 5s.
5492         Pass criteria:  The TUT should respond with 1270Hz after 1+-0.2s.
5493         Comments:       The TUT should indicate that Bell 103 mode has been selected. Bell 103 modems
5494                         use 2225Hz as both answer tone and higher frequency of the upper channel.
5495      */
5496     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_18_put_text_msg, (void *) (intptr_t) 0);
5497     logging = v18_get_logging_state(v18[TESTER]);
5498     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5499     span_log_set_tag(logging, "Tester");
5500     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_18_put_text_msg, (void *) (intptr_t) 1);
5501     logging = v18_get_logging_state(v18[TUT]);
5502     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5503     span_log_set_tag(logging, "TUT");
5504 
5505     if ((model = both_ways_line_model_init(line_model_no,
5506                                            noise_level,
5507                                            echo_level_cpe1,
5508                                            echo_level_co1,
5509                                            line_model_no,
5510                                            noise_level,
5511                                            echo_level_cpe2,
5512                                            echo_level_co2,
5513                                            channel_codec,
5514                                            rbs_pattern)) == NULL)
5515     {
5516         fprintf(stderr, "    Failed to create line model\n");
5517         exit(2);
5518     }
5519 
5520     result[TESTER][0] =
5521     result[TUT][0] = '\0';
5522     for (i = 0;  i < 10000;  i++)
5523     {
5524         for (j = 0;  j < 2;  j++)
5525         {
5526             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5527                 push = 10;
5528             if (samples < SAMPLES_PER_CHUNK)
5529             {
5530                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5531                 samples = SAMPLES_PER_CHUNK;
5532             }
5533         }
5534         if (log_audio)
5535         {
5536             for (j = 0;  j < samples;  j++)
5537             {
5538                 out_amp[2*j + 0] = amp[0][j];
5539                 out_amp[2*j + 1] = amp[1][j];
5540             }
5541             outframes = sf_writef_short(outhandle, out_amp, samples);
5542             if (outframes != samples)
5543             {
5544                 fprintf(stderr, "    Error writing audio file\n");
5545                 exit(2);
5546             }
5547         }
5548 #if 1
5549         both_ways_line_model(model,
5550                              model_amp[0],
5551                              amp[0],
5552                              model_amp[1],
5553                              amp[1],
5554                              samples);
5555 #else
5556         vec_copyi16(model_amp[0], amp[0], samples);
5557         vec_copyi16(model_amp[1], amp[1], samples);
5558 #endif
5559         v18_rx(v18[TESTER], model_amp[1], samples);
5560         v18_rx(v18[TUT], model_amp[0], samples);
5561     }
5562 
5563     v18_free(v18[TESTER]);
5564     v18_free(v18[TUT]);
5565     printf("Test not yet implemented\n");
5566     return 1;
5567 }
5568 /*- End of function --------------------------------------------------------*/
5569 
ans_19_put_text_msg(void * user_data,const uint8_t * msg,int len)5570 static void ans_19_put_text_msg(void *user_data, const uint8_t *msg, int len)
5571 {
5572 }
5573 /*- End of function --------------------------------------------------------*/
5574 
test_ans_19(void)5575 static int test_ans_19(void)
5576 {
5577     logging_state_t *logging;
5578     int16_t amp[2][SAMPLES_PER_CHUNK];
5579     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5580     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5581     int outframes;
5582     int samples;
5583     int push;
5584     int i;
5585     int j;
5586 
5587     /*
5588         III.5.4.3.19    V.21 Reverse mode (1650Hz) detection
5589         Purpose:        To ensure correct detection and selection of V.21 reverse mode.
5590         Preamble:       N/A
5591         Method:         The tester sends 1650Hz to TUT for 5s.
5592         Pass criteria:  The TUT should respond with 980Hz after 0.4+-0.2s.
5593         Comments:       The TUT should indicate that V.21 mode has been selected.
5594      */
5595     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_19_put_text_msg, (void *) (intptr_t) 0);
5596     logging = v18_get_logging_state(v18[TESTER]);
5597     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5598     span_log_set_tag(logging, "Tester");
5599     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_19_put_text_msg, (void *) (intptr_t) 1);
5600     logging = v18_get_logging_state(v18[TUT]);
5601     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5602     span_log_set_tag(logging, "TUT");
5603 
5604     if ((model = both_ways_line_model_init(line_model_no,
5605                                            noise_level,
5606                                            echo_level_cpe1,
5607                                            echo_level_co1,
5608                                            line_model_no,
5609                                            noise_level,
5610                                            echo_level_cpe2,
5611                                            echo_level_co2,
5612                                            channel_codec,
5613                                            rbs_pattern)) == NULL)
5614     {
5615         fprintf(stderr, "    Failed to create line model\n");
5616         exit(2);
5617     }
5618 
5619     result[TESTER][0] =
5620     result[TUT][0] = '\0';
5621     for (i = 0;  i < 10000;  i++)
5622     {
5623         for (j = 0;  j < 2;  j++)
5624         {
5625             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5626                 push = 10;
5627             if (samples < SAMPLES_PER_CHUNK)
5628             {
5629                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5630                 samples = SAMPLES_PER_CHUNK;
5631             }
5632         }
5633         if (log_audio)
5634         {
5635             for (j = 0;  j < samples;  j++)
5636             {
5637                 out_amp[2*j + 0] = amp[0][j];
5638                 out_amp[2*j + 1] = amp[1][j];
5639             }
5640             outframes = sf_writef_short(outhandle, out_amp, samples);
5641             if (outframes != samples)
5642             {
5643                 fprintf(stderr, "    Error writing audio file\n");
5644                 exit(2);
5645             }
5646         }
5647 #if 1
5648         both_ways_line_model(model,
5649                              model_amp[0],
5650                              amp[0],
5651                              model_amp[1],
5652                              amp[1],
5653                              samples);
5654 #else
5655         vec_copyi16(model_amp[0], amp[0], samples);
5656         vec_copyi16(model_amp[1], amp[1], samples);
5657 #endif
5658         v18_rx(v18[TESTER], model_amp[1], samples);
5659         v18_rx(v18[TUT], model_amp[0], samples);
5660     }
5661 
5662     v18_free(v18[TESTER]);
5663     v18_free(v18[TUT]);
5664     printf("Test not yet implemented\n");
5665     return 1;
5666 }
5667 /*- End of function --------------------------------------------------------*/
5668 
ans_20_put_text_msg(void * user_data,const uint8_t * msg,int len)5669 static void ans_20_put_text_msg(void *user_data, const uint8_t *msg, int len)
5670 {
5671 }
5672 /*- End of function --------------------------------------------------------*/
5673 
test_ans_20(void)5674 static int test_ans_20(void)
5675 {
5676     logging_state_t *logging;
5677     int16_t amp[2][SAMPLES_PER_CHUNK];
5678     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5679     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5680     int outframes;
5681     int samples;
5682     int push;
5683     int i;
5684     int j;
5685 
5686     /*
5687         III.5.4.3.20    1300Hz calling tone discrimination
5688         Purpose:        To confirm correct detection of 1300Hz calling tones as defined in ITU-T V.25.
5689         Preamble:       N/A
5690         Method:         The tester will send 1300Hz bursts of (a) 400ms, (b) 500ms, (c) 700ms and
5691                         (d) 800ms followed by 1s of silence.
5692         Pass criteria:  1) The TUT should not respond to bursts of 400ms or 800ms.
5693                         2) The TUT should immediately begin probing after a burst of 1300Hz for 500ms or
5694                            700ms followed by 1s of silence.
5695         Comments:       The probe sent by the TUT will depend on the country setting.
5696      */
5697     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_20_put_text_msg, (void *) (intptr_t) 0);
5698     logging = v18_get_logging_state(v18[TESTER]);
5699     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5700     span_log_set_tag(logging, "Tester");
5701     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_20_put_text_msg, (void *) (intptr_t) 1);
5702     logging = v18_get_logging_state(v18[TUT]);
5703     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5704     span_log_set_tag(logging, "TUT");
5705 
5706     if ((model = both_ways_line_model_init(line_model_no,
5707                                            noise_level,
5708                                            echo_level_cpe1,
5709                                            echo_level_co1,
5710                                            line_model_no,
5711                                            noise_level,
5712                                            echo_level_cpe2,
5713                                            echo_level_co2,
5714                                            channel_codec,
5715                                            rbs_pattern)) == NULL)
5716     {
5717         fprintf(stderr, "    Failed to create line model\n");
5718         exit(2);
5719     }
5720 
5721     result[TESTER][0] =
5722     result[TUT][0] = '\0';
5723     for (i = 0;  i < 10000;  i++)
5724     {
5725         for (j = 0;  j < 2;  j++)
5726         {
5727             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5728                 push = 10;
5729             if (samples < SAMPLES_PER_CHUNK)
5730             {
5731                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5732                 samples = SAMPLES_PER_CHUNK;
5733             }
5734         }
5735         if (log_audio)
5736         {
5737             for (j = 0;  j < samples;  j++)
5738             {
5739                 out_amp[2*j + 0] = amp[0][j];
5740                 out_amp[2*j + 1] = amp[1][j];
5741             }
5742             outframes = sf_writef_short(outhandle, out_amp, samples);
5743             if (outframes != samples)
5744             {
5745                 fprintf(stderr, "    Error writing audio file\n");
5746                 exit(2);
5747             }
5748         }
5749 #if 1
5750         both_ways_line_model(model,
5751                              model_amp[0],
5752                              amp[0],
5753                              model_amp[1],
5754                              amp[1],
5755                              samples);
5756 #else
5757         vec_copyi16(model_amp[0], amp[0], samples);
5758         vec_copyi16(model_amp[1], amp[1], samples);
5759 #endif
5760         v18_rx(v18[TESTER], model_amp[1], samples);
5761         v18_rx(v18[TUT], model_amp[0], samples);
5762     }
5763 
5764     v18_free(v18[TESTER]);
5765     v18_free(v18[TUT]);
5766     printf("Test not yet implemented\n");
5767     return 1;
5768 }
5769 /*- End of function --------------------------------------------------------*/
5770 
ans_21_put_text_msg(void * user_data,const uint8_t * msg,int len)5771 static void ans_21_put_text_msg(void *user_data, const uint8_t *msg, int len)
5772 {
5773 }
5774 /*- End of function --------------------------------------------------------*/
5775 
test_ans_21(void)5776 static int test_ans_21(void)
5777 {
5778     logging_state_t *logging;
5779     int16_t amp[2][SAMPLES_PER_CHUNK];
5780     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5781     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5782     int outframes;
5783     int samples;
5784     int push;
5785     int i;
5786     int j;
5787 
5788     /*
5789         III.5.4.3.21    V.23 Reverse mode (1300Hz) detection
5790         Purpose:        To ensure correct detection and selection of V.23 reverse mode.
5791         Preamble:       N/A
5792         Method:         The tester sends 1300Hz only, with no XCI signals, to TUT for 5s.
5793                         Pass criteria: The TUT should respond with 390Hz after 1.7+-0.1s.
5794         Comments:       The TUT should indicate that V.23 mode has been selected.
5795      */
5796     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_21_put_text_msg, (void *) (intptr_t) 0);
5797     logging = v18_get_logging_state(v18[TESTER]);
5798     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5799     span_log_set_tag(logging, "Tester");
5800     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_21_put_text_msg, (void *) (intptr_t) 1);
5801     logging = v18_get_logging_state(v18[TUT]);
5802     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5803     span_log_set_tag(logging, "TUT");
5804 
5805     if ((model = both_ways_line_model_init(line_model_no,
5806                                            noise_level,
5807                                            echo_level_cpe1,
5808                                            echo_level_co1,
5809                                            line_model_no,
5810                                            noise_level,
5811                                            echo_level_cpe2,
5812                                            echo_level_co2,
5813                                            channel_codec,
5814                                            rbs_pattern)) == NULL)
5815     {
5816         fprintf(stderr, "    Failed to create line model\n");
5817         exit(2);
5818     }
5819 
5820     result[TESTER][0] =
5821     result[TUT][0] = '\0';
5822     for (i = 0;  i < 10000;  i++)
5823     {
5824         for (j = 0;  j < 2;  j++)
5825         {
5826             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5827                 push = 10;
5828             if (samples < SAMPLES_PER_CHUNK)
5829             {
5830                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5831                 samples = SAMPLES_PER_CHUNK;
5832             }
5833         }
5834         if (log_audio)
5835         {
5836             for (j = 0;  j < samples;  j++)
5837             {
5838                 out_amp[2*j + 0] = amp[0][j];
5839                 out_amp[2*j + 1] = amp[1][j];
5840             }
5841             outframes = sf_writef_short(outhandle, out_amp, samples);
5842             if (outframes != samples)
5843             {
5844                 fprintf(stderr, "    Error writing audio file\n");
5845                 exit(2);
5846             }
5847         }
5848 #if 1
5849         both_ways_line_model(model,
5850                              model_amp[0],
5851                              amp[0],
5852                              model_amp[1],
5853                              amp[1],
5854                              samples);
5855 #else
5856         vec_copyi16(model_amp[0], amp[0], samples);
5857         vec_copyi16(model_amp[1], amp[1], samples);
5858 #endif
5859         v18_rx(v18[TESTER], model_amp[1], samples);
5860         v18_rx(v18[TUT], model_amp[0], samples);
5861     }
5862 
5863     v18_free(v18[TESTER]);
5864     v18_free(v18[TUT]);
5865     printf("Test not yet implemented\n");
5866     return 1;
5867 }
5868 /*- End of function --------------------------------------------------------*/
5869 
ans_22_put_text_msg(void * user_data,const uint8_t * msg,int len)5870 static void ans_22_put_text_msg(void *user_data, const uint8_t *msg, int len)
5871 {
5872 }
5873 /*- End of function --------------------------------------------------------*/
5874 
test_ans_22(void)5875 static int test_ans_22(void)
5876 {
5877     logging_state_t *logging;
5878     int16_t amp[2][SAMPLES_PER_CHUNK];
5879     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5880     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5881     int outframes;
5882     int samples;
5883     int push;
5884     int i;
5885     int j;
5886 
5887     /*
5888         III.5.4.3.22    1300Hz with XCI test
5889         Purpose:        To ensure correct detection of the XCI signal and selection of V.18 mode.
5890         Preamble:       N/A
5891         Method:         The tester sends XCI signal as defined in 3.11. On reception of ANS it will become
5892                         silent for 500ms then transmit the TXP signal in V.21 (1) mode.
5893         Pass criteria:  The TUT should respond with TXP using V.21 (2) and select V.18 mode.
5894      */
5895     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_22_put_text_msg, (void *) (intptr_t) 0);
5896     logging = v18_get_logging_state(v18[TESTER]);
5897     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5898     span_log_set_tag(logging, "Tester");
5899     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_22_put_text_msg, (void *) (intptr_t) 1);
5900     logging = v18_get_logging_state(v18[TUT]);
5901     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
5902     span_log_set_tag(logging, "TUT");
5903 
5904     if ((model = both_ways_line_model_init(line_model_no,
5905                                            noise_level,
5906                                            echo_level_cpe1,
5907                                            echo_level_co1,
5908                                            line_model_no,
5909                                            noise_level,
5910                                            echo_level_cpe2,
5911                                            echo_level_co2,
5912                                            channel_codec,
5913                                            rbs_pattern)) == NULL)
5914     {
5915         fprintf(stderr, "    Failed to create line model\n");
5916         exit(2);
5917     }
5918 
5919     result[TESTER][0] =
5920     result[TUT][0] = '\0';
5921     for (i = 0;  i < 10000;  i++)
5922     {
5923         for (j = 0;  j < 2;  j++)
5924         {
5925             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
5926                 push = 10;
5927             if (samples < SAMPLES_PER_CHUNK)
5928             {
5929                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
5930                 samples = SAMPLES_PER_CHUNK;
5931             }
5932         }
5933         if (log_audio)
5934         {
5935             for (j = 0;  j < samples;  j++)
5936             {
5937                 out_amp[2*j + 0] = amp[0][j];
5938                 out_amp[2*j + 1] = amp[1][j];
5939             }
5940             outframes = sf_writef_short(outhandle, out_amp, samples);
5941             if (outframes != samples)
5942             {
5943                 fprintf(stderr, "    Error writing audio file\n");
5944                 exit(2);
5945             }
5946         }
5947 #if 1
5948         both_ways_line_model(model,
5949                              model_amp[0],
5950                              amp[0],
5951                              model_amp[1],
5952                              amp[1],
5953                              samples);
5954 #else
5955         vec_copyi16(model_amp[0], amp[0], samples);
5956         vec_copyi16(model_amp[1], amp[1], samples);
5957 #endif
5958         v18_rx(v18[TESTER], model_amp[1], samples);
5959         v18_rx(v18[TUT], model_amp[0], samples);
5960     }
5961 
5962     v18_free(v18[TESTER]);
5963     v18_free(v18[TUT]);
5964     printf("Test not yet implemented\n");
5965     return 1;
5966 }
5967 /*- End of function --------------------------------------------------------*/
5968 
ans_23_put_text_msg(void * user_data,const uint8_t * msg,int len)5969 static void ans_23_put_text_msg(void *user_data, const uint8_t *msg, int len)
5970 {
5971 }
5972 /*- End of function --------------------------------------------------------*/
5973 
test_ans_23(void)5974 static int test_ans_23(void)
5975 {
5976     logging_state_t *logging;
5977     int16_t amp[2][SAMPLES_PER_CHUNK];
5978     int16_t model_amp[2][SAMPLES_PER_CHUNK];
5979     int16_t out_amp[2*SAMPLES_PER_CHUNK];
5980     int outframes;
5981     int samples;
5982     int push;
5983     int i;
5984     int j;
5985 
5986     /*
5987         III.5.4.3.23    Stimulate mode country settings
5988         Purpose:        To ensure that the TUT steps through the probes in the specified order for the
5989                         country selected.
5990         Preamble:       The TUT should be configured for each of the possible probe orders specified in
5991                         Appendix I in turn.
5992         Method:         The tester will call the TUT, wait for Ta to expire and then monitor the probes sent
5993                         by the TUT.
5994         Pass criteria:  The TUT should use the orders described in Appendix I.
5995         Comments:       The order of the probes is not mandatory.
5996      */
5997     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_23_put_text_msg, (void *) (intptr_t) 0);
5998     logging = v18_get_logging_state(v18[TESTER]);
5999     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6000     span_log_set_tag(logging, "Tester");
6001     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_23_put_text_msg, (void *) (intptr_t) 1);
6002     logging = v18_get_logging_state(v18[TUT]);
6003     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6004     span_log_set_tag(logging, "TUT");
6005 
6006     if ((model = both_ways_line_model_init(line_model_no,
6007                                            noise_level,
6008                                            echo_level_cpe1,
6009                                            echo_level_co1,
6010                                            line_model_no,
6011                                            noise_level,
6012                                            echo_level_cpe2,
6013                                            echo_level_co2,
6014                                            channel_codec,
6015                                            rbs_pattern)) == NULL)
6016     {
6017         fprintf(stderr, "    Failed to create line model\n");
6018         exit(2);
6019     }
6020 
6021     result[TESTER][0] =
6022     result[TUT][0] = '\0';
6023     for (i = 0;  i < 10000;  i++)
6024     {
6025         for (j = 0;  j < 2;  j++)
6026         {
6027             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6028                 push = 10;
6029             if (samples < SAMPLES_PER_CHUNK)
6030             {
6031                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6032                 samples = SAMPLES_PER_CHUNK;
6033             }
6034         }
6035         if (log_audio)
6036         {
6037             for (j = 0;  j < samples;  j++)
6038             {
6039                 out_amp[2*j + 0] = amp[0][j];
6040                 out_amp[2*j + 1] = amp[1][j];
6041             }
6042             outframes = sf_writef_short(outhandle, out_amp, samples);
6043             if (outframes != samples)
6044             {
6045                 fprintf(stderr, "    Error writing audio file\n");
6046                 exit(2);
6047             }
6048         }
6049 #if 1
6050         both_ways_line_model(model,
6051                              model_amp[0],
6052                              amp[0],
6053                              model_amp[1],
6054                              amp[1],
6055                              samples);
6056 #else
6057         vec_copyi16(model_amp[0], amp[0], samples);
6058         vec_copyi16(model_amp[1], amp[1], samples);
6059 #endif
6060         v18_rx(v18[TESTER], model_amp[1], samples);
6061         v18_rx(v18[TUT], model_amp[0], samples);
6062     }
6063 
6064     v18_free(v18[TESTER]);
6065     v18_free(v18[TUT]);
6066     printf("Test not yet implemented\n");
6067     return 1;
6068 }
6069 /*- End of function --------------------------------------------------------*/
6070 
ans_24_put_text_msg(void * user_data,const uint8_t * msg,int len)6071 static void ans_24_put_text_msg(void *user_data, const uint8_t *msg, int len)
6072 {
6073 }
6074 /*- End of function --------------------------------------------------------*/
6075 
test_ans_24(void)6076 static int test_ans_24(void)
6077 {
6078     logging_state_t *logging;
6079     int16_t amp[2][SAMPLES_PER_CHUNK];
6080     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6081     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6082     int outframes;
6083     int samples;
6084     int push;
6085     int i;
6086     int j;
6087 
6088     /*
6089         III.5.4.3.24    Stimulate carrierless mode probe message
6090         Purpose:        To ensure that the TUT sends the correct probe message for each of the carrierless
6091                         modes.
6092         Preamble:       N/A
6093         Method:         The tester will call the TUT, wait for Ta to expire and then monitor the probes sent
6094                         by the TUT.
6095         Pass criteria:  The TUT should send the user defined probe message for Annexes A, B, and C
6096                         modes followed by a pause of Tm (default 3)s.
6097         Comments:       The carrierless modes are those described in Annexes A, B and C.
6098      */
6099     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_24_put_text_msg, (void *) (intptr_t) 0);
6100     logging = v18_get_logging_state(v18[TESTER]);
6101     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6102     span_log_set_tag(logging, "Tester");
6103     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_24_put_text_msg, (void *) (intptr_t) 1);
6104     logging = v18_get_logging_state(v18[TUT]);
6105     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6106     span_log_set_tag(logging, "TUT");
6107 
6108     if ((model = both_ways_line_model_init(line_model_no,
6109                                            noise_level,
6110                                            echo_level_cpe1,
6111                                            echo_level_co1,
6112                                            line_model_no,
6113                                            noise_level,
6114                                            echo_level_cpe2,
6115                                            echo_level_co2,
6116                                            channel_codec,
6117                                            rbs_pattern)) == NULL)
6118     {
6119         fprintf(stderr, "    Failed to create line model\n");
6120         exit(2);
6121     }
6122 
6123     result[TESTER][0] =
6124     result[TUT][0] = '\0';
6125     for (i = 0;  i < 10000;  i++)
6126     {
6127         for (j = 0;  j < 2;  j++)
6128         {
6129             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6130                 push = 10;
6131             if (samples < SAMPLES_PER_CHUNK)
6132             {
6133                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6134                 samples = SAMPLES_PER_CHUNK;
6135             }
6136         }
6137         if (log_audio)
6138         {
6139             for (j = 0;  j < samples;  j++)
6140             {
6141                 out_amp[2*j + 0] = amp[0][j];
6142                 out_amp[2*j + 1] = amp[1][j];
6143             }
6144             outframes = sf_writef_short(outhandle, out_amp, samples);
6145             if (outframes != samples)
6146             {
6147                 fprintf(stderr, "    Error writing audio file\n");
6148                 exit(2);
6149             }
6150         }
6151 #if 1
6152         both_ways_line_model(model,
6153                              model_amp[0],
6154                              amp[0],
6155                              model_amp[1],
6156                              amp[1],
6157                              samples);
6158 #else
6159         vec_copyi16(model_amp[0], amp[0], samples);
6160         vec_copyi16(model_amp[1], amp[1], samples);
6161 #endif
6162         v18_rx(v18[TESTER], model_amp[1], samples);
6163         v18_rx(v18[TUT], model_amp[0], samples);
6164     }
6165 
6166     v18_free(v18[TESTER]);
6167     v18_free(v18[TUT]);
6168     printf("Test not yet implemented\n");
6169     return 1;
6170 }
6171 /*- End of function --------------------------------------------------------*/
6172 
ans_25_put_text_msg(void * user_data,const uint8_t * msg,int len)6173 static void ans_25_put_text_msg(void *user_data, const uint8_t *msg, int len)
6174 {
6175 }
6176 /*- End of function --------------------------------------------------------*/
6177 
test_ans_25(void)6178 static int test_ans_25(void)
6179 {
6180     logging_state_t *logging;
6181     int16_t amp[2][SAMPLES_PER_CHUNK];
6182     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6183     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6184     int outframes;
6185     int samples;
6186     int push;
6187     int i;
6188     int j;
6189 
6190     /*
6191         III.5.4.3.25    Interrupted carrierless mode probe
6192         Purpose:        To ensure that the TUT continues probing from the point of interruption a maximum
6193                         of 20s after a failed connect attempt.
6194         Preamble:       The TUT should be configured for the UK country setting.
6195         Method:         The tester will call the TUT, wait for Ta to expire and then during the pause after
6196                         the first Baudot probe it will send a 200ms burst of 1270Hz followed by silence
6197                         for 30s.
6198         Pass criteria:  The TUT should transmit silence on detecting the 1270Hz tone and then continue
6199                         probing starting with the V.23 probe 20s after the end of the 1270Hz signal.
6200      */
6201     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_25_put_text_msg, (void *) (intptr_t) 0);
6202     logging = v18_get_logging_state(v18[TESTER]);
6203     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6204     span_log_set_tag(logging, "Tester");
6205     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_25_put_text_msg, (void *) (intptr_t) 1);
6206     logging = v18_get_logging_state(v18[TUT]);
6207     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6208     span_log_set_tag(logging, "TUT");
6209 
6210     if ((model = both_ways_line_model_init(line_model_no,
6211                                            noise_level,
6212                                            echo_level_cpe1,
6213                                            echo_level_co1,
6214                                            line_model_no,
6215                                            noise_level,
6216                                            echo_level_cpe2,
6217                                            echo_level_co2,
6218                                            channel_codec,
6219                                            rbs_pattern)) == NULL)
6220     {
6221         fprintf(stderr, "    Failed to create line model\n");
6222         exit(2);
6223     }
6224 
6225     result[TESTER][0] =
6226     result[TUT][0] = '\0';
6227     for (i = 0;  i < 10000;  i++)
6228     {
6229         for (j = 0;  j < 2;  j++)
6230         {
6231             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6232                 push = 10;
6233             if (samples < SAMPLES_PER_CHUNK)
6234             {
6235                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6236                 samples = SAMPLES_PER_CHUNK;
6237             }
6238         }
6239         if (log_audio)
6240         {
6241             for (j = 0;  j < samples;  j++)
6242             {
6243                 out_amp[2*j + 0] = amp[0][j];
6244                 out_amp[2*j + 1] = amp[1][j];
6245             }
6246             outframes = sf_writef_short(outhandle, out_amp, samples);
6247             if (outframes != samples)
6248             {
6249                 fprintf(stderr, "    Error writing audio file\n");
6250                 exit(2);
6251             }
6252         }
6253 #if 1
6254         both_ways_line_model(model,
6255                              model_amp[0],
6256                              amp[0],
6257                              model_amp[1],
6258                              amp[1],
6259                              samples);
6260 #else
6261         vec_copyi16(model_amp[0], amp[0], samples);
6262         vec_copyi16(model_amp[1], amp[1], samples);
6263 #endif
6264         v18_rx(v18[TESTER], model_amp[1], samples);
6265         v18_rx(v18[TUT], model_amp[0], samples);
6266     }
6267 
6268     v18_free(v18[TESTER]);
6269     v18_free(v18[TUT]);
6270     printf("Test not yet implemented\n");
6271     return 1;
6272 }
6273 /*- End of function --------------------------------------------------------*/
6274 
ans_26_put_text_msg(void * user_data,const uint8_t * msg,int len)6275 static void ans_26_put_text_msg(void *user_data, const uint8_t *msg, int len)
6276 {
6277 }
6278 /*- End of function --------------------------------------------------------*/
6279 
test_ans_26(void)6280 static int test_ans_26(void)
6281 {
6282     logging_state_t *logging;
6283     int16_t amp[2][SAMPLES_PER_CHUNK];
6284     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6285     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6286     int outframes;
6287     int samples;
6288     int push;
6289     int i;
6290     int j;
6291 
6292     /*
6293         III.5.4.3.26    Stimulate carrier mode probe time
6294         Purpose:        To ensure that the TUT sends each carrier mode for time Tc (default 6s)
6295                         preceded by the correct answer tone.
6296         Preamble:       None.
6297         Method:         The tester will call the TUT, wait for Ta to expire and then monitor the probes sent
6298                         by the TUT.
6299         Pass criteria:  The TUT should send the ANS tone (2100Hz) for 1s followed by silence for
6300                         75+-5ms and then the 1650Hz, 1300Hz and 2225Hz probes for time Tc.
6301         Comments:       The carrier modes are those described in Annexes D, E, and F.
6302      */
6303     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_26_put_text_msg, (void *) (intptr_t) 0);
6304     logging = v18_get_logging_state(v18[TESTER]);
6305     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6306     span_log_set_tag(logging, "Tester");
6307     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_26_put_text_msg, (void *) (intptr_t) 1);
6308     logging = v18_get_logging_state(v18[TUT]);
6309     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6310     span_log_set_tag(logging, "TUT");
6311 
6312     if ((model = both_ways_line_model_init(line_model_no,
6313                                            noise_level,
6314                                            echo_level_cpe1,
6315                                            echo_level_co1,
6316                                            line_model_no,
6317                                            noise_level,
6318                                            echo_level_cpe2,
6319                                            echo_level_co2,
6320                                            channel_codec,
6321                                            rbs_pattern)) == NULL)
6322     {
6323         fprintf(stderr, "    Failed to create line model\n");
6324         exit(2);
6325     }
6326 
6327     result[TESTER][0] =
6328     result[TUT][0] = '\0';
6329     for (i = 0;  i < 10000;  i++)
6330     {
6331         for (j = 0;  j < 2;  j++)
6332         {
6333             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6334                 push = 10;
6335             if (samples < SAMPLES_PER_CHUNK)
6336             {
6337                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6338                 samples = SAMPLES_PER_CHUNK;
6339             }
6340         }
6341         if (log_audio)
6342         {
6343             for (j = 0;  j < samples;  j++)
6344             {
6345                 out_amp[2*j + 0] = amp[0][j];
6346                 out_amp[2*j + 1] = amp[1][j];
6347             }
6348             outframes = sf_writef_short(outhandle, out_amp, samples);
6349             if (outframes != samples)
6350             {
6351                 fprintf(stderr, "    Error writing audio file\n");
6352                 exit(2);
6353             }
6354         }
6355 #if 1
6356         both_ways_line_model(model,
6357                              model_amp[0],
6358                              amp[0],
6359                              model_amp[1],
6360                              amp[1],
6361                              samples);
6362 #else
6363         vec_copyi16(model_amp[0], amp[0], samples);
6364         vec_copyi16(model_amp[1], amp[1], samples);
6365 #endif
6366         v18_rx(v18[TESTER], model_amp[1], samples);
6367         v18_rx(v18[TUT], model_amp[0], samples);
6368     }
6369 
6370     v18_free(v18[TESTER]);
6371     v18_free(v18[TUT]);
6372     printf("Test not yet implemented\n");
6373     return 1;
6374 }
6375 /*- End of function --------------------------------------------------------*/
6376 
ans_27_put_text_msg(void * user_data,const uint8_t * msg,int len)6377 static void ans_27_put_text_msg(void *user_data, const uint8_t *msg, int len)
6378 {
6379 }
6380 /*- End of function --------------------------------------------------------*/
6381 
test_ans_27(void)6382 static int test_ans_27(void)
6383 {
6384     logging_state_t *logging;
6385     int16_t amp[2][SAMPLES_PER_CHUNK];
6386     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6387     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6388     int outframes;
6389     int samples;
6390     int push;
6391     int i;
6392     int j;
6393 
6394     /*
6395         III.5.4.3.27    V.23 mode (390Hz) detection
6396         Purpose:        To confirm correct selection of V.23 mode.
6397         Preamble:       N/A
6398         Method:         The tester waits until the 1300Hz probe is detected from the TUT and then
6399                         transmits 390Hz for 11s.
6400         Pass criteria:  1) After 3s of the 390Hz signal the TUT should indicate that V.23 has
6401                            been selected.
6402                         2) The tester will confirm that the 1300Hz carrier is maintained for at least
6403                            4s beyond the normal probe duration, i.e. Tc (= 6s default) + 4s =
6404                            10s total.
6405         Comments:       All known V.23 devices need to receive 1300Hz tone before they will respond with
6406                         390Hz. When the 1300Hz probe is not being transmitted, a 390Hz tone may be
6407                         interpreted as a 400Hz network tone.
6408      */
6409     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_27_put_text_msg, (void *) (intptr_t) 0);
6410     logging = v18_get_logging_state(v18[TESTER]);
6411     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6412     span_log_set_tag(logging, "Tester");
6413     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_27_put_text_msg, (void *) (intptr_t) 1);
6414     logging = v18_get_logging_state(v18[TUT]);
6415     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6416     span_log_set_tag(logging, "TUT");
6417 
6418     if ((model = both_ways_line_model_init(line_model_no,
6419                                            noise_level,
6420                                            echo_level_cpe1,
6421                                            echo_level_co1,
6422                                            line_model_no,
6423                                            noise_level,
6424                                            echo_level_cpe2,
6425                                            echo_level_co2,
6426                                            channel_codec,
6427                                            rbs_pattern)) == NULL)
6428     {
6429         fprintf(stderr, "    Failed to create line model\n");
6430         exit(2);
6431     }
6432 
6433     result[TESTER][0] =
6434     result[TUT][0] = '\0';
6435     for (i = 0;  i < 10000;  i++)
6436     {
6437         for (j = 0;  j < 2;  j++)
6438         {
6439             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6440                 push = 10;
6441             if (samples < SAMPLES_PER_CHUNK)
6442             {
6443                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6444                 samples = SAMPLES_PER_CHUNK;
6445             }
6446         }
6447         if (log_audio)
6448         {
6449             for (j = 0;  j < samples;  j++)
6450             {
6451                 out_amp[2*j + 0] = amp[0][j];
6452                 out_amp[2*j + 1] = amp[1][j];
6453             }
6454             outframes = sf_writef_short(outhandle, out_amp, samples);
6455             if (outframes != samples)
6456             {
6457                 fprintf(stderr, "    Error writing audio file\n");
6458                 exit(2);
6459             }
6460         }
6461 #if 1
6462         both_ways_line_model(model,
6463                              model_amp[0],
6464                              amp[0],
6465                              model_amp[1],
6466                              amp[1],
6467                              samples);
6468 #else
6469         vec_copyi16(model_amp[0], amp[0], samples);
6470         vec_copyi16(model_amp[1], amp[1], samples);
6471 #endif
6472         v18_rx(v18[TESTER], model_amp[1], samples);
6473         v18_rx(v18[TUT], model_amp[0], samples);
6474     }
6475 
6476     v18_free(v18[TESTER]);
6477     v18_free(v18[TUT]);
6478     printf("Test not yet implemented\n");
6479     return 1;
6480 }
6481 /*- End of function --------------------------------------------------------*/
6482 
ans_28_put_text_msg(void * user_data,const uint8_t * msg,int len)6483 static void ans_28_put_text_msg(void *user_data, const uint8_t *msg, int len)
6484 {
6485 }
6486 /*- End of function --------------------------------------------------------*/
6487 
test_ans_28(void)6488 static int test_ans_28(void)
6489 {
6490     logging_state_t *logging;
6491     int16_t amp[2][SAMPLES_PER_CHUNK];
6492     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6493     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6494     int outframes;
6495     int samples;
6496     int push;
6497     int i;
6498     int j;
6499 
6500     /*
6501         III.5.4.3.28    Interrupted carrier mode probe
6502         Purpose:        To ensure that the TUT continues probing from the point of interruption a maximum
6503                         of 4s after a failed connect attempt.
6504         Preamble:       The TUT should be configured for the UK country setting.
6505         Method:         The tester will call the TUT, wait for Ta to expire and then during the first V.21
6506                         probe it will send a 200ms burst of 1270Hz followed by silence for 30s.
6507         Pass criteria:  The TUT should transmit silence on detecting the 1270Hz tone and then continue
6508                         probing with the Baudot stored message 4s after the end of the 1270Hz
6509                         burst.
6510         Comments:       It is most likely that the TUT will return to probing time Ta (3s) after the
6511                         1270Hz tone ceases. This condition needs further clarification.
6512      */
6513     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_28_put_text_msg, (void *) (intptr_t) 0);
6514     logging = v18_get_logging_state(v18[TESTER]);
6515     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6516     span_log_set_tag(logging, "Tester");
6517     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_28_put_text_msg, (void *) (intptr_t) 1);
6518     logging = v18_get_logging_state(v18[TUT]);
6519     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6520     span_log_set_tag(logging, "TUT");
6521 
6522     if ((model = both_ways_line_model_init(line_model_no,
6523                                            noise_level,
6524                                            echo_level_cpe1,
6525                                            echo_level_co1,
6526                                            line_model_no,
6527                                            noise_level,
6528                                            echo_level_cpe2,
6529                                            echo_level_co2,
6530                                            channel_codec,
6531                                            rbs_pattern)) == NULL)
6532     {
6533         fprintf(stderr, "    Failed to create line model\n");
6534         exit(2);
6535     }
6536 
6537     result[TESTER][0] =
6538     result[TUT][0] = '\0';
6539     for (i = 0;  i < 10000;  i++)
6540     {
6541         for (j = 0;  j < 2;  j++)
6542         {
6543             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6544                 push = 10;
6545             if (samples < SAMPLES_PER_CHUNK)
6546             {
6547                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6548                 samples = SAMPLES_PER_CHUNK;
6549             }
6550         }
6551         if (log_audio)
6552         {
6553             for (j = 0;  j < samples;  j++)
6554             {
6555                 out_amp[2*j + 0] = amp[0][j];
6556                 out_amp[2*j + 1] = amp[1][j];
6557             }
6558             outframes = sf_writef_short(outhandle, out_amp, samples);
6559             if (outframes != samples)
6560             {
6561                 fprintf(stderr, "    Error writing audio file\n");
6562                 exit(2);
6563             }
6564         }
6565 #if 1
6566         both_ways_line_model(model,
6567                              model_amp[0],
6568                              amp[0],
6569                              model_amp[1],
6570                              amp[1],
6571                              samples);
6572 #else
6573         vec_copyi16(model_amp[0], amp[0], samples);
6574         vec_copyi16(model_amp[1], amp[1], samples);
6575 #endif
6576         v18_rx(v18[TESTER], model_amp[1], samples);
6577         v18_rx(v18[TUT], model_amp[0], samples);
6578     }
6579 
6580     v18_free(v18[TESTER]);
6581     v18_free(v18[TUT]);
6582     printf("Test not yet implemented\n");
6583     return 1;
6584 }
6585 /*- End of function --------------------------------------------------------*/
6586 
ans_29_put_text_msg(void * user_data,const uint8_t * msg,int len)6587 static void ans_29_put_text_msg(void *user_data, const uint8_t *msg, int len)
6588 {
6589 }
6590 /*- End of function --------------------------------------------------------*/
6591 
test_ans_29(void)6592 static int test_ans_29(void)
6593 {
6594     logging_state_t *logging;
6595     int16_t amp[2][SAMPLES_PER_CHUNK];
6596     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6597     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6598     int outframes;
6599     int samples;
6600     int push;
6601     int i;
6602     int j;
6603 
6604     /*
6605         III.5.4.3.29    Stimulate mode response during probe
6606         Purpose:        To ensure that the TUT is able to detect an incoming signal while transmitting a
6607                         carrier mode probe.
6608         Preamble:       N/A
6609         Method:         The tester will step through each possible response as defined in tests ANS-08 to
6610                         ANS-23 for each of the carrier mode probes and for each pause after a carrierless
6611                         mode probe message.
6612         Pass criteria:  The TUT should respond as described in the appropriate test above.
6613         Comments:       The TUT may not respond to any signals while a carrierless mode probe is being
6614                         sent since these modes are half duplex.
6615      */
6616     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_29_put_text_msg, (void *) (intptr_t) 0);
6617     logging = v18_get_logging_state(v18[TESTER]);
6618     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6619     span_log_set_tag(logging, "Tester");
6620     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_29_put_text_msg, (void *) (intptr_t) 1);
6621     logging = v18_get_logging_state(v18[TUT]);
6622     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6623     span_log_set_tag(logging, "TUT");
6624 
6625     if ((model = both_ways_line_model_init(line_model_no,
6626                                            noise_level,
6627                                            echo_level_cpe1,
6628                                            echo_level_co1,
6629                                            line_model_no,
6630                                            noise_level,
6631                                            echo_level_cpe2,
6632                                            echo_level_co2,
6633                                            channel_codec,
6634                                            rbs_pattern)) == NULL)
6635     {
6636         fprintf(stderr, "    Failed to create line model\n");
6637         exit(2);
6638     }
6639 
6640     result[TESTER][0] =
6641     result[TUT][0] = '\0';
6642     for (i = 0;  i < 10000;  i++)
6643     {
6644         for (j = 0;  j < 2;  j++)
6645         {
6646             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6647                 push = 10;
6648             if (samples < SAMPLES_PER_CHUNK)
6649             {
6650                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6651                 samples = SAMPLES_PER_CHUNK;
6652             }
6653         }
6654         if (log_audio)
6655         {
6656             for (j = 0;  j < samples;  j++)
6657             {
6658                 out_amp[2*j + 0] = amp[0][j];
6659                 out_amp[2*j + 1] = amp[1][j];
6660             }
6661             outframes = sf_writef_short(outhandle, out_amp, samples);
6662             if (outframes != samples)
6663             {
6664                 fprintf(stderr, "    Error writing audio file\n");
6665                 exit(2);
6666             }
6667         }
6668 #if 1
6669         both_ways_line_model(model,
6670                              model_amp[0],
6671                              amp[0],
6672                              model_amp[1],
6673                              amp[1],
6674                              samples);
6675 #else
6676         vec_copyi16(model_amp[0], amp[0], samples);
6677         vec_copyi16(model_amp[1], amp[1], samples);
6678 #endif
6679         v18_rx(v18[TESTER], model_amp[1], samples);
6680         v18_rx(v18[TUT], model_amp[0], samples);
6681     }
6682 
6683     v18_free(v18[TESTER]);
6684     v18_free(v18[TUT]);
6685     printf("Test not yet implemented\n");
6686     return 1;
6687 }
6688 /*- End of function --------------------------------------------------------*/
6689 
ans_30_put_text_msg(void * user_data,const uint8_t * msg,int len)6690 static void ans_30_put_text_msg(void *user_data, const uint8_t *msg, int len)
6691 {
6692 }
6693 /*- End of function --------------------------------------------------------*/
6694 
test_ans_30(void)6695 static int test_ans_30(void)
6696 {
6697     logging_state_t *logging;
6698     int16_t amp[2][SAMPLES_PER_CHUNK];
6699     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6700     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6701     int outframes;
6702     int samples;
6703     int push;
6704     int i;
6705     int j;
6706 
6707     /*
6708         III.5.4.3.30    Immunity to network tones
6709         Purpose:        To ensure that the TUT does not interpret network tones as valid signals.
6710         Preamble:       N/A
6711         Method:         The tester will first send a busy tone to the TUT this will be followed by a number
6712                         unobtainable tone. The frequencies and cadences of the tones will vary according to
6713                         the country setting. The tester must be configured for the same country as the TUT.
6714         Pass criteria:  The countries supported by the TUT should be noted along with the response to
6715                         each tone. The tones should either be ignored or reported as the relevant network
6716                         tone to the user.
6717         Comments:       V.18 is required to recognize and report RINGING and BUSY tones. Other network
6718                         tones may be ignored. Some devices may only provide a visual indication of the
6719                         presence and cadence of the tones for instance by a flashing light.
6720      */
6721     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_30_put_text_msg, (void *) (intptr_t) 0);
6722     logging = v18_get_logging_state(v18[TESTER]);
6723     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6724     span_log_set_tag(logging, "Tester");
6725     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_30_put_text_msg, (void *) (intptr_t) 1);
6726     logging = v18_get_logging_state(v18[TUT]);
6727     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6728     span_log_set_tag(logging, "TUT");
6729 
6730     if ((model = both_ways_line_model_init(line_model_no,
6731                                            noise_level,
6732                                            echo_level_cpe1,
6733                                            echo_level_co1,
6734                                            line_model_no,
6735                                            noise_level,
6736                                            echo_level_cpe2,
6737                                            echo_level_co2,
6738                                            channel_codec,
6739                                            rbs_pattern)) == NULL)
6740     {
6741         fprintf(stderr, "    Failed to create line model\n");
6742         exit(2);
6743     }
6744 
6745     result[TESTER][0] =
6746     result[TUT][0] = '\0';
6747     for (i = 0;  i < 10000;  i++)
6748     {
6749         for (j = 0;  j < 2;  j++)
6750         {
6751             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6752                 push = 10;
6753             if (samples < SAMPLES_PER_CHUNK)
6754             {
6755                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6756                 samples = SAMPLES_PER_CHUNK;
6757             }
6758         }
6759         if (log_audio)
6760         {
6761             for (j = 0;  j < samples;  j++)
6762             {
6763                 out_amp[2*j + 0] = amp[0][j];
6764                 out_amp[2*j + 1] = amp[1][j];
6765             }
6766             outframes = sf_writef_short(outhandle, out_amp, samples);
6767             if (outframes != samples)
6768             {
6769                 fprintf(stderr, "    Error writing audio file\n");
6770                 exit(2);
6771             }
6772         }
6773 #if 1
6774         both_ways_line_model(model,
6775                              model_amp[0],
6776                              amp[0],
6777                              model_amp[1],
6778                              amp[1],
6779                              samples);
6780 #else
6781         vec_copyi16(model_amp[0], amp[0], samples);
6782         vec_copyi16(model_amp[1], amp[1], samples);
6783 #endif
6784         v18_rx(v18[TESTER], model_amp[1], samples);
6785         v18_rx(v18[TUT], model_amp[0], samples);
6786     }
6787 
6788     v18_free(v18[TESTER]);
6789     v18_free(v18[TUT]);
6790     printf("Test not yet implemented\n");
6791     return 1;
6792 }
6793 /*- End of function --------------------------------------------------------*/
6794 
ans_31_put_text_msg(void * user_data,const uint8_t * msg,int len)6795 static void ans_31_put_text_msg(void *user_data, const uint8_t *msg, int len)
6796 {
6797 }
6798 /*- End of function --------------------------------------------------------*/
6799 
test_ans_31(void)6800 static int test_ans_31(void)
6801 {
6802     logging_state_t *logging;
6803     int16_t amp[2][SAMPLES_PER_CHUNK];
6804     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6805     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6806     int outframes;
6807     int samples;
6808     int push;
6809     int i;
6810     int j;
6811 
6812     /*
6813         III.5.4.3.31    Immunity to fax calling tones
6814         Purpose:        To determine whether the TUT can discriminate fax calling tones.
6815         Preamble:       N/A
6816         Method:         The tester will call the TUT and send the fax calling tone, CNG. This is an 1100Hz
6817                         tone with cadence of 0.5s ON and 3s OFF as defined in ITU-T T.30.
6818         Pass criteria:  The TUT should not respond to this signal and may report it as being a calling fax
6819                         machine.
6820         Comments:       This is an optional test as detection of the fax calling tone is not required by
6821                         ITU-T V.18.
6822      */
6823     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_31_put_text_msg, (void *) (intptr_t) 0);
6824     logging = v18_get_logging_state(v18[TESTER]);
6825     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6826     span_log_set_tag(logging, "Tester");
6827     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_31_put_text_msg, (void *) (intptr_t) 1);
6828     logging = v18_get_logging_state(v18[TUT]);
6829     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6830     span_log_set_tag(logging, "TUT");
6831 
6832     if ((model = both_ways_line_model_init(line_model_no,
6833                                            noise_level,
6834                                            echo_level_cpe1,
6835                                            echo_level_co1,
6836                                            line_model_no,
6837                                            noise_level,
6838                                            echo_level_cpe2,
6839                                            echo_level_co2,
6840                                            channel_codec,
6841                                            rbs_pattern)) == NULL)
6842     {
6843         fprintf(stderr, "    Failed to create line model\n");
6844         exit(2);
6845     }
6846 
6847     result[TESTER][0] =
6848     result[TUT][0] = '\0';
6849     for (i = 0;  i < 10000;  i++)
6850     {
6851         for (j = 0;  j < 2;  j++)
6852         {
6853             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6854                 push = 10;
6855             if (samples < SAMPLES_PER_CHUNK)
6856             {
6857                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6858                 samples = SAMPLES_PER_CHUNK;
6859             }
6860         }
6861         if (log_audio)
6862         {
6863             for (j = 0;  j < samples;  j++)
6864             {
6865                 out_amp[2*j + 0] = amp[0][j];
6866                 out_amp[2*j + 1] = amp[1][j];
6867             }
6868             outframes = sf_writef_short(outhandle, out_amp, samples);
6869             if (outframes != samples)
6870             {
6871                 fprintf(stderr, "    Error writing audio file\n");
6872                 exit(2);
6873             }
6874         }
6875 #if 1
6876         both_ways_line_model(model,
6877                              model_amp[0],
6878                              amp[0],
6879                              model_amp[1],
6880                              amp[1],
6881                              samples);
6882 #else
6883         vec_copyi16(model_amp[0], amp[0], samples);
6884         vec_copyi16(model_amp[1], amp[1], samples);
6885 #endif
6886         v18_rx(v18[TESTER], model_amp[1], samples);
6887         v18_rx(v18[TUT], model_amp[0], samples);
6888     }
6889 
6890     v18_free(v18[TESTER]);
6891     v18_free(v18[TUT]);
6892     printf("Test not yet implemented\n");
6893     return 1;
6894 }
6895 /*- End of function --------------------------------------------------------*/
6896 
ans_32_put_text_msg(void * user_data,const uint8_t * msg,int len)6897 static void ans_32_put_text_msg(void *user_data, const uint8_t *msg, int len)
6898 {
6899 }
6900 /*- End of function --------------------------------------------------------*/
6901 
test_ans_32(void)6902 static int test_ans_32(void)
6903 {
6904     logging_state_t *logging;
6905     int16_t amp[2][SAMPLES_PER_CHUNK];
6906     int16_t model_amp[2][SAMPLES_PER_CHUNK];
6907     int16_t out_amp[2*SAMPLES_PER_CHUNK];
6908     int outframes;
6909     int samples;
6910     int push;
6911     int i;
6912     int j;
6913 
6914     /*
6915         III.5.4.3.32    Immunity to voice
6916         Purpose:        To ensure that the TUT does not misinterpret speech as a valid textphone signal.
6917         Preamble:       N/A
6918         Method:         The tester will respond with sampled speech. A number of phrases recorded from
6919                         typical male and female speakers will be transmitted. This will include a typical
6920                         network announcement.
6921         Pass criteria:  The TUT should ignore the speech.
6922         Comments:       Ideally the TUT should report the presence of speech back to the user. This is an
6923                         optional test.
6924      */
6925     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_32_put_text_msg, (void *) (intptr_t) 0);
6926     logging = v18_get_logging_state(v18[TESTER]);
6927     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6928     span_log_set_tag(logging, "Tester");
6929     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_32_put_text_msg, (void *) (intptr_t) 1);
6930     logging = v18_get_logging_state(v18[TUT]);
6931     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
6932     span_log_set_tag(logging, "TUT");
6933 
6934     if ((model = both_ways_line_model_init(line_model_no,
6935                                            noise_level,
6936                                            echo_level_cpe1,
6937                                            echo_level_co1,
6938                                            line_model_no,
6939                                            noise_level,
6940                                            echo_level_cpe2,
6941                                            echo_level_co2,
6942                                            channel_codec,
6943                                            rbs_pattern)) == NULL)
6944     {
6945         fprintf(stderr, "    Failed to create line model\n");
6946         exit(2);
6947     }
6948 
6949     result[TESTER][0] =
6950     result[TUT][0] = '\0';
6951     for (i = 0;  i < 10000;  i++)
6952     {
6953         for (j = 0;  j < 2;  j++)
6954         {
6955             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
6956                 push = 10;
6957             if (samples < SAMPLES_PER_CHUNK)
6958             {
6959                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
6960                 samples = SAMPLES_PER_CHUNK;
6961             }
6962         }
6963         if (log_audio)
6964         {
6965             for (j = 0;  j < samples;  j++)
6966             {
6967                 out_amp[2*j + 0] = amp[0][j];
6968                 out_amp[2*j + 1] = amp[1][j];
6969             }
6970             outframes = sf_writef_short(outhandle, out_amp, samples);
6971             if (outframes != samples)
6972             {
6973                 fprintf(stderr, "    Error writing audio file\n");
6974                 exit(2);
6975             }
6976         }
6977 #if 1
6978         both_ways_line_model(model,
6979                              model_amp[0],
6980                              amp[0],
6981                              model_amp[1],
6982                              amp[1],
6983                              samples);
6984 #else
6985         vec_copyi16(model_amp[0], amp[0], samples);
6986         vec_copyi16(model_amp[1], amp[1], samples);
6987 #endif
6988         v18_rx(v18[TESTER], model_amp[1], samples);
6989         v18_rx(v18[TUT], model_amp[0], samples);
6990     }
6991 
6992     v18_free(v18[TESTER]);
6993     v18_free(v18[TUT]);
6994     printf("Test not yet implemented\n");
6995     return 1;
6996 }
6997 /*- End of function --------------------------------------------------------*/
6998 
ans_33_put_text_msg(void * user_data,const uint8_t * msg,int len)6999 static void ans_33_put_text_msg(void *user_data, const uint8_t *msg, int len)
7000 {
7001 }
7002 /*- End of function --------------------------------------------------------*/
7003 
test_ans_33(void)7004 static int test_ans_33(void)
7005 {
7006     logging_state_t *logging;
7007     int16_t amp[2][SAMPLES_PER_CHUNK];
7008     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7009     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7010     int outframes;
7011     int samples;
7012     int push;
7013     int i;
7014     int j;
7015 
7016     /*
7017         III.5.4.3.33    CM detection and V.8 answering
7018         Purpose:        To confirm that the TUT will respond correctly to CM signals and connect
7019                         according to V.8 procedures.
7020         Preamble:       N/A
7021         Method:         The tester will transmit 2 sequences of 4 CI patterns separated by 2s. On
7022                         reception of the ANSam tone the tester will wait 0.5s and then begin
7023                         transmitting the CM signal with textphone and V.21 specified.
7024         Pass criteria:  1) On reception of the CM signal, the TUT should transmit JM with textphone
7025                            and V.21.
7026                         2) The TUT should then transmit in V.21 (2) mode.
7027                         3) The JM should be followed by continuous 1650Hz.
7028                         4) Correct transmission and reception of T.140 data should be verified after the
7029                            V.18 mode connection is completed.
7030         Comments:       The TUT should indicate V.18 mode.
7031      */
7032     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_33_put_text_msg, (void *) (intptr_t) 0);
7033     logging = v18_get_logging_state(v18[TESTER]);
7034     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7035     span_log_set_tag(logging, "Tester");
7036     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, ans_33_put_text_msg, (void *) (intptr_t) 1);
7037     logging = v18_get_logging_state(v18[TUT]);
7038     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7039     span_log_set_tag(logging, "TUT");
7040 
7041     if ((model = both_ways_line_model_init(line_model_no,
7042                                            noise_level,
7043                                            echo_level_cpe1,
7044                                            echo_level_co1,
7045                                            line_model_no,
7046                                            noise_level,
7047                                            echo_level_cpe2,
7048                                            echo_level_co2,
7049                                            channel_codec,
7050                                            rbs_pattern)) == NULL)
7051     {
7052         fprintf(stderr, "    Failed to create line model\n");
7053         exit(2);
7054     }
7055 
7056     result[TESTER][0] =
7057     result[TUT][0] = '\0';
7058     for (i = 0;  i < 10000;  i++)
7059     {
7060         for (j = 0;  j < 2;  j++)
7061         {
7062             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7063                 push = 10;
7064             if (samples < SAMPLES_PER_CHUNK)
7065             {
7066                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7067                 samples = SAMPLES_PER_CHUNK;
7068             }
7069         }
7070         if (log_audio)
7071         {
7072             for (j = 0;  j < samples;  j++)
7073             {
7074                 out_amp[2*j + 0] = amp[0][j];
7075                 out_amp[2*j + 1] = amp[1][j];
7076             }
7077             outframes = sf_writef_short(outhandle, out_amp, samples);
7078             if (outframes != samples)
7079             {
7080                 fprintf(stderr, "    Error writing audio file\n");
7081                 exit(2);
7082             }
7083         }
7084 #if 1
7085         both_ways_line_model(model,
7086                              model_amp[0],
7087                              amp[0],
7088                              model_amp[1],
7089                              amp[1],
7090                              samples);
7091 #else
7092         vec_copyi16(model_amp[0], amp[0], samples);
7093         vec_copyi16(model_amp[1], amp[1], samples);
7094 #endif
7095         v18_rx(v18[TESTER], model_amp[1], samples);
7096         v18_rx(v18[TUT], model_amp[0], samples);
7097     }
7098 
7099     v18_free(v18[TESTER]);
7100     v18_free(v18[TUT]);
7101     printf("Test not yet implemented\n");
7102     return 1;
7103 }
7104 /*- End of function --------------------------------------------------------*/
7105 
mon_01_put_text_msg(void * user_data,const uint8_t * msg,int len)7106 static void mon_01_put_text_msg(void *user_data, const uint8_t *msg, int len)
7107 {
7108 }
7109 /*- End of function --------------------------------------------------------*/
7110 
test_mon_01(void)7111 static int test_mon_01(void)
7112 {
7113     printf("Test not yet implemented\n");
7114     return 1;
7115 }
7116 /*- End of function --------------------------------------------------------*/
7117 
mon_21_put_text_msg(void * user_data,const uint8_t * msg,int len)7118 static void mon_21_put_text_msg(void *user_data, const uint8_t *msg, int len)
7119 {
7120 }
7121 /*- End of function --------------------------------------------------------*/
7122 
test_mon_21(void)7123 static int test_mon_21(void)
7124 {
7125     logging_state_t *logging;
7126     int16_t amp[2][SAMPLES_PER_CHUNK];
7127     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7128     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7129     int outframes;
7130     int samples;
7131     int push;
7132     int i;
7133     int j;
7134 
7135     /*
7136         III.5.4.4.1     Automode monitor Ta timer test
7137         Purpose:        To ensure that on entering monitor mode, timer Ta (3s) is not active and that
7138                         the TUT does not enter the probing state.
7139         Preamble:       N/A
7140         Method:         The TUT should be put into monitor state. The tester will then monitor for signals
7141                         for 1 minute.
7142         Pass criteria:  The TUT should not start probing.
7143      */
7144     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, mon_21_put_text_msg, (void *) (intptr_t) 0);
7145     logging = v18_get_logging_state(v18[TESTER]);
7146     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7147     span_log_set_tag(logging, "Tester");
7148     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, mon_21_put_text_msg, (void *) (intptr_t) 1);
7149     logging = v18_get_logging_state(v18[TUT]);
7150     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7151     span_log_set_tag(logging, "TUT");
7152 
7153     if ((model = both_ways_line_model_init(line_model_no,
7154                                            noise_level,
7155                                            echo_level_cpe1,
7156                                            echo_level_co1,
7157                                            line_model_no,
7158                                            noise_level,
7159                                            echo_level_cpe2,
7160                                            echo_level_co2,
7161                                            channel_codec,
7162                                            rbs_pattern)) == NULL)
7163     {
7164         fprintf(stderr, "    Failed to create line model\n");
7165         exit(2);
7166     }
7167 
7168     result[TESTER][0] =
7169     result[TUT][0] = '\0';
7170     for (i = 0;  i < 10000;  i++)
7171     {
7172         for (j = 0;  j < 2;  j++)
7173         {
7174             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7175                 push = 10;
7176             if (samples < SAMPLES_PER_CHUNK)
7177             {
7178                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7179                 samples = SAMPLES_PER_CHUNK;
7180             }
7181         }
7182         if (log_audio)
7183         {
7184             for (j = 0;  j < samples;  j++)
7185             {
7186                 out_amp[2*j + 0] = amp[0][j];
7187                 out_amp[2*j + 1] = amp[1][j];
7188             }
7189             outframes = sf_writef_short(outhandle, out_amp, samples);
7190             if (outframes != samples)
7191             {
7192                 fprintf(stderr, "    Error writing audio file\n");
7193                 exit(2);
7194             }
7195         }
7196 #if 1
7197         both_ways_line_model(model,
7198                              model_amp[0],
7199                              amp[0],
7200                              model_amp[1],
7201                              amp[1],
7202                              samples);
7203 #else
7204         vec_copyi16(model_amp[0], amp[0], samples);
7205         vec_copyi16(model_amp[1], amp[1], samples);
7206 #endif
7207         v18_rx(v18[TESTER], model_amp[1], samples);
7208         v18_rx(v18[TUT], model_amp[0], samples);
7209     }
7210 
7211     v18_free(v18[TESTER]);
7212     v18_free(v18[TUT]);
7213     printf("Test not yet implemented\n");
7214     return 1;
7215 }
7216 /*- End of function --------------------------------------------------------*/
7217 
mon_22_put_text_msg(void * user_data,const uint8_t * msg,int len)7218 static void mon_22_put_text_msg(void *user_data, const uint8_t *msg, int len)
7219 {
7220 }
7221 /*- End of function --------------------------------------------------------*/
7222 
test_mon_22(void)7223 static int test_mon_22(void)
7224 {
7225     logging_state_t *logging;
7226     int16_t amp[2][SAMPLES_PER_CHUNK];
7227     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7228     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7229     int outframes;
7230     int samples;
7231     int push;
7232     int i;
7233     int j;
7234 
7235     /*
7236         III.5.4.4.2     Automode monitor 1300Hz calling tone discrimination
7237         Purpose:        To confirm correct detection and reporting of 1300Hz calling tones as defined in
7238                         ITU-T V.25.
7239         Preamble:       N/A
7240         Method:         The tester will send 1300Hz bursts of (a) 400ms, (b) 500ms, (c) 700ms and
7241                         (d) 800ms followed by 1s of silence.
7242         Pass criteria:  1) The TUT should not respond to bursts of 400ms or 800ms.
7243                         2) The TUT should report detection of calling tones to the DTE after a burst of
7244                            1300Hz for 500ms or 700ms followed by 1s of silence.
7245         Comments:       In automode answer, the 1300Hz calling causes the DCE to start probing. In
7246                         monitor mode it should only report detection to the DTE.
7247      */
7248     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, mon_22_put_text_msg, (void *) (intptr_t) 0);
7249     logging = v18_get_logging_state(v18[TESTER]);
7250     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7251     span_log_set_tag(logging, "Tester");
7252     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, mon_22_put_text_msg, (void *) (intptr_t) 1);
7253     logging = v18_get_logging_state(v18[TUT]);
7254     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7255     span_log_set_tag(logging, "TUT");
7256 
7257     if ((model = both_ways_line_model_init(line_model_no,
7258                                            noise_level,
7259                                            echo_level_cpe1,
7260                                            echo_level_co1,
7261                                            line_model_no,
7262                                            noise_level,
7263                                            echo_level_cpe2,
7264                                            echo_level_co2,
7265                                            channel_codec,
7266                                            rbs_pattern)) == NULL)
7267     {
7268         fprintf(stderr, "    Failed to create line model\n");
7269         exit(2);
7270     }
7271 
7272     result[TESTER][0] =
7273     result[TUT][0] = '\0';
7274     for (i = 0;  i < 10000;  i++)
7275     {
7276         for (j = 0;  j < 2;  j++)
7277         {
7278             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7279                 push = 10;
7280             if (samples < SAMPLES_PER_CHUNK)
7281             {
7282                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7283                 samples = SAMPLES_PER_CHUNK;
7284             }
7285         }
7286         if (log_audio)
7287         {
7288             for (j = 0;  j < samples;  j++)
7289             {
7290                 out_amp[2*j + 0] = amp[0][j];
7291                 out_amp[2*j + 1] = amp[1][j];
7292             }
7293             outframes = sf_writef_short(outhandle, out_amp, samples);
7294             if (outframes != samples)
7295             {
7296                 fprintf(stderr, "    Error writing audio file\n");
7297                 exit(2);
7298             }
7299         }
7300 #if 1
7301         both_ways_line_model(model,
7302                              model_amp[0],
7303                              amp[0],
7304                              model_amp[1],
7305                              amp[1],
7306                              samples);
7307 #else
7308         vec_copyi16(model_amp[0], amp[0], samples);
7309         vec_copyi16(model_amp[1], amp[1], samples);
7310 #endif
7311         v18_rx(v18[TESTER], model_amp[1], samples);
7312         v18_rx(v18[TUT], model_amp[0], samples);
7313     }
7314 
7315     v18_free(v18[TESTER]);
7316     v18_free(v18[TUT]);
7317     printf("Test not yet implemented\n");
7318     return 1;
7319 }
7320 /*- End of function --------------------------------------------------------*/
7321 
mon_23_put_text_msg(void * user_data,const uint8_t * msg,int len)7322 static void mon_23_put_text_msg(void *user_data, const uint8_t *msg, int len)
7323 {
7324 }
7325 /*- End of function --------------------------------------------------------*/
7326 
test_mon_23(void)7327 static int test_mon_23(void)
7328 {
7329     logging_state_t *logging;
7330     int16_t amp[2][SAMPLES_PER_CHUNK];
7331     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7332     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7333     int outframes;
7334     int samples;
7335     int push;
7336     int i;
7337     int j;
7338 
7339     /*
7340         III.5.4.4.3     Automode monitor 980Hz calling tone discrimination
7341         Purpose:        To confirm correct detection and reporting of 980Hz calling tones as defined in
7342                         ITU-T V.25.
7343         Preamble:       N/A
7344         Method:         The tester will send 980Hz bursts of (a) 400ms, (b) 500ms, (c) 700ms and
7345                         (d) 800ms followed by 1s of silence.
7346         Pass criteria:  1) The TUT should not respond to bursts of 400ms or 800ms.
7347                         2) The TUT should report detection of calling tones to the DTE after a burst of
7348                            980Hz for 500ms or 700ms followed by 1s of silence.
7349         Comments:       In automode answer, the 980Hz calling causes the DCE to start probing. In monitor
7350                         mode it should only report detection to the DTE.
7351      */
7352     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, mon_23_put_text_msg, (void *) (intptr_t) 0);
7353     logging = v18_get_logging_state(v18[TESTER]);
7354     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7355     span_log_set_tag(logging, "Tester");
7356     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, mon_23_put_text_msg, (void *) (intptr_t) 1);
7357     logging = v18_get_logging_state(v18[TUT]);
7358     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7359     span_log_set_tag(logging, "TUT");
7360 
7361     if ((model = both_ways_line_model_init(line_model_no,
7362                                            noise_level,
7363                                            echo_level_cpe1,
7364                                            echo_level_co1,
7365                                            line_model_no,
7366                                            noise_level,
7367                                            echo_level_cpe2,
7368                                            echo_level_co2,
7369                                            channel_codec,
7370                                            rbs_pattern)) == NULL)
7371     {
7372         fprintf(stderr, "    Failed to create line model\n");
7373         exit(2);
7374     }
7375 
7376     result[TESTER][0] =
7377     result[TUT][0] = '\0';
7378     for (i = 0;  i < 10000;  i++)
7379     {
7380         for (j = 0;  j < 2;  j++)
7381         {
7382             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7383                 push = 10;
7384             if (samples < SAMPLES_PER_CHUNK)
7385             {
7386                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7387                 samples = SAMPLES_PER_CHUNK;
7388             }
7389         }
7390         if (log_audio)
7391         {
7392             for (j = 0;  j < samples;  j++)
7393             {
7394                 out_amp[2*j + 0] = amp[0][j];
7395                 out_amp[2*j + 1] = amp[1][j];
7396             }
7397             outframes = sf_writef_short(outhandle, out_amp, samples);
7398             if (outframes != samples)
7399             {
7400                 fprintf(stderr, "    Error writing audio file\n");
7401                 exit(2);
7402             }
7403         }
7404 #if 1
7405         both_ways_line_model(model,
7406                              model_amp[0],
7407                              amp[0],
7408                              model_amp[1],
7409                              amp[1],
7410                              samples);
7411 #else
7412         vec_copyi16(model_amp[0], amp[0], samples);
7413         vec_copyi16(model_amp[1], amp[1], samples);
7414 #endif
7415         v18_rx(v18[TESTER], model_amp[1], samples);
7416         v18_rx(v18[TUT], model_amp[0], samples);
7417     }
7418 
7419     v18_free(v18[TESTER]);
7420     v18_free(v18[TUT]);
7421     printf("Test not yet implemented\n");
7422     return 1;
7423 }
7424 /*- End of function --------------------------------------------------------*/
7425 
x_01_put_text_msg(void * user_data,const uint8_t * msg,int len)7426 static void x_01_put_text_msg(void *user_data, const uint8_t *msg, int len)
7427 {
7428 printf("1-1 %d '%s'\n", len, msg);
7429     if (user_data == NULL)
7430         strcat(result[TUT], (const char *) msg);
7431     else
7432         v18_put(v18[TUT], "abcdefghij", 10);
7433 }
7434 /*- End of function --------------------------------------------------------*/
7435 
test_x_01(void)7436 static int test_x_01(void)
7437 {
7438     logging_state_t *logging;
7439     int16_t amp[2][SAMPLES_PER_CHUNK];
7440     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7441     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7442     int outframes;
7443     int samples;
7444     int push;
7445     int i;
7446     int j;
7447     const char *ref;
7448 
7449     /*
7450         III.5.4.5.1     Baudot carrier timing and receiver disabling
7451         Purpose:        To verify that the TUT sends unmodulated carrier for 150ms before a new character
7452                         and disables its receiver for 300ms after a character is transmitted.
7453         Preamble:       Establish a call between the tester and TUT in Baudot mode.
7454         Method:         The operator should send a single character from the TUT. The tester will
7455                         immediately start sending a unique character sequence. Examination of the TUT
7456                         display will show when its receiver is re-enabled.
7457         Pass criteria:  1) The TUT should send unmodulated carrier for 150ms before the beginning of
7458                            the start bit.
7459                         2) The receiver should be re-enabled after 300ms.
7460                         3) The tester will confirm that 1 start bit and at least 1.5 stop bits are used.
7461         Comments:       The carrier should be maintained during the 300ms after a character.
7462      */
7463     v18[TESTER] = v18_init(NULL, true, V18_MODE_5BIT_4545, V18_AUTOMODING_GLOBAL, x_01_put_text_msg, (void *) (intptr_t) 0);
7464     logging = v18_get_logging_state(v18[TESTER]);
7465     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7466     span_log_set_tag(logging, "Tester");
7467     v18[TUT] = v18_init(NULL, false, V18_MODE_5BIT_4545, V18_AUTOMODING_GLOBAL, x_01_put_text_msg, (void *) (intptr_t) 1);
7468     logging = v18_get_logging_state(v18[TUT]);
7469     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7470     span_log_set_tag(logging, "TUT");
7471 
7472     if ((model = both_ways_line_model_init(line_model_no,
7473                                            noise_level,
7474                                            echo_level_cpe1,
7475                                            echo_level_co1,
7476                                            line_model_no,
7477                                            noise_level,
7478                                            echo_level_cpe2,
7479                                            echo_level_co2,
7480                                            channel_codec,
7481                                            rbs_pattern)) == NULL)
7482     {
7483         fprintf(stderr, "    Failed to create line model\n");
7484         exit(2);
7485     }
7486 
7487     result[TESTER][0] =
7488     result[TUT][0] = '\0';
7489     v18_put(v18[TESTER], "zabcdefghijklmnopq", -1);
7490     for (i = 0;  i < 10000;  i++)
7491     {
7492         for (j = 0;  j < 2;  j++)
7493         {
7494             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7495                 push = 10;
7496             if (samples < SAMPLES_PER_CHUNK)
7497             {
7498                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7499                 samples = SAMPLES_PER_CHUNK;
7500             }
7501         }
7502         if (log_audio)
7503         {
7504             for (j = 0;  j < samples;  j++)
7505             {
7506                 out_amp[2*j + 0] = amp[0][j];
7507                 out_amp[2*j + 1] = amp[1][j];
7508             }
7509             outframes = sf_writef_short(outhandle, out_amp, samples);
7510             if (outframes != samples)
7511             {
7512                 fprintf(stderr, "    Error writing audio file\n");
7513                 exit(2);
7514             }
7515         }
7516 #if 1
7517         both_ways_line_model(model,
7518                              model_amp[0],
7519                              amp[0],
7520                              model_amp[1],
7521                              amp[1],
7522                              samples);
7523 #else
7524         vec_copyi16(model_amp[0], amp[0], samples);
7525         vec_copyi16(model_amp[1], amp[1], samples);
7526 #endif
7527         v18_rx(v18[TESTER], model_amp[1], samples);
7528         v18_rx(v18[TUT], model_amp[0], samples);
7529     }
7530 
7531     v18_free(v18[TESTER]);
7532     v18_free(v18[TUT]);
7533     ref = "cdefghij";
7534     printf("Result:\n%s\n", result[TUT]);
7535     printf("Reference result:\n%s\n", ref);
7536     if (unexpected_echo  ||  strcmp(result[TUT], ref) != 0)
7537         return -1;
7538     return 1;
7539 }
7540 /*- End of function --------------------------------------------------------*/
7541 
x_02_put_text_msg(void * user_data,const uint8_t * msg,int len)7542 static void x_02_put_text_msg(void *user_data, const uint8_t *msg, int len)
7543 {
7544 }
7545 /*- End of function --------------------------------------------------------*/
7546 
test_x_02(void)7547 static int test_x_02(void)
7548 {
7549     logging_state_t *logging;
7550     int16_t amp[2][SAMPLES_PER_CHUNK];
7551     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7552     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7553     int outframes;
7554     int samples;
7555     int push;
7556     int i;
7557     int j;
7558 
7559     /*
7560         III.5.4.5.2     Baudot bit rate confirmation
7561         Purpose:        To verify that the TUT uses the correct bit rates in the Baudot mode.
7562         Preamble:       Establish a call between the tester and TUT in Baudot mode for each of the two
7563                         tests.
7564         Method:         The operator should select Baudot (a) 45 bit/s followed by (b) 50 bit/s modes and
7565                         transmit the string "abcdef" at each rate.
7566         Pass criteria:  The tester will measure the bit timings and confirm the rates.
7567      */
7568     v18[TESTER] = v18_init(NULL, true, V18_MODE_5BIT_4545, V18_AUTOMODING_GLOBAL, x_02_put_text_msg, (void *) (intptr_t) 0);
7569     logging = v18_get_logging_state(v18[TESTER]);
7570     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7571     span_log_set_tag(logging, "Tester");
7572     v18[TUT] = v18_init(NULL, false, V18_MODE_5BIT_4545, V18_AUTOMODING_GLOBAL, x_02_put_text_msg, (void *) (intptr_t) 1);
7573     logging = v18_get_logging_state(v18[TUT]);
7574     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7575     span_log_set_tag(logging, "TUT");
7576 
7577     if ((model = both_ways_line_model_init(line_model_no,
7578                                            noise_level,
7579                                            echo_level_cpe1,
7580                                            echo_level_co1,
7581                                            line_model_no,
7582                                            noise_level,
7583                                            echo_level_cpe2,
7584                                            echo_level_co2,
7585                                            channel_codec,
7586                                            rbs_pattern)) == NULL)
7587     {
7588         fprintf(stderr, "    Failed to create line model\n");
7589         exit(2);
7590     }
7591 
7592     result[TESTER][0] =
7593     result[TUT][0] = '\0';
7594     for (i = 0;  i < 10000;  i++)
7595     {
7596         for (j = 0;  j < 2;  j++)
7597         {
7598             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7599                 push = 10;
7600             if (samples < SAMPLES_PER_CHUNK)
7601             {
7602                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7603                 samples = SAMPLES_PER_CHUNK;
7604             }
7605         }
7606         if (log_audio)
7607         {
7608             for (j = 0;  j < samples;  j++)
7609             {
7610                 out_amp[2*j + 0] = amp[0][j];
7611                 out_amp[2*j + 1] = amp[1][j];
7612             }
7613             outframes = sf_writef_short(outhandle, out_amp, samples);
7614             if (outframes != samples)
7615             {
7616                 fprintf(stderr, "    Error writing audio file\n");
7617                 exit(2);
7618             }
7619         }
7620 #if 1
7621         both_ways_line_model(model,
7622                              model_amp[0],
7623                              amp[0],
7624                              model_amp[1],
7625                              amp[1],
7626                              samples);
7627 #else
7628         vec_copyi16(model_amp[0], amp[0], samples);
7629         vec_copyi16(model_amp[1], amp[1], samples);
7630 #endif
7631         v18_rx(v18[TESTER], model_amp[1], samples);
7632         v18_rx(v18[TUT], model_amp[0], samples);
7633     }
7634 
7635     v18_free(v18[TESTER]);
7636     v18_free(v18[TUT]);
7637     printf("Test not yet implemented\n");
7638     return 1;
7639 }
7640 /*- End of function --------------------------------------------------------*/
7641 
x_03_put_text_msg(void * user_data,const uint8_t * msg,int len)7642 static void x_03_put_text_msg(void *user_data, const uint8_t *msg, int len)
7643 {
7644 }
7645 /*- End of function --------------------------------------------------------*/
7646 
test_x_03(void)7647 static int test_x_03(void)
7648 {
7649     logging_state_t *logging;
7650     int16_t amp[2][SAMPLES_PER_CHUNK];
7651     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7652     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7653     int outframes;
7654     int samples;
7655     int push;
7656     int i;
7657     int j;
7658 
7659     /*
7660         III.5.4.5.3     Baudot probe bit rate confirmation
7661         Purpose:        To verify that the TUT uses the correct bit rates in the Baudot mode probe during
7662                         automoding.
7663         Preamble:       Set the user defined carrierless mode probe message to the string "abcdef" if
7664                         possible. Set the TUT country setting to "United States". A call should be initiated
7665                         from the tester to the TUT.
7666         Method:         The tester will wait for the Baudot mode probe and measure the bit rate.
7667         Pass criteria:  The tester will measure the bit timings and confirm the rate of 47.6 bit/s.
7668         Comments:       The probe message must be long enough for the tester to establish the bit rate. "GA"
7669                         may not be sufficient.
7670      */
7671     v18[TESTER] = v18_init(NULL, true, V18_MODE_5BIT_4545, V18_AUTOMODING_USA, x_03_put_text_msg, (void *) (intptr_t) 0);
7672     logging = v18_get_logging_state(v18[TESTER]);
7673     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7674     span_log_set_tag(logging, "Tester");
7675     v18[TUT] = v18_init(NULL, false, V18_MODE_5BIT_4545, V18_AUTOMODING_USA, x_03_put_text_msg, (void *) (intptr_t) 1);
7676     logging = v18_get_logging_state(v18[TUT]);
7677     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7678     span_log_set_tag(logging, "TUT");
7679 
7680     if ((model = both_ways_line_model_init(line_model_no,
7681                                            noise_level,
7682                                            echo_level_cpe1,
7683                                            echo_level_co1,
7684                                            line_model_no,
7685                                            noise_level,
7686                                            echo_level_cpe2,
7687                                            echo_level_co2,
7688                                            channel_codec,
7689                                            rbs_pattern)) == NULL)
7690     {
7691         fprintf(stderr, "    Failed to create line model\n");
7692         exit(2);
7693     }
7694 
7695     result[TESTER][0] =
7696     result[TUT][0] = '\0';
7697     for (i = 0;  i < 10000;  i++)
7698     {
7699         for (j = 0;  j < 2;  j++)
7700         {
7701             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7702                 push = 10;
7703             if (samples < SAMPLES_PER_CHUNK)
7704             {
7705                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7706                 samples = SAMPLES_PER_CHUNK;
7707             }
7708         }
7709         if (log_audio)
7710         {
7711             for (j = 0;  j < samples;  j++)
7712             {
7713                 out_amp[2*j + 0] = amp[0][j];
7714                 out_amp[2*j + 1] = amp[1][j];
7715             }
7716             outframes = sf_writef_short(outhandle, out_amp, samples);
7717             if (outframes != samples)
7718             {
7719                 fprintf(stderr, "    Error writing audio file\n");
7720                 exit(2);
7721             }
7722         }
7723 #if 1
7724         both_ways_line_model(model,
7725                              model_amp[0],
7726                              amp[0],
7727                              model_amp[1],
7728                              amp[1],
7729                              samples);
7730 #else
7731         vec_copyi16(model_amp[0], amp[0], samples);
7732         vec_copyi16(model_amp[1], amp[1], samples);
7733 #endif
7734         v18_rx(v18[TESTER], model_amp[1], samples);
7735         v18_rx(v18[TUT], model_amp[0], samples);
7736     }
7737 
7738     v18_free(v18[TESTER]);
7739     v18_free(v18[TUT]);
7740     printf("Test not yet implemented\n");
7741     return 1;
7742 }
7743 /*- End of function --------------------------------------------------------*/
7744 
x_04_put_text_msg(void * user_data,const uint8_t * msg,int len)7745 static void x_04_put_text_msg(void *user_data, const uint8_t *msg, int len)
7746 {
7747     if (user_data == NULL)
7748     {
7749         strcat(result[TESTER], (const char *) msg);
7750 printf("Unexpected ECHO received (%d) '%s'\n", len, msg);
7751         unexpected_echo = true;
7752     }
7753     else
7754     {
7755 printf("1-1 %d '%s'\n", len, msg);
7756         strcat(result[TUT], (const char *) msg);
7757         /* Echo each received character */
7758         //v18_put(v18[TUT], msg, len);
7759     }
7760 }
7761 /*- End of function --------------------------------------------------------*/
7762 
test_x_04(void)7763 static int test_x_04(void)
7764 {
7765     char msg[1024];
7766     logging_state_t *logging;
7767     int16_t amp[2][SAMPLES_PER_CHUNK];
7768     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7769     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7770     int outframes;
7771     int samples;
7772     int i;
7773     int j;
7774 
7775     /*
7776         III.5.4.5.4     5 Bit to T.50 character conversion
7777         Purpose:        To check that the character conversion tables in Annex A have been correctly
7778                         implemented.
7779         Preamble:       Establish a call between the tester and TUT in Baudot mode at 45 bit/s.
7780         Method:         The tester will send all possible characters preceded by the relevant case shift
7781                         command one at a time and wait for a response from the TUT operator. Each
7782                         character should be responded to at the TUT by typing the received character or
7783                         <CR> if the character is not available.
7784         Pass criteria:  1) The tester will verify that each character is correctly echoed back by the TUT.
7785                            The operator should verify that each character is correctly displayed on the TUT.
7786                         2) The TUT will send the LTRS symbol before its first character and the
7787                            appropriate mode character (either LTRS or FIGS) after every 72 subsequent
7788                            characters.
7789         Comments:       The tester should indicate which character has been sent in each case. Some of the
7790                         characters may not be available from the TUT keyboard and can be ignored. It is
7791                         assumed that the character conversion is the same for Baudot at 50 bit/s and any
7792                         other supported speed.
7793      */
7794     v18[TESTER] = v18_init(NULL, true, V18_MODE_5BIT_4545 | V18_MODE_REPETITIVE_SHIFTS_OPTION, V18_AUTOMODING_GLOBAL, x_04_put_text_msg, (void *) (intptr_t) 0);
7795     logging = v18_get_logging_state(v18[TESTER]);
7796     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7797     span_log_set_tag(logging, "Tester");
7798     v18[TUT] = v18_init(NULL, false, V18_MODE_5BIT_4545 | V18_MODE_REPETITIVE_SHIFTS_OPTION, V18_AUTOMODING_GLOBAL, x_04_put_text_msg, (void *) (intptr_t) 1);
7799     logging = v18_get_logging_state(v18[TUT]);
7800     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7801     span_log_set_tag(logging, "TUT");
7802 
7803     if ((model = both_ways_line_model_init(line_model_no,
7804                                            noise_level,
7805                                            echo_level_cpe1,
7806                                            echo_level_co1,
7807                                            line_model_no,
7808                                            noise_level,
7809                                            echo_level_cpe2,
7810                                            echo_level_co2,
7811                                            channel_codec,
7812                                            rbs_pattern)) == NULL)
7813     {
7814         fprintf(stderr, "    Failed to create line model\n");
7815         exit(2);
7816     }
7817 
7818     result[TESTER][0] =
7819     result[TUT][0] = '\0';
7820     unexpected_echo = false;
7821     for (i = 0;  i < 127;  i++)
7822         msg[i] = i + 1;
7823     msg[127] = '\0';
7824     v18_put(v18[TESTER], msg, 127);
7825 
7826     for (i = 0;  i < 2000;  i++)
7827     {
7828         for (j = 0;  j < 2;  j++)
7829         {
7830             samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK);
7831             if (samples < SAMPLES_PER_CHUNK)
7832             {
7833                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7834                 samples = SAMPLES_PER_CHUNK;
7835             }
7836         }
7837         if (log_audio)
7838         {
7839             for (j = 0;  j < samples;  j++)
7840             {
7841                 out_amp[2*j + 0] = amp[0][j];
7842                 out_amp[2*j + 1] = amp[1][j];
7843             }
7844             outframes = sf_writef_short(outhandle, out_amp, samples);
7845             if (outframes != samples)
7846             {
7847                 fprintf(stderr, "    Error writing audio file\n");
7848                 exit(2);
7849             }
7850         }
7851 #if 1
7852         both_ways_line_model(model,
7853                              model_amp[0],
7854                              amp[0],
7855                              model_amp[1],
7856                              amp[1],
7857                              samples);
7858 #else
7859         vec_copyi16(model_amp[0], amp[0], samples);
7860         vec_copyi16(model_amp[1], amp[1], samples);
7861 #endif
7862         v18_rx(v18[TESTER], model_amp[1], samples);
7863         v18_rx(v18[TUT], model_amp[0], samples);
7864     }
7865 
7866     v18_free(v18[TESTER]);
7867     v18_free(v18[TUT]);
7868     printf("Result:\n%s\n", result[TESTER]);
7869     printf("Result:\n%s\n", result[TUT]);
7870     printf("Reference result:\n%s\n", full_baudot_rx);
7871     if (unexpected_echo  ||  strcmp(result[TUT], full_baudot_rx) != 0)
7872         return -1;
7873     return 0;
7874 }
7875 /*- End of function --------------------------------------------------------*/
7876 
x_05_put_text_msg(void * user_data,const uint8_t * msg,int len)7877 static void x_05_put_text_msg(void *user_data, const uint8_t *msg, int len)
7878 {
7879     if (user_data == NULL)
7880     {
7881         /* Gather the received characters, which should be like the transmitted characters,
7882            but with the first three characters missing. */
7883         strcat(result[TESTER], (const char *) msg);
7884     }
7885     else
7886     {
7887         /* Receiving a character from the far end should block out its receiver
7888            for a while. If we send a stream of DTMF back, the first few characters
7889            (actually 3 for this particular text string) should be lost. */
7890         v18_put(v18[TUT], "behknqtwz", 9);
7891     }
7892 }
7893 /*- End of function --------------------------------------------------------*/
7894 
test_x_05(void)7895 static int test_x_05(void)
7896 {
7897     logging_state_t *logging;
7898     int16_t amp[2][SAMPLES_PER_CHUNK];
7899     int16_t model_amp[2][SAMPLES_PER_CHUNK];
7900     int16_t out_amp[2*SAMPLES_PER_CHUNK];
7901     int outframes;
7902     int samples;
7903     int push;
7904     int i;
7905     int j;
7906     const char *ref;
7907 
7908     /*
7909         III.5.4.5.5     DTMF receiver disabling
7910         Purpose:        To verify that the TUT disables its DTMF receiver for 300ms when a character is
7911                         transmitted.
7912         Preamble:       Establish a call between the tester and TUT in DTMF mode.
7913         Method:         The operator should send a single "e" character from the TUT which will result in
7914                         sending a single DTMF tone to the tester. The tester will immediately start sending a
7915                         unique character sequence using single DTMF tones. Examination of the TUT
7916                         display will show when its receiver is re-enabled.
7917         Pass criteria:  The receiver should be re-enabled after 300ms.
7918      */
7919     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_05_put_text_msg, (void *) (intptr_t) 0);
7920     logging = v18_get_logging_state(v18[TESTER]);
7921     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7922     span_log_set_tag(logging, "Tester");
7923     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_05_put_text_msg, (void *) (intptr_t) 1);
7924     logging = v18_get_logging_state(v18[TUT]);
7925     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
7926     span_log_set_tag(logging, "TUT");
7927 
7928     if ((model = both_ways_line_model_init(line_model_no,
7929                                            noise_level,
7930                                            echo_level_cpe1,
7931                                            echo_level_co1,
7932                                            line_model_no,
7933                                            noise_level,
7934                                            echo_level_cpe2,
7935                                            echo_level_co2,
7936                                            channel_codec,
7937                                            rbs_pattern)) == NULL)
7938     {
7939         fprintf(stderr, "    Failed to create line model\n");
7940         exit(2);
7941     }
7942 
7943     result[TESTER][0] =
7944     result[TUT][0] = '\0';
7945     /* Sending a character should block out the receiver for a while */
7946     v18_put(v18[TESTER], "z", 1);
7947 
7948     for (i = 0;  i < 1000;  i++)
7949     {
7950         for (j = 0;  j < 2;  j++)
7951         {
7952             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
7953                 push = 10;
7954             if (samples < SAMPLES_PER_CHUNK)
7955             {
7956                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
7957                 samples = SAMPLES_PER_CHUNK;
7958             }
7959         }
7960         if (log_audio)
7961         {
7962             for (j = 0;  j < samples;  j++)
7963             {
7964                 out_amp[2*j + 0] = amp[0][j];
7965                 out_amp[2*j + 1] = amp[1][j];
7966             }
7967             outframes = sf_writef_short(outhandle, out_amp, samples);
7968             if (outframes != samples)
7969             {
7970                 fprintf(stderr, "    Error writing audio file\n");
7971                 exit(2);
7972             }
7973         }
7974 #if 1
7975         both_ways_line_model(model,
7976                              model_amp[0],
7977                              amp[0],
7978                              model_amp[1],
7979                              amp[1],
7980                              samples);
7981 #else
7982         vec_copyi16(model_amp[0], amp[0], samples);
7983         vec_copyi16(model_amp[1], amp[1], samples);
7984 #endif
7985         v18_rx(v18[TESTER], model_amp[1], samples);
7986         v18_rx(v18[TUT], model_amp[0], samples);
7987     }
7988 
7989     v18_free(v18[TESTER]);
7990     v18_free(v18[TUT]);
7991     ref = "knqtwz";
7992     printf("Result:\n%s\n", result[TESTER]);
7993     printf("Reference result:\n%s\n", ref);
7994     if (strcmp(result[TESTER], ref) != 0)
7995         return -1;
7996     return 0;
7997 }
7998 /*- End of function --------------------------------------------------------*/
7999 
x_06_put_text_msg(void * user_data,const uint8_t * msg,int len)8000 static void x_06_put_text_msg(void *user_data, const uint8_t *msg, int len)
8001 {
8002     if (user_data == NULL)
8003         ;
8004     else
8005         strcat(result[TUT], (const char *) msg);
8006 }
8007 /*- End of function --------------------------------------------------------*/
8008 
test_x_06(void)8009 static int test_x_06(void)
8010 {
8011     char msg[128];
8012     const char *ref;
8013     logging_state_t *logging;
8014     int16_t amp[2][SAMPLES_PER_CHUNK];
8015     int16_t model_amp[2][SAMPLES_PER_CHUNK];
8016     int16_t out_amp[2*SAMPLES_PER_CHUNK];
8017     int outframes;
8018     int samples;
8019     int push;
8020     int i;
8021     int j;
8022 
8023     /*
8024         III.5.4.5.6     DTMF character conversion
8025         Purpose:        To check that the character conversion tables in Annex B have been correctly
8026                         implemented.
8027         Preamble:       Establish a call between the tester and TUT in DTMF mode.
8028         Method:         The tester will send each character from the set in Annex B, waiting for a response
8029                         after each one. Each character should be responded to at the TUT by typing the
8030                         same character.
8031         Pass criteria:  The tester will verify that each character is correctly echoed back by the TUT.
8032         Comments:       The conversion table is specified in Annex B. The receiver at the tester may be
8033                         re-enabled 100ms after transmission of each character to maximize likelihood of
8034                         receiving character from the TUT. It is assumed that the echo delay in the test
8035                         system is negligible.
8036      */
8037     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_06_put_text_msg, (void *) (intptr_t) 0);
8038     logging = v18_get_logging_state(v18[TESTER]);
8039     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8040     span_log_set_tag(logging, "Tester");
8041     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_06_put_text_msg, (void *) (intptr_t) 1);
8042     logging = v18_get_logging_state(v18[TUT]);
8043     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8044     span_log_set_tag(logging, "TUT");
8045 
8046     if ((model = both_ways_line_model_init(line_model_no,
8047                                            noise_level,
8048                                            echo_level_cpe1,
8049                                            echo_level_co1,
8050                                            line_model_no,
8051                                            noise_level,
8052                                            echo_level_cpe2,
8053                                            echo_level_co2,
8054                                            channel_codec,
8055                                            rbs_pattern)) == NULL)
8056     {
8057         fprintf(stderr, "    Failed to create line model\n");
8058         exit(2);
8059     }
8060 
8061     result[TESTER][0] =
8062     result[TUT][0] = '\0';
8063     for (i = 0;  i < 127;  i++)
8064         msg[i] = i + 1;
8065     msg[127] = '\0';
8066     v18_put(v18[TESTER], msg, 127);
8067 
8068     for (i = 0;  i < 10000;  i++)
8069     {
8070         for (j = 0;  j < 2;  j++)
8071         {
8072             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
8073                 push = 10;
8074             if (samples < SAMPLES_PER_CHUNK)
8075             {
8076                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
8077                 samples = SAMPLES_PER_CHUNK;
8078             }
8079         }
8080         if (log_audio)
8081         {
8082             for (j = 0;  j < samples;  j++)
8083             {
8084                 out_amp[2*j + 0] = amp[0][j];
8085                 out_amp[2*j + 1] = amp[1][j];
8086             }
8087             outframes = sf_writef_short(outhandle, out_amp, samples);
8088             if (outframes != samples)
8089             {
8090                 fprintf(stderr, "    Error writing audio file\n");
8091                 exit(2);
8092             }
8093         }
8094 #if 1
8095         both_ways_line_model(model,
8096                              model_amp[0],
8097                              amp[0],
8098                              model_amp[1],
8099                              amp[1],
8100                              samples);
8101 #else
8102         vec_copyi16(model_amp[0], amp[0], samples);
8103         vec_copyi16(model_amp[1], amp[1], samples);
8104 #endif
8105         v18_rx(v18[TESTER], model_amp[1], samples);
8106         v18_rx(v18[TUT], model_amp[0], samples);
8107     }
8108 
8109     ref = "\b \n\n\n?\n\n\n  !%+().+,-.0123456789:;(=)?"
8110           "XABCDEFGHIJKLMNOPQRSTUVWXYZ\xC6\xD8\xC5"
8111           " abcdefghijklmnopqrstuvwxyz\xE6\xF8\xE5 \b";
8112 
8113     printf("Result:\n%s\n", result[TESTER]);
8114     printf("Reference result:\n%s\n", ref);
8115     v18_free(v18[TESTER]);
8116     v18_free(v18[TUT]);
8117     if (strcmp(result[TUT], ref) != 0)
8118         return -1;
8119     return 0;
8120 }
8121 /*- End of function --------------------------------------------------------*/
8122 
x_07_put_text_msg(void * user_data,const uint8_t * msg,int len)8123 static void x_07_put_text_msg(void *user_data, const uint8_t *msg, int len)
8124 {
8125 }
8126 /*- End of function --------------------------------------------------------*/
8127 
test_x_07(void)8128 static int test_x_07(void)
8129 {
8130     logging_state_t *logging;
8131     int16_t amp[2][SAMPLES_PER_CHUNK];
8132     int16_t model_amp[2][SAMPLES_PER_CHUNK];
8133     int16_t out_amp[2*SAMPLES_PER_CHUNK];
8134     int outframes;
8135     int samples;
8136     int push;
8137     int i;
8138     int j;
8139 
8140     /*
8141         III.5.4.5.7     EDT carrier timing and receiver disabling
8142         Purpose:        To verify that the TUT sends unmodulated carrier for 300ms before a character and
8143                         disables its receiver for 300ms after a character is transmitted.
8144         Preamble:       Establish a call between the tester and TUT in EDT mode.
8145         Method:         The operator should send a single character from the TUT. The tester will
8146                         immediately start sending a unique character sequence. Examination of the TUT
8147                         display will show when its receiver is re-enabled.
8148         Pass criteria:  1) The TUT should send unmodulated carrier for 300ms before the beginning of
8149                            the start bit.
8150                         2) The receiver should be re-enabled after 300ms.
8151                         3) The tester will confirm that 1 start bit and at least 1.5 stop bits are used.
8152         Comments:       The carrier should be maintained during the 300ms after a character.
8153      */
8154     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_07_put_text_msg, (void *) (intptr_t) 0);
8155     logging = v18_get_logging_state(v18[TESTER]);
8156     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8157     span_log_set_tag(logging, "Tester");
8158     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_07_put_text_msg, (void *) (intptr_t) 1);
8159     logging = v18_get_logging_state(v18[TUT]);
8160     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8161     span_log_set_tag(logging, "TUT");
8162 
8163     if ((model = both_ways_line_model_init(line_model_no,
8164                                            noise_level,
8165                                            echo_level_cpe1,
8166                                            echo_level_co1,
8167                                            line_model_no,
8168                                            noise_level,
8169                                            echo_level_cpe2,
8170                                            echo_level_co2,
8171                                            channel_codec,
8172                                            rbs_pattern)) == NULL)
8173     {
8174         fprintf(stderr, "    Failed to create line model\n");
8175         exit(2);
8176     }
8177 
8178     result[TESTER][0] =
8179     result[TUT][0] = '\0';
8180     for (i = 0;  i < 10000;  i++)
8181     {
8182         for (j = 0;  j < 2;  j++)
8183         {
8184             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
8185                 push = 10;
8186             if (samples < SAMPLES_PER_CHUNK)
8187             {
8188                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
8189                 samples = SAMPLES_PER_CHUNK;
8190             }
8191         }
8192         if (log_audio)
8193         {
8194             for (j = 0;  j < samples;  j++)
8195             {
8196                 out_amp[2*j + 0] = amp[0][j];
8197                 out_amp[2*j + 1] = amp[1][j];
8198             }
8199             outframes = sf_writef_short(outhandle, out_amp, samples);
8200             if (outframes != samples)
8201             {
8202                 fprintf(stderr, "    Error writing audio file\n");
8203                 exit(2);
8204             }
8205         }
8206 #if 1
8207         both_ways_line_model(model,
8208                              model_amp[0],
8209                              amp[0],
8210                              model_amp[1],
8211                              amp[1],
8212                              samples);
8213 #else
8214         vec_copyi16(model_amp[0], amp[0], samples);
8215         vec_copyi16(model_amp[1], amp[1], samples);
8216 #endif
8217         v18_rx(v18[TESTER], model_amp[1], samples);
8218         v18_rx(v18[TUT], model_amp[0], samples);
8219     }
8220 
8221     v18_free(v18[TESTER]);
8222     v18_free(v18[TUT]);
8223     printf("Test not yet implemented\n");
8224     return 0;
8225 }
8226 /*- End of function --------------------------------------------------------*/
8227 
x_08_put_text_msg(void * user_data,const uint8_t * msg,int len)8228 static void x_08_put_text_msg(void *user_data, const uint8_t *msg, int len)
8229 {
8230 }
8231 /*- End of function --------------------------------------------------------*/
8232 
test_x_08(void)8233 static int test_x_08(void)
8234 {
8235     logging_state_t *logging;
8236     int16_t amp[2][SAMPLES_PER_CHUNK];
8237     int16_t model_amp[2][SAMPLES_PER_CHUNK];
8238     int16_t out_amp[2*SAMPLES_PER_CHUNK];
8239     int outframes;
8240     int samples;
8241     int push;
8242     int i;
8243     int j;
8244 
8245     /*
8246         III.5.4.5.8     EDT bit rate and character structure
8247         Purpose:        To verify that the TUT uses the correct bit rate and character structure in the EDT
8248                         mode.
8249         Preamble:       Establish a call between the tester and TUT in EDT mode.
8250         Method:         The operator should transmit the string "abcdef" from the TUT.
8251         Pass criteria:  1) The tester should measure the bit timings and confirm that the rate is 110 bit/s.
8252                         2) The tester should confirm that 1 start bit, 7 data bits, 1 even parity bit and 2 stop
8253                            bits are used.
8254      */
8255     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_08_put_text_msg, (void *) (intptr_t) 0);
8256     logging = v18_get_logging_state(v18[TESTER]);
8257     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8258     span_log_set_tag(logging, "Tester");
8259     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_08_put_text_msg, (void *) (intptr_t) 1);
8260     logging = v18_get_logging_state(v18[TUT]);
8261     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8262     span_log_set_tag(logging, "TUT");
8263 
8264     if ((model = both_ways_line_model_init(line_model_no,
8265                                            noise_level,
8266                                            echo_level_cpe1,
8267                                            echo_level_co1,
8268                                            line_model_no,
8269                                            noise_level,
8270                                            echo_level_cpe2,
8271                                            echo_level_co2,
8272                                            channel_codec,
8273                                            rbs_pattern)) == NULL)
8274     {
8275         fprintf(stderr, "    Failed to create line model\n");
8276         exit(2);
8277     }
8278 
8279     result[TESTER][0] =
8280     result[TUT][0] = '\0';
8281     for (i = 0;  i < 10000;  i++)
8282     {
8283         for (j = 0;  j < 2;  j++)
8284         {
8285             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
8286                 push = 10;
8287             if (samples < SAMPLES_PER_CHUNK)
8288             {
8289                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
8290                 samples = SAMPLES_PER_CHUNK;
8291             }
8292         }
8293         if (log_audio)
8294         {
8295             for (j = 0;  j < samples;  j++)
8296             {
8297                 out_amp[2*j + 0] = amp[0][j];
8298                 out_amp[2*j + 1] = amp[1][j];
8299             }
8300             outframes = sf_writef_short(outhandle, out_amp, samples);
8301             if (outframes != samples)
8302             {
8303                 fprintf(stderr, "    Error writing audio file\n");
8304                 exit(2);
8305             }
8306         }
8307 #if 1
8308         both_ways_line_model(model,
8309                              model_amp[0],
8310                              amp[0],
8311                              model_amp[1],
8312                              amp[1],
8313                              samples);
8314 #else
8315         vec_copyi16(model_amp[0], amp[0], samples);
8316         vec_copyi16(model_amp[1], amp[1], samples);
8317 #endif
8318         v18_rx(v18[TESTER], model_amp[1], samples);
8319         v18_rx(v18[TUT], model_amp[0], samples);
8320     }
8321 
8322     v18_free(v18[TESTER]);
8323     v18_free(v18[TUT]);
8324     printf("Test not yet implemented\n");
8325     return 0;
8326 }
8327 /*- End of function --------------------------------------------------------*/
8328 
x_09_put_text_msg(void * user_data,const uint8_t * msg,int len)8329 static void x_09_put_text_msg(void *user_data, const uint8_t *msg, int len)
8330 {
8331 }
8332 /*- End of function --------------------------------------------------------*/
8333 
test_x_09(void)8334 static int test_x_09(void)
8335 {
8336     logging_state_t *logging;
8337     int16_t amp[2][SAMPLES_PER_CHUNK];
8338     int16_t model_amp[2][SAMPLES_PER_CHUNK];
8339     int16_t out_amp[2*SAMPLES_PER_CHUNK];
8340     int outframes;
8341     int samples;
8342     int push;
8343     int i;
8344     int j;
8345 
8346     /*
8347         III.5.4.5.9     V.23 calling mode character format
8348         Purpose:        To verify that the TUT uses the correct character format in the V.23 calling mode.
8349         Preamble:       Establish a call from the TUT to the tester in V.23 mode.
8350         Method:         The operator should transmit the string "abcdef" from the TUT. The tester will echo
8351                         characters back to the TUT as they are received. The tester will then transmit the
8352                         string "abcdef" with ODD parity to the TUT.
8353         Pass criteria:  1) Confirm that 1 start bit, 7 data bits, 1 even parity bit and 2 stop bits are
8354                            transmitted.
8355                         2) The operator should confirm that there is no local echo at the TUT by checking
8356                            that there are no duplicate characters on the TUT display.
8357                         3) The received string should be correctly displayed despite the incorrect parity.
8358      */
8359     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_09_put_text_msg, (void *) (intptr_t) 0);
8360     logging = v18_get_logging_state(v18[TESTER]);
8361     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8362     span_log_set_tag(logging, "Tester");
8363     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_09_put_text_msg, (void *) (intptr_t) 1);
8364     logging = v18_get_logging_state(v18[TUT]);
8365     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8366     span_log_set_tag(logging, "TUT");
8367 
8368     if ((model = both_ways_line_model_init(line_model_no,
8369                                            noise_level,
8370                                            echo_level_cpe1,
8371                                            echo_level_co1,
8372                                            line_model_no,
8373                                            noise_level,
8374                                            echo_level_cpe2,
8375                                            echo_level_co2,
8376                                            channel_codec,
8377                                            rbs_pattern)) == NULL)
8378     {
8379         fprintf(stderr, "    Failed to create line model\n");
8380         exit(2);
8381     }
8382 
8383     result[TESTER][0] =
8384     result[TUT][0] = '\0';
8385     for (i = 0;  i < 10000;  i++)
8386     {
8387         for (j = 0;  j < 2;  j++)
8388         {
8389             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
8390                 push = 10;
8391             if (samples < SAMPLES_PER_CHUNK)
8392             {
8393                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
8394                 samples = SAMPLES_PER_CHUNK;
8395             }
8396         }
8397         if (log_audio)
8398         {
8399             for (j = 0;  j < samples;  j++)
8400             {
8401                 out_amp[2*j + 0] = amp[0][j];
8402                 out_amp[2*j + 1] = amp[1][j];
8403             }
8404             outframes = sf_writef_short(outhandle, out_amp, samples);
8405             if (outframes != samples)
8406             {
8407                 fprintf(stderr, "    Error writing audio file\n");
8408                 exit(2);
8409             }
8410         }
8411 #if 1
8412         both_ways_line_model(model,
8413                              model_amp[0],
8414                              amp[0],
8415                              model_amp[1],
8416                              amp[1],
8417                              samples);
8418 #else
8419         vec_copyi16(model_amp[0], amp[0], samples);
8420         vec_copyi16(model_amp[1], amp[1], samples);
8421 #endif
8422         v18_rx(v18[TESTER], model_amp[1], samples);
8423         v18_rx(v18[TUT], model_amp[0], samples);
8424     }
8425 
8426     v18_free(v18[TESTER]);
8427     v18_free(v18[TUT]);
8428     printf("Test not yet implemented\n");
8429     return 0;
8430 }
8431 /*- End of function --------------------------------------------------------*/
8432 
x_10_put_text_msg(void * user_data,const uint8_t * msg,int len)8433 static void x_10_put_text_msg(void *user_data, const uint8_t *msg, int len)
8434 {
8435 }
8436 /*- End of function --------------------------------------------------------*/
8437 
test_x_10(void)8438 static int test_x_10(void)
8439 {
8440     logging_state_t *logging;
8441     int16_t amp[2][SAMPLES_PER_CHUNK];
8442     int16_t model_amp[2][SAMPLES_PER_CHUNK];
8443     int16_t out_amp[2*SAMPLES_PER_CHUNK];
8444     int outframes;
8445     int samples;
8446     int push;
8447     int i;
8448     int j;
8449 
8450     /*
8451         III.5.4.5.10    V.23 answer mode character format
8452         Purpose:        To verify that the TUT uses the correct character format in the V.23 answer mode.
8453         Preamble:       Establish a call from the tester to the TUT in V.23 mode.
8454         Method:         The tester will transmit the string "abcdef" with ODD parity. The TUT should echo
8455                         characters back to the tester as they are received. The operator should then transmit
8456                         the string "abcdef" from the TUT.
8457         Pass criteria:  1) The received string should be correctly displayed at the TUT despite the
8458                            incorrect parity.
8459                         2) Confirm that 1 start bit, 7 data bits, 1 even parity bit and 2 stop bits are
8460                            transmitted by the TUT.
8461                         3) The tester should confirm that there is remote echo from TUT.
8462                         4) The operator should confirm that there is local echo on the TUT.
8463         Comments:       This test is only applicable to Minitel Dialogue terminals. Prestel and Minitel
8464                         Normal terminals cannot operate in this mode.
8465      */
8466     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_10_put_text_msg, (void *) (intptr_t) 0);
8467     logging = v18_get_logging_state(v18[TESTER]);
8468     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8469     span_log_set_tag(logging, "Tester");
8470     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_10_put_text_msg, (void *) (intptr_t) 1);
8471     logging = v18_get_logging_state(v18[TUT]);
8472     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8473     span_log_set_tag(logging, "TUT");
8474 
8475     if ((model = both_ways_line_model_init(line_model_no,
8476                                            noise_level,
8477                                            echo_level_cpe1,
8478                                            echo_level_co1,
8479                                            line_model_no,
8480                                            noise_level,
8481                                            echo_level_cpe2,
8482                                            echo_level_co2,
8483                                            channel_codec,
8484                                            rbs_pattern)) == NULL)
8485     {
8486         fprintf(stderr, "    Failed to create line model\n");
8487         exit(2);
8488     }
8489 
8490     result[TESTER][0] =
8491     result[TUT][0] = '\0';
8492     for (i = 0;  i < 10000;  i++)
8493     {
8494         for (j = 0;  j < 2;  j++)
8495         {
8496             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
8497                 push = 10;
8498             if (samples < SAMPLES_PER_CHUNK)
8499             {
8500                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
8501                 samples = SAMPLES_PER_CHUNK;
8502             }
8503         }
8504         if (log_audio)
8505         {
8506             for (j = 0;  j < samples;  j++)
8507             {
8508                 out_amp[2*j + 0] = amp[0][j];
8509                 out_amp[2*j + 1] = amp[1][j];
8510             }
8511             outframes = sf_writef_short(outhandle, out_amp, samples);
8512             if (outframes != samples)
8513             {
8514                 fprintf(stderr, "    Error writing audio file\n");
8515                 exit(2);
8516             }
8517         }
8518 #if 1
8519         both_ways_line_model(model,
8520                              model_amp[0],
8521                              amp[0],
8522                              model_amp[1],
8523                              amp[1],
8524                              samples);
8525 #else
8526         vec_copyi16(model_amp[0], amp[0], samples);
8527         vec_copyi16(model_amp[1], amp[1], samples);
8528 #endif
8529         v18_rx(v18[TESTER], model_amp[1], samples);
8530         v18_rx(v18[TUT], model_amp[0], samples);
8531     }
8532 
8533     v18_free(v18[TESTER]);
8534     v18_free(v18[TUT]);
8535     printf("Test not yet implemented\n");
8536     return 0;
8537 }
8538 /*- End of function --------------------------------------------------------*/
8539 
x_11_put_text_msg(void * user_data,const uint8_t * msg,int len)8540 static void x_11_put_text_msg(void *user_data, const uint8_t *msg, int len)
8541 {
8542 }
8543 /*- End of function --------------------------------------------------------*/
8544 
test_x_11(void)8545 static int test_x_11(void)
8546 {
8547     logging_state_t *logging;
8548     int16_t amp[2][SAMPLES_PER_CHUNK];
8549     int16_t model_amp[2][SAMPLES_PER_CHUNK];
8550     int16_t out_amp[2*SAMPLES_PER_CHUNK];
8551     int outframes;
8552     int samples;
8553     int push;
8554     int i;
8555     int j;
8556 
8557     /*
8558         III.5.4.5.11    V.21 character structure
8559         Purpose:        To verify that the TUT uses the character structure in the V.21 mode.
8560         Preamble:       Establish a call from the TUT to the tester in V.21 mode.
8561         Method:         The operator should transmit a string from the TUT that is long enough to cause the
8562                         display to word wrap followed by "abcdef", new line (CR+LF). The tester will then
8563                         transmit the string "123456", BACKSPACE (0/8) with ODD parity to the TUT.
8564         Pass criteria:  1) The tester should confirm that 1 start bit, 7 data bits, 1 even parity bit and 1 stop
8565                            bits are transmitted.
8566                         2) The word wrap should not result in CR+LF.
8567                         3) The forced new line should be indicated by CR+LF.
8568                         4) The last five characters on the TUT display should be "12345" (no "6")
8569                            correctly displayed despite the incorrect parity.
8570      */
8571     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_11_put_text_msg, (void *) (intptr_t) 0);
8572     logging = v18_get_logging_state(v18[TESTER]);
8573     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8574     span_log_set_tag(logging, "Tester");
8575     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_11_put_text_msg, (void *) (intptr_t) 1);
8576     logging = v18_get_logging_state(v18[TUT]);
8577     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8578     span_log_set_tag(logging, "TUT");
8579 
8580     if ((model = both_ways_line_model_init(line_model_no,
8581                                            noise_level,
8582                                            echo_level_cpe1,
8583                                            echo_level_co1,
8584                                            line_model_no,
8585                                            noise_level,
8586                                            echo_level_cpe2,
8587                                            echo_level_co2,
8588                                            channel_codec,
8589                                            rbs_pattern)) == NULL)
8590     {
8591         fprintf(stderr, "    Failed to create line model\n");
8592         exit(2);
8593     }
8594 
8595     result[TESTER][0] =
8596     result[TUT][0] = '\0';
8597     for (i = 0;  i < 10000;  i++)
8598     {
8599         for (j = 0;  j < 2;  j++)
8600         {
8601             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
8602                 push = 10;
8603             if (samples < SAMPLES_PER_CHUNK)
8604             {
8605                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
8606                 samples = SAMPLES_PER_CHUNK;
8607             }
8608         }
8609         if (log_audio)
8610         {
8611             for (j = 0;  j < samples;  j++)
8612             {
8613                 out_amp[2*j + 0] = amp[0][j];
8614                 out_amp[2*j + 1] = amp[1][j];
8615             }
8616             outframes = sf_writef_short(outhandle, out_amp, samples);
8617             if (outframes != samples)
8618             {
8619                 fprintf(stderr, "    Error writing audio file\n");
8620                 exit(2);
8621             }
8622         }
8623 #if 1
8624         both_ways_line_model(model,
8625                              model_amp[0],
8626                              amp[0],
8627                              model_amp[1],
8628                              amp[1],
8629                              samples);
8630 #else
8631         vec_copyi16(model_amp[0], amp[0], samples);
8632         vec_copyi16(model_amp[1], amp[1], samples);
8633 #endif
8634         v18_rx(v18[TESTER], model_amp[1], samples);
8635         v18_rx(v18[TUT], model_amp[0], samples);
8636     }
8637 
8638     v18_free(v18[TESTER]);
8639     v18_free(v18[TUT]);
8640     printf("Test not yet implemented\n");
8641     return 0;
8642 }
8643 /*- End of function --------------------------------------------------------*/
8644 
x_12_put_text_msg(void * user_data,const uint8_t * msg,int len)8645 static void x_12_put_text_msg(void *user_data, const uint8_t *msg, int len)
8646 {
8647 }
8648 /*- End of function --------------------------------------------------------*/
8649 
test_x_12(void)8650 static int test_x_12(void)
8651 {
8652     logging_state_t *logging;
8653     int16_t amp[2][SAMPLES_PER_CHUNK];
8654     int16_t model_amp[2][SAMPLES_PER_CHUNK];
8655     int16_t out_amp[2*SAMPLES_PER_CHUNK];
8656     int outframes;
8657     int samples;
8658     int push;
8659     int i;
8660     int j;
8661 
8662     /*
8663         III.5.4.5.12    V.18 mode
8664         Purpose:        To verify that the TUT uses the protocol defined in ITU-T T.140.
8665         Preamble:       Establish a call from the TUT to the tester in V.18 mode.
8666         Method:         The operator should transmit a string from the TUT that is long enough to cause the
8667                         display to word wrap followed by "abcdef", new line (CR+LF), new line
8668                         (UNICODE preferred). The tester will then transmit the string "123456",
8669                         BACKSPACE.
8670         Pass criteria:  The tester should confirm UTF8 encoded UNICODE characters are used with the
8671                         controls specified in ITU-T T.140.
8672      */
8673     v18[TESTER] = v18_init(NULL, true, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_12_put_text_msg, (void *) (intptr_t) 0);
8674     logging = v18_get_logging_state(v18[TESTER]);
8675     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8676     span_log_set_tag(logging, "Tester");
8677     v18[TUT] = v18_init(NULL, false, V18_MODE_DTMF, V18_AUTOMODING_GLOBAL, x_12_put_text_msg, (void *) (intptr_t) 1);
8678     logging = v18_get_logging_state(v18[TUT]);
8679     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8680     span_log_set_tag(logging, "TUT");
8681 
8682     if ((model = both_ways_line_model_init(line_model_no,
8683                                            noise_level,
8684                                            echo_level_cpe1,
8685                                            echo_level_co1,
8686                                            line_model_no,
8687                                            noise_level,
8688                                            echo_level_cpe2,
8689                                            echo_level_co2,
8690                                            channel_codec,
8691                                            rbs_pattern)) == NULL)
8692     {
8693         fprintf(stderr, "    Failed to create line model\n");
8694         exit(2);
8695     }
8696 
8697     result[TESTER][0] =
8698     result[TUT][0] = '\0';
8699     for (i = 0;  i < 10000;  i++)
8700     {
8701         for (j = 0;  j < 2;  j++)
8702         {
8703             if ((samples = v18_tx(v18[j], amp[j], SAMPLES_PER_CHUNK)) == 0)
8704                 push = 10;
8705             if (samples < SAMPLES_PER_CHUNK)
8706             {
8707                 vec_zeroi16(&amp[j][samples], SAMPLES_PER_CHUNK - samples);
8708                 samples = SAMPLES_PER_CHUNK;
8709             }
8710         }
8711         if (log_audio)
8712         {
8713             for (j = 0;  j < samples;  j++)
8714             {
8715                 out_amp[2*j + 0] = amp[0][j];
8716                 out_amp[2*j + 1] = amp[1][j];
8717             }
8718             outframes = sf_writef_short(outhandle, out_amp, samples);
8719             if (outframes != samples)
8720             {
8721                 fprintf(stderr, "    Error writing audio file\n");
8722                 exit(2);
8723             }
8724         }
8725 #if 1
8726         both_ways_line_model(model,
8727                              model_amp[0],
8728                              amp[0],
8729                              model_amp[1],
8730                              amp[1],
8731                              samples);
8732 #else
8733         vec_copyi16(model_amp[0], amp[0], samples);
8734         vec_copyi16(model_amp[1], amp[1], samples);
8735 #endif
8736         v18_rx(v18[TESTER], model_amp[1], samples);
8737         v18_rx(v18[TUT], model_amp[0], samples);
8738     }
8739 
8740     v18_free(v18[TESTER]);
8741     v18_free(v18[TUT]);
8742     printf("Test not yet implemented\n");
8743     return 0;
8744 }
8745 /*- End of function --------------------------------------------------------*/
8746 
put_v18_msg(void * user_data,const uint8_t * msg,int len)8747 static void put_v18_msg(void *user_data, const uint8_t *msg, int len)
8748 {
8749     char buf[1024];
8750 
8751     memcpy(buf, msg, len);
8752     buf[len] = '\0';
8753     printf("Received (%d bytes) '%s'\n", len, buf);
8754 }
8755 /*- End of function --------------------------------------------------------*/
8756 
decode_test_data_file(int mode,const char * filename)8757 static int decode_test_data_file(int mode, const char *filename)
8758 {
8759     int16_t amp[SAMPLES_PER_CHUNK];
8760     SNDFILE *inhandle;
8761     int len;
8762     v18_state_t *v18_state;
8763     logging_state_t *logging;
8764 
8765     printf("Decoding as '%s'\n", v18_mode_to_str(mode));
8766     /* We will decode the audio from a file. */
8767     if ((inhandle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
8768     {
8769         fprintf(stderr, "    Cannot open audio file '%s'\n", decode_test_file);
8770         exit(2);
8771     }
8772     v18_state = v18_init(NULL, false, mode, V18_AUTOMODING_GLOBAL, put_v18_msg, NULL);
8773     logging = v18_get_logging_state(v18_state);
8774     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
8775     span_log_set_tag(logging, "");
8776     for (;;)
8777     {
8778         if ((len = sf_readf_short(inhandle, amp, SAMPLES_PER_CHUNK)) <= 0)
8779             break;
8780         v18_rx(v18_state, amp, len);
8781     }
8782     if (sf_close_telephony(inhandle))
8783     {
8784         fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
8785         exit(2);
8786     }
8787     v18_free(v18_state);
8788     return 0;
8789 }
8790 /*- End of function --------------------------------------------------------*/
8791 
8792 const struct
8793 {
8794     const char *title;
8795     int (*func)(void);
8796 } test_list[] =
8797 {
8798     {"III.3.2.1 Operational requirements tests", NULL},
8799     {"MISC-01         4 (1)       No disconnection test", test_misc_01},
8800     {"MISC-02         4 (2)       Automatic resumption of automoding", test_misc_02},
8801     {"MISC-03         4 (2)       Retention of selected mode on loss of signal", test_misc_03},
8802     {"MISC-04         4 (4)       Detection of BUSY tone", test_misc_04},
8803     {"MISC-05         4 (4)       Detection of RINGING", test_misc_05},
8804     {"MISC-06         4 (4)       LOSS OF CARRIER indication", test_misc_06},
8805     {"MISC-07         4 (4)       Call progress indication", test_misc_07},
8806     {"MISC-08         4 (5)       Circuit 135 test", test_misc_08},
8807     {"MISC-09         4 (6)       Connection procedures", test_misc_09},
8808 
8809     {"III.3.2.2 Automode originate tests", NULL},
8810     {"ORG-01          5.1.1       CI & XCI signal coding and cadence", test_org_01},
8811     {"ORG-02          5.1.3       ANS signal detection", test_org_02},
8812     {"ORG-03          5.2.3.1     End of ANS signal detection", test_org_03},
8813     {"ORG-04          5.1.3.2     ANS tone followed by TXP", test_org_04},
8814     {"ORG-05          5.1.3.3     ANS tone followed by 1650Hz", test_org_05},
8815     {"ORG-06          5.1.3.4     ANS tone followed by 1300Hz", test_org_06},
8816     {"ORG-07          5.1.3       ANS tone followed by no tone", test_org_07},
8817     {"ORG-08          5.1.4       Bell 103 (2225Hz signal) detection", test_org_08},
8818     {"ORG-09          5.1.5       V.21 (1650Hz signal) detection", test_org_09},
8819     {"ORG-10          5.1.6       V.23 (1300Hz signal) detection", test_org_10},
8820     {"ORG-11          5.1.7       V.23 (390Hz signal) detection", test_org_11},
8821     {"ORG-12a to d    5.1.8       5 Bit Mode (baudot) detection Tests", test_org_12},
8822     {"ORG-13          5.1.9       DTMF signal detection", test_org_13},
8823     {"ORG-14          5.1.10      EDT rate detection", test_org_14},
8824     {"ORG-15          5.1.10.1    Rate detection test", test_org_15},
8825     {"ORG-16          5.1.10.2    980Hz detection", test_org_16},
8826     {"ORG-17          5.1.10.3    Loss of signal after 980Hz", test_org_17},
8827     {"ORG-18          5.1.10.3    Tr Timer", test_org_18},
8828     {"ORG-19          5.1.11      Bell 103 (1270Hz signal) detection", test_org_19},
8829     {"ORG-20                      Immunity to network tones", test_org_20},
8830     {"ORG-21a to b                Immunity to other non-textphone modems", test_org_21},
8831     {"ORG-22                      Immunity to Fax tones", test_org_22},
8832     {"ORG-23                      Immunity to voice", test_org_23},
8833     {"ORG-24          5.1.2       ANSam detection", test_org_24},
8834     {"ORG-25          6.1         V.8 originate call", test_org_25},
8835 
8836     {"III.3.2.3 Automode answer tests", NULL},
8837     {"ANS-01          5.2.1       Ta timer", test_ans_01},
8838     {"ANS-02          5.2.2       CI signal detection", test_ans_02},
8839     {"ANS-03          5.2.2.1     Early termination of ANS tone", test_ans_03},
8840     {"ANS-04          5.2.2.2     Tt Timer", test_ans_04},
8841     {"ANS-05          5.2.3.2     ANS tone followed by 980Hz", test_ans_05},
8842     {"ANS-06          5.2.3.2     ANS tone followed by 1300Hz", test_ans_06},
8843     {"ANS-07          5.2.3.3     ANS tone followed by 1650Hz", test_ans_07},
8844     {"ANS-08          5.2.4.1     980Hz followed by 1650Hz", test_ans_08},
8845     {"ANS-09a to d    5.2.4.2     980Hz calling tone detection", test_ans_09},
8846     {"ANS-10          5.2.4.3     V.21 detection by timer", test_ans_10},
8847     {"ANS-11          5.2.4.4.1   EDT detection by rate", test_ans_11},
8848     {"ANS-12          5.2.4.4.2   V.21 detection by rate", test_ans_12},
8849     {"ANS-13          5.2.4.4.3   Tr Timer", test_ans_13},
8850     {"ANS-14          5.2.4.5     Te Timer", test_ans_14},
8851     {"ANS-15a to d    5.2.5       5 bit mode (Baudot) detection tests", test_ans_15},
8852     {"ANS-16          5.2.6       DTMF signal detection", test_ans_16},
8853     {"ANS-17          5.2.7       Bell 103 (1270Hz signal) detection", test_ans_17},
8854     {"ANS-18          5.2.8       Bell 103 (2225Hz signal) detection", test_ans_18},
8855     {"ANS-19          5.2.9       V.21 reverse mode (1650Hz) detection", test_ans_19},
8856     {"ANS-20a to d    5.2.10      1300Hz calling tone discrimination", test_ans_20},
8857     {"ANS-21          5.2.11      V.23 reverse mode (1300Hz) detection", test_ans_21},
8858     {"ANS-22                      1300Hz with XCI Test", test_ans_22},
8859     {"ANS-23          5.2.12      Stimulate mode country settings", test_ans_23},
8860     {"ANS-24          5.2.12.1    Stimulate carrierless mode probe message", test_ans_24},
8861     {"ANS-25          5.2.12.1.1  Interrupted carrierless mode probe", test_ans_25},
8862     {"ANS-26          5.2.12.2    Stimulate carrier mode probe time", test_ans_26},
8863     {"ANS-27          5.2.12.2.1  V.23 mode (390Hz) detection", test_ans_27},
8864     {"ANS-28          5.2.12.2.2  Interrupted carrier mode probe", test_ans_28},
8865     {"ANS-29          5.2.12.2.2  Stimulate mode response during probe", test_ans_29},
8866     {"ANS-30                      Immunity to network tones", test_ans_30},
8867     {"ANS-31                      Immunity to Fax calling tones", test_ans_31},
8868     {"ANS-32                      Immunity to voice", test_ans_32},
8869     {"ANS-33          5.2.2.1     V.8 CM detection and V.8 answering", test_ans_33},
8870 
8871     {"III.3.2.4 Automode monitor tests", NULL},
8872     {"MON-01 to -20   5.3         Repeat all answer mode tests excluding tests ANS-01, ANS-20 and ANS-23 to ANS-29", test_mon_01},
8873     {"MON-21          5.3         Automode monitor Ta timer", test_mon_21},
8874     {"MON-22a to d    5.3         Automode monitor 1300Hz calling tone discrimination", test_mon_22},
8875     {"MON-23a to d    5.3         Automode monitor 980Hz calling tone discrimination", test_mon_23},
8876 
8877     {"III.3.2.5 ITU-T V.18 annexes tests", NULL},
8878     {"X-01            A.1         Baudot carrier timing and receiver disabling", test_x_01},
8879     {"X-02            A.2         Baudot bit rate confirmation", test_x_02},
8880     {"X-03            A.3         Baudot probe bit rate confirmation", test_x_03},
8881     {"X-04            A.4         5 Bit to T.50 character conversion", test_x_04},
8882     {"X-05            B.1         DTMF receiver disabling", test_x_05},
8883     {"X-06            B.2         DTMF character conversion", test_x_06},
8884     {"X-07            C.1         EDT carrier timing and receiver disabling", test_x_07},
8885     {"X-08            C.2-3       EDT bit rate and character structure", test_x_08},
8886     {"X-09            E           V.23 calling mode character format", test_x_09},
8887     {"X-10            E           V.23 answer mode character format", test_x_10},
8888     {"X-11            F.4-5       V.21 character structure", test_x_11},
8889     {"X-12            G.1-3       V.18 mode", test_x_12},
8890 
8891     {"", NULL}
8892 };
8893 
main(int argc,char * argv[])8894 int main(int argc, char *argv[])
8895 {
8896     int i;
8897     int res;
8898     bool hit;
8899     const char *match;
8900     int test_standard;
8901     int opt;
8902 
8903     match = NULL;
8904     test_standard = -1;
8905     while ((opt = getopt(argc, argv, "d:ls:")) != -1)
8906     {
8907         switch (opt)
8908         {
8909         case 'd':
8910             decode_test_file = optarg;
8911             break;
8912         case 'l':
8913             log_audio = true;
8914             break;
8915         case 's':
8916             test_standard = atoi(optarg);
8917             break;
8918         default:
8919             //usage();
8920             exit(2);
8921             break;
8922         }
8923     }
8924     argc -= optind;
8925     argv += optind;
8926     if (decode_test_file)
8927     {
8928         decode_test_data_file(test_standard, decode_test_file);
8929         exit(0);
8930     }
8931     if (argc > 0)
8932         match = argv[0];
8933 
8934     outhandle = NULL;
8935     if (log_audio)
8936     {
8937         if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 2)) == NULL)
8938         {
8939             fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_FILE_NAME);
8940             exit(2);
8941         }
8942     }
8943 
8944     hit = false;
8945     for (i = 0;  test_list[i].title[0];  i++)
8946     {
8947         if (test_list[i].func
8948             &&
8949                (match == NULL
8950                 ||
8951                    (strncmp(match, test_list[i].title, strlen(match)) == 0
8952                     &&
8953                     test_list[i].title[strlen(match)] == ' ')))
8954         {
8955             hit = true;
8956             printf("%s\n", test_list[i].title);
8957             res = test_list[i].func();
8958             if (res < 0)
8959             {
8960                 printf("    Test failed\n");
8961                 exit(2);
8962             }
8963             if (res == 0)
8964             {
8965                 printf("    Test passed\n");
8966             }
8967         }
8968         else
8969         {
8970             if (match == NULL)
8971                 printf("%s\n", test_list[i].title);
8972         }
8973     }
8974     if (!hit)
8975     {
8976         printf("Test not found\n");
8977         exit(2);
8978     }
8979     basic_tests(V18_MODE_5BIT_4545);
8980     basic_tests(V18_MODE_5BIT_4545 | V18_MODE_REPETITIVE_SHIFTS_OPTION);
8981     if (log_audio)
8982     {
8983         if (sf_close_telephony(outhandle))
8984         {
8985             fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
8986             exit(2);
8987         }
8988     }
8989     printf("Tests passed\n");
8990     return 0;
8991 
8992     return 0;
8993 }
8994 /*- End of function --------------------------------------------------------*/
8995 /*- End of file ------------------------------------------------------------*/
8996