otg_rx.c 28.9 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


11 12 13 14
    OpenAirInterface 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.
15

16 17 18 19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

28
 *******************************************************************************/
29 30

/*! \file otg_rx.c
31 32 33 34 35 36 37 38 39
 * \brief function containing the OTG traffic generation functions
 * \author Navid Nikaein and A. Hafsaoui
 * \date 2011
 * \version 0.1
 * \company Eurecom
 * \email: navid.nikaein@eurecom.fr
 * \note
 * \warning
 */
40 41

#include "otg_rx.h"
42
#include "otg_externs.h"
43
#include "UTIL/MATH/oml.h"
44
#include <math.h>
45
#include "otg_form.h"
46
#include "otg_kpi.h"
47 48

#ifdef ENABLE_DB_STATS
49 50 51
#include <mysql.h>
#include <m_ctype.h>
#include <sql_common.h>
52
#endif
53

54 55 56 57 58 59 60 61 62 63
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;

//#include "LAYER2/MAC/extern.h"

#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))


// Check if the packet is well received or not and extract data
64
int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buffer_tx, const unsigned int size)
65
{
66

67
  int              bytes_read      = 0;
68
  otg_hdr_info_t * otg_hdr_info_rx;
69 70 71 72 73 74 75
  otg_hdr_t *      otg_hdr_rx;
  int              is_size_ok      = 0;
  unsigned int     seq_num_rx;
  unsigned int     nb_loss_pkts;
  unsigned int     lost_packet     = 0;
  unsigned int     src_instance;
  unsigned int     dst_instance;
76

77
  if (buffer_tx!=NULL) {
78 79
    otg_hdr_info_rx = (otg_hdr_info_t *) (&buffer_tx[bytes_read]);
    bytes_read += sizeof (otg_hdr_info_t);
80

81 82 83 84 85
    LOG_D(OTG,"otg_rx_pkt functions: destination %d, size %d, otg_hdr_info_rx->flag %.4x, otg_hdr_info_rx->size %d \n",
          dst_instanceP,
          size,
          otg_hdr_info_rx->flag,
          otg_hdr_info_rx->size);
86

87

88
    if (((otg_hdr_info_rx->flag == 0xffff) ||
89 90 91
         (otg_hdr_info_rx->flag == 0xbbbb) ||
         (otg_hdr_info_rx->flag == 0x1000)) &&
        (otg_hdr_info_rx->size == size )) { //data traffic
92

93
      LOG_I(OTG,"MAX_RX_INFO %d %d \n",NB_eNB_INST,  NB_UE_INST);
94

95
      /*is_size_ok= 0;
96
      if (( otg_hdr_info_rx->size ) == size ) {*/
97 98
      is_size_ok= 1;
      otg_hdr_rx = (otg_hdr_t *) (&buffer_tx[bytes_read]);
99 100 101 102 103 104 105 106 107 108 109
      LOG_I(OTG,"[SRC %d][DST %d] [FLOW_idx %d][APP TYPE %d] RX INFO pkt at time %d: flag 0x %x, seq number %d, tx time %d, size (hdr %d, pdcp %d) \n",
            otg_hdr_rx->src_instance,
            otg_hdr_rx->dst_instance,
            otg_hdr_rx->flow_id,
            otg_hdr_rx->traffic_type,
            ctime,
            otg_hdr_info_rx->flag,
            otg_hdr_rx->seq_num,
            otg_hdr_rx->time,
            otg_hdr_info_rx->size, size);

110
      bytes_read += sizeof (otg_hdr_t);
111

112 113 114 115
      src_instance = otg_hdr_rx->src_instance;
      dst_instance = otg_hdr_rx->dst_instance;

      if (dst_instance != dst_instanceP) {
116
//#warning "LG: TODO think about multicast traffic"
117 118 119 120
        LOG_W(OTG,"[SRC %d][DST %d] [FLOW_idx %d][APP TYPE %d] RX INFO pkt at time %d: flag 0x %x, seq number %d, tx time %d, size (hdr %d, pdcp %d)  not for dest instance %u\n",
              dst_instanceP);
      }

121 122
      if(otg_hdr_rx->traffic_type > MAX_NUM_APPLICATION) {
        LOG_W(OTG,"RX packet: application type out of range %d for the pair of (src %d, dst %d) \n",
123
              otg_hdr_rx->traffic_type, src_instance, dst_instance);
124
        otg_hdr_rx->traffic_type=0;
125
      }
126 127 128

      /** unicast traffic **/
      if (otg_hdr_info_rx->flag == 0xffff) {
129
        seq_num_rx=otg_info->seq_num_rx[src_instance][dst_instance][otg_hdr_rx->traffic_type];
130

131 132
        if (src_instance<NB_eNB_INST)
          nb_loss_pkts=otg_info->nb_loss_pkts_dl[src_instance][dst_instance][otg_hdr_rx->traffic_type];
133
        else
134
          nb_loss_pkts=otg_info->nb_loss_pkts_ul[src_instance][dst_instance][otg_hdr_rx->traffic_type];
135 136
      }  /** multicast  traffic **/
      else if (otg_hdr_info_rx->flag == 0x1000) {
137 138 139 140 141 142
        seq_num_rx = otg_multicast_info->rx_sn[src_instance][dst_instance][otg_hdr_rx->traffic_type];
        nb_loss_pkts = otg_multicast_info->loss_pkts_dl[src_instance][dst_instance][otg_hdr_rx->traffic_type];
        //  otg_multicast_info->ran_owd[src_instance][dst_instance][otg_hdr_rx->traffic_type] = ctime- otg_hdr_rx->time;
        //  rx_check_loss(src_instance, dst_instance, otg_hdr_info_rx->flag, otg_hdr_rx->seq_num, &seq_num_rx, &nb_loss_pkts);
        //  otg_multicast_info->loss_rate[src_instance][dst_instance][otg_hdr_rx->traffic_type]=nb_loss_pkts;
        //otg_multicast_info->rx_sn[src_instance][dst_instance][otg_hdr_rx->traffic_type]=seq_num_rx;
143 144 145 146 147
        LOG_I(OTG,"received a multicast packet with size %d sn %d ran owd %d loss rate %d\n",
              otg_hdr_info_rx->size, seq_num_rx, ctime- otg_hdr_rx->time, nb_loss_pkts);
        //return 0;
      }  /** background traffic **/
      else {
148
        seq_num_rx=otg_info->seq_num_rx_background[src_instance][dst_instance];
149

150 151
        if (src_instance<NB_eNB_INST)
          nb_loss_pkts=otg_info->nb_loss_pkts_background_dl[src_instance][dst_instance];
152
        else
153
          nb_loss_pkts=otg_info->nb_loss_pkts_background_ul[src_instance][dst_instance];
154 155
      }

156

157 158
      LOG_D(OTG,"[%d][%d] AGGREGATION LEVEL (RX) %d \n", src_instance, dst_instance, otg_hdr_rx->aggregation_level);
      otg_info->aggregation_level[src_instance][dst_instance]=otg_hdr_rx->aggregation_level;
159

160
      /* Loss and out of sequence data management */
161 162 163 164 165 166 167
      lost_packet= rx_check_loss(
                     src_instance,
                     dst_instance,
                     otg_hdr_info_rx->flag,
                     otg_hdr_rx->seq_num,
                     &seq_num_rx,
                     &nb_loss_pkts);
168 169


170 171
      if (otg_info->owd_const[src_instance][dst_instance][otg_hdr_rx->flow_id]==0)
        owd_const_gen(src_instance,dst_instance,otg_hdr_rx->flow_id, otg_hdr_rx->traffic_type);
172 173 174 175 176 177 178 179 180


      /******/
      /*
      float owd_const_capillary_v=owd_const_capillary()/2;
      float owd_const_mobile_core_v=owd_const_mobile_core()/2;
      float owd_const_IP_backbone_v=owd_const_IP_backbone()/2;
      float owd_const_application_v=owd_const_application()/2;

181 182 183 184 185
      FILE *file;
      file = fopen("/tmp/log_latency_m2m.txt", "a");
      fprintf(file," %d %d [%d] [%d]  %.2f %.2f %.2f %.2f %.2f %.2f\n", otg_hdr_rx->time, otg_hdr_info_rx->size, src, dst, owd_const_capillary_v,otg_info->radio_access_delay[src][dst],owd_const_mobile_core_v, owd_const_IP_backbone_v, owd_const_application_v, owd_const_capillary_v + otg_info->radio_access_delay[src][dst]+owd_const_mobile_core_v + owd_const_IP_backbone_v+ owd_const_application_v);
      fclose(file);
       */
186 187 188 189
      /******/
      //  }

      if (otg_hdr_rx->time<=ctime) {
190 191
        otg_info->radio_access_delay[src_instance][dst_instance]=(float) (ctime- otg_hdr_rx->time);
        otg_multicast_info->radio_access_delay[src_instance][dst_instance]=(float) (ctime- otg_hdr_rx->time);
192
      } else {
193
        LOG_N(OTG,"received packet has tx time %d greater than the current time %d\n",otg_hdr_rx->time,ctime );
194 195
        otg_info->radio_access_delay[src_instance][dst_instance] = 0;
        otg_multicast_info->radio_access_delay[src_instance][dst_instance]=0;
196
      }
197

198
      /* actual radio OWD*/
199
      otg_info->rx_pkt_owd[src_instance][dst_instance]=otg_info->radio_access_delay[src_instance][dst_instance];
200
      /* estimated E2E OWD based on the emulated delays for the other part of the network */
201 202 203 204 205 206 207 208 209 210 211
      otg_info->rx_pkt_owd_e2e[src_instance][dst_instance]=
        otg_info->owd_const[src_instance][dst_instance][otg_hdr_rx->flow_id] + otg_info->radio_access_delay[src_instance][dst_instance];
      otg_multicast_info->rx_pkt_owd[src_instance][dst_instance]=otg_multicast_info->radio_access_delay[src_instance][dst_instance];

      LOG_D(OTG, "[src %d][dst %d] ctime %d tx time %d: OWD %lf E2E OWD %lf \n",
            src_instance,
            dst_instance,
            ctime,
            otg_hdr_rx->time,
            otg_info->rx_pkt_owd[src_instance][dst_instance],
            otg_info->rx_pkt_owd_e2e[src_instance][dst_instance] );
212

213
      // compute the jitter by ignoring the packet loss
214 215
      if (lost_packet == 0) {
        // radio access
216 217
        otg_info->rx_pkt_owd_history[src_instance][dst_instance][1] = otg_info->rx_pkt_owd_history[src_instance][dst_instance][0]; // the previous owd
        otg_info->rx_pkt_owd_history[src_instance][dst_instance][0] = otg_info->rx_pkt_owd[src_instance][dst_instance]; // the current owd
218

219 220
        if (otg_info->rx_pkt_owd_history[src_instance][dst_instance][1] == 0) // first packet
          otg_info->rx_pkt_jitter[src_instance][dst_instance]=0;
221
        else // for the consecutive packets
222 223
          otg_info->rx_pkt_jitter[src_instance][dst_instance]=
            abs(otg_info->rx_pkt_owd_history[src_instance][dst_instance][0] - otg_info->rx_pkt_owd_history[src_instance][dst_instance][1]);
224

225
        LOG_D(OTG,"The packet jitter for the pair (src %d, dst %d)) at %d is %lf (current %lf, previous %lf) \n",
226 227
              src_instance, dst_instance, ctime, otg_info->rx_pkt_jitter[src_instance][dst_instance],
              otg_info->rx_pkt_owd_history[src_instance][dst_instance][0], otg_info->rx_pkt_owd_history[src_instance][dst_instance][1]);
228
        // e2e
229 230
        otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][1] = otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][0]; // the previous owd
        otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][0] = otg_info->rx_pkt_owd_e2e[src_instance][dst_instance]; // the current owd
231

232 233
        if (otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][1] == 0) // first packet
          otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance]=0;
