pdcp_fifo.c 40.5 KB
Newer Older
1
/*******************************************************************************
gauthier's avatar
gauthier committed
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

gauthier's avatar
gauthier committed
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


gauthier's avatar
gauthier committed
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

gauthier's avatar
gauthier committed
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
gauthier's avatar
gauthier committed
22 23 24 25
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

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

gauthier's avatar
gauthier committed
28
 *******************************************************************************/
29 30

/*! \file pdcp_fifo.c
gauthier's avatar
gauthier committed
31 32 33 34 35 36 37
 * \brief pdcp interface with linux IP interface, have a look at http://man7.org/linux/man-pages/man7/netlink.7.html for netlink
 * \author  Lionel GAUTHIER and Navid Nikaein
 * \date 2009
 * \version 0.5
 * \warning This component can be runned only in user-space
 * @ingroup pdcp
 */
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

#define PDCP_FIFO_C
#define PDCP_DEBUG 1
//#define IDROMEL_NEMO 1

#ifndef OAI_EMU
extern int otg_enabled;
#endif

#include "pdcp.h"
#include "pdcp_primitives.h"

#ifdef USER_MODE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define rtf_put write
#define rtf_get read
#else
#include <rtai_fifos.h>
#endif //USER_MODE

#include "../MAC/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
63
#include "NAS/DRIVER/LITE/constant.h"
64 65 66 67
#include "SIMULATION/ETH_TRANSPORT/extern.h"
#include "UTIL/OCG/OCG.h"
#include "UTIL/OCG/OCG_extern.h"
#include "UTIL/LOG/log.h"
68
#include "UTIL/OTG/otg_tx.h"
69
#include "UTIL/FIFO/pad_list.h"
70 71
#include "platform_constants.h"

72
#include "assertions.h"
73 74 75 76 77

#ifdef NAS_NETLINK
#include <sys/socket.h>
#include <linux/netlink.h>

78
extern char nl_rx_buf[NL_MAX_PAYLOAD];
79
extern struct sockaddr_nl nas_src_addr, nas_dest_addr;
80 81 82 83
extern struct nlmsghdr *nas_nlh_tx;
extern struct nlmsghdr *nas_nlh_rx;
extern struct iovec nas_iov_tx;
extern struct iovec nas_iov_rx;
84
extern int nas_sock_fd;
85 86
extern struct msghdr nas_msg_tx;
extern struct msghdr nas_msg_rx;
87 88 89

#define MAX_PAYLOAD 1600

gauthier's avatar
gauthier committed
90
unsigned char pdcp_read_state_g = 0;
91
//unsigned char pdcp_read_payload[MAX_PAYLOAD];
92 93
#endif

94
extern Packet_OTG_List_t *otg_pdcp_buffer;
95

gauthier's avatar
gauthier committed
96
#if defined(LINK_PDCP_TO_GTPV1U)
97
#  include "gtpv1u_eNB_task.h"
gauthier's avatar
gauthier committed
98 99
#endif

gauthier's avatar
gauthier committed
100
pdcp_data_req_header_t pdcp_read_header_g;
101 102

//-----------------------------------------------------------------------------
103
int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const  ctxt_pP)
104 105 106
{
  //-----------------------------------------------------------------------------

gauthier's avatar
gauthier committed
107 108 109
  mem_block_t     *sdu_p            = list_get_head (&pdcp_sdu_list);
  int              bytes_wrote      = 0;
  int              pdcp_nb_sdu_sent = 0;
gauthier's avatar
gauthier committed
110 111
  uint8_t          cont             = 1;
#if defined(LINK_PDCP_TO_GTPV1U)
112
  //MessageDef      *message_p        = NULL;
gauthier's avatar
gauthier committed
113
#endif
114

115 116 117 118
#if defined(NAS_NETLINK) && defined(LINUX)
  int ret = 0;
#endif

gauthier's avatar
gauthier committed
119
  while (sdu_p && cont) {
120

gauthier's avatar
gauthier committed
121
#if ! defined(OAI_EMU)
122
    ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
123 124
#endif

gauthier's avatar
gauthier committed
125 126
#if defined(LINK_PDCP_TO_GTPV1U)

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
    if (ctxt_pP->enb_flag) {
      AssertFatal(0, "Now execution should not go here");
      LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size);
      /*message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_TUNNEL_DATA_REQ);
      GTPV1U_TUNNEL_DATA_REQ(message_p).buffer       = &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]);
      GTPV1U_TUNNEL_DATA_REQ(message_p).length       = ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size;
      GTPV1U_TUNNEL_DATA_REQ(message_p).ue_module_id = ctxt_pP->ue_module_id;
      GTPV1U_TUNNEL_DATA_REQ(message_p).rab_id;      = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
      */
      gtpv1u_new_data_req(
        ctxt_pP->enb_module_id, //gtpv1u_data_t *gtpv1u_data_p,
        ctxt_pP->ue_module_id,//rb_id/maxDRB, TO DO UE ID
        ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4,
        &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]),
        ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size);

      list_remove_head (&pdcp_sdu_list);
      free_mem_block (sdu_p);
      cont = 1;
      pdcp_nb_sdu_sent += 1;
      sdu_p = list_get_head (&pdcp_sdu_list);
      LOG_D(OTG,"After  GTPV1U\n");
      continue; // loop again
    }

gauthier's avatar
gauthier committed
152
#endif /* defined(ENABLE_USE_MME) */
153
#ifdef PDCP_DEBUG
154
    LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to higher layers\n",
155
          ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
gauthier's avatar
gauthier committed
156
          ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id);
157
#endif //PDCP_DEBUG
158
    cont = 0;
159

160 161 162 163
    if (!pdcp_output_sdu_bytes_to_write) {
      if (!pdcp_output_header_bytes_to_write) {
        pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t);
      }
164 165

#ifdef NAS_FIFO
166 167 168
      bytes_wrote = rtf_put (PDCP2NAS_FIFO,
                             &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]),
                             pdcp_output_header_bytes_to_write);
169 170 171 172

#else
#ifdef NAS_NETLINK
#ifdef LINUX
173 174 175
      memcpy(NLMSG_DATA(nas_nlh_tx), &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]),
             pdcp_output_header_bytes_to_write);
      nas_nlh_tx->nlmsg_len = pdcp_output_header_bytes_to_write;
176 177 178
#endif //LINUX
#endif //NAS_NETLINK

179
      bytes_wrote = pdcp_output_header_bytes_to_write;
180 181 182
#endif //NAS_FIFO

#ifdef PDCP_DEBUG
183 184 185
      LOG_D(PDCP, "Frame %d Sent %d Bytes of header to higher layers\n",
            ctxt_pP->frame,
            bytes_wrote);
186 187
#endif //PDCP_DEBUG

188 189
      if (bytes_wrote > 0) {
        pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote;
190

191 192
        if (!pdcp_output_header_bytes_to_write) { // continue with sdu
          pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
193 194

#ifdef NAS_FIFO
195
          bytes_wrote = rtf_put (PDCP2NAS_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write);
196 197 198 199
#else

#ifdef NAS_NETLINK
#ifdef LINUX
200 201 202 203 204 205 206 207 208 209
          memcpy(NLMSG_DATA(nas_nlh_tx)+sizeof(pdcp_data_ind_header_t), &(sdu_p->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write);
          nas_nlh_tx->nlmsg_len += pdcp_output_sdu_bytes_to_write;
          ret = sendmsg(nas_sock_fd,&nas_msg_tx,0);

          if (ret<0) {
            LOG_D(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno);
            mac_xface->macphy_exit("sendmsg failed for nas_sock_fd\n");
            break;
          }

210 211
#endif // LINUX
#endif //NAS_NETLINK
212
          bytes_wrote= pdcp_output_sdu_bytes_to_write;
213 214 215
#endif // NAS_FIFO

#ifdef PDCP_DEBUG
216 217 218 219 220
          LOG_D(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to higher layers\n",
                ctxt_pP->frame,
                ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
                bytes_wrote,
                ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id);
221
#endif //PDCP_DEBUG
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

          if (bytes_wrote > 0) {
            pdcp_output_sdu_bytes_to_write -= bytes_wrote;

            if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU
              // LOG_D(PDCP, "rb sent a sdu qos_sap %d\n", sapiP);
              LOG_D(PDCP,
                    "[FRAME %05d][xxx][PDCP][MOD xx/xx][RB %u][--- PDCP_DATA_IND / %d Bytes --->][IP][INSTANCE %u][RB %u]\n",
                    ctxt_pP->frame,
                    ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id,
                    ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size,
                    ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
                    ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id);

              list_remove_head (&pdcp_sdu_list);
              free_mem_block (sdu_p);
              cont = 1;
              pdcp_nb_sdu_sent += 1;
              sdu_p = list_get_head (&pdcp_sdu_list);
            }
          } else {
            LOG_W(PDCP, "RADIO->IP SEND SDU CONGESTION!\n");
244
          }
245 246 247 248 249 250
        } else {
          LOG_W(PDCP, "RADIO->IP SEND SDU CONGESTION!\n");
        }
      }
    } else {
      // continue writing sdu
251
#ifdef NAS_FIFO
252 253 254
      bytes_wrote = rtf_put (PDCP2NAS_FIFO,
                             (uint8_t *) (&(sdu_p->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size - pdcp_output_sdu_bytes_to_write])),
                             pdcp_output_sdu_bytes_to_write);
255
#else  // NAS_FIFO
256
      bytes_wrote = pdcp_output_sdu_bytes_to_write;
257 258
#endif  // NAS_FIFO

259 260 261 262 263 264 265 266 267 268 269 270
      if (bytes_wrote > 0) {
        pdcp_output_sdu_bytes_to_write -= bytes_wrote;

        if (!pdcp_output_sdu_bytes_to_write) {     // OK finish with this SDU
          //PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n");
          list_remove_head (&pdcp_sdu_list);
          free_mem_block (sdu_p);
          cont = 1;
          pdcp_nb_sdu_sent += 1;
          sdu_p = list_get_head (&pdcp_sdu_list);
          // LOG_D(PDCP, "rb sent a sdu from rab\n");
        }
271
      }
272
    }
273
  }
274

275
#ifdef NAS_FIFO
276

277
  if ((pdcp_nb_sdu_sent)) {
278
    if ((pdcp_2_nas_irq > 0)) {
279
#ifdef PDCP_DEBUG
280 281
      LOG_I(PDCP, "Frame %d : Trigger NAS RX interrupt\n",
            ctxt_pP->frame);
282 283
#endif //PDCP_DEBUG

284 285 286 287 288 289
      rt_pend_linux_srq (pdcp_2_nas_irq);
    } else {
      LOG_E(PDCP, "Frame %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n",
            ctxt_pP->frame,
            pdcp_2_nas_irq);
    }
290
  }
