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

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


gauthier's avatar
gauthier committed
11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

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

  Contact Information
gauthier's avatar
gauthier committed
22 23 24 25
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

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

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

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

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

#ifndef OAI_EMU
extern int otg_enabled;
#endif

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

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

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

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

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

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

#define MAX_PAYLOAD 1600

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

94
extern Packet_OTG_List_t *otg_pdcp_buffer;
95

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

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

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

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

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

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

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

gauthier's avatar
gauthier committed
125
#if defined(LINK_PDCP_TO_GTPV1U)
126
      if (ctxt_pP->enb_flag) {
127
          AssertFatal(0, "Now execution should not go here");
128
          LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size);
gauthier's avatar
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;
gauthier's avatar
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,
gauthier's avatar
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);
147
          LOG_D(OTG,"After  GTPV1U\n");
gauthier's avatar
gauthier committed
148 149 150
          continue; // loop again
       }
#endif /* defined(ENABLE_USE_MME) */
151
#ifdef PDCP_DEBUG
152
      LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to higher layers\n",
153
          ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
gauthier's avatar
gauthier committed
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
gauthier's avatar
gauthier committed
156
      cont = 0;
157

gauthier's avatar
gauthier committed
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
gauthier's avatar
gauthier committed
164
          bytes_wrote = rtf_put (PDCP2NAS_FIFO,
165
              &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]),
gauthier's avatar
gauthier committed
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]),
gauthier's avatar
gauthier committed
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

gauthier's avatar
gauthier committed
177
          bytes_wrote = pdcp_output_header_bytes_to_write;
178 179 180
#endif //NAS_FIFO

#ifdef PDCP_DEBUG
181
          LOG_D(PDCP, "Frame %d Sent %d Bytes of header to higher layers\n",
182
              ctxt_pP->frame,
gauthier's avatar
gauthier committed
183
              bytes_wrote);
184 185
#endif //PDCP_DEBUG

gauthier's avatar
gauthier committed
186 187
          if (bytes_wrote > 0) {
              pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote;
188

gauthier's avatar
gauthier committed
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
gauthier's avatar
gauthier committed
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
gauthier's avatar
gauthier committed
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
gauthier's avatar
gauthier committed
208
                  bytes_wrote= pdcp_output_sdu_bytes_to_write;
209 210 211
#endif // NAS_FIFO

#ifdef PDCP_DEBUG
212
                  LOG_D(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to higher layers\n",
213
                      ctxt_pP->frame,
gauthier's avatar
gauthier committed
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
gauthier's avatar
gauthier committed
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,
gauthier's avatar
gauthier committed
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
          }
gauthier's avatar
gauthier committed
244 245
      } else {
          // continue writing sdu
246
#ifdef NAS_FIFO
gauthier's avatar
gauthier committed
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])),
gauthier's avatar
gauthier committed
249
              pdcp_output_sdu_bytes_to_write);
250
#else  // NAS_FIFO
gauthier's avatar
gauthier committed
251
          bytes_wrote = pdcp_output_sdu_bytes_to_write;
252 253
#endif  // NAS_FIFO

gauthier's avatar
gauthier committed
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)) {
gauthier's avatar
gauthier committed
271
      if ((pdcp_2_nas_irq > 0)) {
272
#ifdef PDCP_DEBUG
gauthier's avatar
gauthier committed
273
          LOG_I(PDCP, "Frame %d : Trigger NAS RX interrupt\n",
274
              ctxt_pP->frame);
275 276
#endif //PDCP_DEBUG

gauthier's avatar
gauthier committed
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,
gauthier's avatar
gauthier committed
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;
gauthier's avatar
gauthier committed
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) {
gauthier's avatar
gauthier committed
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

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

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

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

333
              if (ctxt_pP->enb_flag == 0) {
gauthier's avatar
gauthier committed
334
                  ue_inst  = pdcp_read_header_g.inst;
335
                  rb_id    = pdcp_read_header_g.rb_id;
gauthier's avatar
gauthier committed
336
                  enb_inst = 0;
337
                  pdcp_p   = &pdcp_array_drb_ue[ue_inst][rb_id-1];
gauthier's avatar
gauthier committed
338
              } else {
339 340
                  ue_inst  = pdcp_read_header_g.rb_id / maxDRB;
                  rb_id    = pdcp_read_header_g.rb_id % maxDRB;
gauthier's avatar
gauthier committed
341
                  enb_inst = pdcp_read_header_g.inst;
342
                  pdcp_p   = &pdcp_array_drb_eNB[enb_inst][ue_inst][rb_id-1];
gauthier's avatar
gauthier committed
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);
gauthier's avatar
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);
gauthier's avatar
gauthier committed
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",
gauthier's avatar
gauthier committed
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);
gauthier's avatar
gauthier committed
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)) {
gauthier's avatar
gauthier committed
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",
gauthier's avatar
gauthier committed
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,
gauthier's avatar
gauthier committed
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);
gauthier's avatar
gauthier committed
401 402 403
                      AssertFatal (result == TRUE, "PDCP data request failed!\n");
                  }

