pdcp.c 68.9 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 31 32 33 34 35 36 37 38 39 40

/*! \file pdcp.c
 * \brief pdcp interface with RLC
 * \author  Lionel GAUTHIER and Navid Nikaein
 * \date 2009-2012
 * \version 1.0
 */

#define PDCP_C
#ifndef USER_MODE
#include <rtai_fifos.h>
#endif
41
#include "assertions.h"
42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include "pdcp.h"
#include "pdcp_util.h"
#include "pdcp_sequence_manager.h"
#include "LAYER2/RLC/rlc.h"
#include "LAYER2/MAC/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "pdcp_primitives.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "UTIL/LOG/log.h"
#include <inttypes.h>
#include "platform_constants.h"
#include "UTIL/LOG/vcd_signal_dumper.h"

56 57 58 59
#if defined(ENABLE_SECURITY)
# include "UTIL/OSA/osa_defs.h"
#endif

60 61 62 63
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

64 65
#if defined(LINK_PDCP_TO_GTPV1U)
#  include "gtpv1u_eNB_task.h"
66
#  include "gtpv1u.h"
67 68
#endif

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#ifndef OAI_EMU
extern int otg_enabled;
#endif

//extern char *packet_gen(int src, int dst, int ctime, int *pkt_size);
extern int otg_rx_pkt( int src, int dst, int ctime, char *buffer_tx, unsigned int size);

//-----------------------------------------------------------------------------
/*
 * If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken
 * and PDCP has no longer anything to do with RLC. In this case, after it's handed
 * an SDU it appends PDCP header and returns (by filling in incoming pointer parameters)
 * this mem_block_t to be dissected for testing purposes. For further details see test
 * code at targets/TEST/PDCP/test_pdcp.c:test_pdcp_data_req()
 */
84
boolean_t pdcp_data_req(
85
        const protocol_ctxt_t* const  ctxt_pP,
86 87 88 89 90 91 92
        const srb_flag_t     srb_flagP,
        const rb_id_t        rb_idP,
        const mui_t          muiP,
        const confirm_t      confirmP,
        const sdu_size_t     sdu_buffer_sizeP,
        unsigned char *const sdu_buffer_pP,
        const pdcp_transmission_mode_t modeP)
93 94
{
  //-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
95
  pdcp_t            *pdcp_p          = NULL;
96 97 98 99 100
  uint8_t            i               = 0;
  uint8_t            pdcp_header_len = 0;
  uint8_t            pdcp_tailer_len = 0;
  uint16_t           pdcp_pdu_size   = 0;
  uint16_t           current_sn      = 0;
gauthier's avatar
gauthier committed
101 102
  mem_block_t       *pdcp_pdu_p      = NULL;
  rlc_op_status_t    rlc_status;
103
  boolean_t          ret             = TRUE;
gauthier's avatar
gauthier committed
104

105

106 107
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN);

108 109
  AssertError (ctxt_pP->enb_module_id < NUMBER_OF_eNB_MAX, return FALSE, "eNB id is too high (%u/%d) %u %u!\n", ctxt_pP->enb_module_id, NUMBER_OF_eNB_MAX, ctxt_pP->ue_module_id, rb_idP);
  AssertError (ctxt_pP->ue_module_id < NUMBER_OF_UE_MAX, return FALSE, "UE id is too high (%u/%d) %u %u!\n", ctxt_pP->ue_module_id, NUMBER_OF_UE_MAX, ctxt_pP->enb_module_id, rb_idP);
110
  if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) {
111
      AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->ue_module_id, ctxt_pP->enb_module_id);
112
  } else {
113
      if (srb_flagP) {
114
          AssertError (rb_idP < 2, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, 2, ctxt_pP->ue_module_id, ctxt_pP->enb_module_id);
115
      } else {
116
          AssertError (rb_idP < maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, maxDRB, ctxt_pP->ue_module_id, ctxt_pP->enb_module_id);
117
      }
118
  }
gauthier's avatar
gauthier committed
119

120
  if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
121
      if (srb_flagP) {
122
          pdcp_p = &pdcp_array_srb_ue[ctxt_pP->ue_module_id][rb_idP-1];
123
  } else {
124
          pdcp_p = &pdcp_array_drb_ue[ctxt_pP->ue_module_id][rb_idP-1];
125
      }
126
  } else {
127
      if (srb_flagP) {
128
          pdcp_p = &pdcp_array_srb_eNB[ctxt_pP->enb_module_id][ctxt_pP->ue_module_id][rb_idP-1];
129
      } else {
130
          pdcp_p = &pdcp_array_drb_eNB[ctxt_pP->enb_module_id][ctxt_pP->ue_module_id][rb_idP-1];
131
      }
132
  }
133

134
  if ((pdcp_p->instanciated_instance == FALSE) && (modeP != PDCP_TRANSMISSION_MODE_TRANSPARENT)) {
135
      if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
gauthier's avatar
gauthier committed
136
          LOG_W(PDCP, "[UE %d] Instance is not configured for eNB %d, rb_id %d Ignoring SDU...\n",
137
              ctxt_pP->ue_module_id, ctxt_pP->enb_module_id, rb_idP);
gauthier's avatar
gauthier committed
138 139
      } else {
          LOG_W(PDCP, "[eNB %d] Instance is not configured for UE %d, rb_id %d Ignoring SDU...\n",
140
              ctxt_pP->enb_module_id, ctxt_pP->ue_module_id, rb_idP);
gauthier's avatar
gauthier committed
141 142
      }
      return FALSE;
143
  }
