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
This commit is contained in:
@@ -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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user