291

292 293 294 295 296 297 298 299 300 301 302
#endif  //NAS_FIFO

  return pdcp_nb_sdu_sent;
}

//-----------------------------------------------------------------------------
/*
 * returns a positive value if whole bytes that had to be read were read
 * returns zero  value if whole bytes that had to be read were not read at all
 * returns a negative  value if an error was encountered while reading the rt fifo
 */
303
int pdcp_fifo_read_input_sdus_remaining_bytes (const protocol_ctxt_t* const  ctxt_pP)
304 305
{
  //-----------------------------------------------------------------------------
306
  sdu_size_t             bytes_read = 0;
gauthier's avatar
gauthier committed
307 308 309 310 311 312
  rb_id_t                rab_id     = 0;
  pdcp_t                *pdcp_p     = NULL;
  module_id_t            ue_inst    = 0;
  module_id_t            enb_inst   = 0;
  rb_id_t                rb_id      = 0;
  int                    result     = -1;
313 314 315

  // if remaining bytes to read
  if (pdcp_input_sdu_remaining_size_to_read > 0) {
316 317 318
    bytes_read = rtf_get (NAS2PDCP_FIFO,
                          &(pdcp_input_sdu_buffer[pdcp_input_sdu_size_read]),
                          pdcp_input_sdu_remaining_size_to_read);
319

320 321
    if (bytes_read > 0) {
      LOG_D(PDCP, "[PDCP_FIFOS] Read %d remaining bytes of data from Nas_mesh\n", bytes_read);
322

323 324
      pdcp_input_sdu_remaining_size_to_read = pdcp_input_sdu_remaining_size_to_read - bytes_read;
      pdcp_input_sdu_size_read = pdcp_input_sdu_size_read + bytes_read;
325

326 327 328
      if (pdcp_input_sdu_remaining_size_to_read != 0) {
        return 0;
      } else {
329
#ifdef PDCP_DEBUG
330 331 332 333 334
        LOG_D(PDCP, "Frame %d: IP->RADIO RECEIVED COMPLETE SDU size %d inst %d rb %d\n",
              ctxt_pP->frame,
              pdcp_input_sdu_size_read,
              pdcp_input_header.inst,
              pdcp_input_header.rb_id);
335
#endif //PDCP_DEBUG
336
        pdcp_input_sdu_size_read = 0;
337
#ifdef IDROMEL_NEMO
338
        pdcp_read_header_g.inst = 0;
339 340
#endif

341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
        if (ctxt_pP->enb_flag == 0) {
          ue_inst  = pdcp_read_header_g.inst;
          rb_id    = pdcp_read_header_g.rb_id;
          enb_inst = 0;
          pdcp_p   = &pdcp_array_drb_ue[ue_inst][rb_id-1];
        } else {
          ue_inst  = pdcp_read_header_g.rb_id / maxDRB;
          rb_id    = pdcp_read_header_g.rb_id % maxDRB;
          enb_inst = pdcp_read_header_g.inst;
          pdcp_p   = &pdcp_array_drb_eNB[enb_inst][ue_inst][rb_id-1];
        }

        AssertFatal (enb_inst < NB_eNB_INST, "eNB module id is too high (%u/%d)!\n",       enb_inst, NB_eNB_INST);
        AssertFatal (ue_inst  >= NB_eNB_INST,
                     "UE module id is too low (%u/%d)!\n",
                     ue_inst,
                     NB_eNB_INST);
        AssertFatal (ue_inst  < (NB_eNB_INST + NB_UE_INST),
                     "UE module id is too high (%u/%d)!\n",
                     ue_inst,
                     NB_eNB_INST + NB_UE_INST);
        AssertFatal (rb_id    < maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, maxDRB);
        AssertFatal (rb_id    > 0     ,                       "RB id is too low (%u/%d)!\n", rab_id, maxDRB);

        if (pdcp_input_header.rb_id != 0) {
          LOG_D(PDCP, "[FRAME %5u][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB %u]\n",
                ctxt_pP->frame,
                (ctxt_pP->enb_flag) ? "eNB" : "UE",
                pdcp_read_header_g.inst,
                pdcp_read_header_g.rb_id,
                pdcp_read_header_g.data_size,
                enb_inst,
                ue_inst,
                rb_id);

          if (pdcp_p->instanciated_instance) {
            result = pdcp_data_req (
                       ctxt_pP,
                       SRB_FLAG_NO,
                       rb_id % maxDRB,
                       RLC_MUI_UNDEFINED,
                       RLC_SDU_CONFIRM_NO,
                       pdcp_input_header.data_size,
                       pdcp_input_sdu_buffer,
                       PDCP_TRANSMISSION_MODE_DATA);
            AssertFatal (result == TRUE, "PDCP data request failed!\n");
          }
gauthier's avatar
gauthier committed
388

389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
        } else if ((pdcp_input_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) || (pdcp_input_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST)) {
          LOG_D(PDCP, "[FRAME %5u][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ on MBMS bearer/ %d Bytes --->][PDCP][MOD %u/%u][RB %u]\n",
                ctxt_pP->frame,
                (ctxt_pP->enb_flag) ? "eNB" : "UE",
                pdcp_read_header_g.inst,
                pdcp_read_header_g.rb_id,
                pdcp_read_header_g.data_size,
                enb_inst,
                ue_inst,
                rb_id);

          if (pdcp_p->instanciated_instance) {
            result = pdcp_data_req (
                       ctxt_pP,
                       SRB_FLAG_NO,
                       rb_id,
                       RLC_MUI_UNDEFINED,
                       RLC_SDU_CONFIRM_NO,
                       pdcp_input_header.data_size,
                       pdcp_input_sdu_buffer,
                       PDCP_TRANSMISSION_MODE_TRANSPARENT);
            AssertFatal (result == TRUE, "PDCP data request failed!\n");
gauthier's avatar
gauthier committed
411
          }
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468

        } else if (ctxt_pP->enb_flag) {
          // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
          LOG_D(PDCP, "Checking if could sent on default rabs\n");

          for (ue_inst = 0; ue_inst < NUMBER_OF_UE_MAX; ue_inst++) {
            LOG_D(PDCP, "Checking if could sent on default rab id %d\n", DEFAULT_RAB_ID);
            pdcp_p = &pdcp_array_drb_eNB[enb_inst][ue_inst][DEFAULT_RAB_ID-1];

            if (pdcp_p->instanciated_instance) {
              LOG_D(PDCP, "[FRAME %5u][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB DEFAULT_RAB_ID %u]\n",
                    ctxt_pP->frame,
                    (ctxt_pP->enb_flag) ? "eNB" : "UE",
                    pdcp_read_header_g.inst,
                    pdcp_read_header_g.rb_id,
                    pdcp_read_header_g.data_size,
                    enb_inst,
                    ue_inst,
                    DEFAULT_RAB_ID);
              result = pdcp_data_req (
                         ctxt_pP,
                         SRB_FLAG_NO,
                         DEFAULT_RAB_ID,
                         RLC_MUI_UNDEFINED,
                         RLC_SDU_CONFIRM_NO,
                         pdcp_input_header.data_size,
                         pdcp_input_sdu_buffer,
                         PDCP_TRANSMISSION_MODE_DATA);
              AssertFatal (result == TRUE, "PDCP data request failed!\n");
            }
          }
        } else {
          LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
          LOG_D(PDCP, "[FRAME %5u][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB DEFAULT_RAB_ID %u]\n",
                ctxt_pP->frame,
                (ctxt_pP->enb_flag) ? "eNB" : "UE",
                pdcp_read_header_g.inst,
                pdcp_read_header_g.rb_id,
                pdcp_read_header_g.data_size,
                enb_inst,
                ue_inst,
                DEFAULT_RAB_ID);
          result = pdcp_data_req (
                     ctxt_pP,
                     SRB_FLAG_NO,
                     DEFAULT_RAB_ID,
                     RLC_MUI_UNDEFINED,
                     RLC_SDU_CONFIRM_NO,
                     pdcp_input_header.data_size,
                     pdcp_input_sdu_buffer,
                     PDCP_TRANSMISSION_MODE_DATA);
          AssertFatal (result == TRUE, "PDCP data request failed!\n");
        }

        // not necessary
        //memset(pdcp_input_sdu_buffer, 0, MAX_IP_PACKET_SIZE);
        return 1;
469
      }
470 471 472
    } else {
      return bytes_read;
    }
473
  }
474

475 476 477 478
  return 1;
}

