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

Lionel Gauthier's avatar
Lionel 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


Lionel Gauthier's avatar
Lionel 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

Lionel Gauthier's avatar
Lionel 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
Lionel Gauthier's avatar
Lionel 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

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

/*! \file pdcp_fifo.c
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

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

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

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
{
  //-----------------------------------------------------------------------------

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

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

119
  while (sdu_p && cont) {
120

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

Lionel Gauthier's avatar
Lionel Gauthier committed
125
#if defined(LINK_PDCP_TO_GTPV1U)
126
      if (ctxt_pP->enb_flag) {
127
          AssertFatal(0, "Now execution should not go here");
Raymond Knopp's avatar
 
Raymond Knopp committed
128
          LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size);
Lionel Gauthier's avatar
Lionel Gauthier committed
129 130 131
          /*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;
132
          GTPV1U_TUNNEL_DATA_REQ(message_p).ue_module_id = ctxt_pP->ue_module_id;
Lionel Gauthier's avatar
Lionel Gauthier committed
133 134 135
          GTPV1U_TUNNEL_DATA_REQ(message_p).rab_id;      = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
          */
          gtpv1u_new_data_req(
136 137
              ctxt_pP->enb_module_id, //gtpv1u_data_t *gtpv1u_data_p,
              ctxt_pP->ue_module_id,//rb_id/maxDRB, TO DO UE ID
138
              ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4,
Lionel Gauthier's avatar
Lionel Gauthier committed
139 140 141 142 143 144 145 146
              &(((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);
Raymond Knopp's avatar
 
Raymond Knopp committed
147
          LOG_D(OTG,"After  GTPV1U\n");
Lionel Gauthier's avatar
Lionel Gauthier committed
148 149 150
          continue; // loop again
       }
#endif /* defined(ENABLE_USE_MME) */
151
#ifdef PDCP_DEBUG
152
      LOG_I(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n",
153
          ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
154
          ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id);
155
#endif //PDCP_DEBUG
156
      cont = 0;
157

158 159 160 161
      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);
          }
162 163

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

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

177
          bytes_wrote = pdcp_output_header_bytes_to_write;
178 179 180
#endif //NAS_FIFO

#ifdef PDCP_DEBUG
181
          LOG_I(PDCP, "Frame %d Sent %d Bytes of header to Nas_mesh\n",
182
              ctxt_pP->frame,
183
              bytes_wrote);
184 185
#endif //PDCP_DEBUG

186 187
          if (bytes_wrote > 0) {
              pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote;
188

189 190
              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;
191 192

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

#ifdef NAS_NETLINK
#ifdef LINUX
198 199 200 201 202 203 204 205
                  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;
                  }
206 207
#endif // LINUX
#endif //NAS_NETLINK
208
                  bytes_wrote= pdcp_output_sdu_bytes_to_write;
209 210 211
#endif // NAS_FIFO

#ifdef PDCP_DEBUG
212
                  LOG_I(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to Nas_mesh\n",
213
                      ctxt_pP->frame,
214 215 216
                      ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
                      bytes_wrote,
                      ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id);
217
#endif //PDCP_DEBUG
218 219 220 221 222 223 224
                  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",
225
                              ctxt_pP->frame,
226
                              ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id,
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
                              ((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");
                  }
              } else {
                  LOG_W(PDCP, "RADIO->IP SEND SDU CONGESTION!\n");
              }
243
          }
244 245
      } else {
          // continue writing sdu
246
#ifdef NAS_FIFO
247
          bytes_wrote = rtf_put (PDCP2NAS_FIFO,
248
              (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])),
249
              pdcp_output_sdu_bytes_to_write);
250
#else  // NAS_FIFO
251
          bytes_wrote = pdcp_output_sdu_bytes_to_write;
252 253
#endif  // NAS_FIFO

254 255 256 257 258 259 260 261 262 263 264 265 266
          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");
              }
          }
267 268 269 270
      }
  }
#ifdef NAS_FIFO
  if ((pdcp_nb_sdu_sent)) {
271
      if ((pdcp_2_nas_irq > 0)) {
272
#ifdef PDCP_DEBUG
273
          LOG_I(PDCP, "Frame %d : Trigger NAS RX interrupt\n",
274
              ctxt_pP->frame);
275 276
#endif //PDCP_DEBUG

277 278 279
          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",
280
              ctxt_pP->frame,
281 282
              pdcp_2_nas_irq);
      }
283 284 285 286 287 288 289 290 291 292 293 294
  }
#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
 */
295
int pdcp_fifo_read_input_sdus_remaining_bytes (const protocol_ctxt_t* const  ctxt_pP)
296 297
{
  //-----------------------------------------------------------------------------
298
  sdu_size_t             bytes_read = 0;
299 300 301 302 303 304
  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;
305 306 307

  // if remaining bytes to read
  if (pdcp_input_sdu_remaining_size_to_read > 0) {
308 309 310
      bytes_read = rtf_get (NAS2PDCP_FIFO,
          &(pdcp_input_sdu_buffer[pdcp_input_sdu_size_read]),
          pdcp_input_sdu_remaining_size_to_read);
311

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

315 316
          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;
317

318 319 320
          if (pdcp_input_sdu_remaining_size_to_read != 0) {
              return 0;
          } else {
321
#ifdef PDCP_DEBUG
322
              LOG_I(PDCP, "Frame %d: IP->RADIO RECEIVED COMPLETE SDU size %d inst %d rb %d\n",
323
                  ctxt_pP->frame,
324 325 326
                  pdcp_input_sdu_size_read,
                  pdcp_input_header.inst,
                  pdcp_input_header.rb_id);
327
#endif //PDCP_DEBUG
328
              pdcp_input_sdu_size_read = 0;
329
#ifdef IDROMEL_NEMO
330
              pdcp_read_header_g.inst = 0;
331 332
#endif

333
              if (ctxt_pP->enb_flag == 0) {
334
                  ue_inst  = pdcp_read_header_g.inst;
335
                  rb_id    = pdcp_read_header_g.rb_id;
336
                  enb_inst = 0;
337
                  pdcp_p   = &pdcp_array_drb_ue[ue_inst][rb_id-1];
338
              } else {
339 340
                  ue_inst  = pdcp_read_header_g.rb_id / maxDRB;
                  rb_id    = pdcp_read_header_g.rb_id % maxDRB;
341
                  enb_inst = pdcp_read_header_g.inst;
342
                  pdcp_p   = &pdcp_array_drb_eNB[enb_inst][ue_inst][rb_id-1];
343 344 345 346 347 348 349 350 351 352
              }
              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);
Lionel Gauthier's avatar
Lionel Gauthier committed
353 354
              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);
355 356 357

              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",
358 359
                      ctxt_pP->frame,
                      (ctxt_pP->enb_flag) ? "eNB" : "UE",
360 361 362 363 364 365 366 367
                      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) {
368
                      result = pdcp_data_req (
369
                              ctxt_pP,
370 371 372 373 374 375 376
                              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);
377 378 379
                      AssertFatal (result == TRUE, "PDCP data request failed!\n");
                  }

380
              } else if ((pdcp_input_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) || (pdcp_input_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST)) {
381
                  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",
382 383
                      ctxt_pP->frame,
                      (ctxt_pP->enb_flag) ? "eNB" : "UE",
384 385 386 387 388 389 390 391 392
                          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 (
393
                          ctxt_pP,
394
                          SRB_FLAG_NO,
395 396 397 398 399
                          rb_id,
                          RLC_MUI_UNDEFINED,
                          RLC_SDU_CONFIRM_NO,
                          pdcp_input_header.data_size,
                          pdcp_input_sdu_buffer,
400
                          PDCP_TRANSMISSION_MODE_TRANSPARENT);
401 402 403
                      AssertFatal (result == TRUE, "PDCP data request failed!\n");
                  }