gauthier's avatar
gauthier committed
144 145 146
  if (sdu_buffer_sizeP == 0) {
      LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n");
      return FALSE;
147 148 149 150 151
  }
  /*
   * XXX MAX_IP_PACKET_SIZE is 4096, shouldn't this be MAX SDU size, which is 8188 bytes?
   */

gauthier's avatar
gauthier committed
152 153 154 155 156
  if (sdu_buffer_sizeP > MAX_IP_PACKET_SIZE) {
      LOG_E(PDCP, "Requested SDU size (%d) is bigger than that can be handled by PDCP (%u)!\n",
          sdu_buffer_sizeP, MAX_IP_PACKET_SIZE);
      // XXX What does following call do?
      mac_xface->macphy_exit("PDCP sdu buffer size > MAX_IP_PACKET_SIZE");
157
  }
158

159 160
  if (ctxt_pP->enb_flag == ENB_FLAG_NO)
    start_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_req);
161
  else
162
    start_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_req);
163 164
 
   
165
  // PDCP transparent mode for MBMS traffic
166

167
  if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) {
gauthier's avatar
gauthier committed
168 169 170 171
      LOG_D(PDCP, " [TM] Asking for a new mem_block of size %d\n",sdu_buffer_sizeP);
      pdcp_pdu_p = get_free_mem_block(sdu_buffer_sizeP);
      if (pdcp_pdu_p != NULL) {
          memcpy(&pdcp_pdu_p->data[0], sdu_buffer_pP, sdu_buffer_sizeP);
172
#if defined(DEBUG_PDCP_PAYLOAD)
173 174 175
          rlc_util_print_hex_octets(PDCP,
                                    (unsigned char*)&pdcp_pdu_p->data[0],
                                    sdu_buffer_sizeP);
176
#endif
177
          rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p);
gauthier's avatar
gauthier committed
178 179
      } else {
        rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES;
180
	LOG_W(PDCP,"[FRAME %5u][%s][PDCP][MOD %u/%u][RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n",
181 182 183 184
	      ctxt_pP->frame,
	      (ctxt_pP->enb_flag) ? "eNB" : "UE",
	      ctxt_pP->enb_module_id,
	      ctxt_pP->ue_module_id,
185
	      rb_idP);
gauthier's avatar
gauthier committed
186 187
#if defined(STOP_ON_IP_TRAFFIC_OVERLOAD)
        AssertFatal(0, "[FRAME %5u][%s][PDCP][MOD %u/%u][RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n",
188 189 190 191
            ctxt_pP->frame,
            (ctxt_pP->enb_flag) ? "eNB" : "UE",
            ctxt_pP->enb_module_id,
            ctxt_pP->ue_module_id,
gauthier's avatar
gauthier committed
192 193 194
            rb_idP);
#endif
      }
195
  } else {
gauthier's avatar
gauthier committed
196
      // calculate the pdcp header and trailer size
197
      if (srb_flagP) {
gauthier's avatar
gauthier committed
198 199
          pdcp_header_len = PDCP_CONTROL_PLANE_DATA_PDU_SN_SIZE;
          pdcp_tailer_len = PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE;
200
      } else {
gauthier's avatar
gauthier committed
201 202
          pdcp_header_len = PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE;
          pdcp_tailer_len = 0;
203
      }
gauthier's avatar
gauthier committed
204 205
      pdcp_pdu_size = sdu_buffer_sizeP + pdcp_header_len + pdcp_tailer_len;

206
      LOG_D(PDCP, "Data request notification for PDCP entity %s enb id %u ue_id %u and radio bearer ID %d pdu size %d (header%d, trailer%d)\n",
207 208 209
          (ctxt_pP->enb_flag) ? "eNB" : "UE",
              ctxt_pP->enb_module_id,
              ctxt_pP->ue_module_id,
gauthier's avatar
gauthier committed
210 211 212 213 214
              rb_idP,
              pdcp_pdu_size,
              pdcp_header_len,
              pdcp_tailer_len);

215
      /*
gauthier's avatar
gauthier committed
216
       * Allocate a new block for the new PDU (i.e. PDU header and SDU payload)
217
       */
gauthier's avatar
gauthier committed
218 219 220 221 222 223 224 225 226 227
      LOG_D(PDCP, "Asking for a new mem_block of size %d\n", pdcp_pdu_size);
      pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size);

      if (pdcp_pdu_p != NULL) {
          /*
           * Create a Data PDU with header and append data
           *
           * Place User Plane PDCP Data PDU header first
           */

228
          if (srb_flagP) { // this Control plane PDCP Data PDU
gauthier's avatar
gauthier committed
229 230 231 232
              pdcp_control_plane_data_pdu_header pdu_header;
              pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp_p);
              current_sn = pdu_header.sn;
              memset(&pdu_header.mac_i[0],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE);
233
              memset(&pdcp_pdu_p->data[sdu_buffer_sizeP + pdcp_header_len],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE);
gauthier's avatar
gauthier committed
234 235
              if (pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer((unsigned char*)pdcp_pdu_p->data, &pdu_header) == FALSE) {
                  LOG_E(PDCP, "Cannot fill PDU buffer with relevant header fields!\n");
236 237
                  if (ctxt_pP->enb_flag == ENB_FLAG_NO)
                    stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_req);
gauthier's avatar
gauthier committed
238
                  else
239
                    stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_req);
240
		  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT);
gauthier's avatar
gauthier committed
241
                  return FALSE;
