Commit 2335f5b6 authored by andrewse's avatar andrewse Committed by Robert Schmidt

Don't call mac_rlc_data_ind when SRB0 already exist for UE.

It can happen that L1 gives us a TB that we interpret as receiving UL
MAC TB with LCID "UL_SCH_LCID_CCCH1". This might or might not be
correct, but currently, we observe segfaults when trying to encode the
cellgroup in send_initial_ul_rrc_message() (encode_cellGroupConfig()).

This fix prevents a segfault by not delivering a MAC SDU to RLC if CCCH
is already present. Note that in some cases, this could still happen,
e.g. Resume Request. However, we don't support this message, so ignore
it for the moment.

This fix enables a gNB to operate continuously for extended periods
(days), which is essential for real deployment scenarios.

Closes: #756
parent ccdabb4c
......@@ -3177,9 +3177,14 @@ void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_le
mac->mac_rrc.initial_ul_rrc_message_transfer(0, &ul_rrc_msg);
}
void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
{
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
/* activate SRB0 */
if (!nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message))
return false;
/* create this UE's initial CellGroup */
int CC_id = 0;
int srb_id = 1;
......@@ -3189,9 +3194,6 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
UE->CellGroup = cellGroupConfig;
/* activate SRB0 */
nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message);
/* the cellGroup sent to CU specifies there is SRB1, so create it */
DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1);
const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0];
......@@ -3201,6 +3203,7 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
int priority = bearer->mac_LogicalChannelConfig->ul_SpecificParameters->priority;
nr_lc_config_t c = {.lcid = bearer->logicalChannelIdentity, .priority = priority};
nr_mac_add_lcid(&UE->UE_sched_ctrl, &c);
return true;
}
void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing)
......
......@@ -446,18 +446,19 @@ static int nr_process_mac_pdu(instance_t module_idP,
LOG_D(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti);
prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE);
mac_rlc_data_ind(module_idP,
UE->rnti,
module_idP,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
0,
(char *) (pduP + mac_subheader_len),
mac_len,
1,
NULL);
if (prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE)) {
mac_rlc_data_ind(module_idP,
UE->rnti,
module_idP,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
0,
(char *) (pduP + mac_subheader_len),
mac_len,
1,
NULL);
}
break;
case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28):
......@@ -498,7 +499,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
break;
default:
LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
LOG_E(NR_MAC, "RNTI %0x, received unknown MAC header (LCID = 0x%02x)\n", UE->rnti, rx_lcid);
return -1;
break;
}
......
......@@ -436,7 +436,7 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
long get_lcid_from_drbid(int drb_id);
long get_lcid_from_srbid(int srb_id);
void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE);
bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE);
void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data);
void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid);
......
......@@ -983,10 +983,17 @@ void deliver_sdu_srb0(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
s0->send_initial_ul_rrc_message(s0->ue_id, (unsigned char *)buf, size, s0->data);
}
void nr_rlc_activate_srb0(int ue_id,
bool nr_rlc_activate_srb0(int ue_id,
void *data,
void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data))
{
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
if (ue->srb0 != NULL) {
LOG_W(RLC, "SRB0 already exists for UE %x, do nothing\n", ue_id);
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return false;
}
struct srb0_data *srb0_data = calloc(1, sizeof(struct srb0_data));
AssertFatal(srb0_data, "out of memory\n");
......@@ -994,21 +1001,13 @@ void nr_rlc_activate_srb0(int ue_id,
srb0_data->data = data;
srb0_data->send_initial_ul_rrc_message = send_initial_ul_rrc_message;
nr_rlc_manager_lock(nr_rlc_ue_manager);
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
if (ue->srb0 != NULL) {
LOG_W(RLC, "SRB0 already exists for UE %d, do nothing\n", ue_id);
free(srb0_data);
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return;
}
nr_rlc_entity_t *nr_rlc_tm = new_nr_rlc_entity_tm(10000,
deliver_sdu_srb0, srb0_data);
deliver_sdu_srb0, srb0_data);
nr_rlc_ue_add_srb_rlc_entity(ue, 0, nr_rlc_tm);
LOG_I(RLC, "Activated srb0 for UE %d\n", ue_id);
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return true;
}
rlc_op_status_t rrc_rlc_config_req(const protocol_ctxt_t* const ctxt_pP,
......
......@@ -62,7 +62,7 @@ void nr_rlc_activate_avg_time_to_tx(const int ue_id, const logical_chan_id_t cha
void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size);
void nr_rlc_activate_srb0(int ue_id,
bool nr_rlc_activate_srb0(int ue_id,
void *data,
void (*send_initial_ul_rrc_message)(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data));
......
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