pdcp_fifo.c 38.3 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21 22

/*! \file pdcp_fifo.c
23
 * \brief pdcp interface with linux IP interface, have a look at http://man7.org/linux/man-pages/man7/netlink.7.html for netlink
24 25
 * \author  Navid Nikaein and Lionel GAUTHIER
 * \date 2009 - 2016
26
 * \version 0.5
27
 * \email navid.nikaein@eurecom.fr
28 29 30
 * \warning This component can be runned only in user-space
 * @ingroup pdcp
 */
31 32 33

#define PDCP_FIFO_C
#define PDCP_DEBUG 1
34
//#define DEBUG_PDCP_FIFO_FLUSH_SDU
35 36 37 38 39 40 41 42 43

#ifndef OAI_EMU
extern int otg_enabled;
#endif

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

#ifdef USER_MODE
44
#include <pthread.h>
45 46 47 48 49 50 51 52 53 54 55 56
#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"
57
#include "NETWORK_DRIVER/LITE/constant.h"
58 59 60 61
#include "SIMULATION/ETH_TRANSPORT/extern.h"
#include "UTIL/OCG/OCG.h"
#include "UTIL/OCG/OCG_extern.h"
#include "UTIL/LOG/log.h"
62
#include "UTIL/OTG/otg_tx.h"
63
#include "UTIL/FIFO/pad_list.h"
64
#include "UTIL/LOG/vcd_signal_dumper.h"
65
#include "platform_constants.h"
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
66
#include "msc.h"
67

68
#include "assertions.h"
69

70
#ifdef PDCP_USE_NETLINK
71 72
#include <sys/socket.h>
#include <linux/netlink.h>
73
#include "NETWORK_DRIVER/UE_IP/constant.h"
74

75
extern char nl_rx_buf[NL_MAX_PAYLOAD];
76
extern struct sockaddr_nl nas_src_addr, nas_dest_addr;
77 78 79 80
extern struct nlmsghdr *nas_nlh_tx;
extern struct nlmsghdr *nas_nlh_rx;
extern struct iovec nas_iov_tx;
extern struct iovec nas_iov_rx;
81
extern int nas_sock_fd;
82 83
extern struct msghdr nas_msg_tx;
extern struct msghdr nas_msg_rx;
84

85
unsigned char pdcp_read_state_g = 0;
86 87
#endif

88
extern Packet_OTG_List_t *otg_pdcp_buffer;
89

90
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
91
#  include "gtpv1u_eNB_task.h"
Cedric Roux's avatar
Cedric Roux committed
92
#  include "gtpv1u_eNB_defs.h"
Lionel Gauthier's avatar
Lionel Gauthier committed
93 94
#endif

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/* Prevent de-queueing the same PDCP SDU from the queue twice
 * by multiple threads. This has happened in TDD when thread-odd
 * is flushing a PDCP SDU after UE_RX() processing; whereas
 * thread-even is at a special-subframe, skips the UE_RX() process
 * and goes straight to the PDCP SDU flushing. The 2nd flushing
 * dequeues the same SDU again causing unexpected behavior.
 *
 * comment out the MACRO below to disable this protection
 */
#define PDCP_SDU_FLUSH_LOCK

#ifdef PDCP_SDU_FLUSH_LOCK
static pthread_mutex_t mtex = PTHREAD_MUTEX_INITIALIZER;
#endif

110
pdcp_data_req_header_t pdcp_read_header_g;
111 112

//-----------------------------------------------------------------------------
113
int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const  ctxt_pP)
114 115 116
{
  //-----------------------------------------------------------------------------

117
//#if defined(PDCP_USE_NETLINK) && defined(LINUX)
118
  int ret = 0;
119
//#endif
120

121 122
#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU
#define THREAD_NAME_LEN 16
123
  static char threadname[THREAD_NAME_LEN];
124 125 126 127 128 129 130 131 132
  ret = pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN);
  if (ret != 0)
  {
   perror("pthread_getname_np : ");
   exit_fun("Error getting thread name");
  }