//-----------------------------------------------------------------------------
479
int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
480 481
{
#ifdef NAS_NETLINK
482
# if defined(ENABLE_PDCP_NETLINK_FIFO)
gauthier's avatar
gauthier committed
483 484 485
  module_id_t                    ue_id     = 0;
  rb_id_t                        rab_id    = 0;
  pdcp_t                        *pdcp      = NULL;
486
  pdcp_transmission_mode_t       pdcp_mode = PDCP_TRANSMISSION_MODE_UNKNOWN;
gauthier's avatar
gauthier committed
487
  struct pdcp_netlink_element_s *data      = NULL;
gauthier's avatar
gauthier committed
488
  protocol_ctxt_t                ctxt_cpy;
gauthier's avatar
gauthier committed
489

gauthier's avatar
gauthier committed
490 491 492
  protocol_ctxt_t                ctxt;

  ctxt_cpy = *ctxt_pP;
493

gauthier's avatar
gauthier committed
494
  while (pdcp_netlink_dequeue_element(ctxt_pP, &data) != 0) {
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
    DevAssert(data != NULL);

    if (ctxt_cpy.enb_flag == ENB_FLAG_NO) {
      rab_id = data->pdcp_read_header.rb_id % maxDRB;
      pdcp = &pdcp_array_drb_ue[ctxt_cpy.ue_module_id][rab_id-1];
    } else {
      rab_id = data->pdcp_read_header.rb_id % maxDRB;
      ctxt_cpy.ue_module_id = data->pdcp_read_header.rb_id / maxDRB;
      pdcp = &pdcp_array_drb_eNB[ctxt_cpy.enb_module_id][ctxt_cpy.ue_module_id][rab_id-1];
    }

    if (ctxt_cpy.enb_flag) {
      AssertFatal ((ctxt_cpy.enb_module_id >= oai_emulation.info.first_enb_local) && (oai_emulation.info.nb_enb_local > 0),
                   "eNB module id is too low (%u/%d)!\n",
                   ctxt_cpy.enb_module_id,
                   oai_emulation.info.first_enb_local);
      AssertFatal ((ctxt_cpy.enb_module_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)) && (oai_emulation.info.nb_enb_local > 0),
                   "eNB module id is too high (%u/%d)!\n",
                   ctxt_cpy.enb_module_id,
                   oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);
      AssertFatal (ctxt_cpy.ue_module_id  < NB_UE_INST,
                   "UE module id is too high (%u/%d)!\n",
                   ctxt_cpy.ue_module_id,
                   oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
    } else {
      AssertFatal (ctxt_cpy.ue_module_id  < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),
                   "UE module id is too high (%u/%d)!\n",
                   ctxt_cpy.ue_module_id,
                   oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
      AssertFatal (ctxt_cpy.ue_module_id  >= oai_emulation.info.first_ue_local,
                   "UE module id is too low (%u/%d)!\n",
                   ctxt_cpy.ue_module_id,
                   oai_emulation.info.first_ue_local);
    }

    AssertFatal (rab_id    < maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, maxDRB);

    if (rab_id != 0) {
      if (pdcp->instanciated_instance) {
        LOG_D(PDCP, "[FRAME %05d][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ "
              "/ %d Bytes --->][PDCP][MOD %u/%u][RB %u]\n",
              ctxt_cpy.frame,
              (ctxt_cpy.enb_flag) ? "eNB" : "UE",
              data->pdcp_read_header.inst,
              data->pdcp_read_header.rb_id,
              data->pdcp_read_header.data_size,
gauthier's avatar
gauthier committed
541 542
              ctxt_cpy.enb_module_id,
              ctxt_cpy.ue_module_id,
543 544 545 546 547 548
              rab_id);
#ifdef  OAI_NW_DRIVER_TYPE_ETHERNET

        if ((data->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ ||
            (data->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ ||
            (data->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) {
549
#if defined (Rel10)
550
          PDCP_TRANSMISSION_MODE_TRANSPARENT;
551
#else
552
          pdcp_mode= PDCP_TRANSMISSION_MODE_DATA;
553
#endif
554 555 556 557 558 559 560 561
        } else if ((data->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_UNICAST) /* TRAFFIC_IPV6_TYPE_UNICAST */ ||
                   (data->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_UNICAST) /*TRAFFIC_IPV4_TYPE_UNICAST*/ ) {
          pdcp_mode=  PDCP_TRANSMISSION_MODE_DATA;
        } else {
          pdcp_mode= PDCP_TRANSMISSION_MODE_DATA;
          LOG_W(PDCP,"unknown IP traffic type \n");
        }

562
#else // NASMESH driver does not curreenlty support multicast traffic
563
        pdcp_mode = PDCP_TRANSMISSION_MODE_DATA;
564
#endif
565
        pdcp_data_req(ctxt_pP,
566
                      SRB_FLAG_NO,
567
                      rab_id % maxDRB,
gauthier's avatar
gauthier committed
568 569 570 571
                      RLC_MUI_UNDEFINED,
                      RLC_SDU_CONFIRM_NO,
                      data->pdcp_read_header.data_size,
                      data->data,
572
                      pdcp_mode);
gauthier's avatar
gauthier committed
573
      } else {
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
        LOG_E(PDCP, "Received packet for non-instanciated instance %u with rb_id %u, UE_index %d, ctxt_cpy.enb_flag %d eNB_index %d\n",
              data->pdcp_read_header.inst, data->pdcp_read_header.rb_id, ctxt_cpy.ue_module_id, ctxt_cpy.enb_flag,ctxt_cpy.enb_module_id);
      }
    } else if (ctxt_cpy.enb_flag) {
      /* rb_id = 0, thus interpreated as broadcast and transported as
       * multiple unicast is a broadcast packet, we have to send this
       * packet on all default RABS of all connected UEs
       */
      LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID first_ue_local %u nb_ue_local %u\n", oai_emulation.info.first_ue_local, oai_emulation.info.nb_ue_local);

      for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) {
        pdcp = &pdcp_array_drb_eNB[ctxt_cpy.enb_module_id][ue_id][DEFAULT_RAB_ID-1];

        if (pdcp->instanciated_instance) {
          LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id);
          ctxt.enb_module_id = ctxt_cpy.enb_module_id;
          ctxt.ue_module_id  = ue_id;
          ctxt.frame         = ctxt_cpy.frame;
          ctxt.enb_flag      = ctxt_cpy.enb_flag;

gauthier's avatar
gauthier committed
594
          pdcp_data_req(
595 596 597 598 599 600 601 602 603
            &ctxt,
            SRB_FLAG_NO,
            DEFAULT_RAB_ID,
            RLC_MUI_UNDEFINED,
            RLC_SDU_CONFIRM_NO,
            data->pdcp_read_header.data_size,
            data->data,
            PDCP_TRANSMISSION_MODE_DATA);
        }
gauthier's avatar
gauthier committed
604
      }
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
    } else {
      LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
      pdcp_data_req(
        &ctxt_cpy,
        SRB_FLAG_NO,
        DEFAULT_RAB_ID,
        RLC_MUI_UNDEFINED,
        RLC_SDU_CONFIRM_NO,
        data->pdcp_read_header.data_size,
        data->data,
        PDCP_TRANSMISSION_MODE_DATA);
    }

    free(data->data);
    free(data);
    data = NULL;
gauthier's avatar
gauthier committed
621
  }
622

gauthier's avatar
gauthier committed
623 624
  return 0;
# else /* ENABLE_PDCP_NETLINK_FIFO*/
625 626
  int              len = 1;
  rb_id_t          rab_id  = 0;
627 628 629
  protocol_ctxt_t                ctxt_cpy;
  protocol_ctxt_t                ctxt;
  ctxt_cpy = *ctxt_pP;
630

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
  while (len > 0) {
    len = recvmsg(nas_sock_fd, &nas_msg_rx, 0);

    if (len<=0) {
      // nothing in pdcp NAS socket
      //LOG_I(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len);
    } else {
      for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
           NLMSG_OK (nas_nlh_rx, len);
           nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) {

        if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) {
          LOG_D(PDCP, "[PDCP][FIFO] RX NLMSG_DONE\n");
          //return;
        }

        if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) {
          LOG_E(PDCP, "[PDCP][FIFO] RX NLMSG_ERROR\n");
        }

        if (pdcp_read_state_g == 0) {
          if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) {
            pdcp_read_state_g = 1;  //get
            memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t));
            LOG_D(PDCP, "[PDCP][FIFO] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d\n",
                  pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size);
          } else {
            LOG_E(PDCP, "[PDCP][FIFO] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n",
                  nas_nlh_rx->nlmsg_len);
          }
        } else {
          pdcp_read_state_g = 0;
          // print_active_requests()
664
#ifdef PDCP_DEBUG
665 666
          LOG_D(PDCP, "[PDCP][FIFO] Something in socket, length %d \n",
                nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
667
#endif
668
          //memcpy(pdcp_read_payload, (unsigned char *)NLMSG_DATA(nas_nlh_rx), nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
gauthier's avatar
gauthier committed
669

670
#ifdef OAI_EMU
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706

          // overwrite function input parameters, because only one netlink socket for all instances
          if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) {
            ctxt.frame         = ctxt_cpy.frame;
            ctxt.enb_flag      = ENB_FLAG_YES;
            ctxt.ue_module_id  = pdcp_read_header_g.rb_id / maxDRB + oai_emulation.info.first_ue_local;
            ctxt.enb_module_id = pdcp_read_header_g.inst  +  oai_emulation.info.first_enb_local;
            rab_id    = pdcp_read_header_g.rb_id % maxDRB;
          } else {
            ctxt.frame         = ctxt_cpy.frame;
            ctxt.enb_flag      = ENB_FLAG_NO;
            ctxt.ue_module_id  = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local;
            ctxt.enb_module_id = 0;
            rab_id    = pdcp_read_header_g.rb_id;
          }

          AssertFatal (ctxt.enb_module_id >= oai_emulation.info.first_enb_local,
                       "eNB inst is too low (%u/%d)!\n",
                       ctxt.enb_module_id,
                       oai_emulation.info.first_enb_local);
          AssertFatal (ctxt.enb_module_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local),
                       "eNB inst is too high (%u/%d)!\n",
                       ctxt.enb_module_id,
                       oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);
          AssertFatal (ctxt.ue_module_id  >= oai_emulation.info.first_ue_local,
                       "UE inst is too low (%u/%d)!\n",
                       ctxt.ue_module_id,
                       oai_emulation.info.first_ue_local);
          AssertFatal (ctxt.ue_module_id  < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),
                       "UE inst is too high (%u/%d)!\n",
                       ctxt.ue_module_id,
                       oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
          AssertFatal (rab_id    < maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, maxDRB);
          /*LGpdcp_read_header.inst = (pdcp_read_header_g.inst >= oai_emulation.info.nb_enb_local) ? \
                  pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local :
                  pdcp_read_header_g.inst +  oai_emulation.info.first_enb_local;*/