234
        else // for the consecutive packets
235 236
          otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance]=
            abs(otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][0] - otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][1]);
237 238

        LOG_D(OTG,"The packet jitter for the pair (src %d, dst %d)) at %d is %lf (current %lf, previous %lf) \n",
239 240 241 242 243 244
              src_instance,
              dst_instance,
              ctime,
              otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance],
              otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][0],
              otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][1]);
245

246
      }
247

248 249
      if (otg_hdr_info_rx->flag == 0x1000) {
        LOG_I(OTG,"[SRC%d -> DST %d] Received a multicast packet at time %d with size %d, seq num %d, ran owd %d number loss packet %d\n",
250 251 252 253 254 255
              src_instance,
              dst_instance,
              ctime,otg_hdr_info_rx->size,
              otg_hdr_rx->seq_num,
              ctime - otg_hdr_rx->time,
              nb_loss_pkts);
256 257

        LOG_I(OTG,"INFO LATENCY :: [SRC %d][DST %d] radio access %.2f (tx time %d, ctime %d), OWD:%.2f (ms):\n",
258 259 260 261 262 263 264 265 266
              src_instance,
              dst_instance,
              otg_multicast_info->radio_access_delay[src_instance][dst_instance],
              otg_hdr_rx->time, ctime ,
              otg_multicast_info->rx_pkt_owd[src_instance][dst_instance]);

        if (otg_multicast_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]==0) {
          otg_multicast_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_multicast_info->rx_pkt_owd[src_instance][dst_instance];
          otg_multicast_info->rx_owd_min[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_multicast_info->rx_pkt_owd[src_instance][dst_instance];
267
        } else {
268 269 270 271 272 273
          otg_multicast_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MAX(
                otg_multicast_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_multicast_info->rx_pkt_owd[src_instance][dst_instance] );
          otg_multicast_info->rx_owd_min[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MIN(
                otg_multicast_info->rx_owd_min[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_multicast_info->rx_pkt_owd[src_instance][dst_instance] );
274 275 276 277
        }

        if (g_otg->curve==1) {
          if (g_otg->owd_radio_access==0)
278 279 280 281 282 283
            add_tab_metric(
              src_instance,
              dst_instance,
              otg_multicast_info->rx_pkt_owd[src_instance][dst_instance],
              ((otg_hdr_info_rx->size*1000*8)/(otg_multicast_info->rx_pkt_owd[src_instance][dst_instance]*1024 )),
              otg_hdr_rx->time);
284
          else
285 286 287 288 289
            add_tab_metric(src_instance,
                           dst_instance,
                           otg_multicast_info->radio_access_delay[src_instance][dst_instance],
                           ((otg_hdr_info_rx->size*1000*8)/(otg_multicast_info->rx_pkt_owd[src_instance][dst_instance]*1024 )),
                           otg_hdr_rx->time);
290 291 292 293 294 295
        }

        otg_multicast_info->rx_total_bytes_dl+=otg_hdr_info_rx->size;
      } else {

        LOG_I(OTG,"[SRC %d][DST %d] Stats :: radio access latency %.2f (tx time %d, ctime %d) jitter %.2f, Estimated E2E OWD:%.2f (ms):\n",
296 297 298 299 300 301
              src_instance,
              dst_instance,
              otg_info->radio_access_delay[src_instance][dst_instance],
              otg_hdr_rx->time, ctime ,
              otg_info->rx_pkt_jitter[src_instance][dst_instance],
              otg_info->rx_pkt_owd_e2e[src_instance][dst_instance]);
302 303 304

        if (otg_hdr_info_rx->flag == 0xffff) {

305 306 307 308 309
          if (otg_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]==0) {
            otg_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_owd[src_instance][dst_instance];
            otg_info->rx_owd_min[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_owd[src_instance][dst_instance];
            otg_info->rx_owd_max_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_owd_e2e[src_instance][dst_instance];
            otg_info->rx_owd_min_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_owd_e2e[src_instance][dst_instance];
310
          } else {
311 312 313 314 315 316 317 318
            otg_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MAX(otg_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_owd[src_instance][dst_instance] );
            otg_info->rx_owd_min[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MIN(otg_info->rx_owd_min[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_owd[src_instance][dst_instance] );
            otg_info->rx_owd_max_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MAX(otg_info->rx_owd_max_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_owd_e2e[src_instance][dst_instance] );
            otg_info->rx_owd_min_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MIN(otg_info->rx_owd_min_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_owd_e2e[src_instance][dst_instance] );
319 320
          }

321 322 323 324 325
          if (otg_info->rx_jitter_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]==0) {
            otg_info->rx_jitter_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_jitter[src_instance][dst_instance];
            otg_info->rx_jitter_min[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_jitter[src_instance][dst_instance];
            otg_info->rx_jitter_max_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance];
            otg_info->rx_jitter_min_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance];
326
          } else if (lost_packet==0) {
327 328 329 330 331 332 333 334
            otg_info->rx_jitter_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MAX(otg_info->rx_jitter_max[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_jitter[src_instance][dst_instance] );
            otg_info->rx_jitter_min[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MIN(otg_info->rx_jitter_min[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_jitter[src_instance][dst_instance] );
            otg_info->rx_jitter_max_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MAX(otg_info->rx_jitter_max_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance] );
            otg_info->rx_jitter_min_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type]=MIN(otg_info->rx_jitter_min_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type],
                otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance] );
335
            // avg jitter
336 337 338
            otg_info->rx_jitter_avg[src_instance][dst_instance][otg_hdr_rx->traffic_type] +=  otg_info->rx_pkt_jitter[src_instance][dst_instance];
            otg_info->rx_jitter_avg_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type] +=  otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance];
            otg_info->rx_jitter_sample[src_instance][dst_instance][otg_hdr_rx->traffic_type] +=1;
339 340 341 342 343 344
          }

        }

        if (g_otg->curve==1) {
          if (g_otg->owd_radio_access==0)
345 346 347 348 349 350
            add_tab_metric(
              src_instance,
              dst_instance,
              otg_info->rx_pkt_owd[src_instance][dst_instance],
              ((otg_hdr_info_rx->size*1000*8)/(otg_info->rx_pkt_owd[src_instance][dst_instance]*1024 )),
              otg_hdr_rx->time);
351
          else
352 353 354 355 356
            add_tab_metric(
              src_instance,
              dst_instance, otg_info->radio_access_delay[src_instance][dst_instance],
              ((otg_hdr_info_rx->size*1000*8)/(otg_info->rx_pkt_owd[src_instance][dst_instance]*1024 )),
              otg_hdr_rx->time);
357 358
        }

