pdcp.h 15.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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 63 64 65 66 67 68 69 70 71 72 73 74
/*******************************************************************************

  Eurecom OpenAirInterface
  Copyright(c) 1999 - 2011 Eurecom

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope 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.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information
  Openair Admin: openair_admin@eurecom.fr
  Openair Tech : openair_tech@eurecom.fr
  Forums       : http://forums.eurecom.fsr/openairinterface
  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France

*******************************************************************************/

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

#ifndef __PDCP_H__
#    define __PDCP_H__
//-----------------------------------------------------------------------------
#    ifdef PDCP_C
#        define private_pdcp(x) x
#        define protected_pdcp(x) x
#        define public_pdcp(x) x
#    else
#        define private_pdcp(x)
#        define public_pdcp(x) extern x
#        ifdef PDCP_FIFO_C
#            define protected_pdcp(x) extern x
#        else
#            define protected_pdcp(x)
#        endif
#    endif

#    ifdef PDCP_FIFO_C
#        define private_pdcp_fifo(x) x
#        define protected_pdcp_fifo(x) x
#        define public_pdcp_fifo(x) x
#    else
#        define private_pdcp_fifo(x)
#        define public_pdcp_fifo(x) extern x
#        ifdef PDCP_C
#            define protected_pdcp_fifo(x) extern x
#        else
#            define protected_pdcp_fifo(x)
#        endif
#    endif
//-----------------------------------------------------------------------------
#ifndef NON_ACCESS_STRATUM
  #include "UTIL/MEM/mem_block.h"
  #include "UTIL/LISTS/list.h"
  #include "COMMON/mac_rrc_primitives.h"
#endif //NON_ACCESS_STRATUM
//-----------------------------------------------------------------------------
#include "COMMON/platform_constants.h"
75
#include "COMMON/platform_types.h"
76 77 78 79 80 81 82 83 84
#include "DRB-ToAddMod.h"
#include "DRB-ToAddModList.h"
#include "SRB-ToAddMod.h"
#include "SRB-ToAddModList.h"
#ifdef Rel10
#include "MBMS-SessionInfoList-r9.h"
#include "PMCH-InfoList-r9.h"
#endif

85
#ifndef FALSE
86
#define FALSE (0x00)
87 88
#endif
#ifndef TRUE
89
#define TRUE  !(FALSE)
90
#endif
91 92 93 94 95 96 97

extern pthread_t pdcp_thread;
extern pthread_attr_t pdcp_thread_attr;
extern pthread_mutex_t pdcp_mutex;
extern pthread_cond_t pdcp_cond;
extern int pdcp_instance_cnt;

98
int init_pdcp_thread(void);
99 100
void cleanup_pdcp_thread(void);

101 102 103 104 105 106 107 108 109 110 111 112 113 114
typedef unsigned char BOOL;

public_pdcp(unsigned int Pdcp_stats_tx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_tx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_tx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_tx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);
public_pdcp(unsigned int Pdcp_stats_rx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]);

typedef struct pdcp_t {
  BOOL instanciated_instance;
  u16  header_compression_profile;
115

116 117 118 119 120 121
  /* SR: added this flag to distinguish UE/eNB instance as pdcp_run for virtual
   * mode can receive data on NETLINK for eNB while eNB_flag = 0 and for UE when eNB_flag = 1
   */
  u8 is_ue;

  /* Configured security algorithms */
122 123
  u8 cipheringAlgorithm;
  u8 integrityProtAlgorithm;
124

125 126 127 128 129 130 131 132 133 134 135
  /* User-Plane encryption key
   * Control-Plane RRC encryption key
   * Control-Plane RRC integrity key
   * These keys are configured by RRC layer
   */
  u8 *kUPenc;
  u8 *kRRCint;
  u8 *kRRCenc;

  u8 security_activated;

136
  u8 rlc_mode;
137 138 139
  u8 status_report;
  u8 seq_num_size;

140
  u8 lcid;
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
  /*
   * Sequence number state variables
   *
   * TX and RX window
   */
  u16  next_pdcp_tx_sn;
  u16  next_pdcp_rx_sn;
  /*
   * TX and RX Hyper Frame Numbers
   */
  u16  tx_hfn;
  u16  rx_hfn;
  /*
   * SN of the last PDCP SDU delivered to upper layers
   */
  u16  last_submitted_pdcp_rx_sn;

  /*
   * Following array is used as a bitmap holding missing sequence
   * numbers to generate a PDCP Control PDU for PDCP status
   * report (see 6.2.6)
   */
  u8 missing_pdu_bitmap[512];
  /*
   * This is intentionally signed since we need a 'NULL' value
   * which is not also a valid sequence number
   */
  short int first_missing_pdu;
} pdcp_t;