gauthier's avatar
gauthier committed
707
#else
708
          pdcp_read_header_g.inst = 0;
709
#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
710 711 712 713 714 715 716 717 718 719 720 721 722 723
          ctxt.frame         = ctxt_cpy.frame;

          if (ctxt_cpy.enb_flag) {
            ctxt.enb_flag      = ENB_FLAG_YES;
            ctxt.ue_module_id  = 0;
            ctxt.enb_module_id = 0;
            rab_id      = pdcp_read_header_g.rb_id % maxDRB;
          } else {
            ctxt.enb_flag      = ENB_FLAG_NO;
            ctxt.ue_module_id  = 0;
            ctxt.enb_module_id = 0;
            rab_id      = pdcp_read_header_g.rb_id % maxDRB;
          }

gauthier's avatar
gauthier committed
724 725
#endif

726 727 728 729 730
          if (ctxt.enb_flag) {
            if (rab_id != 0) {
              rab_id = rab_id % maxDRB;

              if (pdcp_array_drb_eNB[ctxt.enb_module_id][ctxt.ue_module_id][rab_id-1].instanciated_instance) {
731
#ifdef PDCP_DEBUG
732 733 734 735 736 737
                LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      len,
                      nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
                      pdcp_read_header_g.rb_id);
738 739
#endif

740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
                LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB %u]\n",
                      ctxt_cpy.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
                      ctxt.enb_module_id,
                      ctxt.ue_module_id,
                      rab_id);

                pdcp_data_req(&ctxt,
                              SRB_FLAG_NO,
                              rab_id,
                              RLC_MUI_UNDEFINED,
                              RLC_SDU_CONFIRM_NO,
                              pdcp_read_header_g.data_size,
                              (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                              PDCP_TRANSMISSION_MODE_DATA);
              } else {
                LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u/%u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n",
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
                      ctxt.enb_module_id,
                      ctxt.ue_module_id,
                      rab_id);
              }
            } else  { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast
              // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
gauthier's avatar
gauthier committed
769
#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
              for (ctxt.ue_module_id = 0; ctxt.ue_module_id < NB_UE_INST; ctxt.ue_module_id++) {
                if (pdcp_array_drb_eNB[ctxt.enb_module_id][ctxt.ue_module_id][rab_id-1].instanciated_instance == TRUE) {
                  LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB DEFAULT_RAB_ID %u]\n",
                        ctxt.frame,
                        pdcp_read_header_g.inst,
                        pdcp_read_header_g.rb_id,
                        pdcp_read_header_g.data_size,
                        ctxt.enb_module_id,
                        ctxt.ue_module_id,
                        DEFAULT_RAB_ID);
                  pdcp_data_req (
                    &ctxt,
                    SRB_FLAG_NO,
                    DEFAULT_RAB_ID,
                    RLC_MUI_UNDEFINED,
                    RLC_SDU_CONFIRM_NO,
                    pdcp_read_header_g.data_size,
                    (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                    PDCP_TRANSMISSION_MODE_DATA);
                }
              }
            }
          } else {
            if (rab_id != 0) {
              if (pdcp_array_drb_ue[ctxt.ue_module_id][rab_id-1].instanciated_instance) {
gauthier's avatar
gauthier committed
795
#ifdef PDCP_DEBUG
796 797 798 799 800 801
                LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      len,
                      nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
                      pdcp_read_header_g.rb_id);
802

803 804 805 806 807 808 809 810 811
                LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB %u]\n",
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
                      ctxt.enb_module_id,
                      ctxt.ue_module_id,
                      rab_id);