gauthier's avatar
gauthier committed
242 243 244
              }
          } else {
              pdcp_user_plane_data_pdu_header_with_long_sn pdu_header;
245
              pdu_header.dc = (modeP == PDCP_TRANSMISSION_MODE_DATA) ? PDCP_DATA_PDU_BIT_SET :  PDCP_CONTROL_PDU_BIT_SET;
gauthier's avatar
gauthier committed
246 247 248 249
              pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp_p);
              current_sn = pdu_header.sn ;
              if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char*)pdcp_pdu_p->data, &pdu_header) == FALSE) {
                  LOG_E(PDCP, "Cannot fill PDU buffer with relevant header fields!\n");
250 251
                  if (ctxt_pP->enb_flag == ENB_FLAG_NO)
                    stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_req);
gauthier's avatar
gauthier committed
252
                  else
253
                    stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_req);
254
		  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT);
gauthier's avatar
gauthier committed
255
                  return FALSE;
gauthier's avatar
gauthier committed
256 257 258 259 260 261 262 263 264 265
              }
          }
          /*
           * Validate incoming sequence number, there might be a problem with PDCP initialization
           */
          if (current_sn > pdcp_calculate_max_seq_num_for_given_size(pdcp_p->seq_num_size)) {
              LOG_E(PDCP, "Generated sequence number (%lu) is greater than a sequence number could ever be!\n", current_sn);
              LOG_E(PDCP, "There must be a problem with PDCP initialization, ignoring this PDU...\n");

              free_mem_block(pdcp_pdu_p);
266 267
              if (ctxt_pP->enb_flag == ENB_FLAG_NO)
                stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_req);
gauthier's avatar
gauthier committed
268
              else
269
                stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_req);
270
	      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT);
gauthier's avatar
gauthier committed
271 272
              return FALSE;
          }
273

gauthier's avatar
gauthier committed
274
          LOG_D(PDCP, "Sequence number %d is assigned to current PDU\n", current_sn);
275

gauthier's avatar
gauthier committed
276 277
          /* Then append data... */
          memcpy(&pdcp_pdu_p->data[pdcp_header_len], sdu_buffer_pP, sdu_buffer_sizeP);
278

gauthier's avatar
gauthier committed
279 280 281 282 283
          //For control plane data that are not integrity protected,
          // the MAC-I field is still present and should be padded with padding bits set to 0.
          // NOTE: user-plane data are never integrity protected
          for (i=0;i<pdcp_tailer_len;i++)
            pdcp_pdu_p->data[pdcp_header_len + sdu_buffer_sizeP + i] = 0x00;// pdu_header.mac_i[i];
284 285

#if defined(ENABLE_SECURITY)
286
          if ((pdcp_p->security_activated != 0) &&
287
              (((pdcp_p->cipheringAlgorithm) != 0) ||
gauthier's avatar
gauthier committed
288 289
              ((pdcp_p->integrityProtAlgorithm) != 0))) {

290 291
              if (ctxt_pP->enb_flag == ENB_FLAG_NO)
                start_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].apply_security);
gauthier's avatar
gauthier committed
292
              else
293 294 295 296 297 298 299 300 301 302 303 304 305
                start_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].apply_security);

              pdcp_apply_security(ctxt_pP,
                                  pdcp_p,
                                  srb_flagP,
                                  rb_idP % maxDRB,
                                  pdcp_header_len,
                                  current_sn,
                                  pdcp_pdu_p->data,
                                  sdu_buffer_sizeP);

              if (ctxt_pP->enb_flag == ENB_FLAG_NO)
                stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].apply_security);
gauthier's avatar
gauthier committed
306
              else
307
                stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].apply_security);
gauthier's avatar
gauthier committed
308
          }
309

310 311
#endif

gauthier's avatar
gauthier committed
312 313 314 315 316 317 318
          /* Print octets of outgoing data in hexadecimal form */
          LOG_D(PDCP, "Following content with size %d will be sent over RLC (PDCP PDU header is the first two bytes)\n",
              pdcp_pdu_size);
          //util_print_hex_octets(PDCP, (unsigned char*)pdcp_pdu_p->data, pdcp_pdu_size);
          //util_flush_hex_octets(PDCP, (unsigned char*)pdcp_pdu->data, pdcp_pdu_size);
      } else {
          LOG_E(PDCP, "Cannot create a mem_block for a PDU!\n");
319 320
          if (ctxt_pP->enb_flag == ENB_FLAG_NO)
              stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_req);
321
          else
322
              stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_req);
gauthier's avatar
gauthier committed
323 324
#if defined(STOP_ON_IP_TRAFFIC_OVERLOAD)
        AssertFatal(0, "[FRAME %5u][%s][PDCP][MOD %u/%u][RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n",
325 326 327 328
            ctxt_pP->frame,
            (ctxt_pP->enb_flag) ? "eNB" : "UE",
            ctxt_pP->enb_module_id,
            ctxt_pP->ue_module_id,
gauthier's avatar
gauthier committed
329 330
            rb_idP);
#endif
331 332
	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT);
	return FALSE;
gauthier's avatar
gauthier committed
333 334 335 336 337
      }
      /*
       * Ask sublayer to transmit data and check return value
       * to see if RLC succeeded
       */
338 339 340 341 342 343 344
#ifdef PDCP_MSG_PRINT
      int i=0;
      LOG_F(PDCP,"[MSG] PDCP DL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP);
      for (i = 0; i < pdcp_pdu_size; i++)
	LOG_F(PDCP,"%02x ", ((uint8_t*)pdcp_pdu_p->data)[i]);
      LOG_F(PDCP,"\n");
#endif 
345
      rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p);
346

