/* * SpanDSP - a series of DSP components for telephony * * g1050.c - IP network modeling, as per G.1050/TIA-921. * * Written by Steve Underwood * * 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 #include #include #include #include #include #include #if defined(HAVE_TGMATH_H) #include #endif #if defined(HAVE_MATH_H) #define GEN_CONST #include #endif #if defined(HAVE_STDBOOL_H) #include #else #include "spandsp/stdbool.h" #endif #include "floating_fudge.h" #include "spandsp.h" #include "spandsp/g1050.h" #define PACKET_LOSS_TIME -1 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; bool 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; bool 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; memmove(&s->segment[0].delays[0], &s->segment[0].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[0].delays[0])); g1050_segment_model(&s->segment[0], &s->segment[0].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC); memmove(&s->segment[1].delays[0], &s->segment[1].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[1].delays[0])); g1050_segment_model(&s->segment[1], &s->segment[1].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC); memmove(&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); memmove(&s->segment[2].delays[0], &s->segment[2].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[2].delays[0])); g1050_segment_model(&s->segment[2], &s->segment[2].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC); memmove(&s->segment[3].delays[0], &s->segment[3].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[3].delays[0])); g1050_segment_model(&s->segment[3], &s->segment[3].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC); memmove(&s->arrival_times_1[0], &s->arrival_times_1[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_1[0])); memmove(&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(int) g1050_free(g1050_state_t *s) { free(s); return 0; } /*- 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 ------------------------------------------------------------*/