404
              } else if (ctxt_pP->enb_flag) {
gauthier's avatar
gauthier committed
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];
gauthier's avatar
gauthier committed
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",
gauthier's avatar
gauthier committed
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,
gauthier's avatar
gauthier committed
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);
gauthier's avatar
gauthier committed
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",
gauthier's avatar
gauthier committed
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,
gauthier's avatar
gauthier committed
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);
gauthier's avatar
gauthier committed
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)
gauthier's avatar
gauthier committed
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;
gauthier's avatar
gauthier committed
474
  struct pdcp_netlink_element_s *data      = NULL;
gauthier's avatar
gauthier committed
475
  protocol_ctxt_t                ctxt_cpy;
gauthier's avatar
gauthier committed
476

gauthier's avatar
gauthier committed
477 478 479 480
  protocol_ctxt_t                ctxt;

  ctxt_cpy = *ctxt_pP;
  while (pdcp_netlink_dequeue_element(ctxt_pP, &data) != 0) {
gauthier's avatar
gauthier committed
481
      DevAssert(data != NULL);
gauthier's avatar
gauthier committed
482
      if (ctxt_cpy.enb_flag == ENB_FLAG_NO) {
483
          rab_id = data->pdcp_read_header.rb_id % maxDRB;
gauthier's avatar
gauthier committed
484
          pdcp = &pdcp_array_drb_ue[ctxt_cpy.ue_module_id][rab_id-1];
gauthier's avatar
gauthier committed
485
      } else {
486
          rab_id = data->pdcp_read_header.rb_id % maxDRB;
gauthier's avatar
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];
gauthier's avatar
gauthier committed
489
      }
gauthier's avatar
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",
gauthier's avatar
gauthier committed
493
              ctxt_cpy.enb_module_id,
494
              oai_emulation.info.first_enb_local);
gauthier's avatar
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",
gauthier's avatar
gauthier committed
497
              ctxt_cpy.enb_module_id,
498
              oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);
gauthier's avatar
gauthier committed
499
          AssertFatal (ctxt_cpy.ue_module_id  < NB_UE_INST,
500
              "UE module id is too high (%u/%d)!\n",
gauthier's avatar
gauthier committed
501
              ctxt_cpy.ue_module_id,
502 503
              oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
      } else {
gauthier's avatar
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",
gauthier's avatar
gauthier committed
506
              ctxt_cpy.ue_module_id,
507
              oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
gauthier's avatar
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",
gauthier's avatar
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);
gauthier's avatar
gauthier committed
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",
gauthier's avatar
gauthier committed
519 520
                  ctxt_cpy.frame,
                  (ctxt_cpy.enb_flag) ? "eNB" : "UE",
gauthier's avatar
gauthier committed
521 522 523
                      data->pdcp_read_header.inst,
                      data->pdcp_read_header.rb_id,
                      data->pdcp_read_header.data_size,
gauthier's avatar
gauthier committed
524 525
                      ctxt_cpy.enb_module_id,
                      ctxt_cpy.ue_module_id,
gauthier's avatar
gauthier committed
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*/ ) {
gauthier's avatar
gauthier committed
538
                  pdcp_mode=  PDCP_TRANSMISSION_MODE_DATA;
539
              } else {
gauthier's avatar
gauthier committed
540
                  pdcp_mode= PDCP_TRANSMISSION_MODE_DATA;
gauthier's avatar
gauthier committed
541 542
                  LOG_W(PDCP,"unknown IP traffic type \n");
              }
543
#else // NASMESH driver does not curreenlty support multicast traffic
gauthier's avatar
gauthier committed
544
              pdcp_mode = PDCP_TRANSMISSION_MODE_DATA;
545
#endif
gauthier's avatar
gauthier committed
546
              pdcp_data_req(ctxt_pP,
547 548
                  SRB_FLAG_NO,
                  rab_id % maxDRB,
gauthier's avatar
gauthier committed
549 550 551 552 553 554
                  RLC_MUI_UNDEFINED,
                  RLC_SDU_CONFIRM_NO,
                  data->pdcp_read_header.data_size,
                  data->data,
                  pdcp_mode);
          } else {
gauthier's avatar
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);
gauthier's avatar
gauthier committed
557
          }