#undef THREAD_NAME_LEN
#endif

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
#ifdef PDCP_SDU_FLUSH_LOCK
  ret = pthread_mutex_trylock(&mtex);
  if (ret == EBUSY) {
#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU
    LOG_W(PDCP, "[%s] at SFN/SF=%d/%d wait for PDCP FIFO to be unlocked\n",
        threadname, ctxt_pP->frame, ctxt_pP->subframe);
#endif
    if (pthread_mutex_lock(&mtex)) {
      exit_fun("PDCP_SDU_FLUSH_LOCK lock error!");
    }
#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU
    LOG_I(PDCP, "[%s] at SFN/SF=%d/%d PDCP FIFO is unlocked\n",
        threadname, ctxt_pP->frame, ctxt_pP->subframe);
#endif
  } else if (ret != 0) {
    exit_fun("PDCP_SDU_FLUSH_LOCK trylock error!");
  }

#endif

  mem_block_t     *sdu_p            = list_get_head (&pdcp_sdu_list);
  int              bytes_wrote      = 0;
  int              pdcp_nb_sdu_sent = 0;
  uint8_t          cont             = 1;
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
  //MessageDef      *message_p        = NULL;
#endif

161
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 1 );
162
  while (sdu_p && cont) {
163

164 165 166 167 168 169
#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU
    LOG_D(PDCP, "[%s] SFN/SF=%d/%d inst=%d size=%d\n",
        threadname, ctxt_pP->frame, ctxt_pP->subframe,
        ((pdcp_data_ind_header_t*) sdu_p->data)->inst,
        ((pdcp_data_ind_header_t *) sdu_p->data)->data_size);
#else
Lionel Gauthier's avatar
Lionel Gauthier committed
170
#if ! defined(OAI_EMU)
Cedric Roux's avatar
Cedric Roux committed
171 172
    /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
//    ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
173
#endif
174
#endif
175

176
#if defined(LINK_ENB_PDCP_TO_GTPV1U)
Lionel Gauthier's avatar
Lionel Gauthier committed
177

178 179 180 181
    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);
      gtpv1u_new_data_req(
182 183 184 185 186 187
			  ctxt_pP->module_id, //gtpv1u_data_t *gtpv1u_data_p,
			  ctxt_pP->rnti,//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,
			  0);
188 189

      list_remove_head (&pdcp_sdu_list);
190
      free_mem_block (sdu_p, __func__);
191 192 193 194 195 196 197
      cont = 1;
      pdcp_nb_sdu_sent += 1;
      sdu_p = list_get_head (&pdcp_sdu_list);
      LOG_D(OTG,"After  GTPV1U\n");
      continue; // loop again
    }

Lionel Gauthier's avatar
Lionel Gauthier committed
198
#endif /* defined(ENABLE_USE_MME) */
199
#ifdef PDCP_DEBUG
200
    LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n",
201
          ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
202
          ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id);
203
#endif //PDCP_DEBUG
204
    cont = 0;
205

206 207 208 209
    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);
      }
210

211 212
#ifdef PDCP_USE_RT_FIFO
      bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO,
213 214
                             &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]),
                             pdcp_output_header_bytes_to_write);
215 216

#else
217
#ifdef PDCP_USE_NETLINK
218
#ifdef LINUX
219 220 221
      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;
222
#endif //LINUX
223
#endif //PDCP_USE_NETLINK
224

225
      bytes_wrote = pdcp_output_header_bytes_to_write;
226
#endif //PDCP_USE_RT_FIFO
227 228

#ifdef PDCP_DEBUG
229
      LOG_D(PDCP, "Frame %d Sent %d Bytes of header to Nas_mesh\n",
230 231
            ctxt_pP->frame,
            bytes_wrote);
232 233
#endif //PDCP_DEBUG

