nr pdcp: pass MAC-I and header to upper layers
Needed by some RRC procedures to validate the integrity of a message before accepting it.
This commit is contained in:
@@ -55,6 +55,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
int sdap_header_size = 0;
|
int sdap_header_size = 0;
|
||||||
int rx_deliv_sn;
|
int rx_deliv_sn;
|
||||||
uint32_t rx_deliv_hfn;
|
uint32_t rx_deliv_hfn;
|
||||||
|
uint32_t mac = 0;
|
||||||
|
uint32_t header = 0;
|
||||||
|
|
||||||
if (entity->entity_suspended) {
|
if (entity->entity_suspended) {
|
||||||
LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id);
|
LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id);
|
||||||
@@ -121,6 +123,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
|
|
||||||
rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn;
|
rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn;
|
||||||
|
|
||||||
|
/* the MAC-I/header/rcvd_count is needed by some RRC procedures, store it */
|
||||||
|
if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
|
||||||
|
mac = (uint32_t)buffer[size-4]
|
||||||
|
| ((uint32_t)buffer[size-3] << 8)
|
||||||
|
| ((uint32_t)buffer[size-2] << 16)
|
||||||
|
| ((uint32_t)buffer[size-1] << 24);
|
||||||
|
|
||||||
|
/* higher byte of 'header' is its size, next 2 or 3 bytes are the header */
|
||||||
|
header = (uint32_t)header_size << 24;
|
||||||
|
if (header_size == 2)
|
||||||
|
header |= (buffer[0] << 16) | (buffer[1] << 8);
|
||||||
|
else
|
||||||
|
header |= (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
|
||||||
|
}
|
||||||
|
|
||||||
if (entity->has_ciphering)
|
if (entity->has_ciphering)
|
||||||
entity->cipher(entity->security_context,
|
entity->cipher(entity->security_context,
|
||||||
buffer + header_size + sdap_header_size,
|
buffer + header_size + sdap_header_size,
|
||||||
@@ -152,7 +169,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
|
|
||||||
sdu = nr_pdcp_new_sdu(rcvd_count,
|
sdu = nr_pdcp_new_sdu(rcvd_count,
|
||||||
(char *)buffer + header_size,
|
(char *)buffer + header_size,
|
||||||
size - header_size - integrity_size);
|
size - header_size - integrity_size,
|
||||||
|
mac, header);
|
||||||
entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu);
|
entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu);
|
||||||
entity->rx_size += size-header_size;
|
entity->rx_size += size-header_size;
|
||||||
|
|
||||||
@@ -168,7 +186,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
while (entity->rx_list != NULL && count == entity->rx_list->count) {
|
while (entity->rx_list != NULL && count == entity->rx_list->count) {
|
||||||
nr_pdcp_sdu_t *cur = entity->rx_list;
|
nr_pdcp_sdu_t *cur = entity->rx_list;
|
||||||
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
||||||
cur->buffer, cur->size);
|
cur->buffer, cur->size,
|
||||||
|
cur->mac, cur->header, cur->count);
|
||||||
entity->rx_list = cur->next;
|
entity->rx_list = cur->next;
|
||||||
entity->rx_size -= cur->size;
|
entity->rx_size -= cur->size;
|
||||||
entity->stats.txsdu_pkts++;
|
entity->stats.txsdu_pkts++;
|
||||||
@@ -358,7 +377,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
|
|||||||
while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) {
|
while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) {
|
||||||
nr_pdcp_sdu_t *cur = entity->rx_list;
|
nr_pdcp_sdu_t *cur = entity->rx_list;
|
||||||
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
||||||
cur->buffer, cur->size);
|
cur->buffer, cur->size,
|
||||||
|
cur->mac, cur->header, cur->count);
|
||||||
entity->rx_list = cur->next;
|
entity->rx_list = cur->next;
|
||||||
entity->rx_size -= cur->size;
|
entity->rx_size -= cur->size;
|
||||||
entity->stats.txsdu_pkts++;
|
entity->stats.txsdu_pkts++;
|
||||||
@@ -371,7 +391,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
|
|||||||
while (entity->rx_list != NULL && count == entity->rx_list->count) {
|
while (entity->rx_list != NULL && count == entity->rx_list->count) {
|
||||||
nr_pdcp_sdu_t *cur = entity->rx_list;
|
nr_pdcp_sdu_t *cur = entity->rx_list;
|
||||||
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
||||||
cur->buffer, cur->size);
|
cur->buffer, cur->size,
|
||||||
|
cur->mac, cur->header, cur->count);
|
||||||
entity->rx_list = cur->next;
|
entity->rx_list = cur->next;
|
||||||
entity->rx_size -= cur->size;
|
entity->rx_size -= cur->size;
|
||||||
entity->stats.txsdu_pkts++;
|
entity->stats.txsdu_pkts++;
|
||||||
@@ -401,7 +422,8 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity)
|
|||||||
while (entity->rx_list != NULL) {
|
while (entity->rx_list != NULL) {
|
||||||
nr_pdcp_sdu_t *cur = entity->rx_list;
|
nr_pdcp_sdu_t *cur = entity->rx_list;
|
||||||
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
entity->deliver_sdu(entity->deliver_sdu_data, entity,
|
||||||
cur->buffer, cur->size);
|
cur->buffer, cur->size,
|
||||||
|
cur->mac, cur->header, cur->count);
|
||||||
entity->rx_list = cur->next;
|
entity->rx_list = cur->next;
|
||||||
entity->rx_size -= cur->size;
|
entity->rx_size -= cur->size;
|
||||||
entity->stats.txsdu_pkts++;
|
entity->stats.txsdu_pkts++;
|
||||||
@@ -522,7 +544,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
|||||||
bool has_sdap_rx,
|
bool has_sdap_rx,
|
||||||
bool has_sdap_tx,
|
bool has_sdap_tx,
|
||||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
||||||
char *buf, int size),
|
char *buf, int size,
|
||||||
|
uint32_t mac, uint32_t header, uint32_t count),
|
||||||
void *deliver_sdu_data,
|
void *deliver_sdu_data,
|
||||||
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
||||||
char *buf, int size, int sdu_id),
|
char *buf, int size, int sdu_id),
|
||||||
|
|||||||
@@ -108,7 +108,8 @@ typedef struct nr_pdcp_entity_t {
|
|||||||
|
|
||||||
/* callbacks provided to the PDCP module */
|
/* callbacks provided to the PDCP module */
|
||||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
||||||
char *buf, int size);
|
char *buf, int size,
|
||||||
|
uint32_t mac, uint32_t header, uint32_t count);
|
||||||
void *deliver_sdu_data;
|
void *deliver_sdu_data;
|
||||||
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
||||||
char *buf, int size, int sdu_id);
|
char *buf, int size, int sdu_id);
|
||||||
@@ -179,7 +180,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
|||||||
bool has_sdap_rx,
|
bool has_sdap_rx,
|
||||||
bool has_sdap_tx,
|
bool has_sdap_tx,
|
||||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
||||||
char *buf, int size),
|
char *buf, int size,
|
||||||
|
uint32_t mac, uint32_t header, uint32_t count),
|
||||||
void *deliver_sdu_data,
|
void *deliver_sdu_data,
|
||||||
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
||||||
char *buf, int size, int sdu_id),
|
char *buf, int size, int sdu_id),
|
||||||
|
|||||||
@@ -658,7 +658,8 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||||
char *buf, int size)
|
char *buf, int size,
|
||||||
|
uint32_t mac, uint32_t header, uint32_t count)
|
||||||
{
|
{
|
||||||
nr_pdcp_ue_t *ue = _ue;
|
nr_pdcp_ue_t *ue = _ue;
|
||||||
int rb_id;
|
int rb_id;
|
||||||
@@ -741,7 +742,8 @@ static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
|
static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
|
||||||
char *buf, int size)
|
char *buf, int size,
|
||||||
|
uint32_t mac, uint32_t header, uint32_t count)
|
||||||
{
|
{
|
||||||
nr_pdcp_ue_t *ue = _ue;
|
nr_pdcp_ue_t *ue = _ue;
|
||||||
int srb_id;
|
int srb_id;
|
||||||
|
|||||||
@@ -24,7 +24,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size)
|
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size,
|
||||||
|
uint32_t mac, uint32_t header)
|
||||||
{
|
{
|
||||||
nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t));
|
nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t));
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
@@ -35,6 +36,8 @@ nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size)
|
|||||||
exit(1);
|
exit(1);
|
||||||
memcpy(ret->buffer, buffer, size);
|
memcpy(ret->buffer, buffer, size);
|
||||||
ret->size = size;
|
ret->size = size;
|
||||||
|
ret->mac = mac;
|
||||||
|
ret->header = header;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,20 @@ typedef struct nr_pdcp_sdu_t {
|
|||||||
uint32_t count;
|
uint32_t count;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int size;
|
int size;
|
||||||
|
uint32_t mac;
|
||||||
|
/* 'header' is decomposed into two parts: higher byte is the size of the
|
||||||
|
* header (2 or 3 bytes), then the next two or three bytes are the header
|
||||||
|
* so the size is: (header >> 24) & 0xff
|
||||||
|
* and first byte of header is: (header >> 16) & 0xff
|
||||||
|
* second byte of header is: (header >> 8) & 0xff
|
||||||
|
* and if there is a third, it is: header & 0xff
|
||||||
|
*/
|
||||||
|
uint32_t header;
|
||||||
struct nr_pdcp_sdu_t *next;
|
struct nr_pdcp_sdu_t *next;
|
||||||
} nr_pdcp_sdu_t;
|
} nr_pdcp_sdu_t;
|
||||||
|
|
||||||
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size);
|
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size,
|
||||||
|
uint32_t mac, uint32_t header);
|
||||||
nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu);
|
nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu);
|
||||||
int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count);
|
int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count);
|
||||||
void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);
|
void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);
|
||||||
|
|||||||
Reference in New Issue
Block a user