gauthier's avatar
gauthier committed
558
      } else if (ctxt_cpy.enb_flag) {
gauthier's avatar
gauthier committed
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++) {
gauthier's avatar
gauthier committed
565
              pdcp = &pdcp_array_drb_eNB[ctxt_cpy.enb_module_id][ue_id][DEFAULT_RAB_ID-1];
gauthier's avatar
gauthier committed
566
              if (pdcp->instanciated_instance) {
567
                  LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id);
gauthier's avatar
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;

gauthier's avatar
gauthier committed
573
                  pdcp_data_req(
gauthier's avatar
gauthier committed
574
                      &ctxt,
575
                      SRB_FLAG_NO,
gauthier's avatar
gauthier committed
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);
gauthier's avatar
gauthier committed
582 583 584 585 586
              }
          }
      } else {
          LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n");
          pdcp_data_req(
gauthier's avatar
gauthier committed
587
              &ctxt_cpy,
588
              SRB_FLAG_NO,
gauthier's avatar
gauthier committed
589 590 591 592
              DEFAULT_RAB_ID,
              RLC_MUI_UNDEFINED,
              RLC_SDU_CONFIRM_NO,
              data->pdcp_read_header.data_size,
gauthier's avatar
gauthier committed
593
              data->data,
594
              PDCP_TRANSMISSION_MODE_DATA);
gauthier's avatar
gauthier committed
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 605 606
  protocol_ctxt_t                ctxt_cpy;
  protocol_ctxt_t                ctxt;
  ctxt_cpy = *ctxt_pP;
607
  while (len > 0) {
gauthier's avatar
gauthier committed
608 609 610 611 612 613 614 615
      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)) {
616

gauthier's avatar
gauthier committed
617
              if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) {
618
                  LOG_D(PDCP, "[PDCP][FIFO] RX NLMSG_DONE\n");
gauthier's avatar
gauthier committed
619 620
                  //return;
              }
621

gauthier's avatar
gauthier committed
622
              if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) {
623
                  LOG_E(PDCP, "[PDCP][FIFO] RX NLMSG_ERROR\n");
gauthier's avatar
gauthier committed
624 625 626 627 628
              }
              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));
629
                      LOG_D(PDCP, "[PDCP][FIFO] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d\n",
gauthier's avatar
gauthier committed
630
                          pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size);
631
                  } else {
gauthier's avatar
gauthier committed
632 633 634 635 636 637
                      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()
638
#ifdef PDCP_DEBUG
639
                  LOG_D(PDCP, "[PDCP][FIFO] Something in socket, length %d \n",
gauthier's avatar
gauthier committed
640
                      nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));
641
#endif
gauthier's avatar
gauthier committed
642 643
                  //memcpy(pdcp_read_payload, (unsigned char *)NLMSG_DATA(nas_nlh_rx), nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr));

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

gauthier's avatar
gauthier committed
696
                  if (ctxt.enb_flag) {
gauthier's avatar
gauthier committed
697
                      if (rab_id != 0) {
698
                          rab_id = rab_id % maxDRB;
gauthier's avatar
gauthier committed
699
                          if (pdcp_array_drb_eNB[ctxt.enb_module_id][ctxt.ue_module_id][rab_id-1].instanciated_instance) {
700
#ifdef PDCP_DEBUG
701
                              LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
gauthier's avatar
gauthier committed
702 703 704 705 706
                                    ctxt.frame,
                                    pdcp_read_header_g.inst,
                                    len,
                                    nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
                                    pdcp_read_header_g.rb_id);
707 708
#endif

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

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

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

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

823 824
              }
          }
gauthier's avatar
gauthier committed
825
      }
826
  }
827
  return len;
828
# endif
829 830 831 832 833 834
#else // neither NAS_NETLINK nor NAS_FIFO
  return 0;
#endif // NAS_NETLINK
}


