diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 374d1cfd55..a90be5f7f0 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -55,6 +55,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, int sdap_header_size = 0; int rx_deliv_sn; uint32_t rx_deliv_hfn; + uint32_t mac = 0; + uint32_t header = 0; if (entity->entity_suspended) { 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; + /* 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) entity->cipher(entity->security_context, 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, (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_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) { nr_pdcp_sdu_t *cur = entity->rx_list; 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_size -= cur->size; 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) { nr_pdcp_sdu_t *cur = entity->rx_list; 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_size -= cur->size; 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) { nr_pdcp_sdu_t *cur = entity->rx_list; 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_size -= cur->size; entity->stats.txsdu_pkts++; @@ -401,7 +422,8 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity) while (entity->rx_list != NULL) { nr_pdcp_sdu_t *cur = entity->rx_list; 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_size -= cur->size; entity->stats.txsdu_pkts++; @@ -522,7 +544,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( bool has_sdap_rx, bool has_sdap_tx, 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_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 82f701f037..94689eac76 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -108,7 +108,8 @@ typedef struct nr_pdcp_entity_t { /* callbacks provided to the PDCP module */ 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_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_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_tx, 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_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 8d3ce255e3..e1d659b3d4 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -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, - char *buf, int size) + char *buf, int size, + uint32_t mac, uint32_t header, uint32_t count) { nr_pdcp_ue_t *ue = _ue; 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, - char *buf, int size) + char *buf, int size, + uint32_t mac, uint32_t header, uint32_t count) { nr_pdcp_ue_t *ue = _ue; int srb_id; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c index 47d95156e3..48af4b945a 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c @@ -24,7 +24,8 @@ #include #include -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)); if (ret == NULL) @@ -35,6 +36,8 @@ nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size) exit(1); memcpy(ret->buffer, buffer, size); ret->size = size; + ret->mac = mac; + ret->header = header; return ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h index 3d4e50a4ce..91d63fefe1 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h @@ -28,10 +28,20 @@ typedef struct nr_pdcp_sdu_t { uint32_t count; char *buffer; 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; } 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); int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count); void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);