359
        if (src_instance<NB_eNB_INST)
360 361 362
          otg_info->rx_total_bytes_dl+=otg_hdr_info_rx->size;
        else
          otg_info->rx_total_bytes_ul+=otg_hdr_info_rx->size;
363

364
      }
365

366
      //LOG_I(OTG,"RX INFO :: RTT MIN(one way) ms: %.2f, RTT MAX(one way) ms: %.2f \n", otg_info->rx_owd_min[src][dst], otg_info->rx_owd_max[src][dst]);
367 368

      /* xforms part: add metrics  */
369

370
      //printf("payload_size %d, header_size %d \n", otg_hdr_rx->pkts_size, otg_hdr_rx->hdr_type);
371
      LOG_I(OTG,"[RX] OTG packet, PACKET SIZE [SRC %d][DST %d]: Flag (0x%x), Traffic %d, time(%d), Seq num (%d), Total size (%d)\n",
372 373 374 375 376 377
            src_instance,
            dst_instance,
            otg_hdr_info_rx->flag,
            otg_hdr_rx->traffic_type,
            ctime,
            otg_hdr_rx->seq_num, size);
378
      /*LOG_I(OTG,"details::RX [SRC %d][DST %d]: Flag (0x%x), time(%d), Seq num (%d), Total size (%d), header(%d), payload (%d) \n",  src, dst, otg_hdr_info_rx->flag, ctime, otg_hdr_rx->seq_num, size, strlen(packet_rx->header), strlen(packet_rx->payload));*/
379 380


381
      if (otg_hdr_info_rx->flag == 0xffff) {
382 383 384
        otg_info->rx_num_pkt[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=1;
        otg_info->rx_num_bytes[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=otg_hdr_info_rx->size;
        otg_info->seq_num_rx[src_instance][dst_instance][otg_hdr_rx->traffic_type]=seq_num_rx;
385

386 387
        if (src_instance<NB_eNB_INST)
          otg_info->nb_loss_pkts_dl[src_instance][dst_instance][otg_hdr_rx->traffic_type]=nb_loss_pkts;
388
        else
389
          otg_info->nb_loss_pkts_ul[src_instance][dst_instance][otg_hdr_rx->traffic_type]=nb_loss_pkts;
390 391 392 393 394 395

        /*Plots of latency and goodput are only plotted for the data traffic*/
        /*measurements are done for the data and background traffic */

        if (g_otg->latency_metric) {
          if (g_otg->owd_radio_access==0) {
396 397
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_info->rx_pkt_owd[src_instance][dst_instance], OTG_LATENCY);
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance], OTG_JITTER);
398
          } else {
399 400
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_info->radio_access_delay[src_instance][dst_instance], OTG_LATENCY);
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_info->rx_pkt_jitter[src_instance][dst_instance], OTG_JITTER);
401 402 403 404
          }
        }

        if (g_otg->throughput_metric)
405 406 407 408 409
          add_log_metric(src_instance,
                         dst_instance,
                         otg_hdr_rx->time,
                         ((otg_hdr_info_rx->size*1000*8)/(otg_info->rx_pkt_owd[src_instance][dst_instance]*1024 )),
                         OTG_GP); /* compute the throughput in Kbit/s  */
410 411

      } else if (otg_hdr_info_rx->flag == 0x1000) {
412 413
        otg_multicast_info->rx_num_pkt[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=1;
        otg_multicast_info->rx_num_bytes[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=otg_hdr_info_rx->size;
414
        //  LOG_D(OTG,"DUY: otg_multicast_info->rx_num_bytes[%d][%d][%d] is %d \nn",src,dst,otg_hdr_rx->traffic_type,otg_multicast_info->rx_num_bytes[src][dst][otg_hdr_rx->traffic_type]);
415 416
        otg_multicast_info->rx_sn[src_instance][dst_instance][otg_hdr_rx->traffic_type]=seq_num_rx;
        otg_multicast_info->loss_pkts_dl[src_instance][dst_instance][otg_hdr_rx->traffic_type]=nb_loss_pkts;
417 418 419 420 421 422

        /*Plots of latency and goodput are only plotted for the data traffic*/
        /*measurements are done for the data and background traffic */

        if (g_otg->latency_metric) {
          if (g_otg->owd_radio_access==0)
423
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_multicast_info->rx_pkt_owd[src_instance][dst_instance], OTG_LATENCY);
424
          else
425
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_multicast_info->radio_access_delay[src_instance][dst_instance], OTG_LATENCY);
426 427 428
        }

        if (g_otg->throughput_metric)
429 430
          add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, ((otg_hdr_info_rx->size*1000*8)/(otg_multicast_info->rx_pkt_owd[src_instance][dst_instance]*1024 )),
                         OTG_GP); /* compute the throughput in Kbit/s  */
431
      } else {
432 433 434
        otg_info->rx_num_pkt_background[src_instance][dst_instance]+=1;
        otg_info->rx_num_bytes_background[src_instance][dst_instance]+=otg_hdr_info_rx->size;
        otg_info->seq_num_rx_background[src_instance][dst_instance]=seq_num_rx;
435

436 437
        if (src_instance<NB_eNB_INST)
          otg_info->nb_loss_pkts_background_dl[src_instance][dst_instance]=nb_loss_pkts;
438
        else
439
          otg_info->nb_loss_pkts_background_ul[src_instance][dst_instance]=nb_loss_pkts;
440 441 442

        if (g_otg->latency_metric) {
          if (g_otg->owd_radio_access==0)
443
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_info->rx_pkt_owd[src_instance][dst_instance], OTG_LATENCY_BG);
444
          else
445
            add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, otg_info->radio_access_delay[src_instance][dst_instance], OTG_LATENCY_BG);
446 447 448
        }

        if (g_otg->throughput_metric)
449
          add_log_metric(src_instance, dst_instance, otg_hdr_rx->time, ((otg_hdr_info_rx->size*1000*8)/(otg_info->rx_pkt_owd[src_instance][dst_instance]*1024 )), OTG_GP_BG);
450
      }
451

452
      if (is_size_ok == 0) {
453
        otg_hdr_rx = (otg_hdr_t *) (&buffer_tx[bytes_read]);
454 455 456
        LOG_W(OTG,"[SRC %d][DST %d] RX pkt: seq number %d size mis-matche (hdr %d, pdcp %d) \n",
              src_instance, dst_instance, otg_hdr_rx->seq_num, otg_hdr_info_rx->size, size);
        otg_info->nb_loss_pkts_otg[src_instance][dst_instance]++;
457
      }
458

459
      return(0);
460
    } else {
461 462
      LOG_W(OTG,"RX: Not an OTG pkt, forward to upper layer (flag %x, size %d, pdcp_size %d) FIX ME \n",
            otg_hdr_info_rx->flag, otg_hdr_info_rx->size, size);
463
      return(1); //to be fixed on the real case to one
464
    }
465

466 467 468 469 470 471 472 473
  }

  return(0);
}




474 475 476 477 478 479 480
int rx_check_loss(
  const int src,
  const int dst,
  const unsigned int flag,
  const int seq_num,
  unsigned int * const seq_num_rx,
  unsigned int * const nb_loss_pkts)
481
{
482 483 484 485

  /* Loss and out of sequence data management, we have 3 case : */
  /* (1) Receieved packet corresponds to the expected one, in terms of the sequence number*/
  int lost_packet=0;
486

487 488 489 490 491
  if (seq_num==*seq_num_rx) {
    LOG_D(OTG,"check_packet :: (src=%d,dst=%d, flag=0x%x) packet seq_num TX=%d, seq_num RX=%d \n",src,dst,flag, seq_num, *seq_num_rx);
    *seq_num_rx+=1;
  }
  /* (2) Receieved packet with a sequence number higher than the expected sequence number (there is a gap): packet loss */
492
  else if (seq_num>*seq_num_rx) { // out of sequence packet:  previous packet lost
493 494 495 496
    LOG_D(OTG,"check_packet :: (src=%d,dst=%d, flag=0x%x) :: out of sequence :: packet seq_num TX=%d > seq_num RX=%d \n",src,dst,flag, seq_num, *seq_num_rx);
    *nb_loss_pkts+=seq_num-(*seq_num_rx);
    *seq_num_rx=seq_num+1;
    lost_packet=1;
497
  }
498
  /* (3) Receieved packet with a sequence number less than the expected sequence number: recovery after loss/out of sequence  */
499
  else if (seq_num< *seq_num_rx) { //the received packet arrived late
500 501
    *nb_loss_pkts-=1;
    LOG_D(OTG,"check_packet :: (src=%d,dst=%d, flag=0x%x) :: recovery after loss or out of sequence :: packet seq_num TX=%d < seq_num RX=%d \n",src,dst,flag, seq_num, *seq_num_rx);
502
  } else {
503 504 505
    LOG_D(OTG,"check_packet :: (src=%d,dst=%d, flag=0x%x) ::  packet seq_num TX=%d , seq_num RX=%d (ERROR)\n",src,dst,flag, seq_num, *seq_num_rx);
    lost_packet=1;
  }
506

507 508 509 510 511 512
  return lost_packet;
}




513 514 515 516 517
void owd_const_gen(
  const int src,
  const int dst,
  const int flow_id,
  const unsigned int flag)
518
{
519 520
  otg_info->owd_const[src][dst][flow_id]=(owd_const_mobile_core()+owd_const_IP_backbone()+owd_const_application())/2;

521 522
  if ((flag==M2M)||(flag==M2M_TRAFFIC)||(flag==AUTO_PILOT_L)||(flag==AUTO_PILOT_M)||(flag==AUTO_PILOT_H)||(flag==VIRTUAL_GAME_L)||(flag==VIRTUAL_GAME_M)|| (flag==VIRTUAL_GAME_H)||(flag==VIRTUAL_GAME_F)
      ||(flag==ALARM_HUMIDITY)||(flag==ALARM_SMOKE)||(flag==ALARM_TEMPERATURE)||(flag==OPENARENA)||(flag==IQSIM_MANGO)||(flag==IQSIM_NEWSTEO)) {
523 524
    otg_info->owd_const[src][dst][flow_id]+=(owd_const_capillary()/2);
    LOG_D(OTG,"(RX) [src %d] [dst %d] [ID %d] TRAFFIC_TYPE IS M2M [Add Capillary const]\n", src, dst, flow_id);
525
  } else
526
    LOG_T(OTG,"(RX) [src %d] [dst %d] [ID %d] TRAFFIC_TYPE WITHOUT M2M [Capillary const]\n", src, dst, flow_id);
527 528 529 530
}



531 532
float owd_const_capillary(void)
{
533
  /*return (uniform_dist(MIN_APPLICATION_PROCESSING_GATEWAY_DELAY, MAX_APPLICATION_PROCESSING_GATEWAY_DELAY) +
534 535 536
   uniform_dist(MIN_FORMATING_TRANSFERRING_DELAY, MAX_FORMATING_TRANSFERRING_DELAY) +
   uniform_dist(MIN_ACCESS_DELAY, MAX_ACCESS_DELAY) +
   TERMINAL_ACCESS_DELAY);*/
537 538
  return ((double)MIN_APPLICATION_PROCESSING_GATEWAY_DELAY+ (double)MAX_APPLICATION_PROCESSING_GATEWAY_DELAY + (double)MIN_FORMATING_TRANSFERRING_DELAY+ (double)MAX_FORMATING_TRANSFERRING_DELAY+
          (double)MIN_ACCESS_DELAY+(double)MAX_ACCESS_DELAY) /2 + (double)TERMINAL_ACCESS_DELAY;
539 540 541
}


542 543
float owd_const_mobile_core(void)
{
544
  /*double delay;
545
  // this is a delay model for a loaded GGSN according to
546
  //"M. Laner, P. Svoboda and M. Rupp, Latency Analysis of 3G Network Components, EW'12, Poznan, Poland, 2012", table 2, page 6.
547
  if(uniform_rng ()<0.3){
548
  delay=uniform_dist (0.4,1.2);
549
  }else{
550 551 552
  // in this case, according to the fit in the paper,
  //     the delay is generalized pareto: GP(k=0.75,s=0.55,t=1.2)
  //     using inverse cdf method we have CDF(x)=1-(k(x-t)/s+1)^(-1/k),
553
  //  x=CDF^(-1)(u)=t+s/k*((1-u)^(-k)-1) , hence when u~uniform, than x~GP(k,s,t)
554 555 556 557 558 559 560

  double k,s,t,u;
  k=0.75;
  s=0.55;
  t=1.2;
  u=uniform_rng();
  delay= t + s/k*(pow(1-u,-k)-1);
561 562 563 564 565 566
  }
  return delay; */
  /*return ( uniform_dist(MIN_U_PLANE_CORE_IP_ACCESS_DELAY, MAX_U_PLANE_CORE_IP_ACCESS_DELAY) + uniform_dist(MIN_FW_PROXY_DELAY,MAX_FW_PROXY_DELAY)); */
  return ((double)MIN_U_PLANE_CORE_IP_ACCESS_DELAY+ (double)MAX_U_PLANE_CORE_IP_ACCESS_DELAY + (double)MIN_FW_PROXY_DELAY + (double)MAX_FW_PROXY_DELAY)/2;
}

567 568
float owd_const_IP_backbone(void)
{
569
  /*return uniform_dist(MIN_NETWORK_ACCESS_DELAY,MAX_NETWORK_ACCESS_DELAY);*/
570
  return ((double)MIN_NETWORK_ACCESS_DELAY+(double)MAX_NETWORK_ACCESS_DELAY)/2;
571 572 573

}

574 575
float owd_const_application(void)
{
576
  /*return uniform_dist(MIN_APPLICATION_ACESS_DELAY, MAX_APPLICATION_ACESS_DELAY);*/
577
  return ((double)MIN_APPLICATION_ACESS_DELAY+(double)MAX_APPLICATION_ACESS_DELAY)/2;
578 579 580 581 582
}