1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * g1050.c - IP network modeling, as per G.1050/TIA-921.
5  *
6  * Written by Steve Underwood <steveu@coppice.org>
7  *
8  * Copyright (C) 2007 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 #if defined(HAVE_CONFIG_H)
27 #include "config.h"
28 #endif
29 
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <inttypes.h>
33 #include <string.h>
34 #include <time.h>
35 #include <stdio.h>
36 #include <fcntl.h>
37 #if defined(HAVE_TGMATH_H)
38 #include <tgmath.h>
39 #endif
40 #if defined(HAVE_MATH_H)
41 #define GEN_CONST
42 #include <math.h>
43 #endif
44 #if defined(HAVE_STDBOOL_H)
45 #include <stdbool.h>
46 #else
47 #include "spandsp/stdbool.h"
48 #endif
49 #include "floating_fudge.h"
50 
51 #include "spandsp.h"
52 #include "spandsp/g1050.h"
53 
54 #define PACKET_LOSS_TIME    -1
55 
56 g1050_constants_t g1050_constants[1] =
57 {
58     {
59         {
60             {   /* Side A LAN */
61                 {
62                     0.004,          /*! Probability of loss rate change low->high */
63                     0.1             /*! Probability of loss rate change high->low */
64                 },
65                 {
66                     {
67                         0.0,        /*! Probability of an impulse */
68                         0.0,
69                     },
70                     {
71                         0.5,
72                         0.0
73                     }
74                 },
75                 1.0,                /*! Impulse height, based on MTU and bit rate */
76                 0.0,                /*! Impulse decay coefficient */
77                 0.001,              /*! Probability of packet loss due to occupancy. */
78                 0.15                /*! Probability of packet loss due to a multiple access collision. */
79             },
80             {   /* Side A access link */
81                 {
82                     0.0002,         /*! Probability of loss rate change low->high */
83                     0.2             /*! Probability of loss rate change high->low */
84                 },
85                 {
86                     {
87                         0.001,      /*! Probability of an impulse */
88                         0.0,
89                     },
90                     {
91                         0.3,
92                         0.4
93                     }
94                 },
95                 40.0,               /*! Impulse height, based on MTU and bit rate */
96                 0.75,               /*! Impulse decay coefficient */
97                 0.0005,             /*! Probability of packet loss due to occupancy. */
98                 0.0                 /*! Probability of packet loss due to a multiple access collision. */
99             },
100             {   /* Side B access link */
101                 {
102                     0.0002,         /*! Probability of loss rate change low->high */
103                     0.2             /*! Probability of loss rate change high->low */
104                 },
105                 {
106                     {
107                         0.001,      /*! Probability of an impulse */
108                         0.0,
109                     },
110                     {
111                         0.3,
112                         0.4
113                     }
114                 },
115                 40.0,               /*! Impulse height, based on MTU and bit rate */
116                 0.75,               /*! Impulse decay coefficient */
117                 0.0005,             /*! Probability of packet loss due to occupancy. */
118                 0.0                 /*! Probability of packet loss due to a multiple access collision. */
119             },
120             {   /* Side B LAN */
121                 {
122                     0.004,          /*! Probability of loss rate change low->high */
123                     0.1             /*! Probability of loss rate change high->low */
124                 },
125                 {
126                     {
127                         0.0,        /*! Probability of an impulse */
128                         0.0,
129                     },
130                     {
131                         0.5,
132                         0.0
133                     }
134                 },
135                 1.0,                /*! Impulse height, based on MTU and bit rate */
136                 0.0,                /*! Impulse decay coefficient */
137                 0.001,              /*! Probability of packet loss due to occupancy. */
138                 0.15                /*! Probability of packet loss due to a multiple access collision. */
139             }
140         }
141     }
142 };
143 
144 g1050_channel_speeds_t g1050_speed_patterns[168] =
145 {
146     {  4000000, 0,   128000,   768000, 0,   4000000, 0,   128000,   768000, 0, 0.360},
147     {  4000000, 0,   128000,   768000, 0,  20000000, 0,   128000,   768000, 0, 0.720},
148     {  4000000, 0,   128000,   768000, 0, 100000000, 0,   128000,   768000, 0, 0.360},
149     { 20000000, 0,   128000,   768000, 0,  20000000, 0,   128000,   768000, 0, 0.360},
150     { 20000000, 0,   128000,   768000, 0, 100000000, 0,   128000,   768000, 0, 0.360},
151     {100000000, 0,   128000,   768000, 0, 100000000, 0,   128000,   768000, 0, 0.090},
152     {  4000000, 0,   128000,  1536000, 0,   4000000, 0,   384000,   768000, 0, 0.720},
153     {  4000000, 0,   128000,  1536000, 0,  20000000, 0,   384000,   768000, 0, 1.470},
154     {  4000000, 0,   128000,  1536000, 0, 100000000, 0,   384000,   768000, 0, 0.840},
155     { 20000000, 0,   128000,  1536000, 0,  20000000, 0,   384000,   768000, 0, 0.750},
156     { 20000000, 0,   128000,  1536000, 0, 100000000, 0,   384000,   768000, 0, 0.855},
157     {100000000, 0,   128000,  1536000, 0, 100000000, 0,   384000,   768000, 0, 0.240},
158     {  4000000, 0,   128000,  3000000, 0,   4000000, 0,   384000,   768000, 0, 0.120},
159     {  4000000, 0,   128000,  3000000, 0,  20000000, 0,   384000,   768000, 0, 0.420},
160     {  4000000, 0,   128000,  3000000, 0, 100000000, 0,   384000,   768000, 0, 0.840},
161     { 20000000, 0,   128000,  3000000, 0,  20000000, 0,   384000,   768000, 0, 0.300},
162     { 20000000, 0,   128000,  3000000, 0, 100000000, 0,   384000,   768000, 0, 0.930},
163     {100000000, 0,   128000,  3000000, 0, 100000000, 0,   384000,   768000, 0, 0.390},
164     {  4000000, 0,   384000,   768000, 0,   4000000, 0,   128000,  1536000, 0, 0.720},
165     {  4000000, 0,   384000,   768000, 0,  20000000, 0,   128000,  1536000, 0, 1.470},
166     {  4000000, 0,   384000,   768000, 0, 100000000, 0,   128000,  1536000, 0, 0.840},
167     { 20000000, 0,   384000,   768000, 0,  20000000, 0,   128000,  1536000, 0, 0.750},
168     { 20000000, 0,   384000,   768000, 0, 100000000, 0,   128000,  1536000, 0, 0.855},
169     {100000000, 0,   384000,   768000, 0, 100000000, 0,   128000,  1536000, 0, 0.240},
170     {  4000000, 0,   384000,  1536000, 0,   4000000, 0,   384000,  1536000, 0, 1.440},
171     {  4000000, 0,   384000,  1536000, 0,  20000000, 0,   384000,  1536000, 0, 3.000},
172     {  4000000, 0,   384000,  1536000, 0, 100000000, 0,   384000,  1536000, 0, 1.920},
173     { 20000000, 0,   384000,  1536000, 0,  20000000, 0,   384000,  1536000, 0, 1.563},
174     { 20000000, 0,   384000,  1536000, 0, 100000000, 0,   384000,  1536000, 0, 2.000},
175     {100000000, 0,   384000,  1536000, 0, 100000000, 0,   384000,  1536000, 0, 0.640},
176     {  4000000, 0,   384000,  3000000, 0,   4000000, 0,   384000,  1536000, 0, 0.240},
177     {  4000000, 0,   384000,  3000000, 0,  20000000, 0,   384000,  1536000, 0, 0.850},
178     {  4000000, 0,   384000,  3000000, 0, 100000000, 0,   384000,  1536000, 0, 1.720},
179     { 20000000, 0,   384000,  3000000, 0,  20000000, 0,   384000,  1536000, 0, 0.625},
180     { 20000000, 0,   384000,  3000000, 0, 100000000, 0,   384000,  1536000, 0, 2.025},
181     {100000000, 0,   384000,  3000000, 0, 100000000, 0,   384000,  1536000, 0, 1.040},
182     {  4000000, 0,   384000,   768000, 0,   4000000, 0,   128000,  3000000, 0, 0.120},
183     {  4000000, 0,   384000,   768000, 0,  20000000, 0,   128000,  3000000, 0, 0.420},
184     {  4000000, 0,   384000,   768000, 0, 100000000, 0,   128000,  3000000, 0, 0.840},
185     { 20000000, 0,   384000,   768000, 0,  20000000, 0,   128000,  3000000, 0, 0.300},
186     { 20000000, 0,   384000,   768000, 0, 100000000, 0,   128000,  3000000, 0, 0.930},
187     {100000000, 0,   384000,   768000, 0, 100000000, 0,   128000,  3000000, 0, 0.390},
188     {  4000000, 0,   384000,  1536000, 0,   4000000, 0,   384000,  3000000, 0, 0.240},
189     {  4000000, 0,   384000,  1536000, 0,  20000000, 0,   384000,  3000000, 0, 0.850},
190     {  4000000, 0,   384000,  1536000, 0, 100000000, 0,   384000,  3000000, 0, 1.720},
191     { 20000000, 0,   384000,  1536000, 0,  20000000, 0,   384000,  3000000, 0, 0.625},
192     { 20000000, 0,   384000,  1536000, 0, 100000000, 0,   384000,  3000000, 0, 2.025},
193     {100000000, 0,   384000,  1536000, 0, 100000000, 0,   384000,  3000000, 0, 1.040},
194     {  4000000, 0,   384000,  3000000, 0,   4000000, 0,   384000,  3000000, 0, 0.040},
195     {  4000000, 0,   384000,  3000000, 0,  20000000, 0,   384000,  3000000, 0, 0.200},
196     {  4000000, 0,   384000,  3000000, 0, 100000000, 0,   384000,  3000000, 0, 0.520},
197     { 20000000, 0,   384000,  3000000, 0,  20000000, 0,   384000,  3000000, 0, 0.250},
198     { 20000000, 0,   384000,  3000000, 0, 100000000, 0,   384000,  3000000, 0, 1.300},
199     {100000000, 0,   384000,  3000000, 0, 100000000, 0,   384000,  3000000, 0, 1.690},
200     {  4000000, 0,   128000,  1536000, 0,  20000000, 0,   768000,  1536000, 0, 0.090},
201     {  4000000, 0,   128000,  1536000, 0, 100000000, 0,   768000,  1536000, 0, 0.360},
202     { 20000000, 0,   128000,  1536000, 0,  20000000, 0,   768000,  1536000, 0, 0.090},
203     { 20000000, 0,   128000,  1536000, 0, 100000000, 0,   768000,  1536000, 0, 0.405},
204     {100000000, 0,   128000,  1536000, 0, 100000000, 0,   768000,  1536000, 0, 0.180},
205     {  4000000, 0,   128000,  7000000, 0,  20000000, 0,   768000,   768000, 0, 0.270},
206     {  4000000, 0,   128000,  7000000, 0, 100000000, 0,   768000,   768000, 0, 1.080},
207     { 20000000, 0,   128000,  7000000, 0,  20000000, 0,   768000,   768000, 0, 0.270},
208     { 20000000, 0,   128000,  7000000, 0, 100000000, 0,   768000,   768000, 0, 1.215},
209     {100000000, 0,   128000,  7000000, 0, 100000000, 0,   768000,   768000, 0, 0.540},
210     {  4000000, 0,   128000, 13000000, 0,  20000000, 0,   768000, 13000000, 0, 0.030},
211     {  4000000, 0,   128000, 13000000, 0, 100000000, 0,   768000, 13000000, 0, 0.120},
212     { 20000000, 0,   128000, 13000000, 0,  20000000, 0,   768000, 13000000, 0, 0.030},
213     { 20000000, 0,   128000, 13000000, 0, 100000000, 0,   768000, 13000000, 0, 0.135},
214     {100000000, 0,   128000, 13000000, 0, 100000000, 0,   768000, 13000000, 0, 0.060},
215     {  4000000, 0,   384000,  1536000, 0,  20000000, 0,  1536000,  1536000, 0, 0.180},
216     {  4000000, 0,   384000,  1536000, 0, 100000000, 0,  1536000,  1536000, 0, 0.720},
217     { 20000000, 0,   384000,  1536000, 0,  20000000, 0,  1536000,  1536000, 0, 0.188},
218     { 20000000, 0,   384000,  1536000, 0, 100000000, 0,  1536000,  1536000, 0, 0.870},
219     {100000000, 0,   384000,  1536000, 0, 100000000, 0,  1536000,  1536000, 0, 0.480},
220     {  4000000, 0,   384000,  7000000, 0,  20000000, 0,   768000,  1536000, 0, 0.540},
221     {  4000000, 0,   384000,  7000000, 0, 100000000, 0,   768000,  1536000, 0, 2.160},
222     { 20000000, 0,   384000,  7000000, 0,  20000000, 0,   768000,  1536000, 0, 0.563},
223     { 20000000, 0,   384000,  7000000, 0, 100000000, 0,   768000,  1536000, 0, 2.610},
224     {100000000, 0,   384000,  7000000, 0, 100000000, 0,   768000,  1536000, 0, 1.440},
225     {  4000000, 0,   384000, 13000000, 0,  20000000, 0,  1536000, 13000000, 0, 0.060},
226     {  4000000, 0,   384000, 13000000, 0, 100000000, 0,  1536000, 13000000, 0, 0.240},
227     { 20000000, 0,   384000, 13000000, 0,  20000000, 0,  1536000, 13000000, 0, 0.063},
228     { 20000000, 0,   384000, 13000000, 0, 100000000, 0,  1536000, 13000000, 0, 0.290},
229     {100000000, 0,   384000, 13000000, 0, 100000000, 0,  1536000, 13000000, 0, 0.160},
230     {  4000000, 0,   384000,  1536000, 0,  20000000, 0,  1536000,  3000000, 0, 0.030},
231     {  4000000, 0,   384000,  1536000, 0, 100000000, 0,  1536000,  3000000, 0, 0.120},
232     { 20000000, 0,   384000,  1536000, 0,  20000000, 0,  1536000,  3000000, 0, 0.075},
233     { 20000000, 0,   384000,  1536000, 0, 100000000, 0,  1536000,  3000000, 0, 0.495},
234     {100000000, 0,   384000,  1536000, 0, 100000000, 0,  1536000,  3000000, 0, 0.780},
235     {  4000000, 0,   384000,  7000000, 0,  20000000, 0,   768000,  3000000, 0, 0.090},
236     {  4000000, 0,   384000,  7000000, 0, 100000000, 0,   768000,  3000000, 0, 0.360},
237     { 20000000, 0,   384000,  7000000, 0,  20000000, 0,   768000,  3000000, 0, 0.225},
238     { 20000000, 0,   384000,  7000000, 0, 100000000, 0,   768000,  3000000, 0, 1.485},
239     {100000000, 0,   384000,  7000000, 0, 100000000, 0,   768000,  3000000, 0, 2.340},
240     {  4000000, 0,   384000, 13000000, 0,  20000000, 0,  3000000, 13000000, 0, 0.010},
241     {  4000000, 0,   384000, 13000000, 0, 100000000, 0,  3000000, 13000000, 0, 0.040},
242     { 20000000, 0,   384000, 13000000, 0,  20000000, 0,  3000000, 13000000, 0, 0.025},
243     { 20000000, 0,   384000, 13000000, 0, 100000000, 0,  3000000, 13000000, 0, 0.165},
244     {100000000, 0,   384000, 13000000, 0, 100000000, 0,  3000000, 13000000, 0, 0.260},
245     {  4000000, 0,   768000,  1536000, 0,  20000000, 0,   128000,  1536000, 0, 0.090},
246     { 20000000, 0,   768000,  1536000, 0,  20000000, 0,   128000,  1536000, 0, 0.090},
247     { 20000000, 0,   768000,  1536000, 0, 100000000, 0,   128000,  1536000, 0, 0.405},
248     {  4000000, 0,   768000,  1536000, 0, 100000000, 0,   128000,  1536000, 0, 0.360},
249     {100000000, 0,   768000,  1536000, 0, 100000000, 0,   128000,  1536000, 0, 0.180},
250     {  4000000, 0,  1536000,  1536000, 0,  20000000, 0,   384000,  1536000, 0, 0.180},
251     { 20000000, 0,  1536000,  1536000, 0,  20000000, 0,   384000,  1536000, 0, 0.188},
252     { 20000000, 0,  1536000,  1536000, 0, 100000000, 0,   384000,  1536000, 0, 0.870},
253     {  4000000, 0,  1536000,  1536000, 0, 100000000, 0,   384000,  1536000, 0, 0.720},
254     {100000000, 0,  1536000,  1536000, 0, 100000000, 0,   384000,  1536000, 0, 0.480},
255     {  4000000, 0,  1536000,  3000000, 0,  20000000, 0,   384000,  1536000, 0, 0.030},
256     { 20000000, 0,  1536000,  3000000, 0,  20000000, 0,   384000,  1536000, 0, 0.075},
257     { 20000000, 0,  1536000,  3000000, 0, 100000000, 0,   384000,  1536000, 0, 0.495},
258     {  4000000, 0,  1536000,  3000000, 0, 100000000, 0,   384000,  1536000, 0, 0.120},
259     {100000000, 0,  1536000,  3000000, 0, 100000000, 0,   384000,  1536000, 0, 0.780},
260     {  4000000, 0,   768000,   768000, 0,  20000000, 0,   128000,  7000000, 0, 0.270},
261     { 20000000, 0,   768000,   768000, 0,  20000000, 0,   128000,  7000000, 0, 0.270},
262     { 20000000, 0,   768000,   768000, 0, 100000000, 0,   128000,  7000000, 0, 1.215},
263     {  4000000, 0,   768000,   768000, 0, 100000000, 0,   128000,  7000000, 0, 1.080},
264     {100000000, 0,   768000,   768000, 0, 100000000, 0,   128000,  7000000, 0, 0.540},
265     {  4000000, 0,   768000,  1536000, 0,  20000000, 0,   384000,  7000000, 0, 0.540},
266     { 20000000, 0,   768000,  1536000, 0,  20000000, 0,   384000,  7000000, 0, 0.563},
267     { 20000000, 0,   768000,  1536000, 0, 100000000, 0,   384000,  7000000, 0, 2.610},
268     {  4000000, 0,   768000,  1536000, 0, 100000000, 0,   384000,  7000000, 0, 2.160},
269     {100000000, 0,   768000,  1536000, 0, 100000000, 0,   384000,  7000000, 0, 1.440},
270     {  4000000, 0,   768000,  3000000, 0,  20000000, 0,   384000,  7000000, 0, 0.090},
271     { 20000000, 0,   768000,  3000000, 0,  20000000, 0,   384000,  7000000, 0, 0.225},
272     { 20000000, 0,   768000,  3000000, 0, 100000000, 0,   384000,  7000000, 0, 1.485},
273     {  4000000, 0,   768000,  3000000, 0, 100000000, 0,   384000,  7000000, 0, 0.360},
274     {100000000, 0,   768000,  3000000, 0, 100000000, 0,   384000,  7000000, 0, 2.340},
275     {  4000000, 0,   768000, 13000000, 0,  20000000, 0,   128000, 13000000, 0, 0.030},
276     { 20000000, 0,   768000, 13000000, 0,  20000000, 0,   128000, 13000000, 0, 0.030},
277     { 20000000, 0,   768000, 13000000, 0, 100000000, 0,   128000, 13000000, 0, 0.135},
278     {  4000000, 0,   768000, 13000000, 0, 100000000, 0,   128000, 13000000, 0, 0.120},
279     {100000000, 0,   768000, 13000000, 0, 100000000, 0,   128000, 13000000, 0, 0.060},
280     {  4000000, 0,  1536000, 13000000, 0,  20000000, 0,   384000, 13000000, 0, 0.060},
281     { 20000000, 0,  1536000, 13000000, 0,  20000000, 0,   384000, 13000000, 0, 0.063},
282     { 20000000, 0,  1536000, 13000000, 0, 100000000, 0,   384000, 13000000, 0, 0.290},
283     {  4000000, 0,  1536000, 13000000, 0, 100000000, 0,   384000, 13000000, 0, 0.240},
284     {100000000, 0,  1536000, 13000000, 0, 100000000, 0,   384000, 13000000, 0, 0.160},
285     {  4000000, 0,  3000000, 13000000, 0,  20000000, 0,   384000, 13000000, 0, 0.010},
286     { 20000000, 0,  3000000, 13000000, 0,  20000000, 0,   384000, 13000000, 0, 0.025},
287     { 20000000, 0,  3000000, 13000000, 0, 100000000, 0,   384000, 13000000, 0, 0.165},
288     {  4000000, 0,  3000000, 13000000, 0, 100000000, 0,   384000, 13000000, 0, 0.040},
289     {100000000, 0,  3000000, 13000000, 0, 100000000, 0,   384000, 13000000, 0, 0.260},
290     { 20000000, 0,  1536000,  1536000, 0,  20000000, 0,  1536000,  1536000, 0, 0.023},
291     { 20000000, 0,  1536000,  1536000, 0, 100000000, 0,  1536000,  1536000, 0, 0.180},
292     {100000000, 0,  1536000,  1536000, 0, 100000000, 0,  1536000,  1536000, 0, 0.360},
293     { 20000000, 0,  1536000,  7000000, 0,  20000000, 0,   768000,  1536000, 0, 0.068},
294     { 20000000, 0,  1536000,  7000000, 0, 100000000, 0,   768000,  1536000, 0, 0.540},
295     {100000000, 0,  1536000,  7000000, 0, 100000000, 0,   768000,  1536000, 0, 1.080},
296     { 20000000, 0,  1536000, 13000000, 0,  20000000, 0,  1536000, 13000000, 0, 0.015},
297     { 20000000, 0,  1536000, 13000000, 0, 100000000, 0,  1536000, 13000000, 0, 0.120},
298     {100000000, 0,  1536000, 13000000, 0, 100000000, 0,  1536000, 13000000, 0, 0.240},
299     { 20000000, 0,   768000,  1536000, 0,  20000000, 0,  1536000,  7000000, 0, 0.068},
300     { 20000000, 0,   768000,  1536000, 0, 100000000, 0,  1536000,  7000000, 0, 0.540},
301     {100000000, 0,   768000,  1536000, 0, 100000000, 0,  1536000,  7000000, 0, 1.080},
302     { 20000000, 0,   768000,  7000000, 0,  20000000, 0,   768000,  7000000, 0, 0.203},
303     { 20000000, 0,   768000,  7000000, 0, 100000000, 0,   768000,  7000000, 0, 1.620},
304     {100000000, 0,   768000,  7000000, 0, 100000000, 0,   768000,  7000000, 0, 3.240},
305     { 20000000, 0,   768000, 13000000, 0,  20000000, 0,  7000000, 13000000, 0, 0.023},
306     { 20000000, 0,   768000, 13000000, 0, 100000000, 0,  7000000, 13000000, 0, 0.180},
307     {100000000, 0,   768000, 13000000, 0, 100000000, 0,  7000000, 13000000, 0, 0.360},
308     { 20000000, 0,  7000000, 13000000, 0,  20000000, 0,   768000, 13000000, 0, 0.023},
309     { 20000000, 0,  7000000, 13000000, 0, 100000000, 0,   768000, 13000000, 0, 0.180},
310     {100000000, 0,  7000000, 13000000, 0, 100000000, 0,   768000, 13000000, 0, 0.360},
311     { 20000000, 0, 13000000, 13000000, 0,  20000000, 0, 13000000, 13000000, 0, 0.003},
312     { 20000000, 0, 13000000, 13000000, 0, 100000000, 0, 13000000, 13000000, 0, 0.020},
313     {100000000, 0, 13000000, 13000000, 0, 100000000, 0, 13000000, 13000000, 0, 0.040}
314 };
315 
316 g1050_model_t g1050_standard_models[9] =
317 {
318     {   /* Severity 0 - no impairment */
319         {
320             0,          /*! Percentage likelihood of occurance in scenario A */
321             0,          /*! Percentage likelihood of occurance in scenario B */
322             0,          /*! Percentage likelihood of occurance in scenario C */
323         },
324         {
325             0.0,        /*! Percentage occupancy */
326             1508,       /*! MTU */
327             0.0         /*! Peak jitter */
328         },
329         {
330             0.0,        /*! Percentage occupancy */
331             512,        /*! MTU */
332             0.0         /*! Peak jitter */
333         },
334         {
335             0.0,        /*! Basic delay of the regional backbone, in seconds */
336             0.0,        /*! Basic delay of the intercontinental backbone, in seconds */
337             0.0,        /*! Percentage packet loss of the backbone */
338             0.0,        /*! Maximum jitter of the backbone, in seconds */
339             0.0,        /*! Interval between the backbone route flapping between two paths, in seconds */
340             0.0,        /*! The difference in backbone delay between the two routes we flap between, in seconds */
341             0.0,        /*! The interval between link failures, in seconds */
342             0.0,        /*! The duration of link failures, in seconds */
343             0.0,        /*! Probability of packet loss in the backbone, in percent */
344             0.0         /*! Probability of a packet going out of sequence in the backbone. */
345         },
346         {
347             0.0,        /*! Percentage occupancy */
348             512,        /*! MTU */
349             0.0         /*! Peak jitter */
350         },
351         {
352             0.0,        /*! Percentage occupancy */
353             1508,       /*! MTU */
354             0.0         /*! Peak jitter */
355         }
356     },
357     {   /* Severity A */
358         {
359             50,         /*! Percentage likelihood of occurance in scenario A */
360             5,          /*! Percentage likelihood of occurance in scenario B */
361             5,          /*! Percentage likelihood of occurance in scenario C */
362         },
363         {
364             1.0,        /*! Percentage occupancy */
365             1508,       /*! MTU */
366             0.0015      /*! Peak jitter */
367         },
368         {
369             0.0,        /*! Percentage occupancy */
370             512,        /*! MTU */
371             0.0         /*! Peak jitter */
372         },
373         {
374             0.004,      /*! Basic delay of the regional backbone, in seconds */
375             0.016,      /*! Basic delay of the intercontinental backbone, in seconds */
376             0.0,        /*! Percentage packet loss of the backbone */
377             0.005,      /*! Maximum jitter of the backbone, in seconds */
378             0.0,        /*! Interval between the backbone route flapping between two paths, in seconds */
379             0.0,        /*! The difference in backbone delay between the two routes we flap between, in seconds */
380             0.0,        /*! The interval between link failures, in seconds */
381             0.0,        /*! The duration of link failures, in seconds */
382             0.0,        /*! Probability of packet loss in the backbone, in percent */
383             0.0         /*! Probability of a packet going out of sequence in the backbone. */
384         },
385         {
386             0.0,        /*! Percentage occupancy */
387             512,        /*! MTU */
388             0.0         /*! Peak jitter */
389         },
390         {
391             1.0,        /*! Percentage occupancy */
392             1508,       /*! MTU */
393             0.0015      /*! Peak jitter */
394         }
395     },
396     {   /* Severity B */
397         {
398             30,         /*! Percentage likelihood of occurance in scenario A */
399             25,         /*! Percentage likelihood of occurance in scenario B */
400             5,          /*! Percentage likelihood of occurance in scenario C */
401         },
402         {
403             2.0,        /*! Percentage occupancy */
404             1508,       /*! MTU */
405             0.0015      /*! Peak jitter */
406         },
407         {
408             1.0,        /*! Percentage occupancy */
409             512,        /*! MTU */
410             0.0         /*! Peak jitter */
411         },
412         {
413             0.008,      /*! Basic delay of the regional backbone, in seconds */
414             0.032,      /*! Basic delay of the intercontinental backbone, in seconds */
415             0.01,       /*! Percentage packet loss of the backbone */
416             0.01,       /*! Maximum jitter of the backbone, in seconds */
417             3600.0,     /*! Interval between the backbone route flapping between two paths, in seconds */
418             0.002,      /*! The difference in backbone delay between the two routes we flap between, in seconds */
419             3600.0,     /*! The interval between link failures, in seconds */
420             0.064,      /*! The duration of link failures, in seconds */
421             0.0,        /*! Probability of packet loss in the backbone, in percent */
422             0.0         /*! Probability of a packet going out of sequence in the backbone. */
423         },
424         {
425             1.0,        /*! Percentage occupancy */
426             512,        /*! MTU */
427             0.0         /*! Peak jitter */
428         },
429         {
430             2.0,        /*! Percentage occupancy */
431             1508,       /*! MTU */
432             0.0015      /*! Peak jitter */
433         }
434     },
435     {   /* Severity C */
436         {
437             15,         /*! Percentage likelihood of occurance in scenario A */
438             30,         /*! Percentage likelihood of occurance in scenario B */
439             10,         /*! Percentage likelihood of occurance in scenario C */
440         },
441         {
442             3.0,        /*! Percentage occupancy */
443             1508,       /*! MTU */
444             0.0015      /*! Peak jitter */
445         },
446         {
447             2.0,        /*! Percentage occupancy */
448             1508,       /*! MTU */
449             0.0         /*! Peak jitter */
450         },
451         {
452             0.016,      /*! Basic delay of the regional backbone, in seconds */
453             0.064,      /*! Basic delay of the intercontinental backbone, in seconds */
454             0.02,       /*! Percentage packet loss of the backbone */
455             0.016,      /*! Maximum jitter of the backbone, in seconds */
456             1800.0,     /*! Interval between the backbone route flapping between two paths, in seconds */
457             0.004,      /*! The difference in backbone delay between the two routes we flap between, in seconds */
458             1800.0,     /*! The interval between link failures, in seconds */
459             0.128,      /*! The duration of link failures, in seconds */
460             0.0,        /*! Probability of packet loss in the backbone, in percent */
461             0.0         /*! Probability of a packet going out of sequence in the backbone. */
462         },
463         {
464             2.0,        /*! Percentage occupancy */
465             1508,       /*! MTU */
466             0.0         /*! Peak jitter */
467         },
468         {
469             3.0,        /*! Percentage occupancy */
470             1508,       /*! MTU */
471             0.0015      /*! Peak jitter */
472         }
473     },
474     {   /* Severity D */
475         {
476             5,          /*! Percentage likelihood of occurance in scenario A */
477             25,         /*! Percentage likelihood of occurance in scenario B */
478             15,         /*! Percentage likelihood of occurance in scenario C */
479         },
480         {
481             5.0,         /*! Percentage occupancy */
482             1508,       /*! MTU */
483             0.0015      /*! Peak jitter */
484         },
485         {
486             4.0,        /*! Percentage occupancy */
487             1508,       /*! MTU */
488             0.0         /*! Peak jitter */
489         },
490         {
491             0.032,      /*! Basic delay of the regional backbone, in seconds */
492             0.128,      /*! Basic delay of the intercontinental backbone, in seconds */
493             0.04,       /*! Percentage packet loss of the backbone */
494             0.04,       /*! Maximum jitter of the backbone, in seconds */
495             900.0,      /*! Interval between the backbone route flapping between two paths, in seconds */
496             0.008,      /*! The difference in backbone delay between the two routes we flap between, in seconds */
497             900.0,      /*! The interval between link failures, in seconds */
498             0.256,      /*! The duration of link failures, in seconds */
499             0.0,        /*! Probability of packet loss in the backbone, in percent */
500             0.0         /*! Probability of a packet going out of sequence in the backbone. */
501         },
502         {
503             4.0,        /*! Percentage occupancy */
504             1508,       /*! MTU */
505             0.0         /*! Peak jitter */
506         },
507         {
508             5.0,        /*! Percentage occupancy */
509             1508,       /*! MTU */
510             0.0015      /*! Peak jitter */
511         }
512     },
513     {   /* Severity E */
514         {
515             0,          /*! Percentage likelihood of occurance in scenario A */
516             10,         /*! Percentage likelihood of occurance in scenario B */
517             20,         /*! Percentage likelihood of occurance in scenario C */
518         },
519         {
520             8.0,        /*! Percentage occupancy */
521             1508,       /*! MTU */
522             0.0015      /*! Peak jitter */
523         },
524         {
525             8.0,        /*! Percentage occupancy */
526             1508,       /*! MTU */
527             0.0         /*! Peak jitter */
528         },
529         {
530             0.064,      /*! Basic delay of the regional backbone, in seconds */
531             0.196,      /*! Basic delay of the intercontinental backbone, in seconds */
532             0.1,        /*! Percentage packet loss of the backbone */
533             0.07,       /*! Maximum jitter of the backbone, in seconds */
534             480.0,      /*! Interval between the backbone route flapping between two paths, in seconds */
535             0.016,      /*! The difference in backbone delay between the two routes we flap between, in seconds */
536             480.0,      /*! The interval between link failures, in seconds */
537             0.4,        /*! The duration of link failures, in seconds */
538             0.0,        /*! Probability of packet loss in the backbone, in percent */
539             0.0         /*! Probability of a packet going out of sequence in the backbone. */
540         },
541         {
542             8.0,        /*! Percentage occupancy */
543             1508,       /*! MTU */
544             0.0         /*! Peak jitter */
545         },
546         {
547             8.0,        /*! Percentage occupancy */
548             1508,       /*! MTU */
549             0.0015      /*! Peak jitter */
550         }
551     },
552     {   /* Severity F */
553         {
554             0,          /*! Percentage likelihood of occurance in scenario A */
555             0,          /*! Percentage likelihood of occurance in scenario B */
556             25,         /*! Percentage likelihood of occurance in scenario C */
557         },
558         {
559             12.0,       /*! Percentage occupancy */
560             1508,       /*! MTU */
561             0.0015      /*! Peak jitter */
562         },
563         {
564             15.0,       /*! Percentage occupancy */
565             1508,       /*! MTU */
566             0.0         /*! Peak jitter */
567         },
568         {
569             0.128,      /*! Basic delay of the regional backbone, in seconds */
570             0.256,      /*! Basic delay of the intercontinental backbone, in seconds */
571             0.2,        /*! Percentage packet loss of the backbone */
572             0.1,        /*! Maximum jitter of the backbone, in seconds */
573             240.0,      /*! Interval between the backbone route flapping between two paths, in seconds */
574             0.032,      /*! The difference in backbone delay between the two routes we flap between, in seconds */
575             240.0,      /*! The interval between link failures, in seconds */
576             0.8,        /*! The duration of link failures, in seconds */
577             0.0,        /*! Probability of packet loss in the backbone, in percent */
578             0.0         /*! Probability of a packet going out of sequence in the backbone. */
579         },
580         {
581             15.0,       /*! Percentage occupancy */
582             1508,       /*! MTU */
583             0.0         /*! Peak jitter */
584         },
585         {
586             12.0,       /*! Percentage occupancy */
587             1508,       /*! MTU */
588             0.0015      /*! Peak jitter */
589         }
590     },
591     {   /* Severity G */
592         {
593             0,          /*! Percentage likelihood of occurance in scenario A */
594             0,          /*! Percentage likelihood of occurance in scenario B */
595             15,         /*! Percentage likelihood of occurance in scenario C */
596         },
597         {
598             16.0,       /*! Percentage occupancy */
599             1508,       /*! MTU */
600             0.0015      /*! Peak jitter */
601         },
602         {
603             30.0,       /*! Percentage occupancy */
604             1508,       /*! MTU */
605             0.0         /*! Peak jitter */
606         },
607         {
608             0.256,      /*! Basic delay of the regional backbone, in seconds */
609             0.512,      /*! Basic delay of the intercontinental backbone, in seconds */
610             0.5,        /*! Percentage packet loss of the backbone */
611             0.15,       /*! Maximum jitter of the backbone, in seconds */
612             120.0,      /*! Interval between the backbone route flapping between two paths, in seconds */
613             0.064,      /*! The difference in backbone delay between the two routes we flap between, in seconds */
614             120.0,      /*! The interval between link failures, in seconds */
615             1.6,        /*! The duration of link failures, in seconds */
616             0.0,        /*! Probability of packet loss in the backbone, in percent */
617             0.0         /*! Probability of a packet going out of sequence in the backbone. */
618         },
619         {
620             30.0,       /*! Percentage occupancy */
621             1508,       /*! MTU */
622             0.0         /*! Peak jitter */
623         },
624         {
625             16.0,       /*! Percentage occupancy */
626             1508,       /*! MTU */
627             0.0015      /*! Peak jitter */
628         }
629     },
630     {   /* Severity H */
631         {
632             0,          /*! Percentage likelihood of occurance in scenario A */
633             0,          /*! Percentage likelihood of occurance in scenario B */
634             5,          /*! Percentage likelihood of occurance in scenario C */
635         },
636         {
637             20.0,       /*! Percentage occupancy */
638             1508,       /*! MTU */
639             0.0015      /*! Peak jitter */
640         },
641         {
642             50.0,       /*! Percentage occupancy */
643             1508,       /*! MTU */
644             0.0         /*! Peak jitter */
645         },
646         {
647             0.512,      /*! Basic delay of the regional backbone, in seconds */
648             0.768,      /*! Basic delay of the intercontinental backbone, in seconds */
649             1.0,        /*! Percentage packet loss of the backbone */
650             0.5,        /*! Maximum jitter of the backbone, in seconds */
651             60.0,       /*! Interval between the backbone route flapping between two paths, in seconds */
652             0.128,      /*! The difference in backbone delay between the two routes we flap between, in seconds */
653             60.0,       /*! The interval between link failures, in seconds */
654             3.0,        /*! The duration of link failures, in seconds */
655             1.0,        /*! Probability of packet loss in the backbone, in percent */
656             1.0         /*! Probability of a packet going out of sequence in the backbone. */
657         },
658         {
659             50.0,       /*! Percentage occupancy */
660             1508,       /*! MTU */
661             0.0         /*! Peak jitter */
662         },
663         {
664             20.0,       /*! Percentage occupancy */
665             1508,       /*! MTU */
666             0.0015      /*! Peak jitter */
667         }
668     }
669 };
670 
671 #if defined(HAVE_DRAND48)
q1050_rand_init(void)672 static __inline__ void q1050_rand_init(void)
673 {
674     srand48(time(NULL));
675 }
676 /*- End of function --------------------------------------------------------*/
677 
q1050_rand(void)678 static __inline__ double q1050_rand(void)
679 {
680     return drand48();
681 }
682 /*- End of function --------------------------------------------------------*/
683 #else
q1050_rand_init(void)684 static __inline__ void q1050_rand_init(void)
685 {
686     srand(time(NULL));
687 }
688 /*- End of function --------------------------------------------------------*/
689 
q1050_rand(void)690 static __inline__ double q1050_rand(void)
691 {
692     return (double) rand()/(double) RAND_MAX;
693 }
694 /*- End of function --------------------------------------------------------*/
695 #endif
696 
scale_probability(double prob,double scale)697 static __inline__ double scale_probability(double prob, double scale)
698 {
699     /* Re-calculate probability based on a different time interval */
700     return 1.0 - pow(1.0 - prob, scale);
701 }
702 /*- End of function --------------------------------------------------------*/
703 
g1050_segment_init(g1050_segment_state_t * s,int link_type,g1050_segment_constants_t * constants,g1050_segment_model_t * parms,int bit_rate,int multiple_access,int qos_enabled,int packet_size,int packet_rate)704 static void g1050_segment_init(g1050_segment_state_t *s,
705                                int link_type,
706                                g1050_segment_constants_t *constants,
707                                g1050_segment_model_t *parms,
708                                int bit_rate,
709                                int multiple_access,
710                                int qos_enabled,
711                                int packet_size,
712                                int packet_rate)
713 {
714     double x;
715     double packet_interval;
716 
717     memset(s, 0, sizeof(*s));
718 
719     packet_interval = 1000.0/packet_rate;
720     /* Some calculatons are common to both LAN and access links, and those that are not. */
721     s->link_type = link_type;
722     s->prob_loss_rate_change[0] = scale_probability(constants->prob_loss_rate_change[0]*parms->percentage_occupancy, 1.0/packet_interval);
723 
724     s->serial_delay = packet_size*8.0/bit_rate;
725     if (link_type == G1050_LAN_LINK)
726     {
727         s->prob_loss_rate_change[1] = scale_probability(constants->prob_loss_rate_change[1], 1.0/packet_interval);
728         s->prob_impulse[0] = constants->prob_impulse[0][0];
729         s->prob_impulse[1] = constants->prob_impulse[1][0];
730         s->impulse_coeff = constants->impulse_coeff;
731         s->impulse_height = parms->mtu*(8.0/bit_rate)*(1.0 + parms->percentage_occupancy/constants->impulse_height);
732     }
733     else if (link_type == G1050_ACCESS_LINK)
734     {
735         s->prob_loss_rate_change[1] = scale_probability(constants->prob_loss_rate_change[1]/(1.0 + parms->percentage_occupancy), 1.0/packet_interval);
736         s->prob_impulse[0] = scale_probability(constants->prob_impulse[0][0] + (parms->percentage_occupancy/2000.0), 1.0/packet_interval);
737         s->prob_impulse[1] = scale_probability(constants->prob_impulse[1][0] + (constants->prob_impulse[1][1]*parms->percentage_occupancy/100.0), 1.0/packet_interval);
738         s->impulse_coeff = 1.0 - scale_probability(1.0 - constants->impulse_coeff, 1.0/packet_interval);
739         x = (1.0 - constants->impulse_coeff)/(1.0 - s->impulse_coeff);
740         s->impulse_height = x*parms->mtu*(8.0/bit_rate)*(1.0 + parms->percentage_occupancy/constants->impulse_height);
741     }
742 
743     /* The following are calculated the same way for LAN and access links */
744     s->prob_packet_loss = constants->prob_packet_loss*parms->percentage_occupancy;
745     s->qos_enabled = qos_enabled;
746     s->multiple_access = multiple_access;
747     s->prob_packet_collision_loss = constants->prob_packet_collision_loss;
748     s->max_jitter = parms->max_jitter;
749 
750     /* The following is common state information to all links. */
751     s->high_loss = false;
752     s->congestion_delay = 0.0;
753     s->last_arrival_time = 0.0;
754 
755     /* Count of packets lost in this segment. */
756     s->lost_packets = 0;
757     s->lost_packets_2 = 0;
758 }
759 /*- End of function --------------------------------------------------------*/
760 
g1050_core_init(g1050_core_state_t * s,g1050_core_model_t * parms,int packet_rate)761 static void g1050_core_init(g1050_core_state_t *s, g1050_core_model_t *parms, int packet_rate)
762 {
763     memset(s, 0, sizeof(*s));
764 
765     /* Set up route flapping. */
766     /* This is the length of the period of both the delayed duration and the non-delayed. */
767     s->route_flap_interval = parms->route_flap_interval*G1050_TICKS_PER_SEC;
768 
769     /* How much additional delay is added or subtracted during route flaps. */
770     s->route_flap_delta = parms->route_flap_delay;
771 
772     /* Current tick count. This is initialized so that we are part way into the first
773        CLEAN interval before the first change occurs. This is a random portion of the
774        period. When we reach the first flap, the flapping in both directions becomes
775        periodic. */
776     s->route_flap_counter = s->route_flap_interval - 99 - floor(s->route_flap_interval*q1050_rand());
777     s->link_failure_interval_ticks = parms->link_failure_interval*G1050_TICKS_PER_SEC;
778 
779     /* Link failures occur when the count reaches this number of ticks. */
780     /* Duration of a failure. */
781     s->link_failure_duration_ticks = floor((G1050_TICKS_PER_SEC*parms->link_failure_duration));
782     /* How far into the first CLEAN interval we are. This is like the route flap initialzation. */
783     s->link_failure_counter = s->link_failure_interval_ticks - 99 - floor(s->link_failure_interval_ticks*q1050_rand());
784     s->link_recovery_counter = s->link_failure_duration_ticks;
785 
786     s->base_delay = parms->base_regional_delay;
787     s->max_jitter = parms->max_jitter;
788     s->prob_packet_loss = parms->prob_packet_loss/100.0;
789     s->prob_oos = parms->prob_oos/100.0;
790     s->last_arrival_time = 0.0;
791     s->delay_delta = 0;
792 
793     /* Count of packets lost in this segment. */
794     s->lost_packets = 0;
795     s->lost_packets_2 = 0;
796 }
797 /*- End of function --------------------------------------------------------*/
798 
g1050_segment_model(g1050_segment_state_t * s,double delays[],int len)799 static void g1050_segment_model(g1050_segment_state_t *s, double delays[], int len)
800 {
801     int i;
802     bool lose;
803     int was_high_loss;
804     double impulse;
805     double slice_delay;
806 
807     /* Compute delay and loss value for each time slice. */
808     for (i = 0;  i < len;  i++)
809     {
810         lose = false;
811         /* Initialize delay to the serial delay plus some jitter. */
812         slice_delay = s->serial_delay + s->max_jitter*q1050_rand();
813         /* If no QoS, do congestion delay and packet loss analysis. */
814         if (!s->qos_enabled)
815         {
816             /* To match the logic in G.1050 we need to record the current loss state, before
817                checking if we should change. */
818             was_high_loss = s->high_loss;
819             /* Toggle between the low-loss and high-loss states, based on the transition probability. */
820             if (q1050_rand() < s->prob_loss_rate_change[was_high_loss])
821                 s->high_loss = !s->high_loss;
822             impulse = 0.0;
823             if (q1050_rand() < s->prob_impulse[was_high_loss])
824             {
825                 impulse = s->impulse_height;
826                 if (!was_high_loss  ||  s->link_type == G1050_LAN_LINK)
827                     impulse *= q1050_rand();
828             }
829 
830             if (was_high_loss  &&  q1050_rand() < s->prob_packet_loss)
831                 lose = true;
832             /* Single pole LPF for the congestion delay impulses. */
833             s->congestion_delay = s->congestion_delay*s->impulse_coeff + impulse*(1.0 - s->impulse_coeff);
834             slice_delay += s->congestion_delay;
835         }
836         /* If duplex mismatch on LAN, packet loss based on loss probability. */
837         if (s->multiple_access  &&  (q1050_rand() < s->prob_packet_collision_loss))
838             lose = true;
839         /* Put computed delay into time slice array. */
840         if (lose)
841         {
842             delays[i] = PACKET_LOSS_TIME;
843             s->lost_packets++;
844         }
845         else
846         {
847             delays[i] = slice_delay;
848         }
849     }
850 }
851 /*- End of function --------------------------------------------------------*/
852 
g1050_core_model(g1050_core_state_t * s,double delays[],int len)853 static void g1050_core_model(g1050_core_state_t *s, double delays[], int len)
854 {
855     int32_t i;
856     bool lose;
857     double jitter_delay;
858 
859     for (i = 0;  i < len;  i++)
860     {
861         lose = false;
862         jitter_delay = s->base_delay + s->max_jitter*q1050_rand();
863         /* Route flapping */
864         if (--s->route_flap_counter <= 0)
865         {
866             /* Route changed */
867             s->delay_delta = s->route_flap_delta - s->delay_delta;
868             s->route_flap_counter = s->route_flap_interval;
869         }
870         if (q1050_rand() < s->prob_packet_loss)
871             lose = true;
872         /* Link failures */
873         if (--s->link_failure_counter <= 0)
874         {
875             /* We are in a link failure */
876             lose = true;
877             if (--s->link_recovery_counter <= 0)
878             {
879                 /* Leave failure state. */
880                 s->link_failure_counter = s->link_failure_interval_ticks;
881                 s->link_recovery_counter = s->link_failure_duration_ticks;
882                 lose = false;
883             }
884         }
885         if (lose)
886         {
887             delays[i] = PACKET_LOSS_TIME;
888             s->lost_packets++;
889         }
890         else
891         {
892             delays[i] = jitter_delay + s->delay_delta;
893         }
894     }
895 }
896 /*- End of function --------------------------------------------------------*/
897 
g1050_segment_delay(g1050_segment_state_t * s,double base_time,double arrival_times[],double delays[],int num_packets)898 static int g1050_segment_delay(g1050_segment_state_t *s,
899                                double base_time,
900                                double arrival_times[],
901                                double delays[],
902                                int num_packets)
903 {
904     int i;
905     int32_t departure_time;
906     int lost_packets;
907 
908     /* Add appropriate delays to the packets for the segments before the core. */
909     lost_packets = 0;
910     for (i = 0;  i < num_packets;  i++)
911     {
912         /* Apply half a millisecond of rounding, as we working in millisecond steps. */
913         departure_time = (arrival_times[i] + 0.0005 - base_time)*G1050_TICKS_PER_SEC;
914         if (arrival_times[i] == PACKET_LOSS_TIME)
915         {
916             /* Lost already */
917         }
918         else if (delays[departure_time] == PACKET_LOSS_TIME)
919         {
920             arrival_times[i] = PACKET_LOSS_TIME;
921             lost_packets++;
922         }
923         else
924         {
925             arrival_times[i] += delays[departure_time];
926             if (arrival_times[i] < s->last_arrival_time)
927                 arrival_times[i] = s->last_arrival_time;
928             else
929                 s->last_arrival_time = arrival_times[i];
930         }
931     }
932     return lost_packets;
933 }
934 /*- End of function --------------------------------------------------------*/
935 
g1050_segment_delay_preserve_order(g1050_segment_state_t * s,double base_time,double arrival_times_a[],double arrival_times_b[],double delays[],int num_packets)936 static int g1050_segment_delay_preserve_order(g1050_segment_state_t *s,
937                                               double base_time,
938                                               double arrival_times_a[],
939                                               double arrival_times_b[],
940                                               double delays[],
941                                               int num_packets)
942 {
943     int i;
944     int j;
945     int departure_time;
946     double last_arrival_time;
947     double last_arrival_time_temp;
948     int lost_packets;
949 
950     /* Add appropriate delays to the packets for the segments after the core. */
951     last_arrival_time = 0.0;
952     last_arrival_time_temp = 0.0;
953     lost_packets = 0;
954     for (i = 0;  i < num_packets;  i++)
955     {
956         /* We need to preserve the order that came out of the core, so we
957            use an alternate array for the results.  */
958         /* Apply half a millisecond of rounding, as we working in millisecond steps. */
959         departure_time = (arrival_times_a[i] + 0.0005 - base_time)*G1050_TICKS_PER_SEC;
960         if (arrival_times_a[i] == PACKET_LOSS_TIME)
961         {
962             /* Lost already */
963             arrival_times_b[i] = PACKET_LOSS_TIME;
964         }
965         else if (delays[departure_time] == PACKET_LOSS_TIME)
966         {
967             arrival_times_b[i] = PACKET_LOSS_TIME;
968             lost_packets++;
969         }
970         else
971         {
972             arrival_times_b[i] = arrival_times_a[i] + delays[departure_time];
973             if (arrival_times_a[i] < last_arrival_time)
974             {
975                 /* If a legitimate out of sequence packet is detected, search
976                    back a fixed amount of time to preserve order. */
977                 for (j = i - 1;  j >= 0;  j--)
978                 {
979                     if ((arrival_times_a[j] != PACKET_LOSS_TIME)
980                         &&
981                         (arrival_times_b[j] != PACKET_LOSS_TIME))
982                     {
983                         if ((arrival_times_a[i] - arrival_times_a[j]) > SEARCHBACK_PERIOD)
984                             break;
985                         if ((arrival_times_a[j] > arrival_times_a[i])
986                             &&
987                             (arrival_times_b[j] < arrival_times_b[i]))
988                         {
989                             arrival_times_b[j] = arrival_times_b[i];
990                         }
991                     }
992                 }
993             }
994             else
995             {
996                 last_arrival_time = arrival_times_a[i];
997                 if (arrival_times_b[i] < last_arrival_time_temp)
998                     arrival_times_b[i] = last_arrival_time_temp;
999                 else
1000                     last_arrival_time_temp = arrival_times_b[i];
1001             }
1002         }
1003     }
1004     return lost_packets;
1005 }
1006 /*- End of function --------------------------------------------------------*/
1007 
g1050_core_delay(g1050_core_state_t * s,double base_time,double arrival_times[],double delays[],int num_packets)1008 static int g1050_core_delay(g1050_core_state_t *s,
1009                             double base_time,
1010                             double arrival_times[],
1011                             double delays[],
1012                             int num_packets)
1013 {
1014     int i;
1015     int departure_time;
1016     int lost_packets;
1017 
1018     /* This element does NOT preserve packet order. */
1019     lost_packets = 0;
1020     for (i = 0;  i < num_packets;  i++)
1021     {
1022         /* Apply half a millisecond of rounding, as we working in millisecond steps. */
1023         departure_time = (arrival_times[i] + 0.0005 - base_time)*G1050_TICKS_PER_SEC;
1024         if (arrival_times[i] == PACKET_LOSS_TIME)
1025         {
1026             /* Lost already */
1027         }
1028         else if (delays[departure_time] == PACKET_LOSS_TIME)
1029         {
1030             arrival_times[i] = PACKET_LOSS_TIME;
1031             lost_packets++;
1032         }
1033         else
1034         {
1035             /* Not lost. Compute arrival time. */
1036             arrival_times[i] += delays[departure_time];
1037             if (arrival_times[i] < s->last_arrival_time)
1038             {
1039                 /* This packet is EARLIER than the last one. It is out of order! */
1040                 /* Do we allow it to stay out of order? */
1041                 if (q1050_rand() >= s->prob_oos)
1042                     arrival_times[i] = s->last_arrival_time;
1043             }
1044             else
1045             {
1046                 /* Packet is in the correct order, relative to the last one. */
1047                 s->last_arrival_time = arrival_times[i];
1048             }
1049         }
1050     }
1051     return lost_packets;
1052 }
1053 /*- End of function --------------------------------------------------------*/
1054 
g1050_simulate_chunk(g1050_state_t * s)1055 static void g1050_simulate_chunk(g1050_state_t *s)
1056 {
1057     int i;
1058 
1059     s->base_time += 1.0;
1060 
1061     memmove(&s->segment[0].delays[0], &s->segment[0].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[0].delays[0]));
1062     g1050_segment_model(&s->segment[0], &s->segment[0].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
1063 
1064     memmove(&s->segment[1].delays[0], &s->segment[1].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[1].delays[0]));
1065     g1050_segment_model(&s->segment[1], &s->segment[1].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
1066 
1067     memmove(&s->core.delays[0], &s->core.delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->core.delays[0]));
1068     g1050_core_model(&s->core, &s->core.delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
1069 
1070     memmove(&s->segment[2].delays[0], &s->segment[2].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[2].delays[0]));
1071     g1050_segment_model(&s->segment[2], &s->segment[2].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
1072 
1073     memmove(&s->segment[3].delays[0], &s->segment[3].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[3].delays[0]));
1074     g1050_segment_model(&s->segment[3], &s->segment[3].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
1075 
1076     memmove(&s->arrival_times_1[0], &s->arrival_times_1[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_1[0]));
1077     memmove(&s->arrival_times_2[0], &s->arrival_times_2[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_2[0]));
1078     for (i = 0;  i < s->packet_rate;  i++)
1079     {
1080         s->arrival_times_1[2*s->packet_rate + i] = s->base_time + 2.0 + (double) i/(double) s->packet_rate;
1081         s->arrival_times_2[2*s->packet_rate + i] = 0.0;
1082     }
1083 
1084     s->segment[0].lost_packets_2 += g1050_segment_delay(&s->segment[0], s->base_time, s->arrival_times_1, s->segment[0].delays, s->packet_rate);
1085     s->segment[1].lost_packets_2 += g1050_segment_delay(&s->segment[1], s->base_time, s->arrival_times_1, s->segment[1].delays, s->packet_rate);
1086     s->core.lost_packets_2 += g1050_core_delay(&s->core, s->base_time, s->arrival_times_1, s->core.delays, s->packet_rate);
1087     s->segment[2].lost_packets_2 += g1050_segment_delay_preserve_order(&s->segment[2], s->base_time, s->arrival_times_1, s->arrival_times_2, s->segment[2].delays, s->packet_rate);
1088     s->segment[3].lost_packets_2 += g1050_segment_delay_preserve_order(&s->segment[3], s->base_time, s->arrival_times_2, s->arrival_times_1, s->segment[3].delays, s->packet_rate);
1089 }
1090 /*- End of function --------------------------------------------------------*/
1091 
g1050_init(int model,int speed_pattern,int packet_size,int packet_rate)1092 SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
1093                                          int speed_pattern,
1094                                          int packet_size,
1095                                          int packet_rate)
1096 {
1097     g1050_state_t *s;
1098     g1050_constants_t *constants;
1099     g1050_channel_speeds_t *sp;
1100     g1050_model_t *mo;
1101     int i;
1102 
1103     /* If the random generator has not been seeded it might give endless
1104        zeroes - it depends on the platform. */
1105     for (i = 0;  i < 10;  i++)
1106     {
1107         if (q1050_rand() != 0.0)
1108             break;
1109     }
1110     if (i >= 10)
1111         q1050_rand_init();
1112     if ((s = (g1050_state_t *) malloc(sizeof(*s))) == NULL)
1113         return NULL;
1114     memset(s, 0, sizeof(*s));
1115 
1116     constants = &g1050_constants[0];
1117     sp = &g1050_speed_patterns[speed_pattern - 1];
1118     mo = &g1050_standard_models[model];
1119 
1120     memset(s, 0, sizeof(*s));
1121 
1122     s->packet_rate = packet_rate;
1123     s->packet_size = packet_size;
1124 
1125     g1050_segment_init(&s->segment[0],
1126                        G1050_LAN_LINK,
1127                        &constants->segment[0],
1128                        &mo->sidea_lan,
1129                        sp->sidea_lan_bit_rate,
1130                        sp->sidea_lan_multiple_access,
1131                        false,
1132                        packet_size,
1133                        packet_rate);
1134     g1050_segment_init(&s->segment[1],
1135                        G1050_ACCESS_LINK,
1136                        &constants->segment[1],
1137                        &mo->sidea_access_link,
1138                        sp->sidea_access_link_bit_rate_ab,
1139                        false,
1140                        sp->sidea_access_link_qos_enabled,
1141                        packet_size,
1142                        packet_rate);
1143     g1050_core_init(&s->core, &mo->core, packet_rate);
1144     g1050_segment_init(&s->segment[2],
1145                        G1050_ACCESS_LINK,
1146                        &constants->segment[2],
1147                        &mo->sideb_access_link,
1148                        sp->sideb_access_link_bit_rate_ba,
1149                        false,
1150                        sp->sideb_access_link_qos_enabled,
1151                        packet_size,
1152                        packet_rate);
1153     g1050_segment_init(&s->segment[3],
1154                        G1050_LAN_LINK,
1155                        &constants->segment[3],
1156                        &mo->sideb_lan,
1157                        sp->sideb_lan_bit_rate,
1158                        sp->sideb_lan_multiple_access,
1159                        false,
1160                        packet_size,
1161                        packet_rate);
1162 
1163     s->base_time = 0.0;
1164     /* Start with enough of the future modelled to allow for the worst jitter.
1165        After this we will always keep at least 2 seconds of the future modelled. */
1166     g1050_segment_model(&s->segment[0], s->segment[0].delays, 3*G1050_TICKS_PER_SEC);
1167     g1050_segment_model(&s->segment[1], s->segment[1].delays, 3*G1050_TICKS_PER_SEC);
1168     g1050_core_model(&s->core, s->core.delays, 3*G1050_TICKS_PER_SEC);
1169     g1050_segment_model(&s->segment[2], s->segment[2].delays, 3*G1050_TICKS_PER_SEC);
1170     g1050_segment_model(&s->segment[3], s->segment[3].delays, 3*G1050_TICKS_PER_SEC);
1171 
1172     /* Initialise the arrival times to the departure times */
1173     for (i = 0;  i < 3*s->packet_rate;  i++)
1174     {
1175         s->arrival_times_1[i] = s->base_time + (double) i/(double)s->packet_rate;
1176         s->arrival_times_2[i] = 0.0;
1177     }
1178 
1179     s->segment[0].lost_packets_2 += g1050_segment_delay(&s->segment[0], s->base_time, s->arrival_times_1, s->segment[0].delays, s->packet_rate);
1180     s->segment[1].lost_packets_2 += g1050_segment_delay(&s->segment[1], s->base_time, s->arrival_times_1, s->segment[1].delays, s->packet_rate);
1181     s->core.lost_packets_2 += g1050_core_delay(&s->core, s->base_time, s->arrival_times_1, s->core.delays, s->packet_rate);
1182     s->segment[2].lost_packets_2 += g1050_segment_delay_preserve_order(&s->segment[2], s->base_time, s->arrival_times_1, s->arrival_times_2, s->segment[2].delays, s->packet_rate);
1183     s->segment[3].lost_packets_2 += g1050_segment_delay_preserve_order(&s->segment[3], s->base_time, s->arrival_times_2, s->arrival_times_1, s->segment[3].delays, s->packet_rate);
1184 
1185     s->first = NULL;
1186     s->last = NULL;
1187     return s;
1188 }
1189 /*- End of function --------------------------------------------------------*/
1190 
g1050_free(g1050_state_t * s)1191 SPAN_DECLARE(int) g1050_free(g1050_state_t *s)
1192 {
1193     free(s);
1194     return 0;
1195 }
1196 /*- End of function --------------------------------------------------------*/
1197 
g1050_dump_parms(int model,int speed_pattern)1198 SPAN_DECLARE(void) g1050_dump_parms(int model, int speed_pattern)
1199 {
1200     g1050_channel_speeds_t *sp;
1201     g1050_model_t *mo;
1202 
1203     sp = &g1050_speed_patterns[speed_pattern - 1];
1204     mo = &g1050_standard_models[model];
1205 
1206     printf("Model %d%c\n", speed_pattern, 'A' + model - 1);
1207     printf("LOO %.6f%% %.6f%% %.6f%%\n", mo->loo[0]*sp->loo/100.0, mo->loo[1]*sp->loo/100.0, mo->loo[2]*sp->loo/100.0);
1208     printf("Side A LAN %dbps, %.3f%% occupancy, MTU %d, %s MA\n", sp->sidea_lan_bit_rate, mo->sidea_lan.percentage_occupancy, mo->sidea_lan.mtu, (sp->sidea_lan_multiple_access)  ?  ""  :  "no");
1209     printf("Side A access %dbps, %.3f%% occupancy, MTU %d, %s QoS\n", sp->sidea_access_link_bit_rate_ab, mo->sidea_access_link.percentage_occupancy, mo->sidea_access_link.mtu, (sp->sidea_access_link_qos_enabled)  ?  ""  :  "no");
1210     printf("Core delay %.4fs (%.4fs), peak jitter %.4fs, prob loss %.4f%%, prob OOS %.4f%%\n", mo->core.base_regional_delay, mo->core.base_intercontinental_delay, mo->core.max_jitter, mo->core.prob_packet_loss, mo->core.prob_oos);
1211     printf("     Route flap interval %.4fs, delay change %.4fs\n", mo->core.route_flap_interval, mo->core.route_flap_delay);
1212     printf("     Link failure interval %.4fs, duration %.4fs\n", mo->core.link_failure_interval, mo->core.link_failure_duration);
1213     printf("Side B access %dbps, %.3f%% occupancy, MTU %d, %s QoS\n", sp->sideb_access_link_bit_rate_ba, mo->sideb_access_link.percentage_occupancy, mo->sideb_access_link.mtu, (sp->sideb_access_link_qos_enabled)  ?  ""  :  "no");
1214     printf("Side B LAN %dbps, %.3f%% occupancy, MTU %d, %s MA\n", sp->sideb_lan_bit_rate, mo->sideb_lan.percentage_occupancy, mo->sideb_lan.mtu, (sp->sideb_lan_multiple_access)  ?  ""  :  "no");
1215 }
1216 /*- End of function --------------------------------------------------------*/
1217 
g1050_put(g1050_state_t * s,const uint8_t buf[],int len,int seq_no,double departure_time)1218 SPAN_DECLARE(int) g1050_put(g1050_state_t *s, const uint8_t buf[], int len, int seq_no, double departure_time)
1219 {
1220     g1050_queue_element_t *element;
1221     g1050_queue_element_t *e;
1222     double arrival_time;
1223 
1224     while (departure_time >= s->base_time + 1.0)
1225         g1050_simulate_chunk(s);
1226     arrival_time = s->arrival_times_1[(int) ((departure_time - s->base_time)*(double) s->packet_rate + 0.5)];
1227     if (arrival_time < 0)
1228     {
1229         /* This packet is lost */
1230         return 0;
1231     }
1232     if ((element = (g1050_queue_element_t *) malloc(sizeof(*element) + len)) == NULL)
1233         return -1;
1234     element->next = NULL;
1235     element->prev = NULL;
1236     element->seq_no = seq_no;
1237     element->departure_time = departure_time;
1238     element->arrival_time = arrival_time;
1239     element->len = len;
1240     memcpy(element->pkt, buf, len);
1241     /* Add it to the queue, in order */
1242     if (s->last == NULL)
1243     {
1244         /* The queue is empty */
1245         s->first =
1246         s->last = element;
1247     }
1248     else
1249     {
1250         for (e = s->last;  e;  e = e->prev)
1251         {
1252             if (e->arrival_time <= arrival_time)
1253                 break;
1254         }
1255         if (e)
1256         {
1257             element->next = e->next;
1258             element->prev = e;
1259             e->next = element;
1260         }
1261         else
1262         {
1263             element->next = s->first;
1264             s->first = element;
1265         }
1266         if (element->next)
1267             element->next->prev = element;
1268         else
1269             s->last = element;
1270     }
1271     //printf(">> Seq %d, departs %f, arrives %f\n", seq_no, departure_time, arrival_time);
1272     return len;
1273 }
1274 /*- End of function --------------------------------------------------------*/
1275 
g1050_get(g1050_state_t * s,uint8_t buf[],int max_len,double current_time,int * seq_no,double * departure_time,double * arrival_time)1276 SPAN_DECLARE(int) g1050_get(g1050_state_t *s, uint8_t buf[], int max_len, double current_time, int *seq_no, double *departure_time, double *arrival_time)
1277 {
1278     int len;
1279     g1050_queue_element_t *element;
1280 
1281     element = s->first;
1282     if (element == NULL)
1283     {
1284         if (seq_no)
1285             *seq_no = -1;
1286         if (departure_time)
1287             *departure_time = -1;
1288         if (arrival_time)
1289             *arrival_time = -1;
1290         return -1;
1291     }
1292     if (element->arrival_time > current_time)
1293     {
1294         if (seq_no)
1295             *seq_no = element->seq_no;
1296         if (departure_time)
1297             *departure_time = element->departure_time;
1298         if (arrival_time)
1299             *arrival_time = element->arrival_time;
1300         return -1;
1301     }
1302     /* Return the first packet in the queue */
1303     len = element->len;
1304     memcpy(buf, element->pkt, len);
1305     if (seq_no)
1306         *seq_no = element->seq_no;
1307     if (departure_time)
1308         *departure_time = element->departure_time;
1309     if (arrival_time)
1310         *arrival_time = element->arrival_time;
1311     //printf("<< Seq %d, arrives %f (%f)\n", element->seq_no, element->arrival_time, current_time);
1312 
1313     /* Remove it from the queue */
1314     if (s->first == s->last)
1315         s->last = NULL;
1316     s->first = element->next;
1317     if (element->next)
1318         element->next->prev = NULL;
1319     free(element);
1320     return len;
1321 }
1322 /*- End of function --------------------------------------------------------*/
1323 
g1050_queue_dump(g1050_state_t * s)1324 SPAN_DECLARE(void) g1050_queue_dump(g1050_state_t *s)
1325 {
1326     g1050_queue_element_t *e;
1327 
1328     printf("Queue scanned forewards\n");
1329     for (e = s->first;  e;  e = e->next)
1330         printf("Seq %5d, arrival %10.4f, len %3d\n", e->seq_no, e->arrival_time, e->len);
1331     printf("Queue scanned backwards\n");
1332     for (e = s->last;  e;  e = e->prev)
1333         printf("Seq %5d, arrival %10.4f, len %3d\n", e->seq_no, e->arrival_time, e->len);
1334 }
1335 /*- End of function --------------------------------------------------------*/
1336 /*- End of file ------------------------------------------------------------*/
1337