freeswitch/libs/spandsp/spandsp-sim/g1050.c

1328 lines
62 KiB
C

/*
* SpanDSP - a series of DSP components for telephony
*
* g1050.c - IP network modeling, as per G.1050/TIA-921.
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2007 Steve Underwood
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#if defined(HAVE_TGMATH_H)
#include <tgmath.h>
#endif
#if defined(HAVE_MATH_H)
#define GEN_CONST
#include <math.h>
#endif
#include "floating_fudge.h"
#include "spandsp.h"
#include "spandsp/g1050.h"
#define PACKET_LOSS_TIME -1
#define FALSE 0
#define TRUE (!FALSE)
g1050_constants_t g1050_constants[1] =
{
{
{
{ /* Side A LAN */
{
0.004, /*! Probability of loss rate change low->high */
0.1 /*! Probability of loss rate change high->low */
},
{
{
0.0, /*! Probability of an impulse */
0.0,
},
{
0.5,
0.0
}
},
1.0, /*! Impulse height, based on MTU and bit rate */
0.0, /*! Impulse decay coefficient */
0.001, /*! Probability of packet loss due to occupancy. */
0.15 /*! Probability of packet loss due to a multiple access collision. */
},
{ /* Side A access link */
{
0.0002, /*! Probability of loss rate change low->high */
0.2 /*! Probability of loss rate change high->low */
},
{
{
0.001, /*! Probability of an impulse */
0.0,
},
{
0.3,
0.4
}
},
40.0, /*! Impulse height, based on MTU and bit rate */
0.75, /*! Impulse decay coefficient */
0.0005, /*! Probability of packet loss due to occupancy. */
0.0 /*! Probability of packet loss due to a multiple access collision. */
},
{ /* Side B access link */
{
0.0002, /*! Probability of loss rate change low->high */
0.2 /*! Probability of loss rate change high->low */
},
{
{
0.001, /*! Probability of an impulse */
0.0,
},
{
0.3,
0.4
}
},
40.0, /*! Impulse height, based on MTU and bit rate */
0.75, /*! Impulse decay coefficient */
0.0005, /*! Probability of packet loss due to occupancy. */
0.0 /*! Probability of packet loss due to a multiple access collision. */
},
{ /* Side B LAN */
{
0.004, /*! Probability of loss rate change low->high */
0.1 /*! Probability of loss rate change high->low */
},
{
{
0.0, /*! Probability of an impulse */
0.0,
},
{
0.5,
0.0
}
},
1.0, /*! Impulse height, based on MTU and bit rate */
0.0, /*! Impulse decay coefficient */
0.001, /*! Probability of packet loss due to occupancy. */
0.15 /*! Probability of packet loss due to a multiple access collision. */
}
}
}
};
g1050_channel_speeds_t g1050_speed_patterns[168] =
{
{ 4000000, 0, 128000, 768000, 0, 4000000, 0, 128000, 768000, 0, 0.360},
{ 4000000, 0, 128000, 768000, 0, 20000000, 0, 128000, 768000, 0, 0.720},
{ 4000000, 0, 128000, 768000, 0, 100000000, 0, 128000, 768000, 0, 0.360},
{ 20000000, 0, 128000, 768000, 0, 20000000, 0, 128000, 768000, 0, 0.360},
{ 20000000, 0, 128000, 768000, 0, 100000000, 0, 128000, 768000, 0, 0.360},
{100000000, 0, 128000, 768000, 0, 100000000, 0, 128000, 768000, 0, 0.090},
{ 4000000, 0, 128000, 1536000, 0, 4000000, 0, 384000, 768000, 0, 0.720},
{ 4000000, 0, 128000, 1536000, 0, 20000000, 0, 384000, 768000, 0, 1.470},
{ 4000000, 0, 128000, 1536000, 0, 100000000, 0, 384000, 768000, 0, 0.840},
{ 20000000, 0, 128000, 1536000, 0, 20000000, 0, 384000, 768000, 0, 0.750},
{ 20000000, 0, 128000, 1536000, 0, 100000000, 0, 384000, 768000, 0, 0.855},
{100000000, 0, 128000, 1536000, 0, 100000000, 0, 384000, 768000, 0, 0.240},
{ 4000000, 0, 128000, 3000000, 0, 4000000, 0, 384000, 768000, 0, 0.120},
{ 4000000, 0, 128000, 3000000, 0, 20000000, 0, 384000, 768000, 0, 0.420},
{ 4000000, 0, 128000, 3000000, 0, 100000000, 0, 384000, 768000, 0, 0.840},
{ 20000000, 0, 128000, 3000000, 0, 20000000, 0, 384000, 768000, 0, 0.300},
{ 20000000, 0, 128000, 3000000, 0, 100000000, 0, 384000, 768000, 0, 0.930},
{100000000, 0, 128000, 3000000, 0, 100000000, 0, 384000, 768000, 0, 0.390},
{ 4000000, 0, 384000, 768000, 0, 4000000, 0, 128000, 1536000, 0, 0.720},
{ 4000000, 0, 384000, 768000, 0, 20000000, 0, 128000, 1536000, 0, 1.470},
{ 4000000, 0, 384000, 768000, 0, 100000000, 0, 128000, 1536000, 0, 0.840},
{ 20000000, 0, 384000, 768000, 0, 20000000, 0, 128000, 1536000, 0, 0.750},
{ 20000000, 0, 384000, 768000, 0, 100000000, 0, 128000, 1536000, 0, 0.855},
{100000000, 0, 384000, 768000, 0, 100000000, 0, 128000, 1536000, 0, 0.240},
{ 4000000, 0, 384000, 1536000, 0, 4000000, 0, 384000, 1536000, 0, 1.440},
{ 4000000, 0, 384000, 1536000, 0, 20000000, 0, 384000, 1536000, 0, 3.000},
{ 4000000, 0, 384000, 1536000, 0, 100000000, 0, 384000, 1536000, 0, 1.920},
{ 20000000, 0, 384000, 1536000, 0, 20000000, 0, 384000, 1536000, 0, 1.563},
{ 20000000, 0, 384000, 1536000, 0, 100000000, 0, 384000, 1536000, 0, 2.000},
{100000000, 0, 384000, 1536000, 0, 100000000, 0, 384000, 1536000, 0, 0.640},
{ 4000000, 0, 384000, 3000000, 0, 4000000, 0, 384000, 1536000, 0, 0.240},
{ 4000000, 0, 384000, 3000000, 0, 20000000, 0, 384000, 1536000, 0, 0.850},
{ 4000000, 0, 384000, 3000000, 0, 100000000, 0, 384000, 1536000, 0, 1.720},
{ 20000000, 0, 384000, 3000000, 0, 20000000, 0, 384000, 1536000, 0, 0.625},
{ 20000000, 0, 384000, 3000000, 0, 100000000, 0, 384000, 1536000, 0, 2.025},
{100000000, 0, 384000, 3000000, 0, 100000000, 0, 384000, 1536000, 0, 1.040},
{ 4000000, 0, 384000, 768000, 0, 4000000, 0, 128000, 3000000, 0, 0.120},
{ 4000000, 0, 384000, 768000, 0, 20000000, 0, 128000, 3000000, 0, 0.420},
{ 4000000, 0, 384000, 768000, 0, 100000000, 0, 128000, 3000000, 0, 0.840},
{ 20000000, 0, 384000, 768000, 0, 20000000, 0, 128000, 3000000, 0, 0.300},
{ 20000000, 0, 384000, 768000, 0, 100000000, 0, 128000, 3000000, 0, 0.930},
{100000000, 0, 384000, 768000, 0, 100000000, 0, 128000, 3000000, 0, 0.390},
{ 4000000, 0, 384000, 1536000, 0, 4000000, 0, 384000, 3000000, 0, 0.240},
{ 4000000, 0, 384000, 1536000, 0, 20000000, 0, 384000, 3000000, 0, 0.850},
{ 4000000, 0, 384000, 1536000, 0, 100000000, 0, 384000, 3000000, 0, 1.720},
{ 20000000, 0, 384000, 1536000, 0, 20000000, 0, 384000, 3000000, 0, 0.625},
{ 20000000, 0, 384000, 1536000, 0, 100000000, 0, 384000, 3000000, 0, 2.025},
{100000000, 0, 384000, 1536000, 0, 100000000, 0, 384000, 3000000, 0, 1.040},
{ 4000000, 0, 384000, 3000000, 0, 4000000, 0, 384000, 3000000, 0, 0.040},
{ 4000000, 0, 384000, 3000000, 0, 20000000, 0, 384000, 3000000, 0, 0.200},
{ 4000000, 0, 384000, 3000000, 0, 100000000, 0, 384000, 3000000, 0, 0.520},
{ 20000000, 0, 384000, 3000000, 0, 20000000, 0, 384000, 3000000, 0, 0.250},
{ 20000000, 0, 384000, 3000000, 0, 100000000, 0, 384000, 3000000, 0, 1.300},
{100000000, 0, 384000, 3000000, 0, 100000000, 0, 384000, 3000000, 0, 1.690},
{ 4000000, 0, 128000, 1536000, 0, 20000000, 0, 768000, 1536000, 0, 0.090},
{ 4000000, 0, 128000, 1536000, 0, 100000000, 0, 768000, 1536000, 0, 0.360},
{ 20000000, 0, 128000, 1536000, 0, 20000000, 0, 768000, 1536000, 0, 0.090},
{ 20000000, 0, 128000, 1536000, 0, 100000000, 0, 768000, 1536000, 0, 0.405},
{100000000, 0, 128000, 1536000, 0, 100000000, 0, 768000, 1536000, 0, 0.180},
{ 4000000, 0, 128000, 7000000, 0, 20000000, 0, 768000, 768000, 0, 0.270},
{ 4000000, 0, 128000, 7000000, 0, 100000000, 0, 768000, 768000, 0, 1.080},
{ 20000000, 0, 128000, 7000000, 0, 20000000, 0, 768000, 768000, 0, 0.270},
{ 20000000, 0, 128000, 7000000, 0, 100000000, 0, 768000, 768000, 0, 1.215},
{100000000, 0, 128000, 7000000, 0, 100000000, 0, 768000, 768000, 0, 0.540},
{ 4000000, 0, 128000, 13000000, 0, 20000000, 0, 768000, 13000000, 0, 0.030},
{ 4000000, 0, 128000, 13000000, 0, 100000000, 0, 768000, 13000000, 0, 0.120},
{ 20000000, 0, 128000, 13000000, 0, 20000000, 0, 768000, 13000000, 0, 0.030},
{ 20000000, 0, 128000, 13000000, 0, 100000000, 0, 768000, 13000000, 0, 0.135},
{100000000, 0, 128000, 13000000, 0, 100000000, 0, 768000, 13000000, 0, 0.060},
{ 4000000, 0, 384000, 1536000, 0, 20000000, 0, 1536000, 1536000, 0, 0.180},
{ 4000000, 0, 384000, 1536000, 0, 100000000, 0, 1536000, 1536000, 0, 0.720},
{ 20000000, 0, 384000, 1536000, 0, 20000000, 0, 1536000, 1536000, 0, 0.188},
{ 20000000, 0, 384000, 1536000, 0, 100000000, 0, 1536000, 1536000, 0, 0.870},
{100000000, 0, 384000, 1536000, 0, 100000000, 0, 1536000, 1536000, 0, 0.480},
{ 4000000, 0, 384000, 7000000, 0, 20000000, 0, 768000, 1536000, 0, 0.540},
{ 4000000, 0, 384000, 7000000, 0, 100000000, 0, 768000, 1536000, 0, 2.160},
{ 20000000, 0, 384000, 7000000, 0, 20000000, 0, 768000, 1536000, 0, 0.563},
{ 20000000, 0, 384000, 7000000, 0, 100000000, 0, 768000, 1536000, 0, 2.610},
{100000000, 0, 384000, 7000000, 0, 100000000, 0, 768000, 1536000, 0, 1.440},
{ 4000000, 0, 384000, 13000000, 0, 20000000, 0, 1536000, 13000000, 0, 0.060},
{ 4000000, 0, 384000, 13000000, 0, 100000000, 0, 1536000, 13000000, 0, 0.240},
{ 20000000, 0, 384000, 13000000, 0, 20000000, 0, 1536000, 13000000, 0, 0.063},
{ 20000000, 0, 384000, 13000000, 0, 100000000, 0, 1536000, 13000000, 0, 0.290},
{100000000, 0, 384000, 13000000, 0, 100000000, 0, 1536000, 13000000, 0, 0.160},
{ 4000000, 0, 384000, 1536000, 0, 20000000, 0, 1536000, 3000000, 0, 0.030},
{ 4000000, 0, 384000, 1536000, 0, 100000000, 0, 1536000, 3000000, 0, 0.120},
{ 20000000, 0, 384000, 1536000, 0, 20000000, 0, 1536000, 3000000, 0, 0.075},
{ 20000000, 0, 384000, 1536000, 0, 100000000, 0, 1536000, 3000000, 0, 0.495},
{100000000, 0, 384000, 1536000, 0, 100000000, 0, 1536000, 3000000, 0, 0.780},
{ 4000000, 0, 384000, 7000000, 0, 20000000, 0, 768000, 3000000, 0, 0.090},
{ 4000000, 0, 384000, 7000000, 0, 100000000, 0, 768000, 3000000, 0, 0.360},
{ 20000000, 0, 384000, 7000000, 0, 20000000, 0, 768000, 3000000, 0, 0.225},
{ 20000000, 0, 384000, 7000000, 0, 100000000, 0, 768000, 3000000, 0, 1.485},
{100000000, 0, 384000, 7000000, 0, 100000000, 0, 768000, 3000000, 0, 2.340},
{ 4000000, 0, 384000, 13000000, 0, 20000000, 0, 3000000, 13000000, 0, 0.010},
{ 4000000, 0, 384000, 13000000, 0, 100000000, 0, 3000000, 13000000, 0, 0.040},
{ 20000000, 0, 384000, 13000000, 0, 20000000, 0, 3000000, 13000000, 0, 0.025},
{ 20000000, 0, 384000, 13000000, 0, 100000000, 0, 3000000, 13000000, 0, 0.165},
{100000000, 0, 384000, 13000000, 0, 100000000, 0, 3000000, 13000000, 0, 0.260},
{ 4000000, 0, 768000, 1536000, 0, 20000000, 0, 128000, 1536000, 0, 0.090},
{ 20000000, 0, 768000, 1536000, 0, 20000000, 0, 128000, 1536000, 0, 0.090},
{ 20000000, 0, 768000, 1536000, 0, 100000000, 0, 128000, 1536000, 0, 0.405},
{ 4000000, 0, 768000, 1536000, 0, 100000000, 0, 128000, 1536000, 0, 0.360},
{100000000, 0, 768000, 1536000, 0, 100000000, 0, 128000, 1536000, 0, 0.180},
{ 4000000, 0, 1536000, 1536000, 0, 20000000, 0, 384000, 1536000, 0, 0.180},
{ 20000000, 0, 1536000, 1536000, 0, 20000000, 0, 384000, 1536000, 0, 0.188},
{ 20000000, 0, 1536000, 1536000, 0, 100000000, 0, 384000, 1536000, 0, 0.870},
{ 4000000, 0, 1536000, 1536000, 0, 100000000, 0, 384000, 1536000, 0, 0.720},
{100000000, 0, 1536000, 1536000, 0, 100000000, 0, 384000, 1536000, 0, 0.480},
{ 4000000, 0, 1536000, 3000000, 0, 20000000, 0, 384000, 1536000, 0, 0.030},
{ 20000000, 0, 1536000, 3000000, 0, 20000000, 0, 384000, 1536000, 0, 0.075},
{ 20000000, 0, 1536000, 3000000, 0, 100000000, 0, 384000, 1536000, 0, 0.495},
{ 4000000, 0, 1536000, 3000000, 0, 100000000, 0, 384000, 1536000, 0, 0.120},
{100000000, 0, 1536000, 3000000, 0, 100000000, 0, 384000, 1536000, 0, 0.780},
{ 4000000, 0, 768000, 768000, 0, 20000000, 0, 128000, 7000000, 0, 0.270},
{ 20000000, 0, 768000, 768000, 0, 20000000, 0, 128000, 7000000, 0, 0.270},
{ 20000000, 0, 768000, 768000, 0, 100000000, 0, 128000, 7000000, 0, 1.215},
{ 4000000, 0, 768000, 768000, 0, 100000000, 0, 128000, 7000000, 0, 1.080},
{100000000, 0, 768000, 768000, 0, 100000000, 0, 128000, 7000000, 0, 0.540},
{ 4000000, 0, 768000, 1536000, 0, 20000000, 0, 384000, 7000000, 0, 0.540},
{ 20000000, 0, 768000, 1536000, 0, 20000000, 0, 384000, 7000000, 0, 0.563},
{ 20000000, 0, 768000, 1536000, 0, 100000000, 0, 384000, 7000000, 0, 2.610},
{ 4000000, 0, 768000, 1536000, 0, 100000000, 0, 384000, 7000000, 0, 2.160},
{100000000, 0, 768000, 1536000, 0, 100000000, 0, 384000, 7000000, 0, 1.440},
{ 4000000, 0, 768000, 3000000, 0, 20000000, 0, 384000, 7000000, 0, 0.090},
{ 20000000, 0, 768000, 3000000, 0, 20000000, 0, 384000, 7000000, 0, 0.225},
{ 20000000, 0, 768000, 3000000, 0, 100000000, 0, 384000, 7000000, 0, 1.485},
{ 4000000, 0, 768000, 3000000, 0, 100000000, 0, 384000, 7000000, 0, 0.360},
{100000000, 0, 768000, 3000000, 0, 100000000, 0, 384000, 7000000, 0, 2.340},
{ 4000000, 0, 768000, 13000000, 0, 20000000, 0, 128000, 13000000, 0, 0.030},
{ 20000000, 0, 768000, 13000000, 0, 20000000, 0, 128000, 13000000, 0, 0.030},
{ 20000000, 0, 768000, 13000000, 0, 100000000, 0, 128000, 13000000, 0, 0.135},
{ 4000000, 0, 768000, 13000000, 0, 100000000, 0, 128000, 13000000, 0, 0.120},
{100000000, 0, 768000, 13000000, 0, 100000000, 0, 128000, 13000000, 0, 0.060},
{ 4000000, 0, 1536000, 13000000, 0, 20000000, 0, 384000, 13000000, 0, 0.060},
{ 20000000, 0, 1536000, 13000000, 0, 20000000, 0, 384000, 13000000, 0, 0.063},
{ 20000000, 0, 1536000, 13000000, 0, 100000000, 0, 384000, 13000000, 0, 0.290},
{ 4000000, 0, 1536000, 13000000, 0, 100000000, 0, 384000, 13000000, 0, 0.240},
{100000000, 0, 1536000, 13000000, 0, 100000000, 0, 384000, 13000000, 0, 0.160},
{ 4000000, 0, 3000000, 13000000, 0, 20000000, 0, 384000, 13000000, 0, 0.010},
{ 20000000, 0, 3000000, 13000000, 0, 20000000, 0, 384000, 13000000, 0, 0.025},
{ 20000000, 0, 3000000, 13000000, 0, 100000000, 0, 384000, 13000000, 0, 0.165},
{ 4000000, 0, 3000000, 13000000, 0, 100000000, 0, 384000, 13000000, 0, 0.040},
{100000000, 0, 3000000, 13000000, 0, 100000000, 0, 384000, 13000000, 0, 0.260},
{ 20000000, 0, 1536000, 1536000, 0, 20000000, 0, 1536000, 1536000, 0, 0.023},
{ 20000000, 0, 1536000, 1536000, 0, 100000000, 0, 1536000, 1536000, 0, 0.180},
{100000000, 0, 1536000, 1536000, 0, 100000000, 0, 1536000, 1536000, 0, 0.360},
{ 20000000, 0, 1536000, 7000000, 0, 20000000, 0, 768000, 1536000, 0, 0.068},
{ 20000000, 0, 1536000, 7000000, 0, 100000000, 0, 768000, 1536000, 0, 0.540},
{100000000, 0, 1536000, 7000000, 0, 100000000, 0, 768000, 1536000, 0, 1.080},
{ 20000000, 0, 1536000, 13000000, 0, 20000000, 0, 1536000, 13000000, 0, 0.015},
{ 20000000, 0, 1536000, 13000000, 0, 100000000, 0, 1536000, 13000000, 0, 0.120},
{100000000, 0, 1536000, 13000000, 0, 100000000, 0, 1536000, 13000000, 0, 0.240},
{ 20000000, 0, 768000, 1536000, 0, 20000000, 0, 1536000, 7000000, 0, 0.068},
{ 20000000, 0, 768000, 1536000, 0, 100000000, 0, 1536000, 7000000, 0, 0.540},
{100000000, 0, 768000, 1536000, 0, 100000000, 0, 1536000, 7000000, 0, 1.080},
{ 20000000, 0, 768000, 7000000, 0, 20000000, 0, 768000, 7000000, 0, 0.203},
{ 20000000, 0, 768000, 7000000, 0, 100000000, 0, 768000, 7000000, 0, 1.620},
{100000000, 0, 768000, 7000000, 0, 100000000, 0, 768000, 7000000, 0, 3.240},
{ 20000000, 0, 768000, 13000000, 0, 20000000, 0, 7000000, 13000000, 0, 0.023},
{ 20000000, 0, 768000, 13000000, 0, 100000000, 0, 7000000, 13000000, 0, 0.180},
{100000000, 0, 768000, 13000000, 0, 100000000, 0, 7000000, 13000000, 0, 0.360},
{ 20000000, 0, 7000000, 13000000, 0, 20000000, 0, 768000, 13000000, 0, 0.023},
{ 20000000, 0, 7000000, 13000000, 0, 100000000, 0, 768000, 13000000, 0, 0.180},
{100000000, 0, 7000000, 13000000, 0, 100000000, 0, 768000, 13000000, 0, 0.360},
{ 20000000, 0, 13000000, 13000000, 0, 20000000, 0, 13000000, 13000000, 0, 0.003},
{ 20000000, 0, 13000000, 13000000, 0, 100000000, 0, 13000000, 13000000, 0, 0.020},
{100000000, 0, 13000000, 13000000, 0, 100000000, 0, 13000000, 13000000, 0, 0.040}
};
g1050_model_t g1050_standard_models[9] =
{
{ /* Severity 0 - no impairment */
{
0, /*! Percentage likelihood of occurance in scenario A */
0, /*! Percentage likelihood of occurance in scenario B */
0, /*! Percentage likelihood of occurance in scenario C */
},
{
0.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.0, /*! Percentage occupancy */
512, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.0, /*! Basic delay of the regional backbone, in seconds */
0.0, /*! Basic delay of the intercontinental backbone, in seconds */
0.0, /*! Percentage packet loss of the backbone */
0.0, /*! Maximum jitter of the backbone, in seconds */
0.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.0, /*! The difference in backbone delay between the two routes we flap between, in seconds */
0.0, /*! The interval between link failures, in seconds */
0.0, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
0.0, /*! Percentage occupancy */
512, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
}
},
{ /* Severity A */
{
50, /*! Percentage likelihood of occurance in scenario A */
5, /*! Percentage likelihood of occurance in scenario B */
5, /*! Percentage likelihood of occurance in scenario C */
},
{
1.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
0.0, /*! Percentage occupancy */
512, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.004, /*! Basic delay of the regional backbone, in seconds */
0.016, /*! Basic delay of the intercontinental backbone, in seconds */
0.0, /*! Percentage packet loss of the backbone */
0.005, /*! Maximum jitter of the backbone, in seconds */
0.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.0, /*! The difference in backbone delay between the two routes we flap between, in seconds */
0.0, /*! The interval between link failures, in seconds */
0.0, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
0.0, /*! Percentage occupancy */
512, /*! MTU */
0.0 /*! Peak jitter */
},
{
1.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
},
{ /* Severity B */
{
30, /*! Percentage likelihood of occurance in scenario A */
25, /*! Percentage likelihood of occurance in scenario B */
5, /*! Percentage likelihood of occurance in scenario C */
},
{
2.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
1.0, /*! Percentage occupancy */
512, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.008, /*! Basic delay of the regional backbone, in seconds */
0.032, /*! Basic delay of the intercontinental backbone, in seconds */
0.01, /*! Percentage packet loss of the backbone */
0.01, /*! Maximum jitter of the backbone, in seconds */
3600.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.002, /*! The difference in backbone delay between the two routes we flap between, in seconds */
3600.0, /*! The interval between link failures, in seconds */
0.064, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
1.0, /*! Percentage occupancy */
512, /*! MTU */
0.0 /*! Peak jitter */
},
{
2.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
},
{ /* Severity C */
{
15, /*! Percentage likelihood of occurance in scenario A */
30, /*! Percentage likelihood of occurance in scenario B */
10, /*! Percentage likelihood of occurance in scenario C */
},
{
3.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
2.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.016, /*! Basic delay of the regional backbone, in seconds */
0.064, /*! Basic delay of the intercontinental backbone, in seconds */
0.02, /*! Percentage packet loss of the backbone */
0.016, /*! Maximum jitter of the backbone, in seconds */
1800.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.004, /*! The difference in backbone delay between the two routes we flap between, in seconds */
1800.0, /*! The interval between link failures, in seconds */
0.128, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
2.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
3.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
},
{ /* Severity D */
{
5, /*! Percentage likelihood of occurance in scenario A */
25, /*! Percentage likelihood of occurance in scenario B */
15, /*! Percentage likelihood of occurance in scenario C */
},
{
5.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
4.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.032, /*! Basic delay of the regional backbone, in seconds */
0.128, /*! Basic delay of the intercontinental backbone, in seconds */
0.04, /*! Percentage packet loss of the backbone */
0.04, /*! Maximum jitter of the backbone, in seconds */
900.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.008, /*! The difference in backbone delay between the two routes we flap between, in seconds */
900.0, /*! The interval between link failures, in seconds */
0.256, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
4.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
5.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
},
{ /* Severity E */
{
0, /*! Percentage likelihood of occurance in scenario A */
10, /*! Percentage likelihood of occurance in scenario B */
20, /*! Percentage likelihood of occurance in scenario C */
},
{
8.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
8.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.064, /*! Basic delay of the regional backbone, in seconds */
0.196, /*! Basic delay of the intercontinental backbone, in seconds */
0.1, /*! Percentage packet loss of the backbone */
0.07, /*! Maximum jitter of the backbone, in seconds */
480.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.016, /*! The difference in backbone delay between the two routes we flap between, in seconds */
480.0, /*! The interval between link failures, in seconds */
0.4, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
8.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
8.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
},
{ /* Severity F */
{
0, /*! Percentage likelihood of occurance in scenario A */
0, /*! Percentage likelihood of occurance in scenario B */
25, /*! Percentage likelihood of occurance in scenario C */
},
{
12.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
15.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.128, /*! Basic delay of the regional backbone, in seconds */
0.256, /*! Basic delay of the intercontinental backbone, in seconds */
0.2, /*! Percentage packet loss of the backbone */
0.1, /*! Maximum jitter of the backbone, in seconds */
240.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.032, /*! The difference in backbone delay between the two routes we flap between, in seconds */
240.0, /*! The interval between link failures, in seconds */
0.8, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
15.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
12.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
},
{ /* Severity G */
{
0, /*! Percentage likelihood of occurance in scenario A */
0, /*! Percentage likelihood of occurance in scenario B */
15, /*! Percentage likelihood of occurance in scenario C */
},
{
16.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
30.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.256, /*! Basic delay of the regional backbone, in seconds */
0.512, /*! Basic delay of the intercontinental backbone, in seconds */
0.5, /*! Percentage packet loss of the backbone */
0.15, /*! Maximum jitter of the backbone, in seconds */
120.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.064, /*! The difference in backbone delay between the two routes we flap between, in seconds */
120.0, /*! The interval between link failures, in seconds */
1.6, /*! The duration of link failures, in seconds */
0.0, /*! Probability of packet loss in the backbone, in percent */
0.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
30.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
16.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
},
{ /* Severity H */
{
0, /*! Percentage likelihood of occurance in scenario A */
0, /*! Percentage likelihood of occurance in scenario B */
5, /*! Percentage likelihood of occurance in scenario C */
},
{
20.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
},
{
50.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
0.512, /*! Basic delay of the regional backbone, in seconds */
0.768, /*! Basic delay of the intercontinental backbone, in seconds */
1.0, /*! Percentage packet loss of the backbone */
0.5, /*! Maximum jitter of the backbone, in seconds */
60.0, /*! Interval between the backbone route flapping between two paths, in seconds */
0.128, /*! The difference in backbone delay between the two routes we flap between, in seconds */
60.0, /*! The interval between link failures, in seconds */
3.0, /*! The duration of link failures, in seconds */
1.0, /*! Probability of packet loss in the backbone, in percent */
1.0 /*! Probability of a packet going out of sequence in the backbone. */
},
{
50.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0 /*! Peak jitter */
},
{
20.0, /*! Percentage occupancy */
1508, /*! MTU */
0.0015 /*! Peak jitter */
}
}
};
#if defined(HAVE_DRAND48)
static __inline__ void q1050_rand_init(void)
{
srand48(time(NULL));
}
/*- End of function --------------------------------------------------------*/
static __inline__ double q1050_rand(void)
{
return drand48();
}
/*- End of function --------------------------------------------------------*/
#else
static __inline__ void q1050_rand_init(void)
{
srand(time(NULL));
}
/*- End of function --------------------------------------------------------*/
static __inline__ double q1050_rand(void)
{
return (double) rand()/(double) RAND_MAX;
}
/*- End of function --------------------------------------------------------*/
#endif
static __inline__ double scale_probability(double prob, double scale)
{
/* Re-calculate probability based on a different time interval */
return 1.0 - pow(1.0 - prob, scale);
}
/*- End of function --------------------------------------------------------*/
static void 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)
{
double x;
double packet_interval;
memset(s, 0, sizeof(*s));
packet_interval = 1000.0/packet_rate;
/* Some calculatons are common to both LAN and access links, and those that are not. */
s->link_type = link_type;
s->prob_loss_rate_change[0] = scale_probability(constants->prob_loss_rate_change[0]*parms->percentage_occupancy, 1.0/packet_interval);
s->serial_delay = packet_size*8.0/bit_rate;
if (link_type == G1050_LAN_LINK)
{
s->prob_loss_rate_change[1] = scale_probability(constants->prob_loss_rate_change[1], 1.0/packet_interval);
s->prob_impulse[0] = constants->prob_impulse[0][0];
s->prob_impulse[1] = constants->prob_impulse[1][0];
s->impulse_coeff = constants->impulse_coeff;
s->impulse_height = parms->mtu*(8.0/bit_rate)*(1.0 + parms->percentage_occupancy/constants->impulse_height);
}
else if (link_type == G1050_ACCESS_LINK)
{
s->prob_loss_rate_change[1] = scale_probability(constants->prob_loss_rate_change[1]/(1.0 + parms->percentage_occupancy), 1.0/packet_interval);
s->prob_impulse[0] = scale_probability(constants->prob_impulse[0][0] + (parms->percentage_occupancy/2000.0), 1.0/packet_interval);
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);
s->impulse_coeff = 1.0 - scale_probability(1.0 - constants->impulse_coeff, 1.0/packet_interval);
x = (1.0 - constants->impulse_coeff)/(1.0 - s->impulse_coeff);
s->impulse_height = x*parms->mtu*(8.0/bit_rate)*(1.0 + parms->percentage_occupancy/constants->impulse_height);
}
/* The following are calculated the same way for LAN and access links */
s->prob_packet_loss = constants->prob_packet_loss*parms->percentage_occupancy;
s->qos_enabled = qos_enabled;
s->multiple_access = multiple_access;
s->prob_packet_collision_loss = constants->prob_packet_collision_loss;
s->max_jitter = parms->max_jitter;
/* The following is common state information to all links. */
s->high_loss = FALSE;
s->congestion_delay = 0.0;
s->last_arrival_time = 0.0;
/* Count of packets lost in this segment. */
s->lost_packets = 0;
s->lost_packets_2 = 0;
}
/*- End of function --------------------------------------------------------*/
static void g1050_core_init(g1050_core_state_t *s, g1050_core_model_t *parms, int packet_rate)
{
memset(s, 0, sizeof(*s));
/* Set up route flapping. */
/* This is the length of the period of both the delayed duration and the non-delayed. */
s->route_flap_interval = parms->route_flap_interval*G1050_TICKS_PER_SEC;
/* How much additional delay is added or subtracted during route flaps. */
s->route_flap_delta = parms->route_flap_delay;
/* Current tick count. This is initialized so that we are part way into the first
CLEAN interval before the first change occurs. This is a random portion of the
period. When we reach the first flap, the flapping in both directions becomes
periodic. */
s->route_flap_counter = s->route_flap_interval - 99 - floor(s->route_flap_interval*q1050_rand());
s->link_failure_interval_ticks = parms->link_failure_interval*G1050_TICKS_PER_SEC;
/* Link failures occur when the count reaches this number of ticks. */
/* Duration of a failure. */
s->link_failure_duration_ticks = floor((G1050_TICKS_PER_SEC*parms->link_failure_duration));
/* How far into the first CLEAN interval we are. This is like the route flap initialzation. */
s->link_failure_counter = s->link_failure_interval_ticks - 99 - floor(s->link_failure_interval_ticks*q1050_rand());
s->link_recovery_counter = s->link_failure_duration_ticks;
s->base_delay = parms->base_regional_delay;
s->max_jitter = parms->max_jitter;
s->prob_packet_loss = parms->prob_packet_loss/100.0;
s->prob_oos = parms->prob_oos/100.0;
s->last_arrival_time = 0.0;
s->delay_delta = 0;
/* Count of packets lost in this segment. */
s->lost_packets = 0;
s->lost_packets_2 = 0;
}
/*- End of function --------------------------------------------------------*/
static void g1050_segment_model(g1050_segment_state_t *s, double delays[], int len)
{
int i;
int lose;
int was_high_loss;
double impulse;
double slice_delay;
/* Compute delay and loss value for each time slice. */
for (i = 0; i < len; i++)
{
lose = FALSE;
/* Initialize delay to the serial delay plus some jitter. */
slice_delay = s->serial_delay + s->max_jitter*q1050_rand();
/* If no QoS, do congestion delay and packet loss analysis. */
if (!s->qos_enabled)
{
/* To match the logic in G.1050 we need to record the current loss state, before
checking if we should change. */
was_high_loss = s->high_loss;
/* Toggle between the low-loss and high-loss states, based on the transition probability. */
if (q1050_rand() < s->prob_loss_rate_change[was_high_loss])
s->high_loss = !s->high_loss;
impulse = 0.0;
if (q1050_rand() < s->prob_impulse[was_high_loss])
{
impulse = s->impulse_height;
if (!was_high_loss || s->link_type == G1050_LAN_LINK)
impulse *= q1050_rand();
}
if (was_high_loss && q1050_rand() < s->prob_packet_loss)
lose = TRUE;
/* Single pole LPF for the congestion delay impulses. */
s->congestion_delay = s->congestion_delay*s->impulse_coeff + impulse*(1.0 - s->impulse_coeff);
slice_delay += s->congestion_delay;
}
/* If duplex mismatch on LAN, packet loss based on loss probability. */
if (s->multiple_access && (q1050_rand() < s->prob_packet_collision_loss))
lose = TRUE;
/* Put computed delay into time slice array. */
if (lose)
{
delays[i] = PACKET_LOSS_TIME;
s->lost_packets++;
}
else
{
delays[i] = slice_delay;
}
}
}
/*- End of function --------------------------------------------------------*/
static void g1050_core_model(g1050_core_state_t *s, double delays[], int len)
{
int32_t i;
int lose;
double jitter_delay;
for (i = 0; i < len; i++)
{
lose = FALSE;
jitter_delay = s->base_delay + s->max_jitter*q1050_rand();
/* Route flapping */
if (--s->route_flap_counter <= 0)
{
/* Route changed */
s->delay_delta = s->route_flap_delta - s->delay_delta;
s->route_flap_counter = s->route_flap_interval;
}
if (q1050_rand() < s->prob_packet_loss)
lose = TRUE;
/* Link failures */
if (--s->link_failure_counter <= 0)
{
/* We are in a link failure */
lose = TRUE;
if (--s->link_recovery_counter <= 0)
{
/* Leave failure state. */
s->link_failure_counter = s->link_failure_interval_ticks;
s->link_recovery_counter = s->link_failure_duration_ticks;
lose = FALSE;
}
}
if (lose)
{
delays[i] = PACKET_LOSS_TIME;
s->lost_packets++;
}
else
{
delays[i] = jitter_delay + s->delay_delta;
}
}
}
/*- End of function --------------------------------------------------------*/
static int g1050_segment_delay(g1050_segment_state_t *s,
double base_time,
double arrival_times[],
double delays[],
int num_packets)
{
int i;
int32_t departure_time;
int lost_packets;
/* Add appropriate delays to the packets for the segments before the core. */
lost_packets = 0;
for (i = 0; i < num_packets; i++)
{
/* Apply half a millisecond of rounding, as we working in millisecond steps. */
departure_time = (arrival_times[i] + 0.0005 - base_time)*G1050_TICKS_PER_SEC;
if (arrival_times[i] == PACKET_LOSS_TIME)
{
/* Lost already */
}
else if (delays[departure_time] == PACKET_LOSS_TIME)
{
arrival_times[i] = PACKET_LOSS_TIME;
lost_packets++;
}
else
{
arrival_times[i] += delays[departure_time];
if (arrival_times[i] < s->last_arrival_time)
arrival_times[i] = s->last_arrival_time;
else
s->last_arrival_time = arrival_times[i];
}
}
return lost_packets;
}
/*- End of function --------------------------------------------------------*/
static int 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)
{
int i;
int j;
int departure_time;
double last_arrival_time;
double last_arrival_time_temp;
int lost_packets;
/* Add appropriate delays to the packets for the segments after the core. */
last_arrival_time = 0.0;
last_arrival_time_temp = 0.0;
lost_packets = 0;
for (i = 0; i < num_packets; i++)
{
/* We need to preserve the order that came out of the core, so we
use an alternate array for the results. */
/* Apply half a millisecond of rounding, as we working in millisecond steps. */
departure_time = (arrival_times_a[i] + 0.0005 - base_time)*G1050_TICKS_PER_SEC;
if (arrival_times_a[i] == PACKET_LOSS_TIME)
{
/* Lost already */
arrival_times_b[i] = PACKET_LOSS_TIME;
}
else if (delays[departure_time] == PACKET_LOSS_TIME)
{
arrival_times_b[i] = PACKET_LOSS_TIME;
lost_packets++;
}
else
{
arrival_times_b[i] = arrival_times_a[i] + delays[departure_time];
if (arrival_times_a[i] < last_arrival_time)
{
/* If a legitimate out of sequence packet is detected, search
back a fixed amount of time to preserve order. */
for (j = i - 1; j >= 0; j--)
{
if ((arrival_times_a[j] != PACKET_LOSS_TIME)
&&
(arrival_times_b[j] != PACKET_LOSS_TIME))
{
if ((arrival_times_a[i] - arrival_times_a[j]) > SEARCHBACK_PERIOD)
break;
if ((arrival_times_a[j] > arrival_times_a[i])
&&
(arrival_times_b[j] < arrival_times_b[i]))
{
arrival_times_b[j] = arrival_times_b[i];
}
}
}
}
else
{
last_arrival_time = arrival_times_a[i];
if (arrival_times_b[i] < last_arrival_time_temp)
arrival_times_b[i] = last_arrival_time_temp;
else
last_arrival_time_temp = arrival_times_b[i];
}
}
}
return lost_packets;
}
/*- End of function --------------------------------------------------------*/
static int g1050_core_delay(g1050_core_state_t *s,
double base_time,
double arrival_times[],
double delays[],
int num_packets)
{
int i;
int departure_time;
int lost_packets;
/* This element does NOT preserve packet order. */
lost_packets = 0;
for (i = 0; i < num_packets; i++)
{
/* Apply half a millisecond of rounding, as we working in millisecond steps. */
departure_time = (arrival_times[i] + 0.0005 - base_time)*G1050_TICKS_PER_SEC;
if (arrival_times[i] == PACKET_LOSS_TIME)
{
/* Lost already */
}
else if (delays[departure_time] == PACKET_LOSS_TIME)
{
arrival_times[i] = PACKET_LOSS_TIME;
lost_packets++;
}
else
{
/* Not lost. Compute arrival time. */
arrival_times[i] += delays[departure_time];
if (arrival_times[i] < s->last_arrival_time)
{
/* This packet is EARLIER than the last one. It is out of order! */
/* Do we allow it to stay out of order? */
if (q1050_rand() >= s->prob_oos)
arrival_times[i] = s->last_arrival_time;
}
else
{
/* Packet is in the correct order, relative to the last one. */
s->last_arrival_time = arrival_times[i];
}
}
}
return lost_packets;
}
/*- End of function --------------------------------------------------------*/
static void g1050_simulate_chunk(g1050_state_t *s)
{
int i;
s->base_time += 1.0;
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]));
g1050_segment_model(&s->segment[0], &s->segment[0].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
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]));
g1050_segment_model(&s->segment[1], &s->segment[1].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
memcpy(&s->core.delays[0], &s->core.delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->core.delays[0]));
g1050_core_model(&s->core, &s->core.delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
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]));
g1050_segment_model(&s->segment[2], &s->segment[2].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
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]));
g1050_segment_model(&s->segment[3], &s->segment[3].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
memcpy(&s->arrival_times_1[0], &s->arrival_times_1[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_1[0]));
memcpy(&s->arrival_times_2[0], &s->arrival_times_2[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_2[0]));
for (i = 0; i < s->packet_rate; i++)
{
s->arrival_times_1[2*s->packet_rate + i] = s->base_time + 2.0 + (double) i/(double) s->packet_rate;
s->arrival_times_2[2*s->packet_rate + i] = 0.0;
}
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);
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);
s->core.lost_packets_2 += g1050_core_delay(&s->core, s->base_time, s->arrival_times_1, s->core.delays, s->packet_rate);
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);
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);
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
int speed_pattern,
int packet_size,
int packet_rate)
{
g1050_state_t *s;
g1050_constants_t *constants;
g1050_channel_speeds_t *sp;
g1050_model_t *mo;
int i;
/* If the random generator has not been seeded it might give endless
zeroes - it depends on the platform. */
for (i = 0; i < 10; i++)
{
if (q1050_rand() != 0.0)
break;
}
if (i >= 10)
q1050_rand_init();
if ((s = (g1050_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
memset(s, 0, sizeof(*s));
constants = &g1050_constants[0];
sp = &g1050_speed_patterns[speed_pattern - 1];
mo = &g1050_standard_models[model];
memset(s, 0, sizeof(*s));
s->packet_rate = packet_rate;
s->packet_size = packet_size;
g1050_segment_init(&s->segment[0],
G1050_LAN_LINK,
&constants->segment[0],
&mo->sidea_lan,
sp->sidea_lan_bit_rate,
sp->sidea_lan_multiple_access,
FALSE,
packet_size,
packet_rate);
g1050_segment_init(&s->segment[1],
G1050_ACCESS_LINK,
&constants->segment[1],
&mo->sidea_access_link,
sp->sidea_access_link_bit_rate_ab,
FALSE,
sp->sidea_access_link_qos_enabled,
packet_size,
packet_rate);
g1050_core_init(&s->core, &mo->core, packet_rate);
g1050_segment_init(&s->segment[2],
G1050_ACCESS_LINK,
&constants->segment[2],
&mo->sideb_access_link,
sp->sideb_access_link_bit_rate_ba,
FALSE,
sp->sideb_access_link_qos_enabled,
packet_size,
packet_rate);
g1050_segment_init(&s->segment[3],
G1050_LAN_LINK,
&constants->segment[3],
&mo->sideb_lan,
sp->sideb_lan_bit_rate,
sp->sideb_lan_multiple_access,
FALSE,
packet_size,
packet_rate);
s->base_time = 0.0;
/* Start with enough of the future modelled to allow for the worst jitter.
After this we will always keep at least 2 seconds of the future modelled. */
g1050_segment_model(&s->segment[0], s->segment[0].delays, 3*G1050_TICKS_PER_SEC);
g1050_segment_model(&s->segment[1], s->segment[1].delays, 3*G1050_TICKS_PER_SEC);
g1050_core_model(&s->core, s->core.delays, 3*G1050_TICKS_PER_SEC);
g1050_segment_model(&s->segment[2], s->segment[2].delays, 3*G1050_TICKS_PER_SEC);
g1050_segment_model(&s->segment[3], s->segment[3].delays, 3*G1050_TICKS_PER_SEC);
/* Initialise the arrival times to the departure times */
for (i = 0; i < 3*s->packet_rate; i++)
{
s->arrival_times_1[i] = s->base_time + (double) i/(double)s->packet_rate;
s->arrival_times_2[i] = 0.0;
}
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);
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);
s->core.lost_packets_2 += g1050_core_delay(&s->core, s->base_time, s->arrival_times_1, s->core.delays, s->packet_rate);
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);
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);
s->first = NULL;
s->last = NULL;
return s;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) g1050_dump_parms(int model, int speed_pattern)
{
g1050_channel_speeds_t *sp;
g1050_model_t *mo;
sp = &g1050_speed_patterns[speed_pattern - 1];
mo = &g1050_standard_models[model];
printf("Model %d%c\n", speed_pattern, 'A' + model - 1);
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);
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");
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");
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);
printf(" Route flap interval %.4fs, delay change %.4fs\n", mo->core.route_flap_interval, mo->core.route_flap_delay);
printf(" Link failure interval %.4fs, duration %.4fs\n", mo->core.link_failure_interval, mo->core.link_failure_duration);
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");
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");
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) g1050_put(g1050_state_t *s, const uint8_t buf[], int len, int seq_no, double departure_time)
{
g1050_queue_element_t *element;
g1050_queue_element_t *e;
double arrival_time;
while (departure_time >= s->base_time + 1.0)
g1050_simulate_chunk(s);
arrival_time = s->arrival_times_1[(int) ((departure_time - s->base_time)*(double) s->packet_rate + 0.5)];
if (arrival_time < 0)
{
/* This packet is lost */
return 0;
}
if ((element = (g1050_queue_element_t *) malloc(sizeof(*element) + len)) == NULL)
return -1;
element->next = NULL;
element->prev = NULL;
element->seq_no = seq_no;
element->departure_time = departure_time;
element->arrival_time = arrival_time;
element->len = len;
memcpy(element->pkt, buf, len);
/* Add it to the queue, in order */
if (s->last == NULL)
{
/* The queue is empty */
s->first =
s->last = element;
}
else
{
for (e = s->last; e; e = e->prev)
{
if (e->arrival_time <= arrival_time)
break;
}
if (e)
{
element->next = e->next;
element->prev = e;
e->next = element;
}
else
{
element->next = s->first;
s->first = element;
}
if (element->next)
element->next->prev = element;
else
s->last = element;
}
//printf(">> Seq %d, departs %f, arrives %f\n", seq_no, departure_time, arrival_time);
return len;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) g1050_get(g1050_state_t *s, uint8_t buf[], int max_len, double current_time, int *seq_no, double *departure_time, double *arrival_time)
{
int len;
g1050_queue_element_t *element;
element = s->first;
if (element == NULL)
{
if (seq_no)
*seq_no = -1;
if (departure_time)
*departure_time = -1;
if (arrival_time)
*arrival_time = -1;
return -1;
}
if (element->arrival_time > current_time)
{
if (seq_no)
*seq_no = element->seq_no;
if (departure_time)
*departure_time = element->departure_time;
if (arrival_time)
*arrival_time = element->arrival_time;
return -1;
}
/* Return the first packet in the queue */
len = element->len;
memcpy(buf, element->pkt, len);
if (seq_no)
*seq_no = element->seq_no;
if (departure_time)
*departure_time = element->departure_time;
if (arrival_time)
*arrival_time = element->arrival_time;
//printf("<< Seq %d, arrives %f (%f)\n", element->seq_no, element->arrival_time, current_time);
/* Remove it from the queue */
if (s->first == s->last)
s->last = NULL;
s->first = element->next;
if (element->next)
element->next->prev = NULL;
free(element);
return len;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) g1050_queue_dump(g1050_state_t *s)
{
g1050_queue_element_t *e;
printf("Queue scanned forewards\n");
for (e = s->first; e; e = e->next)
printf("Seq %5d, arrival %10.4f, len %3d\n", e->seq_no, e->arrival_time, e->len);
printf("Queue scanned backwards\n");
for (e = s->last; e; e = e->prev)
printf("Seq %5d, arrival %10.4f, len %3d\n", e->seq_no, e->arrival_time, e->len);
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/