404
              } else if (ctxt_pP->enb_flag) {
405 406 407 408
                  // 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);
409
                      pdcp_p = &pdcp_array_drb_eNB[enb_inst][ue_inst][DEFAULT_RAB_ID-1];
410 411
                      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",
412 413
                              ctxt_pP->frame,
                              (ctxt_pP->enb_flag) ? "eNB" : "UE",
414 415 416 417 418 419 420
                              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 (
421
                              ctxt_pP,
422
                              SRB_FLAG_NO,
423 424 425 426 427
                              DEFAULT_RAB_ID,
                              RLC_MUI_UNDEFINED,
                              RLC_SDU_CONFIRM_NO,
                              pdcp_input_header.data_size,
                              pdcp_input_sdu_buffer,
428
                              PDCP_TRANSMISSION_MODE_DATA);
429 430 431 432 433 434
                          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",
435 436
                      ctxt_pP->frame,
                      (ctxt_pP->enb_flag) ? "eNB" : "UE",
437 438 439 440 441 442 443
                      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 (
444
                      ctxt_pP,
445
                      SRB_FLAG_NO,
446 447 448 449 450
                      DEFAULT_RAB_ID,
                      RLC_MUI_UNDEFINED,
                      RLC_SDU_CONFIRM_NO,
                      pdcp_input_header.data_size,
                      pdcp_input_sdu_buffer,
451
                      PDCP_TRANSMISSION_MODE_DATA);
452 453 454 455 456 457 458 459
                  AssertFatal (result == TRUE, "PDCP data request failed!\n");
              }
              // not necessary
              //memset(pdcp_input_sdu_buffer, 0, MAX_IP_PACKET_SIZE);
              return 1;
          }
      } else {
          return bytes_read;
460 461 462 463 464 465
      }
  }
  return 1;
}

//-----------------------------------------------------------------------------
466
int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
467 468
{
#ifdef NAS_NETLINK
469
# if defined(ENABLE_PDCP_NETLINK_FIFO)
470 471 472
  module_id_t                    ue_id     = 0;
  rb_id_t                        rab_id    = 0;
  pdcp_t                        *pdcp      = NULL;
473
  pdcp_transmission_mode_t       pdcp_mode = PDCP_TRANSMISSION_MODE_UNKNOWN;
474
  struct pdcp_netlink_element_s *data      = NULL;
Lionel Gauthier's avatar
Lionel Gauthier committed
475
  protocol_ctxt_t                ctxt_cpy;
476

Lionel Gauthier's avatar
Lionel Gauthier committed
477 478 479 480
  protocol_ctxt_t                ctxt;

  ctxt_cpy = *ctxt_pP;
  while (pdcp_netlink_dequeue_element(ctxt_pP, &data) != 0) {
481
      DevAssert(data != NULL);
Lionel Gauthier's avatar
Lionel Gauthier committed
482
      if (ctxt_cpy.enb_flag == ENB_FLAG_NO) {
483
          rab_id = data->pdcp_read_header.rb_id % maxDRB;
Lionel Gauthier's avatar
Lionel Gauthier committed
484
          pdcp = &pdcp_array_drb_ue[ctxt_cpy.ue_module_id][rab_id-1];
485
      } else {
486
          rab_id = data->pdcp_read_header.rb_id % maxDRB;
Lionel Gauthier's avatar
Lionel Gauthier committed
487 488
          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];
489
      }
Lionel Gauthier's avatar
Lionel Gauthier committed
490 491
      if (ctxt_cpy.enb_flag) {
          AssertFatal ((ctxt_cpy.enb_module_id >= oai_emulation.info.first_enb_local) && (oai_emulation.info.nb_enb_local > 0),
492
              "eNB module id is too low (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
493
              ctxt_cpy.enb_module_id,
494
              oai_emulation.info.first_enb_local);
Lionel Gauthier's avatar
Lionel Gauthier committed
495
          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),
496
              "eNB module id is too high (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
497
              ctxt_cpy.enb_module_id,
498
              oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);