347 348 349 350
  }
  switch (rlc_status) {
  case RLC_OP_STATUS_OK:
    LOG_D(PDCP, "Data sending request over RLC succeeded!\n");
351
    ret=TRUE;
352 353 354 355
    break;

  case RLC_OP_STATUS_BAD_PARAMETER:
    LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n");
356 357
    ret= FALSE;
    break;
358 359
  case RLC_OP_STATUS_INTERNAL_ERROR:
    LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n");
360 361
    ret= FALSE;
    break;
362 363 364

  case RLC_OP_STATUS_OUT_OF_RESSOURCES:
    LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
365 366
    ret= FALSE;
    break;
367 368 369

  default:
    LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
370 371
    ret= FALSE;
    break;
372
  }
373 374
  if (ctxt_pP->enb_flag == ENB_FLAG_NO)
    stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_req);
375
  else
376
    stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_req);
377 378 379 380
  /*
   * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK
   * so we return TRUE afterwards
   */
381
  /*
382
   if (rb_id>=DTCH) {
383
    if (ctxt_pP->enb_flag == 1) {
384 385 386 387 388 389 390
      Pdcp_stats_tx[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH]++;
      Pdcp_stats_tx_bytes[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH] += sdu_buffer_size;
    } else {
      Pdcp_stats_tx[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH]++;
      Pdcp_stats_tx_bytes[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH] += sdu_buffer_size;
    }
    }*/
391
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT);
392
  return ret;
393 394 395

}

gauthier's avatar
gauthier committed
396

397
boolean_t pdcp_data_ind(
398
        const protocol_ctxt_t* const ctxt_pP,
399 400 401 402
        const srb_flag_t   srb_flagP,
        const MBMS_flag_t  MBMS_flagP,
        const rb_id_t      rb_idP,
        const sdu_size_t   sdu_buffer_sizeP,
403
        mem_block_t* const sdu_buffer_pP)
404 405
{
  //-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
406 407 408
  pdcp_t      *pdcp_p          = NULL;
  list_t      *sdu_list_p      = NULL;
  mem_block_t *new_sdu_p       = NULL;
409 410
  uint8_t      pdcp_header_len = 0;
  uint8_t      pdcp_tailer_len = 0;
gauthier's avatar
gauthier committed
411
  pdcp_sn_t    sequence_number = 0;
412
  volatile sdu_size_t   payload_offset  = 0;
413
  rb_id_t      rb_id            = rb_idP;
414
  boolean_t    packet_forwarded = FALSE;
415 416
#if defined(LINK_PDCP_TO_GTPV1U)
  MessageDef  *message_p        = NULL;
417
  uint8_t     *gtpu_buffer_p    = NULL;
418
#endif
419
 
420

421 422 423
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN);

  #ifdef OAI_EMU
424 425
  if (ctxt_pP->enb_flag) {
      AssertFatal ((ctxt_pP->enb_module_id  == oai_emulation.info.first_enb_local) && (oai_emulation.info.nb_enb_local > 0),
426
          "eNB module id is too low (%u/%d)!\n",
427
          ctxt_pP->enb_module_id,
428
          oai_emulation.info.first_enb_local);
429
      AssertFatal ((ctxt_pP->enb_module_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)) && (oai_emulation.info.nb_enb_local > 0),
430
          "eNB module id is too high (%u/%d)!\n",
431
          ctxt_pP->enb_module_id,
432
          oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);
433
      AssertFatal (ctxt_pP->ue_module_id  < NB_UE_INST,
434
          "UE module id is too high (%u/%d)!\n",
435
          ctxt_pP->ue_module_id,
436 437
          oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
  } else {
438
      AssertFatal (ctxt_pP->ue_module_id  < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),
439
          "UE module id is too high (%u/%d)!\n",
440
          ctxt_pP->ue_module_id,
441
          oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);
442
      AssertFatal (ctxt_pP->ue_module_id  >= oai_emulation.info.first_ue_local,
443
          "UE module id is too low (%u/%d)!\n",
444
          ctxt_pP->ue_module_id,
445 446 447
          oai_emulation.info.first_ue_local);
  }
#endif
448 449 450 451 452 453 454 455
#ifdef PDCP_MSG_PRINT
      int i=0;
      LOG_F(PDCP,"[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP);
      for (i = 0; i < sdu_buffer_sizeP; i++)
	LOG_F(PDCP,"%02x ", ((uint8_t*)sdu_buffer_pP->data)[i]);
      LOG_F(PDCP,"\n");
#endif 

456
  if (MBMS_flagP) {
457 458
      AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->ue_module_id, ctxt_pP->enb_module_id);
      if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
459
          LOG_I(PDCP, "e-MBMS Data indication notification for PDCP entity from eNB %u to UE %u "
460 461
                "and radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n",
                ctxt_pP->enb_module_id, ctxt_pP->ue_module_id, rb_idP, sdu_buffer_sizeP, ctxt_pP->enb_flag);
462 463
      } else {
          LOG_I(PDCP, "Data indication notification for PDCP entity from UE %u to eNB %u "
464 465
          "and radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d eNB_id %d\n",
          ctxt_pP->ue_module_id, ctxt_pP->enb_module_id , rb_idP, sdu_buffer_sizeP, ctxt_pP->enb_flag, ctxt_pP->enb_module_id);
466
      }