234 235
      if (bytes_wrote > 0) {
        pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote;
236

237 238
        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;
239
          AssertFatal(pdcp_output_sdu_bytes_to_write >= 0, "invalid data_size!");
240

241 242
#ifdef PDCP_USE_RT_FIFO
          bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write);
243 244
#else

245
#ifdef PDCP_USE_NETLINK
246
#ifdef LINUX
247 248
          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;
249 250
          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_SIZE, pdcp_output_sdu_bytes_to_write);
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER, 1 );
251
          ret = sendmsg(nas_sock_fd,&nas_msg_tx,0);
252 253
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER, 0 );
          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_ERR, ret );
254 255

          if (ret<0) {
256
            LOG_E(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno);
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
257 258 259 260 261 262 263 264 265
      	    MSC_LOG_TX_MESSAGE_FAILED(
      	      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
      	      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
      	      NULL,
      	      0,
      	      MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u",
      	      MSC_AS_TIME_ARGS(ctxt_pP),
      	      ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id,
      	      ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size);
266
	    AssertFatal(1==0,"sendmsg failed for nas_sock_fd\n");
267
            break;
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
268 269 270 271 272 273 274 275 276 277
          } else {
        	  MSC_LOG_TX_MESSAGE(
        	    (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
        	    (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
        	    NULL,
        	    0,
        	    MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u",
        	    MSC_AS_TIME_ARGS(ctxt_pP),
        	    ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id,
        	    ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size);
278 279
          }

280
#endif // LINUX
281
#endif //PDCP_USE_NETLINK
282
          bytes_wrote= pdcp_output_sdu_bytes_to_write;
283
#endif // PDCP_USE_RT_FIFO
284 285

#ifdef PDCP_DEBUG
286 287 288 289 290
          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);
291
#endif //PDCP_DEBUG
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306

          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);
307
              free_mem_block (sdu_p, __func__);
308 309 310
              cont = 1;
              pdcp_nb_sdu_sent += 1;
              sdu_p = list_get_head (&pdcp_sdu_list);
311 312 313
            } else {
              LOG_D(PDCP, "1 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write);
              AssertFatal(pdcp_output_sdu_bytes_to_write > 0, "pdcp_output_sdu_bytes_to_write cannot be negative!");
314 315
            }
          } else {
316
            LOG_W(PDCP, "2: RADIO->IP SEND SDU CONGESTION!\n");
317
          }
318
        } else {
319
          LOG_W(PDCP, "3: RADIO->IP SEND SDU CONGESTION!\n");
320
        }
321 322
      } else {
        LOG_D(PDCP, "4 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote);
323 324 325
      }
    } else {
      // continue writing sdu
326 327
#ifdef PDCP_USE_RT_FIFO
      bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO,
328 329
                             (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);
330
#else  // PDCP_USE_RT_FIFO
331
      bytes_wrote = pdcp_output_sdu_bytes_to_write;
332
#endif  // PDCP_USE_RT_FIFO
333

334 335 336 337 338 339
      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);
340
          free_mem_block (sdu_p, __func__);
341 342 343 344
          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");
345 346
        } else {
          LOG_D(PDCP, "5 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write);
347
        }
348 349
      } else {
        LOG_D(PDCP, "6 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote);
350
      }
351
    }
352
  }
353
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 0 );
354

355
#ifdef PDCP_USE_RT_FIFO
356

357
  if ((pdcp_nb_sdu_sent)) {
358
    if ((pdcp_2_nas_irq > 0)) {
359
#ifdef PDCP_DEBUG
360
      LOG_D(PDCP, "Frame %d : Trigger NAS RX interrupt\n",
361
            ctxt_pP->frame);
362
#endif //PDCP_DEBUG
363
      rt_pend_linux_srq (pdcp_2_nas_irq);
364

365 366 367 368 369
    } 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);
    }
370
  }
371

372
#endif  //PDCP_USE_RT_FIFO
373

374 375 376 377
#ifdef PDCP_SDU_FLUSH_LOCK
  if (pthread_mutex_unlock(&mtex)) exit_fun("PDCP_SDU_FLUSH_LOCK unlock error!");
#endif

378 379 380 381
  return pdcp_nb_sdu_sent;
}

//-----------------------------------------------------------------------------
382
int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
383
{
384
#ifdef PDCP_USE_NETLINK
385
  protocol_ctxt_t                ctxt_cpy = *ctxt_pP;
386 387 388 389
  protocol_ctxt_t                ctxt;
  hash_key_t                     key       = HASHTABLE_NOT_A_KEY_VALUE;
  hashtable_rc_t                 h_rc;
  struct pdcp_netlink_element_s* data_p    = NULL;
Cedric Roux's avatar
Cedric Roux committed
390 391
  /* avoid gcc warnings */
  (void)data_p;
392
  module_id_t                    ue_id     = 0;
393
  pdcp_t*                        pdcp_p    = NULL;
394
# if defined(PDCP_USE_NETLINK_QUEUES)
395
  rb_id_t                        rab_id    = 0;
396

397
  pdcp_transmission_mode_t       pdcp_mode = PDCP_TRANSMISSION_MODE_UNKNOWN;
398

Lionel Gauthier's avatar
Lionel Gauthier committed
399

400
  while (pdcp_netlink_dequeue_element(ctxt_pP, &data_p) != 0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
401
    DevAssert(data_p != NULL);
402 403 404 405 406 407 408 409 410 411 412 413 414
    rab_id = data_p->pdcp_read_header.rb_id % maxDRB;
    // ctxt_pP->rnti is NOT_A_RNTI
    ctxt_cpy.rnti = pdcp_module_id_to_rnti[ctxt_cpy.module_id][data_p->pdcp_read_header.inst];
    key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_cpy.rnti, ctxt_pP->enb_flag, rab_id, SRB_FLAG_NO);
    h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);

    if (h_rc != HASH_TABLE_OK) {
      LOG_W(PDCP, PROTOCOL_CTXT_FMT" Dropped IP PACKET cause no PDCP instanciated\n",
            PROTOCOL_CTXT_ARGS(ctxt_pP));
      free(data_p->data);
      free(data_p);
      data_p = NULL;
      continue;
415 416
    }

417
    CHECK_CTXT_ARGS(&ctxt_cpy);
418 419 420 421 422

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

    if (rab_id != 0) {
        LOG_D(PDCP, "[FRAME %05d][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ "
423
            "/ %d Bytes --->][PDCP][MOD %u][RB %u]\n",
424 425
              ctxt_cpy.frame,
              (ctxt_cpy.enb_flag) ? "eNB" : "UE",
426 427 428 429
            data_p->pdcp_read_header.inst,
            data_p->pdcp_read_header.rb_id,
            data_p->pdcp_read_header.data_size,
            ctxt_cpy.module_id,
430 431 432
              rab_id);
#ifdef  OAI_NW_DRIVER_TYPE_ETHERNET

433 434 435
      if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ ||
          (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ ||
          (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) {
Cedric Roux's avatar
Cedric Roux committed
436
#if defined(Rel10) || defined(Rel14)
437
          PDCP_TRANSMISSION_MODE_TRANSPARENT;
438
#else
439
          pdcp_mode= PDCP_TRANSMISSION_MODE_DATA;
440
#endif
441 442
      } else if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_UNICAST) /* TRAFFIC_IPV6_TYPE_UNICAST */ ||
                 (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_UNICAST) /*TRAFFIC_IPV4_TYPE_UNICAST*/ ) {
443 444 445 446 447 448
          pdcp_mode=  PDCP_TRANSMISSION_MODE_DATA;
        } else {
          pdcp_mode= PDCP_TRANSMISSION_MODE_DATA;
          LOG_W(PDCP,"unknown IP traffic type \n");
        }

449
#else // OAI_NW_DRIVER_TYPE_ETHERNET NASMESH driver does not curreenlty support multicast traffic
450
        pdcp_mode = PDCP_TRANSMISSION_MODE_DATA;
451
#endif
452
      pdcp_data_req(&ctxt_cpy,
453
                      SRB_FLAG_NO,
454
                      rab_id % maxDRB,
455 456
                      RLC_MUI_UNDEFINED,
                      RLC_SDU_CONFIRM_NO,
457 458
                    data_p->pdcp_read_header.data_size,
                    data_p->data,
459 460 461 462 463 464 465 466 467
                      pdcp_mode);
    } 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++) {
468
        if (pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) {
469
          LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id);
470 471
          ctxt.module_id     = ctxt_cpy.module_id;
          ctxt.rnti          = ctxt_cpy.pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id];
472 473 474
          ctxt.frame         = ctxt_cpy.frame;
          ctxt.enb_flag      = ctxt_cpy.enb_flag;

475
          pdcp_data_req(
476 477 478 479 480
            &ctxt,
            SRB_FLAG_NO,
            DEFAULT_RAB_ID,
            RLC_MUI_UNDEFINED,
            RLC_SDU_CONFIRM_NO,
481 482
            data_p->pdcp_read_header.data_size,
            data_p->data,
483 484
            PDCP_TRANSMISSION_MODE_DATA);
        }
485
      }
486 487 488 489 490 491 492 493
    } 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,
494 495
        data_p->pdcp_read_header.data_size,
        data_p->data,
496 497 498
        PDCP_TRANSMISSION_MODE_DATA);
    }

499 500 501
    free(data_p->data);
    free(data_p);
    data_p = NULL;
502
  }
503

504
  return 0;
505
# else /* PDCP_USE_NETLINK_QUEUES*/
506
  int              len = 1;
507
  int  msg_len;
508
  rb_id_t          rab_id  = 0;
509 510 511
  int rlc_data_req_flag = 3;
 
  while ((len > 0) && (rlc_data_req_flag !=0))  {
512 513
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
514
    len = recvmsg(nas_sock_fd, &nas_msg_rx, 0);
515
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
516 517 518

    if (len<=0) {
      // nothing in pdcp NAS socket
519
      //LOG_D(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len);
520
    } else {
521 522
    
      msg_len = len;
523
      for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf;
524 525
           NLMSG_OK (nas_nlh_rx, msg_len);
           nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, msg_len)) {
526 527

        if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) {
528
          LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n");
529 530 531 532
          //return;
        }

        if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) {
533
          LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n");
534 535 536 537 538 539
        }

        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));
540
            LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d\n",
541 542
                  pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size);
          } else {
543
            LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n",
544 545 546 547 548
                  nas_nlh_rx->nlmsg_len);
          }
        } else {
          pdcp_read_state_g = 0;
          // print_active_requests()
549
#ifdef PDCP_DEBUG
550
          LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n",
551
                nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
552
#endif
553

554
#ifdef OAI_EMU
555 556 557 558 559

          // 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;
560 561
            ctxt.module_id     = pdcp_read_header_g.inst  +  oai_emulation.info.first_enb_local;
            ctxt.rnti          = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / maxDRB + oai_emulation.info.first_ue_local];
562 563 564 565
            rab_id    = pdcp_read_header_g.rb_id % maxDRB;
          } else {
            ctxt.frame         = ctxt_cpy.frame;
            ctxt.enb_flag      = ENB_FLAG_NO;
566 567
            ctxt.module_id     = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local;
            ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
Navid Nikaein's avatar
Navid Nikaein committed
568
            rab_id    = pdcp_read_header_g.rb_id % maxDRB;
569 570
          }

571
          CHECK_CTXT_ARGS(&ctxt);
572 573 574 575
          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;*/
576
#else // OAI_EMU
Cedric Roux's avatar
Cedric Roux committed
577 578
          /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