#endif
gauthier's avatar
gauthier committed
812

813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
                pdcp_data_req(
                  &ctxt,
                  SRB_FLAG_NO,
                  rab_id,
                  RLC_MUI_UNDEFINED,
                  RLC_SDU_CONFIRM_NO,
                  pdcp_read_header_g.data_size,
                  (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                  PDCP_TRANSMISSION_MODE_DATA);
              } else {
                LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u/%u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n",
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
                      ctxt.enb_module_id,
                      ctxt.ue_module_id,
                      rab_id);
831
              }
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
            }  else {
              LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
              LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB DEFAULT_RAB_ID %u]\n",
                    ctxt.frame,
                    pdcp_read_header_g.inst,
                    pdcp_read_header_g.rb_id,
                    pdcp_read_header_g.data_size,
                    ctxt.enb_module_id,
                    ctxt.ue_module_id,
                    DEFAULT_RAB_ID);
              pdcp_data_req (
                &ctxt,
                SRB_FLAG_NO,
                DEFAULT_RAB_ID,
                RLC_MUI_UNDEFINED,
                RLC_SDU_CONFIRM_NO,
                pdcp_read_header_g.data_size,
                (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                PDCP_TRANSMISSION_MODE_DATA);
            }
852
          }
853 854

        }
gauthier's avatar
gauthier committed
855
      }
856
    }
857
  }
858

859
  return len;
860
# endif
861 862 863 864 865 866
#else // neither NAS_NETLINK nor NAS_FIFO
  return 0;
#endif // NAS_NETLINK
}


867 868
void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const  ctxt_pP)
{
869
  unsigned char       *otg_pkt=NULL;
870
  module_id_t          src_id; // src for otg
871 872
  module_id_t          dst_id; // dst for otg
  rb_id_t              rb_id;
nikaeinn's avatar
nikaeinn committed
873
  signed long          pkt_size=0;
gauthier's avatar
gauthier committed
874
  protocol_ctxt_t      ctxt;
875 876

  src_id = ctxt_pP->enb_module_id;
877

878 879
  // we need to add conditions to avoid transmitting data when the UE is not RRC connected.
#if defined(USER_MODE) && defined(OAI_EMU)
880 881 882 883 884 885
  module_id_t          module_id;
  static unsigned int  pkt_cnt_enb=0, pkt_cnt_ue=0;
  uint8_t              pdcp_mode, is_ue=0;
  Packet_otg_elt_t    *otg_pkt_info=NULL;
  int                  result;

886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954
  if (oai_emulation.info.otg_enabled ==1 ) {
    module_id = (ctxt_pP->enb_flag == 1) ?  ctxt_pP->enb_module_id : ctxt_pP->ue_module_id+NB_eNB_INST;
    //rb_id    = (ctxt_pP->enb_flag == 1) ? ctxt_pP->enb_module_id * MAX_NUM_RB + DTCH : (NB_eNB_INST + UE_index -1 ) * MAX_NUM_RB + DTCH ;
    src_id = module_id;

    while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]))) != NULL) {
      LOG_D(OTG,"Mod_id %d Frame %d Got a packet (%p), HEAD of otg_pdcp_buffer[%d] is %p and Nb elements is %d\n",
            module_id,ctxt_pP->frame, otg_pkt_info, module_id, pkt_list_get_head(&(otg_pdcp_buffer[module_id])), otg_pdcp_buffer[module_id].nb_elements);
      //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]));
      dst_id    = (otg_pkt_info->otg_pkt).dst_id;
      module_id = (otg_pkt_info->otg_pkt).module_id;
      rb_id     = (otg_pkt_info->otg_pkt).rb_id;
      is_ue     = (otg_pkt_info->otg_pkt).is_ue;
      pdcp_mode = (otg_pkt_info->otg_pkt).mode;
      //    LOG_I(PDCP,"pdcp_fifo, pdcp mode is= %d\n",pdcp_mode);

      // generate traffic if the ue is rrc reconfigured state
      // if (mac_get_rrc_status(module_id, ctxt_pP->enb_flag, dst_id ) > 2 /*RRC_CONNECTED*/) { // not needed: this test is already done in update_otg_enb
      otg_pkt = (unsigned char*) (otg_pkt_info->otg_pkt).sdu_buffer;
      pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size;

      if (otg_pkt != NULL) {
        if (is_ue == 0 ) {
          /*rlc_util_print_hex_octets(PDCP,
                                    otg_pkt,
                                    pkt_size);
           */
          //rb_id = (/*NB_eNB_INST +*/ dst_id -1 ) * MAX_NUM_RB + DTCH;
          ctxt.enb_module_id = ctxt_pP->enb_module_id;
          ctxt.ue_module_id  = dst_id;
          ctxt.frame         = ctxt_pP->frame;
          ctxt.enb_flag      = ctxt_pP->enb_flag;

          LOG_D(OTG,"[eNB %d] Frame %d sending packet %d from module %d on rab id %d (src %d, dst %d) pkt size %d for pdcp mode %d\n",
                ctxt_pP->enb_module_id, ctxt_pP->frame, pkt_cnt_enb++, module_id, rb_id, module_id, dst_id, pkt_size, pdcp_mode);
          result = pdcp_data_req(&ctxt,
                                 SRB_FLAG_NO,
                                 rb_id,
                                 RLC_MUI_UNDEFINED,
                                 RLC_SDU_CONFIRM_NO,
                                 pkt_size,
                                 otg_pkt,
                                 pdcp_mode);
          AssertFatal (result == TRUE, "PDCP data request failed!\n");
        } else {
          //rb_id= eNB_index * MAX_NUM_RB + DTCH;


          LOG_D(OTG,"[UE %d] Frame %d: sending packet %d from module %d on rab id %d (src %d, dst %d) pkt size %d\n",
                ctxt_pP->ue_module_id, ctxt_pP->frame, pkt_cnt_ue++, src_id, rb_id, src_id, dst_id, pkt_size);

          ctxt.enb_module_id = dst_id;
          ctxt.ue_module_id  = ctxt_pP->ue_module_id;
          ctxt.frame         = ctxt_pP->frame;
          ctxt.enb_flag      = ctxt_pP->enb_flag;

          result = pdcp_data_req( &ctxt,
                                  SRB_FLAG_NO,
                                  rb_id,
                                  RLC_MUI_UNDEFINED,
                                  RLC_SDU_CONFIRM_NO,
                                  pkt_size,
                                  otg_pkt,
                                  PDCP_TRANSMISSION_MODE_DATA);
          AssertFatal (result == TRUE, "PDCP data request failed!\n");
        }

        free(otg_pkt);
        otg_pkt = NULL;
955
      }
956 957 958 959

      // } //else LOG_D(OTG,"ctxt_pP->frame %d enb %d-> ue %d link not yet established state %d  \n", ctxt_pP->frame, eNB_index,dst_id - NB_eNB_INST, mac_get_rrc_status(module_id, ctxt_pP->enb_flag, dst_id - NB_eNB_INST));

    }
