Commit 90dffd46 authored by Guido Casati's avatar Guido Casati Committed by sagar arora

Define for PDCP Formats

- short and long SN sizes
- PDCP PDU header sizes
- PDCP integrity size
- getter for maximim PDCP PDU size
parent cbffb10e
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
*/ */
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "nr_pdcp_entity.h"
int decode_t_reordering(int v) int decode_t_reordering(int v)
{ {
...@@ -36,16 +37,16 @@ int decode_t_reordering(int v) ...@@ -36,16 +37,16 @@ int decode_t_reordering(int v)
int decode_sn_size_ul(long s) int decode_sn_size_ul(long s)
{ {
if (s == 0) return 12; if (s == 0) return SHORT_SN_SIZE;
if (s == 1) return 18; if (s == 1) return LONG_SN_SIZE;
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1); exit(1);
} }
int decode_sn_size_dl(long s) int decode_sn_size_dl(long s)
{ {
if (s == 0) return 12; if (s == 0) return SHORT_SN_SIZE;
if (s == 1) return 18; if (s == 1) return LONG_SN_SIZE;
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1); exit(1);
} }
......
...@@ -32,6 +32,16 @@ ...@@ -32,6 +32,16 @@
#include "LOG/log.h" #include "LOG/log.h"
/**
* @brief returns the maximum PDCP PDU size
* which corresponds to data PDU for DRBs with 18 bits PDCP SN
* and integrity enabled
*/
int nr_max_pdcp_pdu_size(sdu_size_t sdu_size)
{
return (sdu_size + LONG_PDCP_HEADER_SIZE + PDCP_INTEGRITY_SIZE);
}
static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
char *_buffer, int size) char *_buffer, int size)
{ {
...@@ -65,21 +75,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -65,21 +75,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
if (entity->has_sdap_rx) sdap_header_size = 1; // SDAP Header is one byte if (entity->has_sdap_rx) sdap_header_size = 1; // SDAP Header is one byte
if (entity->sn_size == 12) { if (entity->sn_size == SHORT_SN_SIZE) {
rcvd_sn = ((buffer[0] & 0xf) << 8) | rcvd_sn = ((buffer[0] & 0xf) << 8) |
buffer[1]; buffer[1];
header_size = 2; header_size = SHORT_PDCP_HEADER_SIZE;
} else { } else {
rcvd_sn = ((buffer[0] & 0x3) << 16) | rcvd_sn = ((buffer[0] & 0x3) << 16) |
(buffer[1] << 8) | (buffer[1] << 8) |
buffer[2]; buffer[2];
header_size = 3; header_size = LONG_PDCP_HEADER_SIZE;
} }
entity->stats.rxpdu_sn = rcvd_sn; entity->stats.rxpdu_sn = rcvd_sn;
/* SRBs always have MAC-I, even if integrity is not active */ /* SRBs always have MAC-I, even if integrity is not active */
if (entity->has_integrity || entity->type == NR_PDCP_SRB) { if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
integrity_size = 4; integrity_size = PDCP_INTEGRITY_SIZE;
} else { } else {
integrity_size = 0; integrity_size = 0;
} }
...@@ -113,11 +123,11 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -113,11 +123,11 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1); entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
if (entity->has_integrity) { if (entity->has_integrity) {
unsigned char integrity[4] = {0}; unsigned char integrity[PDCP_INTEGRITY_SIZE] = {0};
entity->integrity(entity->integrity_context, integrity, entity->integrity(entity->integrity_context, integrity,
buffer, size - integrity_size, buffer, size - integrity_size,
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1); entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) { if (memcmp(integrity, buffer + size - integrity_size, PDCP_INTEGRITY_SIZE) != 0) {
LOG_E(PDCP, "discard NR PDU, integrity failed\n"); LOG_E(PDCP, "discard NR PDU, integrity failed\n");
entity->stats.rxpdu_dd_pkts++; entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size; entity->stats.rxpdu_dd_bytes += size;
...@@ -189,7 +199,7 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, ...@@ -189,7 +199,7 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
int integrity_size; int integrity_size;
int sdap_header_size = 0; int sdap_header_size = 0;
char *buf = pdu_buffer; char *buf = pdu_buffer;
DevAssert(size + 3 + 4 <= pdu_max_size); DevAssert(nr_max_pdcp_pdu_size(size) <= pdu_max_size);
int dc_bit; int dc_bit;
entity->stats.rxsdu_pkts++; entity->stats.rxsdu_pkts++;
entity->stats.rxsdu_bytes += size; entity->stats.rxsdu_bytes += size;
...@@ -207,20 +217,20 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, ...@@ -207,20 +217,20 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
dc_bit = 0; dc_bit = 0;
} }
if (entity->sn_size == 12) { if (entity->sn_size == SHORT_SN_SIZE) {
buf[0] = dc_bit | ((sn >> 8) & 0xf); buf[0] = dc_bit | ((sn >> 8) & 0xf);
buf[1] = sn & 0xff; buf[1] = sn & 0xff;
header_size = 2; header_size = SHORT_PDCP_HEADER_SIZE;
} else { } else {
buf[0] = dc_bit | ((sn >> 16) & 0x3); buf[0] = dc_bit | ((sn >> 16) & 0x3);
buf[1] = (sn >> 8) & 0xff; buf[1] = (sn >> 8) & 0xff;
buf[2] = sn & 0xff; buf[2] = sn & 0xff;
header_size = 3; header_size = LONG_PDCP_HEADER_SIZE;
} }
/* SRBs always have MAC-I, even if integrity is not active */ /* SRBs always have MAC-I, even if integrity is not active */
if (entity->has_integrity || entity->type == NR_PDCP_SRB) { if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
integrity_size = 4; integrity_size = PDCP_INTEGRITY_SIZE;
} else { } else {
integrity_size = 0; integrity_size = 0;
} }
...@@ -228,16 +238,16 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, ...@@ -228,16 +238,16 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
memcpy(buf + header_size, buffer, size); memcpy(buf + header_size, buffer, size);
if (entity->has_integrity) { if (entity->has_integrity) {
uint8_t integrity[4] = {0}; uint8_t integrity[PDCP_INTEGRITY_SIZE] = {0};
entity->integrity(entity->integrity_context, entity->integrity(entity->integrity_context,
integrity, integrity,
(unsigned char *)buf, header_size + size, (unsigned char *)buf, header_size + size,
entity->rb_id, count, entity->is_gnb ? 1 : 0); entity->rb_id, count, entity->is_gnb ? 1 : 0);
memcpy((unsigned char *)buf + header_size + size, integrity, 4); memcpy((unsigned char *)buf + header_size + size, integrity, PDCP_INTEGRITY_SIZE);
} else if (integrity_size == 4) { } else if (integrity_size == PDCP_INTEGRITY_SIZE) {
// set MAC-I to 0 for SRBs with integrity not active // set MAC-I to 0 for SRBs with integrity not active
memset(buf + header_size + size, 0, 4); memset(buf + header_size + size, 0, PDCP_INTEGRITY_SIZE);
} }
if (entity->has_ciphering && (entity->is_gnb || entity->security_mode_completed)) { if (entity->has_ciphering && (entity->is_gnb || entity->security_mode_completed)) {
......
...@@ -29,6 +29,18 @@ ...@@ -29,6 +29,18 @@
#include "nr_pdcp_sdu.h" #include "nr_pdcp_sdu.h"
#include "openair2/RRC/NR/rrc_gNB_radio_bearers.h" #include "openair2/RRC/NR/rrc_gNB_radio_bearers.h"
/* PDCP Formats according to clause 6.2 of 3GPP TS 38.323 */
/* SN Size applicable to SRBs, UM DRBs and AM DRBs */
#define SHORT_SN_SIZE 12
/* SN Size applicable to UM DRBs and AM DRBs */
#define LONG_SN_SIZE 18
/* Data PDU for SRBs and DRBs with 12 bits PDCP SN (unit: byte) */
#define SHORT_PDCP_HEADER_SIZE 2
/* Data PDU for DRBs with 18 bits PDCP SN (unit: byte) */
#define LONG_PDCP_HEADER_SIZE 3
/* MAC-I size (unit: byte) */
#define PDCP_INTEGRITY_SIZE 4
typedef enum { typedef enum {
NR_PDCP_DRB_AM, NR_PDCP_DRB_AM,
NR_PDCP_DRB_UM, NR_PDCP_DRB_UM,
...@@ -190,4 +202,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -190,4 +202,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
unsigned char *ciphering_key, unsigned char *ciphering_key,
unsigned char *integrity_key); unsigned char *integrity_key);
/* Get maximum PDCP PDU size */
int nr_max_pdcp_pdu_size(sdu_size_t sdu_size);
#endif /* _NR_PDCP_ENTITY_H_ */ #endif /* _NR_PDCP_ENTITY_H_ */
...@@ -817,10 +817,19 @@ void add_srb(int is_gnb, ...@@ -817,10 +817,19 @@ void add_srb(int is_gnb,
if (nr_pdcp_get_rb(ue, srb_id, true) != NULL) { if (nr_pdcp_get_rb(ue, srb_id, true) != NULL) {
LOG_E(PDCP, "warning SRB %d already exist for UE ID %ld, do nothing\n", srb_id, UEid); LOG_E(PDCP, "warning SRB %d already exist for UE ID %ld, do nothing\n", srb_id, UEid);
} else { } else {
pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id, pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB,
0, false, false, // sdap parameters is_gnb,
deliver_sdu_srb, ue, NULL, ue, srb_id,
12, t_Reordering, -1, 0, // PDU session ID (not relevant)
false, // has SDAP RX (not relevant)
false, // has SDAP TX (not relevant)
deliver_sdu_srb,
ue,
NULL,
ue,
SHORT_SN_SIZE,
t_Reordering,
-1,
ciphering_algorithm, ciphering_algorithm,
integrity_algorithm, integrity_algorithm,
ciphering_key, ciphering_key,
...@@ -1075,7 +1084,7 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, ...@@ -1075,7 +1084,7 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id,
return 0; return 0;
} }
int max_size = sdu_buffer_size + 3 + 4; // 3: max header, 4: max integrity int max_size = nr_max_pdcp_pdu_size(sdu_buffer_size);
char pdu_buf[max_size]; char pdu_buf[max_size];
int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size); int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size);
AssertFatal(rb->deliver_pdu == NULL, "SRB callback should be NULL, to be provided on every invocation\n"); AssertFatal(rb->deliver_pdu == NULL, "SRB callback should be NULL, to be provided on every invocation\n");
...@@ -1257,7 +1266,7 @@ bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, ...@@ -1257,7 +1266,7 @@ bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP,
return 0; return 0;
} }
int max_size = sdu_buffer_size + 3 + 4; // 3: max header, 4: max integrity int max_size = nr_max_pdcp_pdu_size(sdu_buffer_size);
char pdu_buf[max_size]; char pdu_buf[max_size];
int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size); int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size);
deliver_pdu deliver_pdu_cb = rb->deliver_pdu; deliver_pdu deliver_pdu_cb = rb->deliver_pdu;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment