managing RLC bearer configuration at RRC UE
This commit is contained in:
@@ -42,6 +42,7 @@
|
|||||||
#define NR_MAX_HARQ_PROCESSES 16
|
#define NR_MAX_HARQ_PROCESSES 16
|
||||||
#define NR_NB_REG_PER_CCE 6
|
#define NR_NB_REG_PER_CCE 6
|
||||||
#define NR_NB_SC_PER_RB 12
|
#define NR_NB_SC_PER_RB 12
|
||||||
|
#define NR_MAX_NUM_LCID 32
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
nr_FR1 = 0,
|
nr_FR1 = 0,
|
||||||
|
|||||||
@@ -402,7 +402,6 @@ typedef struct {
|
|||||||
#define UL_SCH_LCID_L_BSR 0x3E
|
#define UL_SCH_LCID_L_BSR 0x3E
|
||||||
#define UL_SCH_LCID_PADDING 0x3F
|
#define UL_SCH_LCID_PADDING 0x3F
|
||||||
|
|
||||||
#define NR_MAX_NUM_LCID 32
|
|
||||||
#define NR_MAX_NUM_LCGID 8
|
#define NR_MAX_NUM_LCGID 8
|
||||||
#define MAX_RLC_SDU_SUBHEADER_SIZE 3
|
#define MAX_RLC_SDU_SUBHEADER_SIZE 3
|
||||||
|
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ int decode_t_poll_retransmit(int v)
|
|||||||
int decode_poll_pdu(int v)
|
int decode_poll_pdu(int v)
|
||||||
{
|
{
|
||||||
static const int tab[24] = {
|
static const int tab[24] = {
|
||||||
4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144,
|
4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144,
|
||||||
8192, 12288, 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536 - 1 /* -1 means infinity */
|
8192, 12288, 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536, - 1 /* -1 means infinity */
|
||||||
};
|
};
|
||||||
|
|
||||||
if (v < 0 || v > 23) {
|
if (v < 0 || v > 23) {
|
||||||
|
|||||||
@@ -243,3 +243,33 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
|
|||||||
|
|
||||||
return (nr_rlc_entity_t *)ret;
|
return (nr_rlc_entity_t *)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nr_rlc_entity_um_reconfigure(nr_rlc_entity_t *_entity,
|
||||||
|
int t_reassembly,
|
||||||
|
int *sn_field_length)
|
||||||
|
{
|
||||||
|
nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity;
|
||||||
|
entity->t_reassembly = t_reassembly;
|
||||||
|
if (sn_field_length)
|
||||||
|
entity->sn_field_length = *sn_field_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_rlc_entity_am_reconfigure(nr_rlc_entity_t *_entity,
|
||||||
|
int t_poll_retransmit,
|
||||||
|
int t_reassembly,
|
||||||
|
int t_status_prohibit,
|
||||||
|
int poll_pdu,
|
||||||
|
int poll_byte,
|
||||||
|
int max_retx_threshold,
|
||||||
|
int *sn_field_length)
|
||||||
|
{
|
||||||
|
nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
|
||||||
|
entity->t_poll_retransmit = t_poll_retransmit;
|
||||||
|
entity->t_reassembly = t_reassembly;
|
||||||
|
entity->t_status_prohibit = t_status_prohibit;
|
||||||
|
entity->poll_pdu = poll_pdu;
|
||||||
|
entity->poll_byte = poll_byte;
|
||||||
|
entity->max_retx_threshold = max_retx_threshold;
|
||||||
|
if (sn_field_length)
|
||||||
|
entity->sn_field_length = *sn_field_length;
|
||||||
|
}
|
||||||
|
|||||||
@@ -176,4 +176,17 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
|
|||||||
char *buf, int size),
|
char *buf, int size),
|
||||||
void *deliver_sdu_data);
|
void *deliver_sdu_data);
|
||||||
|
|
||||||
|
void nr_rlc_entity_um_reconfigure(nr_rlc_entity_t *_entity,
|
||||||
|
int t_reassembly,
|
||||||
|
int *sn_field_length);
|
||||||
|
|
||||||
|
void nr_rlc_entity_am_reconfigure(nr_rlc_entity_t *_entity,
|
||||||
|
int t_poll_retransmit,
|
||||||
|
int t_reassembly,
|
||||||
|
int t_status_prohibit,
|
||||||
|
int poll_pdu,
|
||||||
|
int poll_byte,
|
||||||
|
int max_retx_threshold,
|
||||||
|
int *sn_field_length);
|
||||||
|
|
||||||
#endif /* _NR_RLC_ENTITY_H_ */
|
#endif /* _NR_RLC_ENTITY_H_ */
|
||||||
|
|||||||
@@ -582,6 +582,106 @@ rb_found:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nr_rlc_reestablish_entity(int rnti, int lc_id)
|
||||||
|
{
|
||||||
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||||
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
||||||
|
|
||||||
|
if(ue == NULL)
|
||||||
|
LOG_E(RLC, "RLC instance for the given UE was not found \n");
|
||||||
|
|
||||||
|
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id);
|
||||||
|
|
||||||
|
if (rb != NULL) {
|
||||||
|
LOG_D(RLC, "RB found! (channel ID %d) \n", lc_id);
|
||||||
|
rb->reestablishment(rb);
|
||||||
|
} else {
|
||||||
|
LOG_E(RLC, "no RLC entity found (channel ID %d) for reestablishment\n",
|
||||||
|
lc_id);
|
||||||
|
}
|
||||||
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_rlc_reconfigure_entity(int rnti,
|
||||||
|
int lc_id,
|
||||||
|
struct NR_RLC_Config *rlc_Config,
|
||||||
|
struct NR_LogicalChannelConfig *lc_Config)
|
||||||
|
{
|
||||||
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||||
|
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti);
|
||||||
|
|
||||||
|
if (ue == NULL)
|
||||||
|
LOG_E(RLC, "RLC instance for the given UE was not found \n");
|
||||||
|
|
||||||
|
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id);
|
||||||
|
if (lc_Config) {
|
||||||
|
if(lc_Config->ul_SpecificParameters &&
|
||||||
|
lc_Config->ul_SpecificParameters->logicalChannelGroup)
|
||||||
|
AssertFatal(*lc_Config->ul_SpecificParameters->logicalChannelGroup == 0,
|
||||||
|
"LCG %ld not supported\n",
|
||||||
|
*lc_Config->ul_SpecificParameters->logicalChannelGroup);
|
||||||
|
}
|
||||||
|
if (rlc_Config) {
|
||||||
|
if (rb->stats.mode == NR_RLC_AM) {
|
||||||
|
AssertFatal(rlc_Config->present == NR_RLC_Config_PR_am,
|
||||||
|
"Invalid RLC Config type\n");
|
||||||
|
struct NR_RLC_Config__am *am = rlc_Config->choice.am;
|
||||||
|
int t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly);
|
||||||
|
int t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
|
||||||
|
int t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
|
||||||
|
int poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
|
||||||
|
int poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte);
|
||||||
|
int max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold);
|
||||||
|
int *sn_field_length = NULL;
|
||||||
|
if (am->dl_AM_RLC.sn_FieldLength) {
|
||||||
|
AssertFatal(am->ul_AM_RLC.sn_FieldLength != NULL,
|
||||||
|
"Cannot handle different sn_FieldLength for DL and UL\n");
|
||||||
|
if (am->ul_AM_RLC.sn_FieldLength) {
|
||||||
|
AssertFatal(*am->dl_AM_RLC.sn_FieldLength == *am->ul_AM_RLC.sn_FieldLength,
|
||||||
|
"Cannot handle different sn_FieldLength for DL and UL\n");
|
||||||
|
sn_field_length = calloc(1, sizeof(*sn_field_length));
|
||||||
|
*sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertFatal(am->ul_AM_RLC.sn_FieldLength == NULL,
|
||||||
|
"Cannot handle different sn_FieldLength for DL and UL\n");
|
||||||
|
nr_rlc_entity_am_reconfigure(rb,
|
||||||
|
t_poll_retransmit,
|
||||||
|
t_reassembly,
|
||||||
|
t_status_prohibit,
|
||||||
|
poll_pdu,
|
||||||
|
poll_byte,
|
||||||
|
max_retx_threshold,
|
||||||
|
sn_field_length);
|
||||||
|
}
|
||||||
|
else { // UM
|
||||||
|
AssertFatal(rlc_Config->present == NR_RLC_Config_PR_um_Bi_Directional,
|
||||||
|
"Invalid RLC Config type\n");
|
||||||
|
struct NR_RLC_Config__um_Bi_Directional *um = rlc_Config->choice.um_Bi_Directional;
|
||||||
|
int t_reassembly = decode_t_reassembly(um->dl_UM_RLC.t_Reassembly);
|
||||||
|
int *sn_field_length = NULL;
|
||||||
|
if (um->dl_UM_RLC.sn_FieldLength) {
|
||||||
|
AssertFatal(um->ul_UM_RLC.sn_FieldLength != NULL,
|
||||||
|
"Cannot handle different sn_FieldLength for DL and UL\n");
|
||||||
|
if (um->ul_UM_RLC.sn_FieldLength) {
|
||||||
|
AssertFatal(*um->dl_UM_RLC.sn_FieldLength == *um->ul_UM_RLC.sn_FieldLength,
|
||||||
|
"Cannot handle different sn_FieldLength for DL and UL\n");
|
||||||
|
sn_field_length = calloc(1, sizeof(*sn_field_length));
|
||||||
|
*sn_field_length = decode_sn_field_length_um(*um->dl_UM_RLC.sn_FieldLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AssertFatal(um->ul_UM_RLC.sn_FieldLength == NULL,
|
||||||
|
"Cannot handle different sn_FieldLength for DL and UL\n");
|
||||||
|
nr_rlc_entity_um_reconfigure(rb,
|
||||||
|
t_reassembly,
|
||||||
|
sn_field_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||||
|
}
|
||||||
|
|
||||||
void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
|
||||||
{
|
{
|
||||||
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
|
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
|
||||||
@@ -600,7 +700,12 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
|
|||||||
AssertFatal(srb_id > 0 && srb_id < 4,
|
AssertFatal(srb_id > 0 && srb_id < 4,
|
||||||
"Invalid srb id %d\n", srb_id);
|
"Invalid srb id %d\n", srb_id);
|
||||||
|
|
||||||
logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup;
|
if (l &&
|
||||||
|
l->ul_SpecificParameters &&
|
||||||
|
l->ul_SpecificParameters->logicalChannelGroup)
|
||||||
|
logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup;
|
||||||
|
else
|
||||||
|
logical_channel_group = 0; // default value as in 9.2.1 of 38.331
|
||||||
|
|
||||||
/* TODO: accept other values? */
|
/* TODO: accept other values? */
|
||||||
if (logical_channel_group != 0) {
|
if (logical_channel_group != 0) {
|
||||||
@@ -608,26 +713,31 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (r->present) {
|
if (r &&
|
||||||
case NR_RLC_Config_PR_am: {
|
r-> present == NR_RLC_Config_PR_am) {
|
||||||
struct NR_RLC_Config__am *am;
|
struct NR_RLC_Config__am *am;
|
||||||
am = r->choice.am;
|
am = r->choice.am;
|
||||||
t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly);
|
t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly);
|
||||||
t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
|
t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
|
||||||
t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
|
t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
|
||||||
poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
|
poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
|
||||||
poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte);
|
poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte);
|
||||||
max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold);
|
max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold);
|
||||||
if (*am->dl_AM_RLC.sn_FieldLength != *am->ul_AM_RLC.sn_FieldLength) {
|
if (*am->dl_AM_RLC.sn_FieldLength != *am->ul_AM_RLC.sn_FieldLength) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength);
|
sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
else {
|
||||||
LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
|
// default values as in 9.2.1 of 38.331
|
||||||
exit(1);
|
t_reassembly = 35;
|
||||||
|
t_status_prohibit = 0;
|
||||||
|
t_poll_retransmit = 45;
|
||||||
|
poll_pdu = -1;
|
||||||
|
poll_byte = -1;
|
||||||
|
max_retx_threshold = 8;
|
||||||
|
sn_field_length = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||||
@@ -642,14 +752,6 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
|
|||||||
if (ue->srb[srb_id-1] != NULL) {
|
if (ue->srb[srb_id-1] != NULL) {
|
||||||
LOG_E(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
|
LOG_E(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
|
||||||
} else {
|
} else {
|
||||||
/* hack: hardcode values for NR */
|
|
||||||
t_poll_retransmit = 45;
|
|
||||||
t_reassembly = 35;
|
|
||||||
t_status_prohibit = 0;
|
|
||||||
poll_pdu = -1;
|
|
||||||
poll_byte = -1;
|
|
||||||
max_retx_threshold = 8;
|
|
||||||
sn_field_length = 12;
|
|
||||||
nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
|
nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
|
||||||
RLC_TX_MAXSIZE,
|
RLC_TX_MAXSIZE,
|
||||||
deliver_sdu, ue,
|
deliver_sdu, ue,
|
||||||
|
|||||||
@@ -44,12 +44,18 @@ struct NR_LogicalChannelConfig;
|
|||||||
void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
||||||
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
||||||
|
|
||||||
|
void nr_rlc_reestablish_entity(int rnti, int lc_id);
|
||||||
void nr_rlc_remove_ue(int rnti);
|
void nr_rlc_remove_ue(int rnti);
|
||||||
bool nr_rlc_update_rnti(int from_rnti, int to_rnti);
|
bool nr_rlc_update_rnti(int from_rnti, int to_rnti);
|
||||||
|
|
||||||
/* test function for CI to trigger reestablishments */
|
/* test function for CI to trigger reestablishments */
|
||||||
void nr_rlc_test_trigger_reestablishment(int rnti);
|
void nr_rlc_test_trigger_reestablishment(int rnti);
|
||||||
|
|
||||||
|
void nr_rlc_reconfigure_entity(int rnti,
|
||||||
|
int lc_id,
|
||||||
|
struct NR_RLC_Config *rlc_Config,
|
||||||
|
struct NR_LogicalChannelConfig *lc_Config);
|
||||||
|
|
||||||
int nr_rlc_get_available_tx_space(
|
int nr_rlc_get_available_tx_space(
|
||||||
const rnti_t rntiP,
|
const rnti_t rntiP,
|
||||||
const logical_chan_id_t channel_idP);
|
const logical_chan_id_t channel_idP);
|
||||||
|
|||||||
+63
-72
@@ -120,50 +120,10 @@ nr_rrc_ue_generate_rrcReestablishmentComplete(
|
|||||||
|
|
||||||
mui_t nr_rrc_mui=0;
|
mui_t nr_rrc_mui=0;
|
||||||
|
|
||||||
static void nr_rrc_addmod_drbs(int rnti,
|
|
||||||
const NR_DRB_ToAddModList_t *drb_list,
|
|
||||||
const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list)
|
|
||||||
{
|
|
||||||
if (drb_list == NULL || bearer_list == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0; i < drb_list->list.count; i++) {
|
|
||||||
const NR_DRB_ToAddMod_t *drb = drb_list->list.array[i];
|
|
||||||
for (int j = 0; j < bearer_list->list.count; j++) {
|
|
||||||
const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j];
|
|
||||||
if (bearer->servedRadioBearer != NULL
|
|
||||||
&& bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity
|
|
||||||
&& drb->drb_Identity == bearer->servedRadioBearer->choice.drb_Identity) {
|
|
||||||
nr_rlc_add_drb(rnti, drb->drb_Identity, bearer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
|
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
|
||||||
int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
|
int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
|
||||||
const uint8_t *buffer,
|
NR_CellGroupConfig_t *cell_group_config)
|
||||||
const uint32_t size)
|
|
||||||
{
|
{
|
||||||
NR_CellGroupConfig_t *cell_group_config = NULL;
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
asn_dec_rval_t dec_rval = uper_decode(NULL,
|
|
||||||
&asn_DEF_NR_CellGroupConfig,
|
|
||||||
(void **)&cell_group_config,
|
|
||||||
(uint8_t *)buffer,
|
|
||||||
size, 0, 0);
|
|
||||||
|
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
|
||||||
LOG_E(NR_RRC, "NR_CellGroupConfig decode error\n");
|
|
||||||
for (i=0; i<size; i++)
|
|
||||||
LOG_E(NR_RRC, "%02x ",buffer[i]);
|
|
||||||
LOG_E(NR_RRC, "\n");
|
|
||||||
// free the memory
|
|
||||||
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(NR_UE_rrc_inst[module_id].scell_group_config == NULL)
|
if(NR_UE_rrc_inst[module_id].scell_group_config == NULL)
|
||||||
NR_UE_rrc_inst[module_id].scell_group_config = cell_group_config;
|
NR_UE_rrc_inst[module_id].scell_group_config = cell_group_config;
|
||||||
else
|
else
|
||||||
@@ -177,8 +137,8 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
|
|||||||
|
|
||||||
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded)
|
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded)
|
||||||
// RRCReconfiguration
|
// RRCReconfiguration
|
||||||
int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration){
|
int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration)
|
||||||
|
{
|
||||||
switch(rrcReconfiguration->criticalExtensions.present){
|
switch(rrcReconfiguration->criticalExtensions.present){
|
||||||
case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration:
|
case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration:
|
||||||
if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){
|
if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){
|
||||||
@@ -192,16 +152,27 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){
|
if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){
|
||||||
|
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||||
|
int size = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size;
|
||||||
|
uint8_t *buffer = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf;
|
||||||
|
asn_dec_rval_t dec_rval = uper_decode(NULL,
|
||||||
|
&asn_DEF_NR_CellGroupConfig, //might be added prefix later
|
||||||
|
(void **)&cellGroupConfig,
|
||||||
|
(uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf,
|
||||||
|
size, 0, 0);
|
||||||
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
|
LOG_E(NR_RRC, "NR_CellGroupConfig decode error\n");
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
LOG_E(NR_RRC, "%02x ", buffer[i]);
|
||||||
|
LOG_E(NR_RRC, "\n");
|
||||||
|
// free the memory
|
||||||
|
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cellGroupConfig, 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nr_rrc_manage_rlc_bearers(cellGroupConfig, &NR_UE_rrc_inst[module_id], 0, NR_UE_rrc_inst[module_id].rnti);
|
||||||
|
|
||||||
if(get_softmodem_params()->sa || get_softmodem_params()->nsa) {
|
if(get_softmodem_params()->sa || get_softmodem_params()->nsa) {
|
||||||
|
|
||||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
|
||||||
uper_decode(NULL,
|
|
||||||
&asn_DEF_NR_CellGroupConfig, //might be added prefix later
|
|
||||||
(void **)&cellGroupConfig,
|
|
||||||
(uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf,
|
|
||||||
rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0);
|
|
||||||
|
|
||||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||||
}
|
}
|
||||||
@@ -223,9 +194,7 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nr_rrc_ue_decode_secondary_cellgroup_config(module_id,
|
nr_rrc_ue_decode_secondary_cellgroup_config(module_id, cellGroupConfig);
|
||||||
rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf,
|
|
||||||
rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size);
|
|
||||||
}
|
}
|
||||||
if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){
|
if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){
|
||||||
if(NR_UE_rrc_inst[module_id].meas_config == NULL){
|
if(NR_UE_rrc_inst[module_id].meas_config == NULL){
|
||||||
@@ -788,6 +757,45 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig,
|
||||||
|
NR_UE_RRC_INST_t *rrc,
|
||||||
|
int gNB_index,
|
||||||
|
int rnti)
|
||||||
|
{
|
||||||
|
if(cellGroupConfig->rlc_BearerToReleaseList != NULL) {
|
||||||
|
//TODO (perform RLC bearer release as specified in 5.3.5.5.3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cellGroupConfig->rlc_BearerToAddModList != NULL) {
|
||||||
|
//TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
|
||||||
|
for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||||
|
NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i];
|
||||||
|
NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity;
|
||||||
|
if (rrc->active_RLC_entity[gNB_index][lcid]) {
|
||||||
|
if (rlc_bearer->reestablishRLC)
|
||||||
|
nr_rlc_reestablish_entity(rnti, lcid);
|
||||||
|
nr_rlc_reconfigure_entity(rnti,
|
||||||
|
lcid,
|
||||||
|
rlc_bearer->rlc_Config,
|
||||||
|
rlc_bearer->mac_LogicalChannelConfig);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rrc->active_RLC_entity[gNB_index][lcid] = true;
|
||||||
|
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n");
|
||||||
|
AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING,
|
||||||
|
"Invalid RB for RLC configuration\n");
|
||||||
|
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
|
||||||
|
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
||||||
|
nr_rlc_add_srb(rnti, srb_id, rlc_bearer);
|
||||||
|
}
|
||||||
|
else { // DRB
|
||||||
|
NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
|
||||||
|
nr_rlc_add_drb(rnti, drb_id, rlc_bearer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
|
void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
|
||||||
uint8_t gNB_index,
|
uint8_t gNB_index,
|
||||||
@@ -811,20 +819,7 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
|
|||||||
rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
|
rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cellGroupConfig->rlc_BearerToReleaseList != NULL){
|
nr_rrc_manage_rlc_bearers(cellGroupConfig, rrc, gNB_index, ctxt_pP->rntiMaybeUEid);
|
||||||
//TODO (perform RLC bearer release as specified in 5.3.5.5.3)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cellGroupConfig->rlc_BearerToAddModList != NULL){
|
|
||||||
//TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
|
|
||||||
if(rrc->cell_group_config->rlc_BearerToAddModList != NULL){
|
|
||||||
// Laurent: there are cases where the not NULL value is also not coming from a previous malloc
|
|
||||||
// so it is better to let the potential memory leak than corrupting the heap //free(rrc->cell_group_config->rlc_BearerToAddModList);
|
|
||||||
}
|
|
||||||
rrc->cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
|
|
||||||
memcpy(rrc->cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList,
|
|
||||||
sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cellGroupConfig->mac_CellGroupConfig != NULL){
|
if(cellGroupConfig->mac_CellGroupConfig != NULL){
|
||||||
//TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
|
//TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
|
||||||
@@ -1596,10 +1591,6 @@ void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP,
|
|||||||
kUPenc,
|
kUPenc,
|
||||||
kUPint,
|
kUPint,
|
||||||
ue_rrc->cell_group_config->rlc_BearerToAddModList);
|
ue_rrc->cell_group_config->rlc_BearerToAddModList);
|
||||||
// Refresh DRBs
|
|
||||||
nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid,
|
|
||||||
radioBearerConfig->drb_ToAddModList,
|
|
||||||
ue_rrc->cell_group_config->rlc_BearerToAddModList);
|
|
||||||
|
|
||||||
} // drb_ToAddModList //
|
} // drb_ToAddModList //
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
#include "RRC/NR/nr_rrc_common.h"
|
#include "RRC/NR/nr_rrc_common.h"
|
||||||
#include "as_message.h"
|
#include "as_message.h"
|
||||||
|
#include "common/utils/nr/nr_common.h"
|
||||||
|
|
||||||
#define NB_NR_UE_INST 1
|
#define NB_NR_UE_INST 1
|
||||||
#define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE
|
#define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE
|
||||||
@@ -208,6 +209,7 @@ typedef struct NR_UE_RRC_INST_s {
|
|||||||
rnti_t rnti;
|
rnti_t rnti;
|
||||||
|
|
||||||
NR_UE_RRC_SRB_INFO_t Srb[NB_CNX_UE][NR_NUM_SRB];
|
NR_UE_RRC_SRB_INFO_t Srb[NB_CNX_UE][NR_NUM_SRB];
|
||||||
|
bool active_RLC_entity [NB_CNX_UE][NR_MAX_NUM_LCID];
|
||||||
|
|
||||||
OAI_NR_UECapability_t *UECap;
|
OAI_NR_UECapability_t *UECap;
|
||||||
uint8_t *UECapability;
|
uint8_t *UECapability;
|
||||||
|
|||||||
@@ -65,14 +65,6 @@ NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *);
|
|||||||
/**\brief Initial the top level RRC structure instance*/
|
/**\brief Initial the top level RRC structure instance*/
|
||||||
NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *);
|
NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *);
|
||||||
|
|
||||||
/**\brief Decode RRC Connection Reconfiguration, sent from E-UTRA RRC Connection Reconfiguration v1510 carring EN-DC config
|
|
||||||
\param buffer encoded NR-RRC-Connection-Reconfiguration/Secondary-Cell-Group-Config message.
|
|
||||||
\param size length of buffer*/
|
|
||||||
//TODO check to use which one
|
|
||||||
//int8_t nr_rrc_ue_decode_rrcReconfiguration(const uint8_t *buffer, const uint32_t size);
|
|
||||||
int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, const uint8_t *buffer, const uint32_t size);
|
|
||||||
|
|
||||||
|
|
||||||
/**\brief Process NR RRC connection reconfiguration via SRB3
|
/**\brief Process NR RRC connection reconfiguration via SRB3
|
||||||
\param rrcReconfiguration decoded rrc connection reconfiguration*/
|
\param rrcReconfiguration decoded rrc connection reconfiguration*/
|
||||||
int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration);
|
int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration);
|
||||||
@@ -171,6 +163,11 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac,
|
|||||||
void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc,
|
void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc,
|
||||||
struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants);
|
struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants);
|
||||||
|
|
||||||
|
void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig,
|
||||||
|
NR_UE_RRC_INST_t *rrc,
|
||||||
|
int gNB_index,
|
||||||
|
int rnti);
|
||||||
|
|
||||||
int configure_NR_SL_Preconfig(int sync_source);
|
int configure_NR_SL_Preconfig(int sync_source);
|
||||||
/** @}*/
|
/** @}*/
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user