960
  }
961

962
#else
963

964
  if ((otg_enabled==1) && (ctxt_pP->enb_flag == 1)) { // generate DL traffic
965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
    unsigned int ctime=0;
    ctime = ctxt_pP->frame * 100;

    /*if  ((mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 0 ) > 2) &&
    (mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 1 ) > 2)) { */
    ctxt.enb_module_id = ctxt_pP->enb_module_id;
    ctxt.frame         = ctxt_pP->frame;
    ctxt.enb_flag      = ctxt_pP->enb_flag;

    for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) {
      if (mac_get_rrc_status(ctxt_pP->enb_module_id, ctxt_pP->enb_flag, dst_id ) > 2) {
        unsigned int temp = 0;
        otg_pkt = packet_gen( src_id, dst_id, 0, ctime, &temp );
        pkt_size = temp;

        if (otg_pkt != NULL) {
          rb_id = dst_id * maxDRB + DTCH;
          ctxt.ue_module_id  = dst_id;
          pdcp_data_req(&ctxt,
                        SRB_FLAG_NO,
                        rb_id,
                        RLC_MUI_UNDEFINED,
                        RLC_SDU_CONFIRM_NO,
                        pkt_size,
                        otg_pkt,
                        PDCP_TRANSMISSION_MODE_DATA);
          LOG_D(OTG,"send packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", ctxt_pP->enb_module_id, rb_id, src_id, dst_id, pkt_size);
          free(otg_pkt);
        }

        /*else {
        LOG_I(OTG,"nothing generated (src %d, dst %d)\n",src_id, dst_id);
        }*/
gauthier's avatar
gauthier committed
998
      }
999 1000 1001 1002 1003

      /*else {
      LOG_I(OTG,"rrc_status (src %d, dst %d) = %d\n",src_id, dst_id, mac_get_rrc_status(src_id, ctxt_pP->enb_flag, dst_id ));
      }*/
    }
1004
  }
1005

1006 1007
#endif
}