467
  } else {
468
      rb_id = rb_idP % maxDRB;
469 470 471
      AssertError (rb_id < maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_id, maxDRB, ctxt_pP->ue_module_id, ctxt_pP->enb_module_id);
      AssertError (rb_id > 0, return FALSE, "RB id is too low (%u/%d) %u %u!\n", rb_id, maxDRB, ctxt_pP->ue_module_id, ctxt_pP->enb_module_id);
      if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
472
          if (srb_flagP) {
473
              pdcp_p = &pdcp_array_srb_ue[ctxt_pP->ue_module_id][rb_id-1];
474
#if 0
475
              LOG_D(PDCP, "Data indication notification for PDCP entity from eNB %u to UE %u "
476 477
                    "and signalling radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n",
                    ctxt_pP->enb_module_id, ctxt_pP->ue_module_id, rb_id, sdu_buffer_sizeP, ctxt_pP->enb_flag);
478
#endif
479
          } else {
480
              pdcp_p = &pdcp_array_drb_ue[ctxt_pP->ue_module_id][rb_id-1];
481
#if 0
482
              LOG_D(PDCP, "Data indication notification for PDCP entity from eNB %u to UE %u "
483 484
                    "and data radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n",
                    ctxt_pP->enb_module_id, ctxt_pP->ue_module_id, rb_id, sdu_buffer_sizeP, ctxt_pP->enb_flag);
485
#endif
486
          }
487

488
      } else {
489
          if (srb_flagP) {
490
              pdcp_p = &pdcp_array_srb_eNB[ctxt_pP->enb_module_id][ctxt_pP->ue_module_id][rb_id-1];
491
#if 0
492
              LOG_D(PDCP, "Data indication notification for PDCP entity from UE %u to eNB %u "
493 494
                  "and signalling radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d eNB_id %d\n",
                  ctxt_pP->ue_module_id, ctxt_pP->enb_module_id , rb_id, sdu_buffer_sizeP, ctxt_pP->enb_flag, ctxt_pP->enb_module_id);
495
#endif
496
          } else {
497
              pdcp_p = &pdcp_array_drb_eNB[ctxt_pP->enb_module_id][ctxt_pP->ue_module_id][rb_id-1];
498
#if 0
499
              LOG_D(PDCP, "Data indication notification for PDCP entity from UE %u to eNB %u "
500 501
                  "and data radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d eNB_id %d\n",
                  ctxt_pP->ue_module_id, ctxt_pP->enb_module_id , rb_id, sdu_buffer_sizeP, ctxt_pP->enb_flag, ctxt_pP->enb_module_id);
502
#endif
503
          }
504 505

      }
506
  }
507
  
gauthier's avatar
gauthier committed
508
  sdu_list_p = &pdcp_sdu_list;
509

gauthier's avatar
gauthier committed
510 511 512
  if (sdu_buffer_sizeP == 0) {
      LOG_W(PDCP, "SDU buffer size is zero! Ignoring this chunk!\n");
      return FALSE;
513
  }
514
  
515 516
  if (ctxt_pP->enb_flag)
    start_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_ind);
517
  else
518
    start_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_ind);
519 520

  /*
521 522
   * Parse the PDU placed at the beginning of SDU to check
   * if incoming SN is in line with RX window
gauthier's avatar
gauthier committed
523
   */
524
  
525
  if (MBMS_flagP == 0 ) {
526 527 528 529 530 531 532 533 534 535 536 537
    if (srb_flagP) { //SRB1/2
      pdcp_header_len = PDCP_CONTROL_PLANE_DATA_PDU_SN_SIZE;
      pdcp_tailer_len = PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE;
      sequence_number =   pdcp_get_sequence_number_of_pdu_with_SRB_sn((unsigned char*)sdu_buffer_pP->data);
    } else { // DRB
      pdcp_tailer_len = 0;
      if (pdcp_p->seq_num_size == PDCP_SN_7BIT){
	pdcp_header_len = PDCP_USER_PLANE_DATA_PDU_SHORT_SN_HEADER_SIZE;
	sequence_number =     pdcp_get_sequence_number_of_pdu_with_short_sn((unsigned char*)sdu_buffer_pP->data);
      }else if (pdcp_p->seq_num_size == PDCP_SN_12BIT){
	pdcp_header_len = PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE;
	sequence_number =     pdcp_get_sequence_number_of_pdu_with_long_sn((unsigned char*)sdu_buffer_pP->data);
gauthier's avatar
gauthier committed
538
      } else {
539 540
	//sequence_number = 4095;
	LOG_E(PDCP,"wrong sequence number  (%d) for this pdcp entity \n", pdcp_p->seq_num_size);
gauthier's avatar
gauthier committed
541
      }
542 543 544 545 546 547 548
      //uint8_t dc = pdcp_get_dc_filed((unsigned char*)sdu_buffer_pP->data);
    }
    
    /*
     * Check if incoming SDU is long enough to carry a PDU header
     */
    if (sdu_buffer_sizeP < pdcp_header_len + pdcp_tailer_len ) {
gauthier's avatar
gauthier committed
549 550
          LOG_W(PDCP, "Incoming (from RLC) SDU is short of size (size:%d)! Ignoring...\n", sdu_buffer_sizeP);
          free_mem_block(sdu_buffer_pP);
551 552
          if (ctxt_pP->enb_flag)
            stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_ind);
gauthier's avatar
gauthier committed
553
          else
554
            stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_ind);
555
	  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT);
gauthier's avatar
gauthier committed
556
          return FALSE;
gauthier's avatar
gauthier committed
557
      }