//          pdcp_read_header_g.inst = 0;
Cedric Roux's avatar
Cedric Roux committed
579
//#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
580
          ctxt.frame         = ctxt_cpy.frame;
581
          ctxt.enb_flag      = ctxt_cpy.enb_flag;
582

583
#ifdef PDCP_DEBUG
gabrielC's avatar
gabrielC committed
584
          LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d\n", pdcp_read_header_g.rb_id);
585 586
#endif

587
          if (ctxt_cpy.enb_flag) {
588
            ctxt.module_id = 0;
589
            rab_id      = pdcp_read_header_g.rb_id % maxDRB;
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
590
            ctxt.rnti          = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index];
591
          } else {
592
            ctxt.module_id = 0;
593
            rab_id      = pdcp_read_header_g.rb_id % maxDRB;
594
            ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
595
          }
596

597

598 599
#endif

600 601 602
          if (ctxt.enb_flag) {
            if (rab_id != 0) {
              rab_id = rab_id % maxDRB;
603 604
              key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
              h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
605

606
              if (h_rc == HASH_TABLE_OK) {
607
#ifdef PDCP_DEBUG
608
                LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n",
609 610 611 612 613
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      len,
                      nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
                      pdcp_read_header_g.rb_id);
614 615
#endif

Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
616 617 618 619 620
          	    MSC_LOG_RX_MESSAGE(
          	      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
          	      NULL,
          	      0,
621
          	      MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
622 623 624 625 626
          	      MSC_AS_TIME_ARGS(ctxt_pP),
                  pdcp_read_header_g.inst,
          	      pdcp_read_header_g.rb_id,
          	      rab_id,
          	      pdcp_read_header_g.data_size);
627
                LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n",
628 629 630 631
                      ctxt_cpy.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
632 633
                      ctxt.module_id,
                      ctxt.rnti,
634 635 636 637 638 639 640 641 642 643 644
                      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 {
645
                LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n",
646 647 648 649
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
650 651
                      ctxt.module_id,
                      ctxt.rnti,
652 653 654 655
                      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
Cedric Roux's avatar
Cedric Roux committed
656
//#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
657 658 659 660
              for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) {
                if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) {
                  ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id];
                  LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
661 662 663 664
                        ctxt.frame,
                        pdcp_read_header_g.inst,
                        pdcp_read_header_g.rb_id,
                        pdcp_read_header_g.data_size,
665 666
                        ctxt.module_id,
                        ctxt.rnti,
667 668 669 670 671 672 673 674 675 676 677 678 679
                        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);
                }
              }
            }
