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