typedef struct pdcp_mbms_t {
  BOOL instanciated_instance;
173 174

  uint16_t service_id;
175 176
  uint32_t session_id; // lcid

177 178
  uint16_t rb_id;

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
} pdcp_mbms_t;
/*
 * Following symbolic constant alters the behaviour of PDCP
 * and makes it linked to PDCP test code under targets/TEST/PDCP/
 *
 * For the version at SVN repository this should be UNDEFINED!
 * XXX And later this should be configured through the Makefile
 * under targets/TEST/PDCP/
 */

/*! \fn BOOL pdcp_data_req(module_id_t, u32_t, u8_t, rb_id_t, sdu_size_t, unsigned char*)
* \brief This functions handles data transfer requests coming either from RRC or from IP
* \param[in] module_id Module ID
* \param[in] frame Frame number
* \param[in] Shows if relevant PDCP entity is part of an eNB or a UE
* \param[in] rab_id Radio Bearer ID
195
* \param[in] muiP
196 197 198
* \param[in] confirmP
* \param[in] sdu_buffer_size Size of incoming SDU in bytes
* \param[in] sdu_buffer Buffer carrying SDU
199
* \param[in] mode flag to indicate whether the userplane data belong to the control plane or data plane or transparent
200 201 202 203
* \return TRUE on success, FALSE otherwise
* \note None
* @ingroup _pdcp
*/
gauthier's avatar
gauthier committed
204
public_pdcp(BOOL pdcp_data_req(module_id_t eNB_id, module_id_t UE_id, frame_t frame, eNB_flag_t eNB_flag, rb_id_t rb_id, mui_t muiP, u32 confirmP, \
205
    sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer, u8 mode));
206

gauthier's avatar
gauthier committed
207
/*! \fn BOOL pdcp_data_ind(module_id_t, module_id_t, u32_t, u8_t, u8_t, rb_id_t, sdu_size_t, unsigned char*)
208 209 210 211 212 213 214 215 216 217 218 219 220
* \brief This functions handles data transfer indications coming from RLC
* \param[in] module_id Module ID
* \param[in] frame Frame number
* \param[in] Shows if relevant PDCP entity is part of an eNB or a UE
* \param[in] Tells if MBMS traffic
* \param[in] rab_id Radio Bearer ID
* \param[in] sdu_buffer_size Size of incoming SDU in bytes
* \param[in] sdu_buffer Buffer carrying SDU
* \param[in] is_data_plane flag to indicate whether the userplane data belong to the control plane or data plane
* \return TRUE on success, FALSE otherwise
* \note None
* @ingroup _pdcp
*/
gauthier's avatar
gauthier committed
221
public_pdcp(BOOL pdcp_data_ind(module_id_t eNB_id, module_id_t UE_id, frame_t frame, eNB_flag_t eNB_flag, u8_t MBMS_flagP, rb_id_t rb_id, sdu_size_t sdu_buffer_size,
222
                   mem_block_t* sdu_buffer, u8 is_data_plane));
223 224 225 226

/*! \fn void rrc_pdcp_config_req(module_id_t, rb_id_t,u8)
* \brief This functions initializes relevant PDCP entity
* \param[in] module_id Module ID of relevant PDCP entity
227
* \param[in] frame frame counter (TTI)
228 229 230 231 232 233
* \param[in] eNB_flag flag indicating the node type
* \param[in] action flag for action: add, remove , modify
* \param[in] rab_id Radio Bearer ID of relevant PDCP entity
* \return none
* \note None
* @ingroup _pdcp
234
*/
gauthier's avatar
gauthier committed
235 236 237 238 239 240 241 242 243
public_pdcp(void rrc_pdcp_config_req (module_id_t enb_idP,
                                      module_id_t ue_idP,
                                      frame_t     frameP,
                                      eNB_flag_t  eNB_flagP,
                                      u32         actionP,
                                      rb_id_t     rb_idP,
                                      u8          security_modeP);)