680
          } else { // enb_flag
681
            if (rab_id != 0) {
682 683 684 685 686
              if (rab_id == UE_IP_DEFAULT_RAB_ID) {
                LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
                    ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
                key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
                h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
687
              } else {
688 689 690 691 692 693
                rab_id = rab_id % maxDRB;
                LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n",
                    ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
                key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
                h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
              }
694 695

              if (h_rc == HASH_TABLE_OK) {
696
                rab_id = pdcp_p->rb_id;
697
#ifdef PDCP_DEBUG
698
                LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n",
699 700 701 702 703
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      len,
                      nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
                      pdcp_read_header_g.rb_id);
704

705
                LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n",
706 707 708 709
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
710 711
                      ctxt.module_id,
                      ctxt.rnti,
712 713
                      rab_id);
#endif
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
714 715 716 717 718
          	    MSC_LOG_RX_MESSAGE(
          	      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
          	      NULL,
          	      0,
719
          	      MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
720 721 722 723 724
          	      MSC_AS_TIME_ARGS(ctxt_pP),
                  pdcp_read_header_g.inst,
          	      pdcp_read_header_g.rb_id,
          	      rab_id,
          	      pdcp_read_header_g.data_size);
725

726 727 728 729 730 731 732 733 734 735
                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 {
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
736 737 738 739 740
            	MSC_LOG_RX_DISCARDED_MESSAGE(
                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
                  (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
                  NULL,
                  0,
741
                  MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
742 743 744 745 746
                  MSC_AS_TIME_ARGS(ctxt_pP),
                  pdcp_read_header_g.inst,
                  pdcp_read_header_g.rb_id,
                  rab_id,
                  pdcp_read_header_g.data_size);
747 748
                LOG_D(PDCP,
                      "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
749 750 751 752
                      ctxt.frame,
                      pdcp_read_header_g.inst,
                      pdcp_read_header_g.rb_id,
                      pdcp_read_header_g.data_size,
753 754 755 756
                      ctxt.module_id,
                      ctxt.rnti,
                      rab_id,
                      key);
757
              }
758 759
            }  else {
              LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
760
              LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
761 762 763 764
                    ctxt.frame,
                    pdcp_read_header_g.inst,
                    pdcp_read_header_g.rb_id,
                    pdcp_read_header_g.data_size,
765 766
                    ctxt.module_id,
                    ctxt.rnti,
767
                    DEFAULT_RAB_ID);
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
768 769 770 771
          	  MSC_LOG_RX_MESSAGE(
                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
                NULL,0,
772
                MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u",
Lionel Gauthier's avatar
msc  
Lionel Gauthier committed
773 774 775 776 777 778
                MSC_AS_TIME_ARGS(ctxt_pP),
                pdcp_read_header_g.inst,
                pdcp_read_header_g.rb_id,
                DEFAULT_RAB_ID,
                pdcp_read_header_g.data_size);

779 780 781 782 783 784 785 786 787 788
              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);
            }
789
          }
790 791

        }
792
      }
793
    }
794
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 );
795
  }
796

797
  return len;
798
# endif
799
#else // neither PDCP_USE_NETLINK nor PDCP_USE_RT_FIFO
800
  return 0;
801
#endif // PDCP_USE_NETLINK
802 803 804
}


805 806
void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const  ctxt_pP) {

807 808 809
  unsigned char       *otg_pkt=NULL;
  module_id_t          dst_id; // dst for otg
  rb_id_t              rb_id;
810
  unsigned int         pkt_size=0;
811
#if defined(USER_MODE) && defined(OAI_EMU)
812
  module_id_t          src_id;
813
  static unsigned int  pkt_cnt_enb=0, pkt_cnt_ue=0;
814

815 816
  Packet_otg_elt_t    *otg_pkt_info=NULL;
  int                  result;
817 818 819 820 821
  uint8_t              pdcp_mode, is_ue=0;
#endif
  protocol_ctxt_t      ctxt;
  // we need to add conditions to avoid transmitting data when the UE is not RRC connected.
#if defined(USER_MODE) && defined(OAI_EMU)
822

823
  if (oai_emulation.info.otg_enabled ==1 ) {
824 825 826 827 828 829 830 831 832
    // module_id is source id
    while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[ctxt_pP->instance]))) != NULL) {
      LOG_I(OTG,"Mod_id %d Frame %d Got a packet (%p), HEAD of otg_pdcp_buffer[%d] is %p and Nb elements is %d\n",
            ctxt_pP->module_id,
            ctxt_pP->frame,
            otg_pkt_info,
            ctxt_pP->instance,
            pkt_list_get_head(&(otg_pdcp_buffer[ctxt_pP->instance])),
            otg_pdcp_buffer[ctxt_pP->instance].nb_elements);
833
      //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]));
834 835
      dst_id    = (otg_pkt_info->otg_pkt).dst_id; // type is module_id_t
      src_id    = (otg_pkt_info->otg_pkt).module_id; // type is module_id_t
836 837 838 839 840 841 842 843 844 845 846 847
      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 ) {
848 849 850 851 852 853
          PROTOCOL_CTXT_SET_BY_MODULE_ID(
            &ctxt,
            src_id,
            ENB_FLAG_YES,
            oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id],
            ctxt_pP->frame,
854 855
            ctxt_pP->subframe,
	    src_id);
