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