/*! \fn bool rrc_pdcp_config_asn1_req (module_id_t module_id, frame_t frame, eNB_flag_t eNB_flag, SRB_ToAddModList_t* srb2add_list, DRB_ToAddModList_t* drb2add_list, DRB_ToReleaseList_t*  drb2release_list)
244 245 246 247 248 249 250 251
* \brief  Function for RRC to configure a Radio Bearer.
* \param[in]  module_id         Virtualized module identifier.
* \param[in]  frame              Frame index.
* \param[in]  eNB_flag           Flag to indicate eNB (1) or UE (0)
* \param[in]  index             index of UE or eNB depending on the eNB_flag
* \param[in]  srb2add_list      SRB configuration list to be created.
* \param[in]  drb2add_list      DRB configuration list to be created.
* \param[in]  drb2release_list  DRB configuration list to be released.
252 253 254 255
* \param[in]  security_mode     Security algorithm to apply for integrity/ciphering
* \param[in]  kRRCenc           RRC encryption key
* \param[in]  kRRCint           RRC integrity key
* \param[in]  kUPenc            User-Plane encryption key
256 257
* \return     A status about the processing, OK or error code.
*/
258
public_pdcp(
gauthier's avatar
gauthier committed
259 260 261 262 263 264 265 266 267 268 269
BOOL rrc_pdcp_config_asn1_req (module_id_t          eNB_idP,
                               module_id_t          ue_idP,
                               frame_t              frameP,
                               eNB_flag_t           eNB_flagP,
                               SRB_ToAddModList_t  *srb2add_list,
                               DRB_ToAddModList_t  *drb2add_list,
                               DRB_ToReleaseList_t *drb2release_list,
                               u8                   security_modeP,
                               u8                  *kRRCenc,
                               u8                  *kRRCint,
                               u8                  *kUPenc
270
#ifdef Rel10
gauthier's avatar
gauthier committed
271
                              ,PMCH_InfoList_r9_t  *pmch_InfoList_r9
272
#endif
273
                               ));
274

gauthier's avatar
gauthier committed
275
/*! \fn BOOL pdcp_config_req_asn1 (module_id_t module_id, frame_t frame, eNB_flag_t eNB_flag, u32  action, rb_id_t rb_id, u8 rb_sn, u8 rb_report, u16 header_compression_profile, u8 security_mode)
276 277 278 279 280 281 282 283 284 285
* \brief  Function for RRC to configure a Radio Bearer.
* \param[in]  module_id         Virtualized module identifier.
* \param[in]  frame              Frame index.
* \param[in]  eNB_flag           Flag to indicate eNB (1) or UE (0)
* \param[in]  action             add, remove, modify a RB
* \param[in]  rb_id              radio bearer id
* \param[in]  rb_sn              sequence number for this radio bearer
* \param[in]  drb_report         set a pdcp report for this drb
* \param[in]  header_compression set the rohc profile
* \param[in]  security_mode      set the integrity and ciphering algs
286 287 288
* \param[in]  kRRCenc            RRC encryption key
* \param[in]  kRRCint            RRC integrity key
* \param[in]  kUPenc             User-Plane encryption key
289 290
* \return     A status about the processing, OK or error code.
*/
gauthier's avatar
gauthier committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
public_pdcp(BOOL pdcp_config_req_asn1 (pdcp_t      *pdcp_pP,
                                       module_id_t enb_idP,
                                       module_id_t ue_idP,
                                       frame_t     frameP,
                                       eNB_flag_t  eNB_flagP,
                                       rlc_mode_t  rlc_mode,
                                       u32         action,
                                       u16         lc_id,
                                       u16         mch_id,
                                       rb_id_t     rb_id,
                                       u8          rb_sn,
                                       u8          rb_report,
                                       u16         header_compression_profile,
                                       u8          security_mode,
                                       u8         *kRRCenc,
                                       u8         *kRRCint,
                                       u8         *kUPenc));
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
/*! \fn void rrc_pdcp_config_release(module_id_t, rb_id_t)
* \brief This functions is unused
* \param[in] module_id Module ID of relevant PDCP entity
* \param[in] rab_id Radio Bearer ID of relevant PDCP entity
* \return none
* \note None
* @ingroup _pdcp
*/
//public_pdcp(void rrc_pdcp_config_release (module_id_t, rb_id_t);)

/*! \fn void pdcp_run(u32_t, u8_t)
* \brief Runs PDCP entity to let it handle incoming/outgoing SDUs
* \param[in] frame Frame number
* \param[in] eNB_flag Indicates if this PDCP entity belongs to an eNB or to a UE
* \return none
* \note None
* @ingroup _pdcp
*/
gauthier's avatar
gauthier committed
326 327 328 329 330 331
public_pdcp(void pdcp_run            (frame_t frameP, eNB_flag_t eNB_flagP, module_id_t ue_mod_idP, module_id_t enb_mod_idP);)
public_pdcp(int pdcp_module_init     (void);)
public_pdcp(void pdcp_module_cleanup (void);)
public_pdcp(void pdcp_layer_init     (void);)
public_pdcp(void pdcp_layer_cleanup  (void);)
public_pdcp(int pdcp_netlink_init    (void);)
332 333 334 335

#define PDCP2NAS_FIFO 21
#define NAS2PDCP_FIFO 22

gauthier's avatar
gauthier committed
336 337 338 339
protected_pdcp_fifo(int pdcp_fifo_flush_sdus                      (frame_t frameP, eNB_flag_t eNB_flagP, module_id_t enb_idP, module_id_t ue_mod_idP);)
protected_pdcp_fifo(int pdcp_fifo_read_input_sdus_remaining_bytes (frame_t frameP, eNB_flag_t eNB_flagP);)
protected_pdcp_fifo(int pdcp_fifo_read_input_sdus                 (frame_t frameP, eNB_flag_t eNB_flagP, module_id_t ue_mod_idP, module_id_t enb_mod_idP);)
protected_pdcp_fifo(void pdcp_fifo_read_input_sdus_from_otg       (frame_t frameP, eNB_flag_t eNB_flagP, module_id_t ue_mod_idP, module_id_t enb_mod_idP);)
340 341 342 343 344 345

//-----------------------------------------------------------------------------

/*
 * Following two types are utilized between NAS driver and PDCP
 */
346 347 348


typedef struct pdcp_data_req_header_s {
349
  rb_id_t             rb_id;
350
  sdu_size_t          data_size;
gauthier's avatar
gauthier committed
351
  signed int          inst;
352
  traffic_type_t      traffic_type;
353
} pdcp_data_req_header_t;
354 355

typedef struct pdcp_data_ind_header_s {
356
  rb_id_t             rb_id;
357
  sdu_size_t          data_size;
gauthier's avatar
gauthier committed
358 359
  signed int          inst;
  traffic_type_t      dummy_traffic_type;
360 361
} pdcp_data_ind_header_t;

362 363 364 365 366 367 368
struct pdcp_netlink_element_s {
    pdcp_data_req_header_t pdcp_read_header;

    /* Data part of the message */
    uint8_t *data;
};

369 370
#if 0
/*
371
 * Missing PDU information struct, a copy of this will be enqueued
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
 * into pdcp.missing_pdus for every missing PDU
 */
typedef struct pdcp_missing_pdu_info_t {
  u16 sequence_number;
} pdcp_missing_pdu_info_t;
#endif

/*
 * PDCP limit values
 */
#define PDCP_MAX_SDU_SIZE 8188 // octets, see 4.3.1 Services provided to upper layers
#define PDCP_MAX_SN_5BIT  31   // 2^5-1
#define PDCP_MAX_SN_7BIT  127  // 2^7-1
#define PDCP_MAX_SN_12BIT 4095 // 2^12-1

protected_pdcp(signed int             pdcp_2_nas_irq;)
388 389
protected_pdcp(pdcp_t                 pdcp_array_ue[NUMBER_OF_UE_MAX][NB_RB_MAX];)
protected_pdcp(pdcp_t                 pdcp_array_eNB[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][NB_RB_MAX];)
gauthier's avatar
gauthier committed
390 391
public_pdcp(pdcp_mbms_t               pdcp_mbms_array_ue[NUMBER_OF_UE_MAX][16*29];) // MAX_SERVICEx MAX_SESSION
public_pdcp(pdcp_mbms_t               pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][16*29];) // MAX_SERVICEx MAX_SESSION
392 393 394 395 396 397 398 399 400 401 402
protected_pdcp(sdu_size_t             pdcp_output_sdu_bytes_to_write;)
protected_pdcp(sdu_size_t             pdcp_output_header_bytes_to_write;)
protected_pdcp(list_t                 pdcp_sdu_list;)
protected_pdcp(int                    pdcp_sent_a_sdu;)
protected_pdcp(pdcp_data_req_header_t pdcp_input_header;)
protected_pdcp(unsigned char          pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];)
protected_pdcp(sdu_size_t             pdcp_input_index_header;)
protected_pdcp(sdu_size_t             pdcp_input_sdu_size_read;)
protected_pdcp(sdu_size_t             pdcp_input_sdu_remaining_size_to_read;)

#endif