856

857
          LOG_D(OTG,"[eNB %d] Frame %d sending packet %d from module %d on rab id %d (src %d, dst %d/%x) pkt size %d for pdcp mode %d\n",
858 859 860 861 862 863 864
                ctxt.module_id,
                ctxt.frame,
                pkt_cnt_enb++,
                src_id,
                rb_id,
                src_id,
                dst_id,
865
		oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id],
866 867
                pkt_size,
                pdcp_mode);
868 869 870 871 872 873 874 875
          result = pdcp_data_req(&ctxt,
                                 SRB_FLAG_NO,
                                 rb_id,
                                 RLC_MUI_UNDEFINED,
                                 RLC_SDU_CONFIRM_NO,
                                 pkt_size,
                                 otg_pkt,
                                 pdcp_mode);
876 877 878
          if (result != TRUE) {
            LOG_W(OTG,"PDCP data request failed!\n");
          }
879 880 881 882
        } else {
          //rb_id= eNB_index * MAX_NUM_RB + DTCH;


883
          LOG_D(OTG,"[UE %d] Frame %d: sending packet %d from module %d on rab id %d (src %d/%x, dst %d) pkt size %d\n",
884 885 886 887 888
                ctxt_pP->module_id,
                ctxt_pP->frame,
                pkt_cnt_ue++,
                ctxt_pP->module_id,
                rb_id,
889 890
                src_id,
		pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id], // [src_id]
891 892 893 894
                dst_id,
                pkt_size);
          PROTOCOL_CTXT_SET_BY_MODULE_ID(
            &ctxt,
895
            ctxt_pP->module_id, //src_id,
896
            ENB_FLAG_NO,
897
            pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id],// [src_id]
898
            ctxt_pP->frame,
899 900
            ctxt_pP->subframe,
	    dst_id);
901 902 903 904 905 906 907 908 909

          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);
910 911 912
          if (result != TRUE) {
            LOG_W(OTG,"PDCP data request failed!\n");
          }
913 914 915 916
        }

        free(otg_pkt);
        otg_pkt = NULL;
917
      }
918 919 920 921

      // } //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));

    }
922
  }
923

924
#else
925

926
  if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic
927 928 929 930 931
    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)) { */
932 933 934 935 936 937
    PROTOCOL_CTXT_SET_BY_MODULE_ID(
      &ctxt,
      ctxt_pP->module_id,
      ctxt_pP->enb_flag,
      NOT_A_RNTI,
      ctxt_pP->frame,
938 939
      ctxt_pP->subframe,
      ctxt_pP->module_id);
940 941

    for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) {
942 943 944 945
      ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id];

      if (ctxt.rnti != NOT_A_RNTI) {
        if (mac_eNB_get_rrc_status(ctxt.module_id, ctxt.rnti ) > 2 /*RRC_SI_RECEIVED*/) {
946
        unsigned int temp = 0;
947 948 949 950 951 952
          otg_pkt=packet_gen(
                    ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id),
                    UE_MODULE_ID_TO_INSTANCE(dst_id),
                    0,
                    ctime,
                    &temp);
953 954 955 956 957 958 959 960 961 962 963 964
        pkt_size = temp;

        if (otg_pkt != NULL) {
          rb_id = dst_id * maxDRB + DTCH;
          pdcp_data_req(&ctxt,
                        SRB_FLAG_NO,
                        rb_id,
                        RLC_MUI_UNDEFINED,
                        RLC_SDU_CONFIRM_NO,
                        pkt_size,
                        otg_pkt,
                        PDCP_TRANSMISSION_MODE_DATA);
965 966 967 968 969
            LOG_I(OTG,
                  "send packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n",
                  ctxt_pP->module_id, rb_id, ctxt_pP->module_id, dst_id, pkt_size);
            free(otg_pkt);
          }
970
        }
971
      }
972
    }
973
  }
974

975 976
#endif
}