558 559
  
    if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == TRUE) {
560
#if 0
561
      LOG_T(PDCP, "Incoming PDU has a sequence number (%d) in accordance with RX window\n", sequence_number);
562
#endif
563 564 565 566 567
      /* if (dc == PDCP_DATA_PDU )
	 LOG_D(PDCP, "Passing piggybacked SDU to NAS driver...\n");
	 else
	 LOG_D(PDCP, "Passing piggybacked SDU to RRC ...\n");*/
    } else {
568
      LOG_W(PDCP, "Incoming PDU has an unexpected sequence number (%d), RX window synchronisation have probably been lost!\n", sequence_number);
gauthier's avatar
gauthier committed
569
      /*
570 571
       * XXX Till we implement in-sequence delivery and duplicate discarding
       * mechanism all out-of-order packets will be delivered to RRC/IP
572 573
       */
#if 0
574 575 576
      LOG_D(PDCP, "Ignoring PDU...\n");
      free_mem_block(sdu_buffer);
      return FALSE;
577
#else
578
      //LOG_W(PDCP, "Delivering out-of-order SDU to upper layer...\n");
579
#endif
580
    }
gauthier's avatar
gauthier committed
581
      // SRB1/2: control-plane data
582
    if (srb_flagP){
583
#if defined(ENABLE_SECURITY)
584
      if (pdcp_p->security_activated == 1) {
585 586
          if (ctxt_pP->enb_flag == ENB_FLAG_NO)
              start_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].validate_security);
587
          else
588
              start_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].validate_security);
589

590 591
          pdcp_validate_security(ctxt_pP,
                  pdcp_p,
592 593 594 595 596 597
                  srb_flagP,
                  rb_idP,
                  pdcp_header_len,
                  sequence_number,
                  sdu_buffer_pP->data,
                  sdu_buffer_sizeP - pdcp_tailer_len);
598 599
          if (ctxt_pP->enb_flag == ENB_FLAG_NO)
              stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].validate_security);
600
          else
601
              stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].validate_security);
gauthier's avatar
gauthier committed
602
      }
603 604
#endif
      //rrc_lite_data_ind(module_id, //Modified MW - L2 Interface
605 606 607 608
      pdcp_rrc_data_ind(ctxt_pP->enb_module_id,
              ctxt_pP->ue_module_id,
              ctxt_pP->frame,
              ctxt_pP->enb_flag,
609 610 611
              rb_id,
              sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len,
              (uint8_t*)&sdu_buffer_pP->data[pdcp_header_len]);
612 613
      free_mem_block(sdu_buffer_pP);
      // free_mem_block(new_sdu);
614 615
      if (ctxt_pP->enb_flag)
          stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_ind);
616
      else
617
          stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_ind);
618
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT);
619 620 621 622 623 624 625 626
      return TRUE;
    }
  /*
   * DRBs 
   */
    payload_offset=pdcp_header_len;// PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE;
#if defined(ENABLE_SECURITY)
    if (pdcp_p->security_activated == 1) {
627 628
      if (ctxt_pP->enb_flag == ENB_FLAG_NO)
          start_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].validate_security);
629
      else
630
          start_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].validate_security);
631
      
632 633 634 635 636 637 638 639 640 641 642
      pdcp_validate_security(
                      ctxt_pP,
                      pdcp_p,
                      srb_flagP,
                      rb_idP,
                      pdcp_header_len,
                      sequence_number,
                      sdu_buffer_pP->data,
                      sdu_buffer_sizeP - pdcp_tailer_len);
      if (ctxt_pP->enb_flag == ENB_FLAG_NO)
          stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].validate_security);
643
      else
644
          stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].validate_security);
645 646 647
      
    }
    
648
#endif
649
  } else {
gauthier's avatar
gauthier committed
650
      payload_offset=0;
651
  }
652
  
653
#if defined(USER_MODE) && defined(OAI_EMU)
654
  if (oai_emulation.info.otg_enabled == 1) {
gauthier's avatar
gauthier committed
655 656
      module_id_t src_id, dst_id;
      int    ctime;
657
   
658
      DevAssert(pdcp_p);
659
      if (pdcp_p->rlc_mode == RLC_MODE_AM ) {
660
          pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
661 662
      }
   
663
#if defined(DEBUG_PDCP_PAYLOAD)
664
      rlc_util_print_hex_octets(PDCP,
665
                                (unsigned char*)&sdu_buffer_pP->data[payload_offset],
666
                                sdu_buffer_sizeP - payload_offset);
667
#endif
gauthier's avatar
gauthier committed
668

669 670
      src_id = (ctxt_pP->enb_flag == ENB_FLAG_NO) ?  ctxt_pP->enb_module_id : ctxt_pP->ue_module_id +   NB_eNB_INST;
      dst_id = (ctxt_pP->enb_flag == ENB_FLAG_NO) ? ctxt_pP->ue_module_id +  NB_eNB_INST: ctxt_pP->enb_module_id;
gauthier's avatar
gauthier committed
671 672
      ctime = oai_emulation.info.time_ms; // avg current simulation time in ms : we may get the exact time through OCG?
      LOG_D(PDCP, "Check received buffer : enb_flag %d  rab id %d (src %d, dst %d)\n",
673
          ctxt_pP->enb_flag, rb_id, src_id, dst_id);
gauthier's avatar
gauthier committed
674 675 676

      if (otg_rx_pkt(src_id, dst_id,ctime,&sdu_buffer_pP->data[payload_offset],
          sdu_buffer_sizeP - payload_offset ) == 0 ) {
677
            free_mem_block(sdu_buffer_pP);
678 679
            if (ctxt_pP->enb_flag)
                stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_ind);
680
            else
681
                stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_ind);
682 683
            vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT);
            return TRUE;
gauthier's avatar
gauthier committed
684
      }
685 686 687
  }
#else
  if (otg_enabled==1) {
gauthier's avatar
gauthier committed
688 689
      LOG_D(OTG,"Discarding received packed\n");
      free_mem_block(sdu_buffer_pP);
690 691
      if (ctxt_pP->enb_flag)
          stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_ind);
692
      else
693
          stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_ind);
