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