Lionel Gauthier's avatar
Lionel Gauthier committed
499
          AssertFatal (ctxt_cpy.ue_module_id  < NB_UE_INST,
500
              "UE module id is too high (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
501
              ctxt_cpy.ue_module_id,
502 503
              oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
      } else {
Lionel Gauthier's avatar
Lionel Gauthier committed
504
          AssertFatal (ctxt_cpy.ue_module_id  < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),
505
              "UE module id is too high (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
506
              ctxt_cpy.ue_module_id,
507
              oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
Lionel Gauthier's avatar
Lionel Gauthier committed
508
          AssertFatal (ctxt_cpy.ue_module_id  >= oai_emulation.info.first_ue_local,
509
              "UE module id is too low (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
510
              ctxt_cpy.ue_module_id,
511 512
              oai_emulation.info.first_ue_local);
      }
513
      AssertFatal (rab_id    < maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, maxDRB);
514 515 516 517 518

      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",
Lionel Gauthier's avatar
Lionel Gauthier committed
519 520
                  ctxt_cpy.frame,
                  (ctxt_cpy.enb_flag) ? "eNB" : "UE",
521 522 523
                      data->pdcp_read_header.inst,
                      data->pdcp_read_header.rb_id,
                      data->pdcp_read_header.data_size,
Lionel Gauthier's avatar
Lionel Gauthier committed
524 525
                      ctxt_cpy.enb_module_id,
                      ctxt_cpy.ue_module_id,
526
                      rab_id);
527
#ifdef 	OAI_NW_DRIVER_TYPE_ETHERNET
528 529 530 531
              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 */ ) {
#if defined (Rel10)
532
                PDCP_TRANSMISSION_MODE_TRANSPARENT;
533 534 535 536 537
#else
                pdcp_mode= PDCP_TRANSMISSION_MODE_DATA;
#endif
              } 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*/ ) {
Lionel Gauthier's avatar
Lionel Gauthier committed
538
                  pdcp_mode=  PDCP_TRANSMISSION_MODE_DATA;
539 540
              } else {
                  pdcp_mode= PDCP_TRANSMISSION_MODE_DATA;
541 542
                  LOG_W(PDCP,"unknown IP traffic type \n");
              }
543
#else // NASMESH driver does not curreenlty support multicast traffic
544
              pdcp_mode = PDCP_TRANSMISSION_MODE_DATA;
545
#endif
Lionel Gauthier's avatar
Lionel Gauthier committed
546
              pdcp_data_req(ctxt_pP,
547 548
                  SRB_FLAG_NO,
                  rab_id % maxDRB,
549 550 551 552 553 554
                  RLC_MUI_UNDEFINED,
                  RLC_SDU_CONFIRM_NO,
                  data->pdcp_read_header.data_size,
                  data->data,
                  pdcp_mode);
          } else {
Lionel Gauthier's avatar
Lionel Gauthier committed
555 556
              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);
557
          }
Lionel Gauthier's avatar
Lionel Gauthier committed
558
      } else if (ctxt_cpy.enb_flag) {
559 560 561 562
          /* 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
           */
563 564
          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++) {
Lionel Gauthier's avatar
Lionel Gauthier committed
565
              pdcp = &pdcp_array_drb_eNB[ctxt_cpy.enb_module_id][ue_id][DEFAULT_RAB_ID-1];
566
              if (pdcp->instanciated_instance) {
567
                  LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id);
Lionel Gauthier's avatar
Lionel Gauthier committed
568 569 570 571 572
                  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;

573
                  pdcp_data_req(
Lionel Gauthier's avatar
Lionel Gauthier committed
574
                      &ctxt,
575
                      SRB_FLAG_NO,
576 577 578 579 580
                      DEFAULT_RAB_ID,
                      RLC_MUI_UNDEFINED,
                      RLC_SDU_CONFIRM_NO,
                      data->pdcp_read_header.data_size,
                      data->data,
581
                      PDCP_TRANSMISSION_MODE_DATA);
582 583 584 585 586
              }
          }
      } else {
          LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
          pdcp_data_req(
Lionel Gauthier's avatar
Lionel Gauthier committed
587
              &ctxt_cpy,
588
              SRB_FLAG_NO,
589 590 591 592 593
              DEFAULT_RAB_ID,
              RLC_MUI_UNDEFINED,
              RLC_SDU_CONFIRM_NO,
              data->pdcp_read_header.data_size,
              data->data,
594
              PDCP_TRANSMISSION_MODE_DATA);
595 596 597 598 599 600 601
      }
      free(data->data);
      free(data);
      data = NULL;
  }
  return 0;
# else /* ENABLE_PDCP_NETLINK_FIFO*/
602 603
  int              len = 1;
  rb_id_t          rab_id  = 0;
604
  while (len > 0) {
605 606 607 608 609 610 611 612
      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)) {
613

614 615 616 617
              if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) {
                  LOG_I(PDCP, "[PDCP][FIFO] RX NLMSG_DONE\n");
                  //return;
              }
618

619 620 621 622 623 624 625 626 627
              if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) {
                  LOG_I(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_I(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);
628
                  } else {
629 630 631 632 633 634
                      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()
635
#ifdef PDCP_DEBUG
636 637
                  LOG_I(PDCP, "[PDCP][FIFO] Something in socket, length %d \n",
                      nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
638
#endif
639 640
                  //memcpy(pdcp_read_payload, (unsigned char *)NLMSG_DATA(nas_nlh_rx), nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));

641
#ifdef OAI_EMU
642 643
                  // overwrite function input parameters, because only one netlink socket for all instances
                  if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) {
Lionel Gauthier's avatar
Lionel Gauthier committed
644 645 646 647
                      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;
648
                      rab_id    = pdcp_read_header_g.rb_id % maxDRB;
649
                  } else {
Lionel Gauthier's avatar
Lionel Gauthier committed
650 651 652 653
                      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;
654 655
                      rab_id    = pdcp_read_header_g.rb_id;
                  }
Lionel Gauthier's avatar
Lionel Gauthier committed
656
                  AssertFatal (ctxt.enb_module_id >= oai_emulation.info.first_enb_local,
657
                              "eNB inst is too low (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
658
                              ctxt.enb_module_id,
659
                              oai_emulation.info.first_enb_local);
Lionel Gauthier's avatar
Lionel Gauthier committed
660
                  AssertFatal (ctxt.enb_module_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local),
661
                              "eNB inst is too high (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
662
                              ctxt.enb_module_id,
663
                              oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);
Lionel Gauthier's avatar
Lionel Gauthier committed
664
                  AssertFatal (ctxt.ue_module_id  >= oai_emulation.info.first_ue_local,
665
                               "UE inst is too low (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
666
                               ctxt.ue_module_id,
667
                               oai_emulation.info.first_ue_local);
Lionel Gauthier's avatar
Lionel Gauthier committed
668
                  AssertFatal (ctxt.ue_module_id  < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),
669
                               "UE inst is too high (%u/%d)!\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
670
                               ctxt.ue_module_id,
671
                               oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
672
                  AssertFatal (rab_id    < maxDRB,                       "RB id is too high (%u/%d)!\n", rab_id, maxDRB);
673 674 675 676 677
                  /*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;*/
#else
                  pdcp_read_header_g.inst = 0;
678
#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
Lionel Gauthier's avatar
Lionel Gauthier committed
679 680 681 682 683 684 685 686 687 688 689 690
                  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;
                  }
691 692
#endif

Lionel Gauthier's avatar
Lionel Gauthier committed
693
                  if (ctxt.enb_flag) {
694
                      if (rab_id != 0) {
695
                          rab_id = rab_id % maxDRB;
Lionel Gauthier's avatar
Lionel Gauthier committed
696
                          if (pdcp_array_drb_eNB[ctxt.enb_module_id][ctxt.ue_module_id][rab_id-1].instanciated_instance) {
697
#ifdef PDCP_DEBUG
698
                              LOG_I(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
Lionel Gauthier's avatar
Lionel Gauthier committed
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
#endif

706
                              LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB %u]\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
707
                                  ctxt_cpy.frame,
708 709 710
                                  pdcp_read_header_g.inst,
                                  pdcp_read_header_g.rb_id,
                                  pdcp_read_header_g.data_size,
Lionel Gauthier's avatar
Lionel Gauthier committed
711 712
                                  ctxt.enb_module_id,
                                  ctxt.ue_module_id,
713 714
                                  rab_id);

Lionel Gauthier's avatar
Lionel Gauthier committed
715 716 717 718 719 720 721 722
                              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);
723
                          } else {
724
                              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",
Lionel Gauthier's avatar
Lionel Gauthier committed
725 726 727 728 729 730
                                    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,
731
                                  rab_id);
732
                          }
733
                      } else  { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast
734
                          // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
735
#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
Lionel Gauthier's avatar
Lionel Gauthier committed
736 737
                          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) {
738
                                  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",
Lionel Gauthier's avatar
Lionel Gauthier committed
739 740 741 742 743 744 745
                                        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);
746
                                  pdcp_data_req (
Lionel Gauthier's avatar
Lionel Gauthier committed
747
                                      &ctxt,
748
                                      SRB_FLAG_NO,
749 750 751 752 753
                                      DEFAULT_RAB_ID,
                                      RLC_MUI_UNDEFINED,
                                      RLC_SDU_CONFIRM_NO,
                                      pdcp_read_header_g.data_size,
                                      (unsigned char *)NLMSG_DATA(nas_nlh_rx),
754
                                      PDCP_TRANSMISSION_MODE_DATA);
755 756
                              }
                          }
757 758 759
                      }
                  } else {
                      if (rab_id != 0) {
Lionel Gauthier's avatar
Lionel Gauthier committed
760
                          if (pdcp_array_drb_ue[ctxt.ue_module_id][rab_id-1].instanciated_instance) {
761 762
#ifdef PDCP_DEBUG
                              LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
Lionel Gauthier's avatar
Lionel Gauthier committed
763 764 765 766 767
                                    ctxt.frame,
                                    pdcp_read_header_g.inst,
                                    len,
                                    nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
                                    pdcp_read_header_g.rb_id);
768 769

                              LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u/%u][RB %u]\n",
Lionel Gauthier's avatar
Lionel Gauthier committed
770 771 772 773 774 775 776
                                    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);
777
#endif
778

779
                              pdcp_data_req(
Lionel Gauthier's avatar
Lionel Gauthier committed
780 781 782 783 784 785 786 787
                                              &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);
788 789
                          } 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",
Lionel Gauthier's avatar
Lionel Gauthier committed
790 791 792 793 794 795 796
                                    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);
797 798 799 800
                          }
                      }  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",
Lionel Gauthier's avatar
Lionel Gauthier committed
801 802 803 804 805 806 807
                                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);
808
                          pdcp_data_req (
Lionel Gauthier's avatar
Lionel Gauthier committed
809 810 811 812 813 814 815 816
                                          &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);
817 818
                      }
                  }
819

820 821
              }
          }
822
      }
823
  }
824
  return len;
825
# endif
826 827 828 829 830 831
#else // neither NAS_NETLINK nor NAS_FIFO
  return 0;
#endif // NAS_NETLINK
}


832
void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const  ctxt_pP) {
833 834 835 836
  unsigned char       *otg_pkt=NULL;
  module_id_t          src_id, module_id; // src for otg
  module_id_t          dst_id; // dst for otg
  rb_id_t              rb_id;
Navid Nikaein's avatar
Navid Nikaein committed
837 838
  signed long          pkt_size=0;
  static unsigned int  pkt_cnt_enb=0, pkt_cnt_ue=0;
839 840 841
  uint8_t              pdcp_mode, is_ue=0;
  Packet_otg_elt_t    *otg_pkt_info=NULL;
  int                  result;
Lionel Gauthier's avatar
Lionel Gauthier committed
842
  protocol_ctxt_t      ctxt;
843 844

  src_id = ctxt_pP->enb_module_id;
845

846 847 848
  // we need to add conditions to avoid transmitting data when the UE is not RRC connected.
#if defined(USER_MODE) && defined(OAI_EMU)
  if (oai_emulation.info.otg_enabled ==1 ){
849 850
      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 ;
851 852 853
      src_id = module_id;
      while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]))) != 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",
854
              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);
855
          //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]));
Lionel Gauthier's avatar
Lionel Gauthier committed
856
          dst_id    = (otg_pkt_info->otg_pkt).dst_id;
857
          module_id = (otg_pkt_info->otg_pkt).module_id;
Lionel Gauthier's avatar
Lionel Gauthier committed
858 859
          rb_id     = (otg_pkt_info->otg_pkt).rb_id;
          is_ue     = (otg_pkt_info->otg_pkt).is_ue;
860 861 862 863
          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
864
          // 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
865
          otg_pkt = (unsigned char*) (otg_pkt_info->otg_pkt).sdu_buffer;
866 867 868
          pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size;
          if (otg_pkt != NULL) {
              if (is_ue == 0 ) {
869
                  /*rlc_util_print_hex_octets(PDCP,
870
                                            otg_pkt,
871
                                            pkt_size);
872
                   */
873
                  //rb_id = (/*NB_eNB_INST +*/ dst_id -1 ) * MAX_NUM_RB + DTCH;
Lionel Gauthier's avatar
Lionel Gauthier committed
874 875 876 877 878
                  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;

879
                  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",
880
                      ctxt_pP->enb_module_id, ctxt_pP->frame, pkt_cnt_enb++, module_id, rb_id, module_id, dst_id, pkt_size, pdcp_mode);
Lionel Gauthier's avatar
Lionel Gauthier committed
881 882 883 884 885 886 887 888
                  result = pdcp_data_req(&ctxt,
                                         SRB_FLAG_NO,
                                         rb_id,
                                         RLC_MUI_UNDEFINED,
                                         RLC_SDU_CONFIRM_NO,
                                         pkt_size,
                                         otg_pkt,
                                         pdcp_mode);
889 890 891 892
                  AssertFatal (result == TRUE, "PDCP data request failed!\n");
              }
              else {
                  //rb_id= eNB_index * MAX_NUM_RB + DTCH;
893 894


Navid Nikaein's avatar
Navid Nikaein committed
895
                  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",
896 897 898
                        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;
Lionel Gauthier's avatar
Lionel Gauthier committed
899
                  ctxt.ue_module_id  = ctxt_pP->ue_module_id;
900 901 902 903
                  ctxt.frame         = ctxt_pP->frame;
                  ctxt.enb_flag      = ctxt_pP->enb_flag;

                  result = pdcp_data_req( &ctxt,
904
                                          SRB_FLAG_NO,
905 906 907 908 909 910
                                          rb_id,
                                          RLC_MUI_UNDEFINED,
                                          RLC_SDU_CONFIRM_NO,
                                          pkt_size,
                                          otg_pkt,
                                          PDCP_TRANSMISSION_MODE_DATA);
911 912 913 914 915
                  AssertFatal (result == TRUE, "PDCP data request failed!\n");
              }
              free(otg_pkt);
              otg_pkt = NULL;
          }
916
          // } //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));
917

918 919 920
      }
  }
#else
921
  if ((otg_enabled==1) && (ctxt_pP->enb_flag == 1)) { // generate DL traffic
922
      unsigned int ctime=0;
923 924 925 926 927 928 929
      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;
930 931

      for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) {
932
          if (mac_get_rrc_status(ctxt_pP->enb_module_id, ctxt_pP->enb_flag, dst_id ) > 2) {
933 934
              otg_pkt=packet_gen(src_id, dst_id, 0, ctime, &pkt_size);
              if (otg_pkt != NULL){
935
                  rb_id = dst_id * maxDRB + DTCH;
936 937 938 939 940 941 942 943 944 945
                  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_I(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);
946 947 948
                  free(otg_pkt);
              }
              /*else {
949 950
      LOG_I(OTG,"nothing generated (src %d, dst %d)\n",src_id, dst_id);
      }*/
951 952
          }
          /*else {
953
    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 ));
954
    }*/
955
      }
956 957 958
  }
#endif
}