694
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT);
gauthier's avatar
gauthier committed
695
      return TRUE;
696 697 698
  }
#endif

gauthier's avatar
gauthier committed
699

700 701 702 703 704 705 706 707 708
  // XXX Decompression would be done at this point

  /*
   * After checking incoming sequence number PDCP header
   * has to be stripped off so here we copy SDU buffer starting
   * from its second byte (skipping 0th and 1st octets, i.e.
   * PDCP header)
   */
#if defined(LINK_PDCP_TO_GTPV1U)
709
  if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) {
710
      //LOG_T(PDCP,"Sending to GTPV1U %d bytes\n", sdu_buffer_sizeP - payload_offset);
711 712
      gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
               sdu_buffer_sizeP - payload_offset + GTPU_HEADER_OVERHEAD_MAX);
713
      AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
714
      memcpy(&gtpu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset);
715
      message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ);
716
      AssertFatal(message_p != NULL, "OUT OF MEMORY");
717 718
      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer       = gtpu_buffer_p;
      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length       = sdu_buffer_sizeP - payload_offset;
719
      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset       = GTPU_HEADER_OVERHEAD_MAX;
720
      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).ue_index     = ctxt_pP->ue_module_id;
721
      GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id       = rb_id + 4;
722
      itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
      packet_forwarded = TRUE;
  }
#else
  packet_forwarded = FALSE;
#endif
  if (FALSE == packet_forwarded) {
      new_sdu_p = get_free_mem_block(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t));

      if (new_sdu_p) {
          if (pdcp_p->rlc_mode == RLC_MODE_AM ) {
              pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
          }
          /*
           * Prepend PDCP indication header which is going to be removed at pdcp_fifo_flush_sdus()
           */
          memset(new_sdu_p->data, 0, sizeof (pdcp_data_ind_header_t));
          ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size = sdu_buffer_sizeP - payload_offset;

          // Here there is no virtualization possible
          // set ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst for IP layer here
743
          if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
744
              ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id;
gauthier's avatar
gauthier committed
745
#if defined(OAI_EMU)
746
              ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = ctxt_pP->ue_module_id + oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local;
gauthier's avatar
gauthier committed
747
#endif
748
          } else {
749
              ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->ue_module_id * maxDRB);
gauthier's avatar
gauthier committed
750
#if defined(OAI_EMU)
751
              ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst  = ctxt_pP->enb_module_id - oai_emulation.info.first_enb_local;
752
#endif
753
          }
gauthier's avatar
gauthier committed
754

755 756 757 758
          memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], \
                  &sdu_buffer_pP->data[payload_offset], \
                  sdu_buffer_sizeP - payload_offset);
          list_add_tail_eurecom (new_sdu_p, sdu_list_p);
759

760 761 762 763 764 765
          /* Print octets of incoming data in hexadecimal form */
          LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n",
              sdu_buffer_sizeP  - payload_offset + sizeof(pdcp_data_ind_header_t),
              sdu_buffer_sizeP  - payload_offset);
          //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset);
          //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset);
gauthier's avatar
gauthier committed
766

767 768 769 770
          /*
           * Update PDCP statistics
           * XXX Following two actions are identical, is there a merge error?
           */
gauthier's avatar
gauthier committed
771

772
          /*if (ctxt_pP->enb_flag == 1) {
773 774 775 776 777 778 779
              Pdcp_stats_rx[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH]++;
              Pdcp_stats_rx_bytes[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH] += sdu_buffer_sizeP;
            } else {
              Pdcp_stats_rx[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH]++;
              Pdcp_stats_rx_bytes[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH] += sdu_buffer_sizeP;
            }*/
      }
gauthier's avatar
gauthier committed
780 781
  }
#if defined(STOP_ON_IP_TRAFFIC_OVERLOAD)
782 783
else {
  AssertFatal(0, "[FRAME %5u][%s][PDCP][MOD %u/%u][RB %u] PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n",
784 785 786 787
        ctxt_pP->frame,
        (ctxt_pP->enb_flag) ? "eNB" : "UE",
        ctxt_pP->enb_module_id,
        ctxt_pP->ue_module_id,
788 789
        rb_id);
}
gauthier's avatar
gauthier committed
790
#endif
791

gauthier's avatar
gauthier committed
792
  free_mem_block(sdu_buffer_pP);
793 794
  if (ctxt_pP->enb_flag)
    stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].data_ind);
795
  else
796
    stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].data_ind);
797
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT);
798 799 800 801
  return TRUE;
}

//-----------------------------------------------------------------------------
802
void pdcp_run (const protocol_ctxt_t* const  ctxt_pP) {
803
  //-----------------------------------------------------------------------------
804
#if defined(ENABLE_ITTI)
805 806 807 808
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  int           result;
809
  protocol_ctxt_t  ctxt;
810
#endif
811 812
  if (ctxt_pP->enb_flag)
    start_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].pdcp_run);
813
  else
814
    start_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].pdcp_run);
815

816
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN);
817

818 819
#if defined(ENABLE_ITTI)
  do {
gauthier's avatar
gauthier committed
820
      // Checks if a message has been sent to PDCP sub-task
821
      itti_poll_msg (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p);
822

gauthier's avatar
gauthier committed
823 824 825
      if (msg_p != NULL) {
          msg_name = ITTI_MSG_NAME (msg_p);
          instance = ITTI_MSG_INSTANCE (msg_p);
826

gauthier's avatar
gauthier committed
827 828
          switch (ITTI_MSG_ID(msg_p)) {
          case RRC_DCCH_DATA_REQ:
829
            LOG_D(PDCP, "Received %s from %s: instance %d, frame %d, ctxt_pP->enb_flag %d, rb_id %d, muiP %d, confirmP %d, mode %d\n",
830
                msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
831 832 833
                RRC_DCCH_DATA_REQ (msg_p).frame, RRC_DCCH_DATA_REQ (msg_p).enb_flag, RRC_DCCH_DATA_REQ (msg_p).rb_id,
                RRC_DCCH_DATA_REQ (msg_p).muip, RRC_DCCH_DATA_REQ (msg_p).confirmp, RRC_DCCH_DATA_REQ (msg_p).mode);

834 835 836 837 838 839
            ctxt.enb_module_id = RRC_DCCH_DATA_REQ (msg_p).eNB_index;
            ctxt.ue_module_id  = RRC_DCCH_DATA_REQ (msg_p).ue_index;
            ctxt.frame         = RRC_DCCH_DATA_REQ (msg_p).frame;
            ctxt.enb_flag      = RRC_DCCH_DATA_REQ (msg_p).enb_flag;

            result = pdcp_data_req (&ctxt,
840 841 842 843 844 845 846
                SRB_FLAG_YES,
                RRC_DCCH_DATA_REQ (msg_p).rb_id,
                RRC_DCCH_DATA_REQ (msg_p).muip,
                RRC_DCCH_DATA_REQ (msg_p).confirmp,
                RRC_DCCH_DATA_REQ (msg_p).sdu_size,
                RRC_DCCH_DATA_REQ (msg_p).sdu_p,
                RRC_DCCH_DATA_REQ (msg_p).mode);
gauthier's avatar
gauthier committed
847
            AssertFatal (result == TRUE, "PDCP data request failed!\n");
848

gauthier's avatar
gauthier committed
849 850 851 852
            // Message buffer has been processed, free it now.
            result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ (msg_p).sdu_p);
            AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
            break;
853

gauthier's avatar
gauthier committed
854 855 856 857
          default:
            LOG_E(PDCP, "Received unexpected message %s\n", msg_name);
            break;
          }
858

gauthier's avatar
gauthier committed
859 860 861
          result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
          AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
      }
862
  } while(msg_p != NULL);
863 864 865

# if 0
  {
gauthier's avatar
gauthier committed
866
      MessageDef *msg_resp_p;
867

gauthier's avatar
gauthier committed
868
      msg_resp_p = itti_alloc_new_message(TASK_PDCP_ENB, MESSAGE_TEST);
869

gauthier's avatar
gauthier committed
870
      itti_send_msg_to_task(TASK_RRC_ENB, 1, msg_resp_p);
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886
  }
  {
    MessageDef *msg_resp_p;

    msg_resp_p = itti_alloc_new_message(TASK_PDCP_ENB, MESSAGE_TEST);

    itti_send_msg_to_task(TASK_ENB_APP, 2, msg_resp_p);
  }
  {
    MessageDef *msg_resp_p;

    msg_resp_p = itti_alloc_new_message(TASK_PDCP_ENB, MESSAGE_TEST);

    itti_send_msg_to_task(TASK_MAC_ENB, 3, msg_resp_p);
  }
# endif
887 888
#endif

889 890
#if defined(USER_MODE) && defined(OAI_EMU)
  pdcp_t            *pdcp_p          = NULL;
nikaeinn's avatar
nikaeinn committed
891 892 893 894
  int               drb_id=1 ;
  int               ue_id=0;
  int               read_otg=1;
    // add check for other rb_ids later
895 896
  if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
    if (pdcp_array_drb_ue[ctxt_pP->ue_module_id][drb_id-1].instanciated_instance  != TRUE )
nikaeinn's avatar
nikaeinn committed
897 898 899
      read_otg=0;
  } else {
    for (ue_id=0; ue_id < NB_UE_INST; ue_id++)
900
      if (pdcp_array_drb_eNB[ctxt_pP->enb_module_id][ue_id][drb_id-1].instanciated_instance  != TRUE ){
nikaeinn's avatar
nikaeinn committed
901 902
	read_otg =0;
	break;
903
      }
nikaeinn's avatar
nikaeinn committed
904 905
  }
  if (read_otg == 1 )
906
    pdcp_fifo_read_input_sdus_from_otg(ctxt_pP);
gauthier's avatar
gauthier committed
907
#endif
908 909

  // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer
gauthier's avatar
gauthier committed
910
#if defined(LINK_PDCP_TO_GTPV1U)
911
  if (ctxt_pP->enb_flag == ENB_FLAG_NO)
gauthier's avatar
gauthier committed
912
#endif
gauthier's avatar
gauthier committed
913
  {
914
      pdcp_fifo_read_input_sdus(ctxt_pP);
gauthier's avatar
gauthier committed
915
  }
916
  // PDCP -> NAS/IP traffic: RX
917 918
  if (ctxt_pP->enb_flag)
    start_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].pdcp_ip);
919
  else
920
    start_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].pdcp_ip);
gauthier's avatar
gauthier committed
921

922
  pdcp_fifo_flush_sdus(ctxt_pP);
923

924 925
  if (ctxt_pP->enb_flag)
    stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].pdcp_ip);
926
  else
927
    stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].pdcp_ip);
928

929 930
  if (ctxt_pP->enb_flag)
    stop_meas(&eNB_pdcp_stats[ctxt_pP->enb_module_id].pdcp_run);
931
  else
932
    stop_meas(&UE_pdcp_stats[ctxt_pP->ue_module_id].pdcp_run);
933

934 935
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT);

936 937
}

938
boolean_t pdcp_remove_UE(const protocol_ctxt_t* const  ctxt_pP) {
939