Merge remote-tracking branch 'origin/nr-pdcp-improvements' into integration_2021_wk10
This commit is contained in:
@@ -1967,7 +1967,8 @@ set(NR_PDCP_SRC
|
|||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c
|
||||||
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
|
||||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
|
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -364,7 +364,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
|||||||
/* send tick to RLC and RRC every ms */
|
/* send tick to RLC and RRC every ms */
|
||||||
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
|
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
|
||||||
void nr_rlc_tick(int frame, int subframe);
|
void nr_rlc_tick(int frame, int subframe);
|
||||||
|
void nr_pdcp_tick(int frame, int subframe);
|
||||||
nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
|
nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||||
|
nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||||
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
|
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,24 +21,222 @@
|
|||||||
|
|
||||||
#include "nr_pdcp_entity.h"
|
#include "nr_pdcp_entity.h"
|
||||||
|
|
||||||
#include "nr_pdcp_entity_drb_am.h"
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "nr_pdcp_security_nea2.h"
|
#include "nr_pdcp_security_nea2.h"
|
||||||
|
#include "nr_pdcp_sdu.h"
|
||||||
|
|
||||||
#include "LOG/log.h"
|
#include "LOG/log.h"
|
||||||
|
|
||||||
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
|
static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||||
int is_gnb, int rb_id,
|
char *_buffer, int size)
|
||||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
|
||||||
char *buf, int size),
|
|
||||||
void *deliver_sdu_data,
|
|
||||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
|
||||||
char *buf, int size, int sdu_id),
|
|
||||||
void *deliver_pdu_data)
|
|
||||||
{
|
{
|
||||||
abort();
|
unsigned char *buffer = (unsigned char *)_buffer;
|
||||||
|
nr_pdcp_sdu_t *sdu;
|
||||||
|
int rcvd_sn;
|
||||||
|
uint32_t rcvd_hfn;
|
||||||
|
uint32_t rcvd_count;
|
||||||
|
int header_size;
|
||||||
|
int integrity_size;
|
||||||
|
int rx_deliv_sn;
|
||||||
|
uint32_t rx_deliv_hfn;
|
||||||
|
|
||||||
|
if (size < 1) {
|
||||||
|
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(buffer[0] & 0x80)) {
|
||||||
|
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->sn_size == 12) {
|
||||||
|
rcvd_sn = (((unsigned char)buffer[0] & 0xf) << 8) |
|
||||||
|
(unsigned char)buffer[1];
|
||||||
|
header_size = 2;
|
||||||
|
} else {
|
||||||
|
rcvd_sn = (((unsigned char)buffer[0] & 0x3) << 16) |
|
||||||
|
((unsigned char)buffer[1] << 8) |
|
||||||
|
(unsigned char)buffer[2];
|
||||||
|
header_size = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
integrity_size = 0;
|
||||||
|
|
||||||
|
if (size < header_size + integrity_size + 1) {
|
||||||
|
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rx_deliv_sn = entity->rx_deliv & entity->sn_max;
|
||||||
|
rx_deliv_hfn = (entity->rx_deliv >> entity->sn_size) & ~entity->sn_max;
|
||||||
|
|
||||||
|
if (rcvd_sn < rx_deliv_sn - entity->window_size) {
|
||||||
|
rcvd_hfn = rx_deliv_hfn + 1;
|
||||||
|
} else if (rcvd_sn >= rx_deliv_sn + entity->window_size) {
|
||||||
|
rcvd_hfn = rx_deliv_hfn - 1;
|
||||||
|
} else {
|
||||||
|
rcvd_hfn = rx_deliv_hfn;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn;
|
||||||
|
|
||||||
|
if (entity->has_ciphering)
|
||||||
|
entity->cipher(entity->security_context,
|
||||||
|
(unsigned char *)buffer+header_size, size-header_size,
|
||||||
|
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
|
||||||
|
|
||||||
|
if (rcvd_count < entity->rx_deliv
|
||||||
|
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
|
||||||
|
LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdu = nr_pdcp_new_sdu(rcvd_count,
|
||||||
|
(char *)buffer + header_size,
|
||||||
|
size - header_size - integrity_size);
|
||||||
|
entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu);
|
||||||
|
entity->rx_size += size-header_size;
|
||||||
|
|
||||||
|
if (rcvd_count >= entity->rx_next) {
|
||||||
|
entity->rx_next = rcvd_count + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO(?): out of order delivery */
|
||||||
|
|
||||||
|
if (rcvd_count == entity->rx_deliv) {
|
||||||
|
/* deliver all SDUs starting from rx_deliv up to discontinuity or end of list */
|
||||||
|
uint32_t count = entity->rx_deliv;
|
||||||
|
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);
|
||||||
|
entity->rx_list = cur->next;
|
||||||
|
entity->rx_size -= cur->size;
|
||||||
|
nr_pdcp_free_sdu(cur);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
entity->rx_deliv = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->t_reordering_start != 0 && entity->rx_deliv > entity->rx_reord) {
|
||||||
|
/* stop and reset t-Reordering */
|
||||||
|
entity->t_reordering_start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->t_reordering_start == 0 && entity->rx_deliv < entity->rx_next) {
|
||||||
|
entity->rx_reord = entity->rx_next;
|
||||||
|
entity->t_reordering_start = entity->t_current;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
|
static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
|
||||||
|
char *buffer, int size, int sdu_id)
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
int sn;
|
||||||
|
int header_size;
|
||||||
|
char buf[size+3+4];
|
||||||
|
|
||||||
|
count = entity->tx_next;
|
||||||
|
sn = entity->tx_next & entity->sn_max;
|
||||||
|
|
||||||
|
if (entity->sn_size == 12) {
|
||||||
|
buf[0] = 0x80 | ((sn >> 8) & 0xf);
|
||||||
|
buf[1] = sn & 0xff;
|
||||||
|
header_size = 2;
|
||||||
|
} else {
|
||||||
|
buf[0] = 0x80 | ((sn >> 16) & 0x3);
|
||||||
|
buf[1] = (sn >> 8) & 0xff;
|
||||||
|
buf[2] = sn & 0xff;
|
||||||
|
header_size = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf+header_size, buffer, size);
|
||||||
|
|
||||||
|
if (entity->has_ciphering)
|
||||||
|
entity->cipher(entity->security_context,
|
||||||
|
(unsigned char *)buf+header_size, size,
|
||||||
|
entity->rb_id, count, entity->is_gnb ? 1 : 0);
|
||||||
|
|
||||||
|
entity->tx_next++;
|
||||||
|
|
||||||
|
entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
|
||||||
|
size+header_size, sdu_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity,
|
||||||
|
char *key)
|
||||||
|
{
|
||||||
|
memcpy(entity->integrity_key, key, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_t_reordering(nr_pdcp_entity_t *entity)
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
|
||||||
|
if (entity->t_reordering_start == 0
|
||||||
|
|| entity->t_current <= entity->t_reordering_start + entity->t_reordering)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* stop timer */
|
||||||
|
entity->t_reordering_start = 0;
|
||||||
|
|
||||||
|
/* deliver all SDUs with count < rx_reord */
|
||||||
|
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);
|
||||||
|
entity->rx_list = cur->next;
|
||||||
|
entity->rx_size -= cur->size;
|
||||||
|
nr_pdcp_free_sdu(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deliver all SDUs starting from rx_reord up to discontinuity or end of list */
|
||||||
|
count = entity->rx_reord;
|
||||||
|
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);
|
||||||
|
entity->rx_list = cur->next;
|
||||||
|
entity->rx_size -= cur->size;
|
||||||
|
nr_pdcp_free_sdu(cur);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity->rx_deliv = count;
|
||||||
|
|
||||||
|
if (entity->rx_deliv < entity->rx_next) {
|
||||||
|
entity->rx_reord = entity->rx_next;
|
||||||
|
entity->t_reordering_start = entity->t_current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now)
|
||||||
|
{
|
||||||
|
entity->t_current = now;
|
||||||
|
|
||||||
|
check_t_reordering(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
|
||||||
|
{
|
||||||
|
nr_pdcp_sdu_t *cur = entity->rx_list;
|
||||||
|
while (cur != NULL) {
|
||||||
|
nr_pdcp_sdu_t *next = cur->next;
|
||||||
|
nr_pdcp_free_sdu(cur);
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
if (entity->free_security != NULL)
|
||||||
|
entity->free_security(entity->security_context);
|
||||||
|
free(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||||
|
nr_pdcp_entity_type_t type,
|
||||||
int is_gnb, int rb_id,
|
int is_gnb, int rb_id,
|
||||||
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),
|
||||||
@@ -54,52 +252,56 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
|
|||||||
unsigned char *ciphering_key,
|
unsigned char *ciphering_key,
|
||||||
unsigned char *integrity_key)
|
unsigned char *integrity_key)
|
||||||
{
|
{
|
||||||
nr_pdcp_entity_drb_am_t *ret;
|
nr_pdcp_entity_t *ret;
|
||||||
|
|
||||||
ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t));
|
ret = calloc(1, sizeof(nr_pdcp_entity_t));
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
|
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu;
|
ret->type = type;
|
||||||
ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu;
|
|
||||||
ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key;
|
|
||||||
|
|
||||||
ret->common.delete = nr_pdcp_entity_drb_am_delete;
|
ret->recv_pdu = nr_pdcp_entity_recv_pdu;
|
||||||
|
ret->recv_sdu = nr_pdcp_entity_recv_sdu;
|
||||||
|
ret->set_integrity_key = nr_pdcp_entity_set_integrity_key;
|
||||||
|
ret->set_time = nr_pdcp_entity_set_time;
|
||||||
|
|
||||||
ret->common.deliver_sdu = deliver_sdu;
|
ret->delete = nr_pdcp_entity_delete;
|
||||||
ret->common.deliver_sdu_data = deliver_sdu_data;
|
|
||||||
|
|
||||||
ret->common.deliver_pdu = deliver_pdu;
|
ret->deliver_sdu = deliver_sdu;
|
||||||
ret->common.deliver_pdu_data = deliver_pdu_data;
|
ret->deliver_sdu_data = deliver_sdu_data;
|
||||||
|
|
||||||
|
ret->deliver_pdu = deliver_pdu;
|
||||||
|
ret->deliver_pdu_data = deliver_pdu_data;
|
||||||
|
|
||||||
ret->rb_id = rb_id;
|
ret->rb_id = rb_id;
|
||||||
ret->sn_size = sn_size;
|
ret->sn_size = sn_size;
|
||||||
ret->t_reordering = t_reordering;
|
ret->t_reordering = t_reordering;
|
||||||
ret->discard_timer = discard_timer;
|
ret->discard_timer = discard_timer;
|
||||||
|
|
||||||
ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1;
|
ret->sn_max = (1 << sn_size) - 1;
|
||||||
|
ret->window_size = 1 << (sn_size - 1);
|
||||||
|
|
||||||
if (ciphering_key != NULL && ciphering_algorithm != 0) {
|
if (ciphering_key != NULL && ciphering_algorithm != 0) {
|
||||||
if (ciphering_algorithm != 2) {
|
if (ciphering_algorithm != 2) {
|
||||||
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
|
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
ret->common.has_ciphering = 1;
|
ret->has_ciphering = 1;
|
||||||
ret->common.ciphering_algorithm = ciphering_algorithm;
|
ret->ciphering_algorithm = ciphering_algorithm;
|
||||||
memcpy(ret->common.ciphering_key, ciphering_key, 16);
|
memcpy(ret->ciphering_key, ciphering_key, 16);
|
||||||
|
|
||||||
ret->common.security_context = nr_pdcp_security_nea2_init(ciphering_key);
|
ret->security_context = nr_pdcp_security_nea2_init(ciphering_key);
|
||||||
ret->common.cipher = nr_pdcp_security_nea2_cipher;
|
ret->cipher = nr_pdcp_security_nea2_cipher;
|
||||||
ret->common.free_security = nr_pdcp_security_nea2_free_security;
|
ret->free_security = nr_pdcp_security_nea2_free_security;
|
||||||
}
|
}
|
||||||
ret->common.is_gnb = is_gnb;
|
ret->is_gnb = is_gnb;
|
||||||
|
|
||||||
if (integrity_key != NULL) {
|
if (integrity_key != NULL) {
|
||||||
printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
|
printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (nr_pdcp_entity_t *)ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,18 +19,29 @@
|
|||||||
* contact@openairinterface.org
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifndef _NR_PDCP_ENTITY_H_
|
#ifndef _NR_PDCP_ENTITY_H_
|
||||||
#define _NR_PDCP_ENTITY_H_
|
#define _NR_PDCP_ENTITY_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "nr_pdcp_sdu.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NR_PDCP_DRB_AM,
|
||||||
|
NR_PDCP_DRB_UM,
|
||||||
|
NR_PDCP_SRB
|
||||||
|
} nr_pdcp_entity_type_t;
|
||||||
|
|
||||||
typedef struct nr_pdcp_entity_t {
|
typedef struct nr_pdcp_entity_t {
|
||||||
|
nr_pdcp_entity_type_t type;
|
||||||
|
|
||||||
/* functions provided by the PDCP module */
|
/* functions provided by the PDCP module */
|
||||||
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
|
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
|
||||||
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
|
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
|
||||||
int sdu_id);
|
int sdu_id);
|
||||||
void (*delete)(struct nr_pdcp_entity_t *entity);
|
void (*delete)(struct nr_pdcp_entity_t *entity);
|
||||||
void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
|
void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
|
||||||
|
void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now);
|
||||||
|
|
||||||
/* 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,
|
||||||
@@ -39,9 +50,28 @@ typedef struct nr_pdcp_entity_t {
|
|||||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
||||||
char *buf, int size, int sdu_id);
|
char *buf, int size, int sdu_id);
|
||||||
void *deliver_pdu_data;
|
void *deliver_pdu_data;
|
||||||
int tx_hfn;
|
|
||||||
int next_nr_pdcp_tx_sn;
|
/* configuration variables */
|
||||||
int maximum_nr_pdcp_sn;
|
int rb_id;
|
||||||
|
|
||||||
|
int sn_size; /* SN size, in bits */
|
||||||
|
int t_reordering; /* unit: ms */
|
||||||
|
int discard_timer; /* unit: ms */
|
||||||
|
|
||||||
|
int sn_max; /* (2^SN_size) - 1 */
|
||||||
|
int window_size; /* 2^(SN_size - 1) */
|
||||||
|
|
||||||
|
/* state variables */
|
||||||
|
uint32_t tx_next;
|
||||||
|
uint32_t rx_next;
|
||||||
|
uint32_t rx_deliv;
|
||||||
|
uint32_t rx_reord;
|
||||||
|
|
||||||
|
/* set to the latest know time by the user of the module. Unit: ms */
|
||||||
|
uint64_t t_current;
|
||||||
|
|
||||||
|
/* timers (stores the ms of activation, 0 means not active) */
|
||||||
|
int t_reordering_start;
|
||||||
|
|
||||||
/* security */
|
/* security */
|
||||||
int has_ciphering;
|
int has_ciphering;
|
||||||
@@ -60,18 +90,15 @@ typedef struct nr_pdcp_entity_t {
|
|||||||
* pdcp entity is for a gnb or an ue
|
* pdcp entity is for a gnb or an ue
|
||||||
*/
|
*/
|
||||||
int is_gnb;
|
int is_gnb;
|
||||||
|
|
||||||
|
/* rx management */
|
||||||
|
nr_pdcp_sdu_t *rx_list;
|
||||||
|
int rx_size;
|
||||||
|
int rx_maxsize;
|
||||||
} nr_pdcp_entity_t;
|
} nr_pdcp_entity_t;
|
||||||
|
|
||||||
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
|
nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||||
int is_gnb, int rb_id,
|
nr_pdcp_entity_type_t type,
|
||||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
|
||||||
char *buf, int size),
|
|
||||||
void *deliver_sdu_data,
|
|
||||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
|
||||||
char *buf, int size, int sdu_id),
|
|
||||||
void *deliver_pdu_data);
|
|
||||||
|
|
||||||
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
|
|
||||||
int is_gnb, int rb_id,
|
int is_gnb, int rb_id,
|
||||||
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),
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
||||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.openairinterface.org/?page_id=698
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*-------------------------------------------------------------------------------
|
|
||||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
||||||
* contact@openairinterface.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nr_pdcp_entity_drb_am.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "common/utils/LOG/log.h"
|
|
||||||
|
|
||||||
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
|
|
||||||
{
|
|
||||||
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
|
|
||||||
int sn;
|
|
||||||
|
|
||||||
if (size < 3) abort();
|
|
||||||
|
|
||||||
if (!(buffer[0] & 0x80))
|
|
||||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
|
||||||
|
|
||||||
sn = (((unsigned char)buffer[0] & 0x3) << 16) |
|
|
||||||
((unsigned char)buffer[1] << 8) |
|
|
||||||
(unsigned char)buffer[2];
|
|
||||||
|
|
||||||
if (entity->common.has_ciphering)
|
|
||||||
entity->common.cipher(entity->common.security_context, (unsigned char *)buffer+3, size-3,
|
|
||||||
entity->rb_id, sn, entity->common.is_gnb ? 0 : 1);
|
|
||||||
|
|
||||||
entity->common.deliver_sdu(entity->common.deliver_sdu_data,
|
|
||||||
(nr_pdcp_entity_t *)entity, buffer+3, size-3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size,
|
|
||||||
int sdu_id)
|
|
||||||
{
|
|
||||||
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
|
|
||||||
int sn;
|
|
||||||
char buf[size+3];
|
|
||||||
|
|
||||||
sn = entity->common.next_nr_pdcp_tx_sn;
|
|
||||||
|
|
||||||
entity->common.next_nr_pdcp_tx_sn++;
|
|
||||||
if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) {
|
|
||||||
entity->common.next_nr_pdcp_tx_sn = 0;
|
|
||||||
entity->common.tx_hfn++;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[0] = 0x80 | ((sn >> 16) & 0x3);
|
|
||||||
buf[1] = (sn >> 8) & 0xff;
|
|
||||||
buf[2] = sn & 0xff;
|
|
||||||
memcpy(buf+3, buffer, size);
|
|
||||||
|
|
||||||
if (entity->common.has_ciphering)
|
|
||||||
entity->common.cipher(entity->common.security_context, (unsigned char *)buf+3, size,
|
|
||||||
entity->rb_id, sn, entity->common.is_gnb ? 1 : 0);
|
|
||||||
|
|
||||||
entity->common.deliver_pdu(entity->common.deliver_pdu_data,
|
|
||||||
(nr_pdcp_entity_t *)entity, buf, size+3, sdu_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
|
|
||||||
{
|
|
||||||
/* nothing to do */
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity)
|
|
||||||
{
|
|
||||||
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
|
|
||||||
if (entity->common.free_security != NULL)
|
|
||||||
entity->common.free_security(entity->common.security_context);
|
|
||||||
free(entity);
|
|
||||||
}
|
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "asn1_utils.h"
|
#include "asn1_utils.h"
|
||||||
#include "nr_pdcp_ue_manager.h"
|
#include "nr_pdcp_ue_manager.h"
|
||||||
|
#include "nr_pdcp_timer_thread.h"
|
||||||
#include "NR_RadioBearerConfig.h"
|
#include "NR_RadioBearerConfig.h"
|
||||||
#include "NR_RLC-BearerConfig.h"
|
#include "NR_RLC-BearerConfig.h"
|
||||||
#include "NR_RLC-Config.h"
|
#include "NR_RLC-Config.h"
|
||||||
@@ -41,6 +42,11 @@
|
|||||||
|
|
||||||
static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
|
static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
|
||||||
|
|
||||||
|
/* TODO: handle time a bit more properly */
|
||||||
|
static uint64_t nr_pdcp_current_time;
|
||||||
|
static int nr_pdcp_current_time_last_frame;
|
||||||
|
static int nr_pdcp_current_time_last_subframe;
|
||||||
|
|
||||||
/* necessary globals for OAI, not used internally */
|
/* necessary globals for OAI, not used internally */
|
||||||
hash_table_t *pdcp_coll_p;
|
hash_table_t *pdcp_coll_p;
|
||||||
static uint64_t pdcp_optmask;
|
static uint64_t pdcp_optmask;
|
||||||
@@ -339,6 +345,8 @@ void pdcp_layer_init(void)
|
|||||||
|
|
||||||
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
|
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
|
||||||
init_nr_rlc_data_req_queue();
|
init_nr_rlc_data_req_queue();
|
||||||
|
|
||||||
|
nr_pdcp_init_timer_thread(nr_pdcp_ue_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "nfapi/oai_integration/vendor_ext.h"
|
#include "nfapi/oai_integration/vendor_ext.h"
|
||||||
@@ -625,11 +633,11 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
|
|||||||
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
|
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
|
||||||
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||||
} else {
|
} else {
|
||||||
pdcp_drb = new_nr_pdcp_entity_drb_am(is_gnb, drb_id,
|
pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id,
|
||||||
deliver_sdu_drb, ue, deliver_pdu_drb, ue,
|
deliver_sdu_drb, ue, deliver_pdu_drb, ue,
|
||||||
sn_size_dl, t_reordering, discard_timer,
|
sn_size_dl, t_reordering, discard_timer,
|
||||||
ciphering_algorithm, integrity_algorithm,
|
ciphering_algorithm, integrity_algorithm,
|
||||||
ciphering_key, integrity_key);
|
ciphering_key, integrity_key);
|
||||||
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
|
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
|
||||||
|
|
||||||
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||||
@@ -976,3 +984,14 @@ void
|
|||||||
pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){
|
pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_tick(int frame, int subframe)
|
||||||
|
{
|
||||||
|
if (frame != nr_pdcp_current_time_last_frame ||
|
||||||
|
subframe != nr_pdcp_current_time_last_subframe) {
|
||||||
|
nr_pdcp_current_time_last_frame = frame;
|
||||||
|
nr_pdcp_current_time_last_subframe = subframe;
|
||||||
|
nr_pdcp_current_time++;
|
||||||
|
nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nr_pdcp_sdu.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size)
|
||||||
|
{
|
||||||
|
nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t));
|
||||||
|
if (ret == NULL)
|
||||||
|
exit(1);
|
||||||
|
ret->count = count;
|
||||||
|
ret->buffer = malloc(size);
|
||||||
|
if (ret->buffer == NULL)
|
||||||
|
exit(1);
|
||||||
|
memcpy(ret->buffer, buffer, size);
|
||||||
|
ret->size = size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu)
|
||||||
|
{
|
||||||
|
nr_pdcp_sdu_t head;
|
||||||
|
nr_pdcp_sdu_t *cur;
|
||||||
|
nr_pdcp_sdu_t *prev;
|
||||||
|
|
||||||
|
head.next = l;
|
||||||
|
cur = l;
|
||||||
|
prev = &head;
|
||||||
|
|
||||||
|
/* order is by 'count' */
|
||||||
|
while (cur != NULL) {
|
||||||
|
/* check if 'sdu' is before 'cur' in the list */
|
||||||
|
if (sdu->count < cur->count)
|
||||||
|
break;
|
||||||
|
prev = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
prev->next = sdu;
|
||||||
|
sdu->next = cur;
|
||||||
|
return head.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count)
|
||||||
|
{
|
||||||
|
while (l != NULL) {
|
||||||
|
if (l->count == count)
|
||||||
|
return 1;
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu)
|
||||||
|
{
|
||||||
|
free(sdu->buffer);
|
||||||
|
free(sdu);
|
||||||
|
}
|
||||||
+14
-16
@@ -19,23 +19,21 @@
|
|||||||
* contact@openairinterface.org
|
* contact@openairinterface.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _NR_PDCP_ENTITY_DRB_AM_H_
|
#ifndef _NR_PDCP_SDU_H_
|
||||||
#define _NR_PDCP_ENTITY_DRB_AM_H_
|
#define _NR_PDCP_SDU_H_
|
||||||
|
|
||||||
#include "nr_pdcp_entity.h"
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct nr_pdcp_sdu_t {
|
||||||
nr_pdcp_entity_t common;
|
uint32_t count;
|
||||||
int rb_id;
|
char *buffer;
|
||||||
int sn_size; /* unit: bits */
|
int size;
|
||||||
int t_reordering; /* unit: ms */
|
struct nr_pdcp_sdu_t *next;
|
||||||
int discard_timer; /* unit: ms, -1 means infinity */
|
} nr_pdcp_sdu_t;
|
||||||
} nr_pdcp_entity_drb_am_t;
|
|
||||||
|
|
||||||
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
|
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size);
|
||||||
void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size,
|
nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu);
|
||||||
int sdu_id);
|
int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count);
|
||||||
void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key);
|
void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);
|
||||||
void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity);
|
|
||||||
|
|
||||||
#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */
|
#endif /* _NR_PDCP_SDU_H_ */
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nr_pdcp_timer_thread.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "LOG/log.h"
|
||||||
|
|
||||||
|
static pthread_mutex_t timer_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static pthread_cond_t timer_thread_cond = PTHREAD_COND_INITIALIZER;
|
||||||
|
static volatile uint64_t timer_thread_curtime = 0;
|
||||||
|
|
||||||
|
static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager)
|
||||||
|
{
|
||||||
|
nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager;
|
||||||
|
nr_pdcp_ue_t **ue_list;
|
||||||
|
int ue_count;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
uint64_t curtime = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (pthread_mutex_lock(&timer_thread_mutex) != 0) abort();
|
||||||
|
while (curtime == timer_thread_curtime)
|
||||||
|
if (pthread_cond_wait(&timer_thread_cond, &timer_thread_mutex) != 0) abort();
|
||||||
|
curtime = timer_thread_curtime;
|
||||||
|
if (pthread_mutex_unlock(&timer_thread_mutex) != 0) abort();
|
||||||
|
|
||||||
|
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||||
|
|
||||||
|
ue_list = nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager);
|
||||||
|
ue_count = nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager);
|
||||||
|
for (i = 0; i < ue_count; i++) {
|
||||||
|
for (j = 0; j < 2; j++) {
|
||||||
|
if (ue_list[i]->srb[j] != NULL)
|
||||||
|
ue_list[i]->srb[j]->set_time(ue_list[i]->srb[j], curtime);
|
||||||
|
}
|
||||||
|
for (j = 0; j < 5; j++) {
|
||||||
|
if (ue_list[i]->drb[j] != NULL)
|
||||||
|
ue_list[i]->drb[j]->set_time(ue_list[i]->drb[j], curtime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager)
|
||||||
|
{
|
||||||
|
pthread_t t;
|
||||||
|
|
||||||
|
if (pthread_create(&t, NULL, nr_pdcp_timer_thread, nr_pdcp_ue_manager) != 0) {
|
||||||
|
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_pdcp_wakeup_timer_thread(uint64_t time)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_lock(&timer_thread_mutex)) abort();
|
||||||
|
timer_thread_curtime = time;
|
||||||
|
if (pthread_cond_broadcast(&timer_thread_cond)) abort();
|
||||||
|
if (pthread_mutex_unlock(&timer_thread_mutex)) abort();
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NR_PDCP_TIMER_THREAD_H_
|
||||||
|
#define _NR_PDCP_TIMER_THREAD_H_
|
||||||
|
|
||||||
|
#include "nr_pdcp_ue_manager.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager);
|
||||||
|
void nr_pdcp_wakeup_timer_thread(uint64_t time);
|
||||||
|
|
||||||
|
#endif /* _NR_PDCP_TIMER_THREAD_H_ */
|
||||||
@@ -189,6 +189,20 @@ void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity
|
|||||||
ue->drb[drb_id] = entity;
|
ue->drb[drb_id] = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* must be called with lock acquired */
|
||||||
|
nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m)
|
||||||
|
{
|
||||||
|
nr_pdcp_ue_manager_internal_t *m = _m;
|
||||||
|
return m->ue_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must be called with lock acquired */
|
||||||
|
int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m)
|
||||||
|
{
|
||||||
|
nr_pdcp_ue_manager_internal_t *m = _m;
|
||||||
|
return m->ue_count;
|
||||||
|
}
|
||||||
|
|
||||||
int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m)
|
int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m)
|
||||||
{
|
{
|
||||||
nr_pdcp_ue_manager_internal_t *m = _m;
|
nr_pdcp_ue_manager_internal_t *m = _m;
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m);
|
|||||||
nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti);
|
nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti);
|
||||||
void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti);
|
void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti);
|
||||||
|
|
||||||
|
nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m);
|
||||||
|
int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m);
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* ue functions */
|
/* ue functions */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|||||||
Reference in New Issue
Block a user