835
void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const  ctxt_pP) {
836
  unsigned char       *otg_pkt=NULL;
837
  module_id_t          src_id; // src for otg
838 839
  module_id_t          dst_id; // dst for otg
  rb_id_t              rb_id;
nikaeinn's avatar
nikaeinn committed
840
  signed long          pkt_size=0;
gauthier's avatar
gauthier committed
841
  protocol_ctxt_t      ctxt;
842 843

  src_id = ctxt_pP->enb_module_id;
844

845 846
  // we need to add conditions to avoid transmitting data when the UE is not RRC connected.
#if defined(USER_MODE) && defined(OAI_EMU)
847 848 849 850 851 852
  module_id_t          module_id;
  static unsigned int  pkt_cnt_enb=0, pkt_cnt_ue=0;
  uint8_t              pdcp_mode, is_ue=0;
  Packet_otg_elt_t    *otg_pkt_info=NULL;
  int                  result;

853
  if (oai_emulation.info.otg_enabled ==1 ){
854 855
      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 ;
gauthier's avatar
gauthier committed
856 857
      src_id = module_id;
      while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]))) != NULL) {
858
          LOG_D(OTG,"Mod_id %d Frame %d Got a packet (%p), HEAD of otg_pdcp_buffer[%d] is %p and Nb elements is %d\n",
859
              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);
gauthier's avatar
gauthier committed
860
          //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id]));
gauthier's avatar
gauthier committed
861
          dst_id    = (otg_pkt_info->otg_pkt).dst_id;
gauthier's avatar
gauthier committed
862
          module_id = (otg_pkt_info->otg_pkt).module_id;
gauthier's avatar
gauthier committed
863 864
          rb_id     = (otg_pkt_info->otg_pkt).rb_id;
          is_ue     = (otg_pkt_info->otg_pkt).is_ue;
gauthier's avatar
gauthier committed
865 866 867 868
          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
869
          // 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
870
          otg_pkt = (unsigned char*) (otg_pkt_info->otg_pkt).sdu_buffer;
gauthier's avatar
gauthier committed
871 872 873
          pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size;
          if (otg_pkt != NULL) {
              if (is_ue == 0 ) {
874
                  /*rlc_util_print_hex_octets(PDCP,
875
                                            otg_pkt,
876
                                            pkt_size);
877
                   */
gauthier's avatar
gauthier committed
878
                  //rb_id = (/*NB_eNB_INST +*/ dst_id -1 ) * MAX_NUM_RB + DTCH;
gauthier's avatar
gauthier committed
879 880 881 882 883
                  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;

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


nikaeinn's avatar
nikaeinn committed
900
                  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",
901 902 903
                        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;
gauthier's avatar
gauthier committed
904
                  ctxt.ue_module_id  = ctxt_pP->ue_module_id;
905 906 907 908
                  ctxt.frame         = ctxt_pP->frame;
                  ctxt.enb_flag      = ctxt_pP->enb_flag;

                  result = pdcp_data_req( &ctxt,
909
                                          SRB_FLAG_NO,
910 911 912 913 914 915
                                          rb_id,
                                          RLC_MUI_UNDEFINED,
                                          RLC_SDU_CONFIRM_NO,
                                          pkt_size,
                                          otg_pkt,
                                          PDCP_TRANSMISSION_MODE_DATA);
gauthier's avatar
gauthier committed
916 917 918 919 920
                  AssertFatal (result == TRUE, "PDCP data request failed!\n");
              }
              free(otg_pkt);
              otg_pkt = NULL;
          }
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));
gauthier's avatar
gauthier committed
922

923 924 925
      }
  }
#else
926
  if ((otg_enabled==1) && (ctxt_pP->enb_flag == 1)) { // generate DL traffic
gauthier's avatar
gauthier committed
927
      unsigned int ctime=0;
928 929 930 931 932 933 934
      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;
gauthier's avatar
gauthier committed
935 936

      for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) {
937
          if (mac_get_rrc_status(ctxt_pP->enb_module_id, ctxt_pP->enb_flag, dst_id ) > 2) {
938 939 940
              unsigned int temp = 0;
              otg_pkt = packet_gen( src_id, dst_id, 0, ctime, &temp );
              pkt_size = temp;
gauthier's avatar
gauthier committed
941
              if (otg_pkt != NULL){
942
                  rb_id = dst_id * maxDRB + DTCH;
943 944 945 946 947 948 949 950 951
                  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);
952
                  LOG_D(OTG,"send packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", ctxt_pP->enb_module_id, rb_id, src_id, dst_id, pkt_size);
gauthier's avatar
gauthier committed
953 954 955
                  free(otg_pkt);
              }
              /*else {
956 957
      LOG_I(OTG,"nothing generated (src %d, dst %d)\n",src_id, dst_id);
      }*/
gauthier's avatar
gauthier committed
958 959
          }
          /*else {
960
    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 ));
961
    }*/
gauthier's avatar
gauthier committed
962
      }
963 964 965
  }
#endif
}