Commit f5cc51b4 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/NR_UE_RRC_manage_RLC_PDCP' into integration_2023_w38

parents deb443dc cf1baafd
...@@ -42,6 +42,7 @@ ...@@ -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 { ...@@ -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
......
...@@ -511,19 +511,28 @@ void configure_ss_coreset(NR_UE_MAC_INST_t *mac, ...@@ -511,19 +511,28 @@ void configure_ss_coreset(NR_UE_MAC_INST_t *mac,
mac->BWP_coresets[i] = NULL; mac->BWP_coresets[i] = NULL;
} }
// todo handle mac_LogicalChannelConfig void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id,
int nr_rrc_mac_config_req_ue_logicalChannelBearer( struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
module_id_t module_id, struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list)
int cc_idP, {
uint8_t gNB_index, NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
long logicalChannelIdentity, if (rlc_toadd_list) {
bool status){ for (int i = 0; i < rlc_toadd_list->list.count; i++) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
mac->logicalChannelBearer_exist[logicalChannelIdentity] = status; int id = rlc_bearer->logicalChannelIdentity - 1;
return 0; mac->active_RLC_bearer[id] = true;
}
}
if (rlc_torelease_list) {
for (int i = 0; i < rlc_torelease_list->list.count; i++) {
if (rlc_torelease_list->list.array[i]) {
int id = *rlc_torelease_list->list.array[i] - 1;
mac->active_RLC_bearer[id] = false;
}
}
}
} }
void configure_current_BWP(NR_UE_MAC_INST_t *mac, void configure_current_BWP(NR_UE_MAC_INST_t *mac,
NR_ServingCellConfigCommonSIB_t *scc, NR_ServingCellConfigCommonSIB_t *scc,
NR_CellGroupConfig_t *cell_group_config) NR_CellGroupConfig_t *cell_group_config)
......
...@@ -503,8 +503,8 @@ typedef struct { ...@@ -503,8 +503,8 @@ typedef struct {
uint8_t BSR_reporting_active; uint8_t BSR_reporting_active;
/// LogicalChannelConfig has bearer. /// LogicalChannelConfig has bearer.
bool logicalChannelBearer_exist[NR_MAX_NUM_LCID]; bool active_RLC_bearer[NR_MAX_NUM_LCID];
NR_UE_SCHEDULING_INFO scheduling_info; NR_UE_SCHEDULING_INFO scheduling_info;
/// PHR /// PHR
uint8_t PHR_reporting_active; uint8_t PHR_reporting_active;
......
...@@ -63,17 +63,9 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, ...@@ -63,17 +63,9 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
uint8_t *pduP, uint8_t *pduP,
uint32_t pdu_len); uint32_t pdu_len);
/**\brief primitive from RRC layer to MAC layer to set if bearer exists for a logical channel. todo handle mac_LogicalChannelConfig void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id,
\param module_id module id struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
\param cc_id component carrier id struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list);
\param gNB_index gNB index
\param long logicalChannelIdentity
\param bool status*/
int nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id,
int cc_idP,
uint8_t gNB_index,
long logicalChannelIdentity,
bool status);
void nr_rrc_mac_config_req_scg(module_id_t module_id, void nr_rrc_mac_config_req_scg(module_id_t module_id,
int cc_idP, int cc_idP,
......
...@@ -51,7 +51,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { ...@@ -51,7 +51,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
//LOG_I(MAC, "[MAIN] init UE MAC functions \n"); //LOG_I(MAC, "[MAIN] init UE MAC functions \n");
//init mac here //init mac here
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t), NB_NR_UE_MAC_INST); nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(NB_NR_UE_MAC_INST, sizeof(NR_UE_MAC_INST_t));
for (int j = 0; j < NB_NR_UE_MAC_INST; j++) for (int j = 0; j < NB_NR_UE_MAC_INST; j++)
nr_ue_init_mac(j); nr_ue_init_mac(j);
...@@ -73,15 +73,16 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { ...@@ -73,15 +73,16 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
NR_RadioBearerConfig_t *rbconfig = NULL; NR_RadioBearerConfig_t *rbconfig = NULL;
NR_RLC_BearerConfig_t *rlc_rbconfig = NULL; NR_RLC_BearerConfig_t *rlc_rbconfig = NULL;
fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig);
struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_bearer_list = {
.list = { .array = &rlc_rbconfig, .count = 1, .size = 1, }
};
// set up PDCP, RLC, MAC // set up PDCP, RLC, MAC
nr_pdcp_layer_init(); nr_pdcp_layer_init();
nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL);
nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
nr_ue_mac_inst->logicalChannelBearer_exist[4] = true; struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_toadd_list;
rlc_toadd_list.list.count = 1;
rlc_toadd_list.list.array = calloc(1, sizeof(NR_RLC_BearerConfig_t));
rlc_toadd_list.list.array[0] = rlc_rbconfig;
nr_rrc_mac_config_req_ue_logicalChannelBearer(0, &rlc_toadd_list, NULL);
// free memory // free memory
free_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); free_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig);
......
...@@ -1119,8 +1119,6 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info) ...@@ -1119,8 +1119,6 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info)
bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index)
{ {
bool bsr_regular_triggered = false; bool bsr_regular_triggered = false;
uint8_t lcid;
uint8_t lcgid;
uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined
uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0}; uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0};
int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID]; int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID];
...@@ -1137,37 +1135,38 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t ...@@ -1137,37 +1135,38 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
// Reset All BSR Infos // Reset All BSR Infos
lcid_bytes_in_buffer[0] = 0; lcid_bytes_in_buffer[0] = 0;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { // TO BE NOTED LCID = 0 is excluded from buffers
// so they need to be addressed with lcid - 1
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
// Reset transmission status // Reset transmission status
lcid_bytes_in_buffer[lcid] = 0; lcid_bytes_in_buffer[lcid - 1] = 0;
mac->scheduling_info.LCID_status[lcid]=LCID_EMPTY; mac->scheduling_info.LCID_status[lcid - 1] = LCID_EMPTY;
} }
for (lcgid=0; lcgid < NR_MAX_NUM_LCGID; lcgid++) { for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
// Reset Buffer Info // Reset Buffer Info
mac->scheduling_info.BSR[lcgid]=0; mac->scheduling_info.BSR[lcgid] = 0;
mac->scheduling_info.BSR_bytes[lcgid]=0; mac->scheduling_info.BSR_bytes[lcgid] = 0;
} }
//Get Buffer Occupancy and fill lcid_reordered_array //Get Buffer Occupancy and fill lcid_reordered_array
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
//if (mac->logicalChannelConfig[lcid]) { if (mac->active_RLC_bearer[lcid - 1]) { // todo
if (mac->logicalChannelBearer_exist[lcid] ) { // todo int lcgid = mac->scheduling_info.LCGID[lcid - 1];
lcgid = mac->scheduling_info.LCGID[lcid];
// Store already available data to transmit per Group // Store already available data to transmit per Group
if (lcgid < NR_MAX_NUM_LCGID) { if (lcgid < NR_MAX_NUM_LCGID) {
lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid]; lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid - 1];
} }
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0);
lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; lcid_bytes_in_buffer[lcid - 1] = rlc_status.bytes_in_buffer;
if (rlc_status.bytes_in_buffer > 0) { if (rlc_status.bytes_in_buffer > 0) {
LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n", LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n",
module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP); module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP);
mac->scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY; mac->scheduling_info.LCID_status[lcid - 1] = LCID_NOT_EMPTY;
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined //Update BSR_bytes and position in lcid_reordered_array only if Group is defined
if (lcgid < NR_MAX_NUM_LCGID) { if (lcgid < NR_MAX_NUM_LCGID) {
...@@ -1181,7 +1180,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t ...@@ -1181,7 +1180,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
//if (mac->logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) { //if (mac->logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) {
if (1) { // todo if (1) { // todo
//Insert if priority is higher or equal (lower or equal in value) //Insert if priority is higher or equal (lower or equal in value)
for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) { for (pos_next = num_lcid_with_data - 1; pos_next > array_index; pos_next--) {
lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1]; lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1];
} }
...@@ -1190,7 +1189,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t ...@@ -1190,7 +1189,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
} }
array_index ++; array_index ++;
} while ((array_index < num_lcid_with_data) && (array_index < NR_MAX_NUM_LCID)); } while ((array_index < num_lcid_with_data) && (array_index <= NR_MAX_NUM_LCID));
} }
} }
} }
...@@ -1204,7 +1203,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t ...@@ -1204,7 +1203,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
lcid_reordered_array[2]); lcid_reordered_array[2]);
for (array_index = 0; array_index < num_lcid_with_data; array_index++) { for (array_index = 0; array_index < num_lcid_with_data; array_index++) {
lcid = lcid_reordered_array[array_index]; int lcid = lcid_reordered_array[array_index];
/* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity
either the data belongs to a logical channel with higher priority than the priorities of the logical channels either the data belongs to a logical channel with higher priority than the priorities of the logical channels
...@@ -1212,10 +1211,13 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t ...@@ -1212,10 +1211,13 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
*/ */
{ {
bsr_regular_triggered = true; bsr_regular_triggered = true;
LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n", LOG_D(NR_MAC,
module_idP, lcid, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n",
mac->scheduling_info.LCGID[lcid], module_idP,
frameP, slotP); lcid,
mac->scheduling_info.LCGID[lcid - 1],
frameP,
slotP);
break; break;
} }
} }
...@@ -1232,8 +1234,8 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t ...@@ -1232,8 +1234,8 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
} }
//Store Buffer Occupancy in remain buffers for next TTI //Store Buffer Occupancy in remain buffers for next TTI
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
mac->scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid]; mac->scheduling_info.LCID_buffer_remain[lcid - 1] = lcid_bytes_in_buffer[lcid - 1];
} }
return bsr_regular_triggered; return bsr_regular_triggered;
...@@ -2688,27 +2690,27 @@ Update the following in mac_ce_p: ...@@ -2688,27 +2690,27 @@ Update the following in mac_ce_p:
bsr_t bsr_t
*/ */
void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
int CC_id, int CC_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframe, sub_frame_t subframe,
uint8_t gNB_index, uint8_t gNB_index,
uint8_t *ulsch_buffer, uint8_t *ulsch_buffer,
uint16_t buflen, uint16_t buflen,
NR_UE_MAC_CE_INFO *mac_ce_p) { NR_UE_MAC_CE_INFO *mac_ce_p)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
// Compute BSR Values and update Nb LCGID with data after multiplexing // Compute BSR Values and update Nb LCGID with data after multiplexing
unsigned short padding_len = 0; unsigned short padding_len = 0;
uint8_t lcid = 0;
int lcg_id = 0; int lcg_id = 0;
int num_lcg_id_with_data = 0; int num_lcg_id_with_data = 0;
int lcg_id_bsr_trunc = 0; int lcg_id_bsr_trunc = 0;
for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) { for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) {
if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) { if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) {
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]); mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
} else { } else {
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]); mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
} }
if (mac->scheduling_info.BSR_bytes[lcg_id]) { if (mac->scheduling_info.BSR_bytes[lcg_id]) {
num_lcg_id_with_data++; num_lcg_id_with_data++;
lcg_id_bsr_trunc = lcg_id; lcg_id_bsr_trunc = lcg_id;
...@@ -2742,8 +2744,8 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, ...@@ -2742,8 +2744,8 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
if (num_lcg_id_with_data > 1) { if (num_lcg_id_with_data > 1) {
// REPORT SHORT TRUNCATED BSR // REPORT SHORT TRUNCATED BSR
//Get LCGID of highest priority LCID with data (todo) //Get LCGID of highest priority LCID with data (todo)
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
lcg_id = mac->scheduling_info.LCGID[lcid]; lcg_id = mac->scheduling_info.LCGID[lcid - 1];
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) { if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) {
lcg_id_bsr_trunc = lcg_id; lcg_id_bsr_trunc = lcg_id;
} }
...@@ -2855,7 +2857,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, ...@@ -2855,7 +2857,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
sub_frame_t subframe, sub_frame_t subframe,
uint8_t gNB_index, uint8_t gNB_index,
uint8_t *ulsch_buffer, uint8_t *ulsch_buffer,
uint16_t buflen) { uint16_t buflen)
{
NR_UE_MAC_CE_INFO mac_ce_info; NR_UE_MAC_CE_INFO mac_ce_info;
NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info; NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info;
int16_t buflen_remain = 0; int16_t buflen_remain = 0;
...@@ -2891,11 +2894,14 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, ...@@ -2891,11 +2894,14 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
// Check for DCCH first // Check for DCCH first
// TO DO: Multiplex in the order defined by the logical channel prioritization // TO DO: Multiplex in the order defined by the logical channel prioritization
for (int lcid = UL_SCH_LCID_SRB1; lcid < NR_MAX_NUM_LCID; lcid++) { for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
if (!mac->active_RLC_bearer[lcid - 1])
continue;
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n", LOG_D(NR_MAC,
__FUNCTION__, "[UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d "
"bytes, buflen_remain %d bytes)\n",
module_idP, module_idP,
frameP, frameP,
subframe, subframe,
...@@ -2905,8 +2911,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, ...@@ -2905,8 +2911,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
mac_ce_p->tot_mac_ce_len, mac_ce_p->tot_mac_ce_len,
buflen_remain); buflen_remain);
while (buflen_remain > 0){ while (buflen_remain > 0) {
// Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU // Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu; NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu;
...@@ -2924,23 +2929,23 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, ...@@ -2924,23 +2929,23 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
0, 0,
0); 0);
AssertFatal(buflen_remain >= sdu_length, "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n", AssertFatal(buflen_remain >= sdu_length,
__FUNCTION__, "LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n",
lcid, lcid,
sdu_length, sdu_length,
buflen_remain); buflen_remain);
if (sdu_length > 0) { if (sdu_length > 0) {
LOG_D(NR_MAC,
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", "[UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x "
__FUNCTION__, "(buflen (TBS) %d bytes)\n",
module_idP, module_idP,
frameP, frameP,
subframe, subframe,
num_sdus + 1, num_sdus + 1,
sdu_length, sdu_length,
lcid, lcid,
buflen); buflen);
header->R = 0; header->R = 0;
header->F = 1; header->F = 1;
...@@ -2962,20 +2967,24 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, ...@@ -2962,20 +2967,24 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
} else { } else {
pdu -= sh_size; pdu -= sh_size;
LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid); LOG_D(NR_MAC, "no data to transmit for RB with LCID 0x%02x\n", lcid);
break; break;
} }
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
//Update Buffer remain and BSR bytes after transmission //Update Buffer remain and BSR bytes after transmission
mac->scheduling_info.LCID_buffer_remain[lcid] -= sdu_length; mac->scheduling_info.LCID_buffer_remain[lcid - 1] -= sdu_length;
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] -= sdu_length; mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] -= sdu_length;
LOG_D(NR_MAC, "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n", LOG_D(NR_MAC,
module_idP, frameP, subframe, mac->scheduling_info.LCGID[lcid], "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n",
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]]); module_idP,
if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] < 0) frameP,
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] = 0; subframe,
mac->scheduling_info.LCGID[lcid - 1],
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]]);
if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] < 0)
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] = 0;
} }
} }
......
...@@ -282,10 +282,6 @@ void mac_top_init_gNB(ngran_node_t node_type, ...@@ -282,10 +282,6 @@ void mac_top_init_gNB(ngran_node_t node_type,
NR_RadioBearerConfig_t *rbconfig = NULL; NR_RadioBearerConfig_t *rbconfig = NULL;
NR_RLC_BearerConfig_t *rlc_rbconfig = NULL; NR_RLC_BearerConfig_t *rlc_rbconfig = NULL;
fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig);
NR_RLC_BearerConfig_t *rlc_rbconfig_list[1] = {rlc_rbconfig};
struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_bearer_list = {
.list = { .array = rlc_rbconfig_list, .count = 1, .size = 1, }
};
/* Note! previously, in nr_DRB_preconfiguration(), we passed ENB_FLAG_NO /* Note! previously, in nr_DRB_preconfiguration(), we passed ENB_FLAG_NO
* if ENB_NAS_USE_TUN was *not* set. It seems to me that we could not set * if ENB_NAS_USE_TUN was *not* set. It seems to me that we could not set
...@@ -295,7 +291,7 @@ void mac_top_init_gNB(ngran_node_t node_type, ...@@ -295,7 +291,7 @@ void mac_top_init_gNB(ngran_node_t node_type,
* will output the packets at a local interface, which is in line with * will output the packets at a local interface, which is in line with
* the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */ * the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */
// setup PDCP, RLC // setup PDCP, RLC
nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL);
nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
// free memory // free memory
......
...@@ -32,8 +32,7 @@ void e1_add_drb(int is_gnb, ...@@ -32,8 +32,7 @@ void e1_add_drb(int is_gnb,
unsigned char *ciphering_key, unsigned char *ciphering_key,
unsigned char *integrity_key) unsigned char *integrity_key)
{ {
add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, add_drb(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key);
ciphering_key, integrity_key);
LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id); LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id);
} }
......
...@@ -369,6 +369,21 @@ void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now) ...@@ -369,6 +369,21 @@ void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now)
check_t_reordering(entity); check_t_reordering(entity);
} }
void nr_pdcp_entity_release(nr_pdcp_entity_t *entity)
{
// deliver the PDCP SDUs stored in the receiving PDCP entity to upper layers
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);
entity->rx_list = cur->next;
entity->rx_size -= cur->size;
entity->stats.txsdu_pkts++;
entity->stats.txsdu_bytes += cur->size;
nr_pdcp_free_sdu(cur);
}
}
void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity) void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
{ {
nr_pdcp_sdu_t *cur = entity->rx_list; nr_pdcp_sdu_t *cur = entity->rx_list;
...@@ -428,6 +443,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -428,6 +443,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
ret->set_time = nr_pdcp_entity_set_time; ret->set_time = nr_pdcp_entity_set_time;
ret->delete_entity = nr_pdcp_entity_delete; ret->delete_entity = nr_pdcp_entity_delete;
ret->release_entity = nr_pdcp_entity_release;
ret->get_stats = nr_pdcp_entity_get_stats; ret->get_stats = nr_pdcp_entity_get_stats;
ret->deliver_sdu = deliver_sdu; ret->deliver_sdu = deliver_sdu;
......
...@@ -76,6 +76,7 @@ typedef struct nr_pdcp_entity_t { ...@@ -76,6 +76,7 @@ typedef struct nr_pdcp_entity_t {
int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id, char *pdu_buffer, int pdu_max_size); int sdu_id, char *pdu_buffer, int pdu_max_size);
void (*delete_entity)(struct nr_pdcp_entity_t *entity); void (*delete_entity)(struct nr_pdcp_entity_t *entity);
void (*release_entity)(struct nr_pdcp_entity_t *entity);
void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out); void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out);
/* set_security: pass -1 to integrity_algorithm / ciphering_algorithm /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
......
...@@ -757,21 +757,32 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, ...@@ -757,21 +757,32 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock); enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock);
} }
static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) void add_srb(int is_gnb,
ue_id_t rntiMaybeUEid,
struct NR_SRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
nr_pdcp_entity_t *pdcp_srb; nr_pdcp_entity_t *pdcp_srb;
nr_pdcp_ue_t *ue; nr_pdcp_ue_t *ue;
int t_Reordering=3000;
int srb_id = s->srb_Identity; int srb_id = s->srb_Identity;
if (s->pdcp_Config == NULL || int t_Reordering = -1; // infinity as per default SRB configuration in 9.2.1 of 38.331
s->pdcp_Config->t_Reordering == NULL) t_Reordering = 3000; if (s->pdcp_Config != NULL && s->pdcp_Config->t_Reordering != NULL)
else t_Reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering); t_Reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
nr_pdcp_manager_lock(nr_pdcp_ue_manager); nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rntiMaybeUEid); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rntiMaybeUEid);
if (ue->srb[srb_id-1] != NULL) { if (ue->srb[srb_id-1] != NULL) {
LOG_D(PDCP, "%s:%d:%s: warning SRB %d already exist for UE ID/RNTI %ld, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rntiMaybeUEid); LOG_E(PDCP,
"%s:%d:%s: warning SRB %d already exist for UE ID/RNTI %ld, do nothing\n",
__FILE__,
__LINE__,
__FUNCTION__,
srb_id,
rntiMaybeUEid);
} else { } else {
pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id, pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id,
0, false, false, // sdap parameters 0, false, false, // sdap parameters
...@@ -788,7 +799,13 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s ...@@ -788,7 +799,13 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s
nr_pdcp_manager_unlock(nr_pdcp_ue_manager); nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
} }
void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) void add_drb(int is_gnb,
ue_id_t rntiMaybeUEid,
struct NR_DRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
nr_pdcp_entity_t *pdcp_drb; nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue; nr_pdcp_ue_t *ue;
...@@ -882,32 +899,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, in ...@@ -882,32 +899,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, in
nr_pdcp_manager_unlock(nr_pdcp_ue_manager); nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
} }
static void add_drb(int is_gnb,
ue_id_t rntiMaybeUEid,
struct NR_DRB_ToAddMod *s,
NR_RLC_Config_t *rlc_Config,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{
switch (rlc_Config->present) {
case NR_RLC_Config_PR_am:
add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key);
break;
case NR_RLC_Config_PR_um_Bi_Directional:
// add_drb_um(rntiMaybeUEid, s);
/* hack */
add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key);
break;
default:
LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID/RNTI %ld\n", __FILE__, __FUNCTION__, __LINE__, rntiMaybeUEid);
}
void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddModList_t *const srb2add_list, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint) void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddModList_t *const srb2add_list, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint)
{ {
if (srb2add_list != NULL) { if (srb2add_list != NULL) {
...@@ -923,12 +914,17 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ...@@ -923,12 +914,17 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
NR_DRB_ToAddModList_t *const drb2add_list, NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP, const uint8_t security_modeP,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint, uint8_t *const kUPint)
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
{ {
if (drb2add_list != NULL) { if (drb2add_list != NULL) {
for (int i = 0; i < drb2add_list->list.count; i++) { for (int i = 0; i < drb2add_list->list.count; i++) {
add_drb(enb_flag, rntiMaybeUEid, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); add_drb(enb_flag,
rntiMaybeUEid,
drb2add_list->list.array[i],
security_modeP & 0x0f,
(security_modeP >> 4) & 0x0f,
kUPenc,
kUPint);
} }
} else } else
LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n");
...@@ -1061,6 +1057,58 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, ...@@ -1061,6 +1057,58 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id,
return 1; return 1;
} }
void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
nr_pdcp_entity_t *srb = ue->srb[srb_id - 1];
int decoded_t_reordering = decode_t_reordering(t_Reordering);
srb->t_reordering = decoded_t_reordering;
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering)
{
/* The enabling/disabling of ciphering or integrity protection
* can be changed only by releasing and adding the DRB
* (so not by reconfiguring).
*/
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
nr_pdcp_entity_t *drb = ue->drb[drb_id - 1];
int decoded_t_reordering = decode_t_reordering(t_Reordering);
drb->t_reordering = decoded_t_reordering;
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void nr_release_srb(ue_id_t ue_id, int srb_id)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
if (ue->srb[srb_id - 1] != NULL) {
ue->srb[srb_id - 1]->delete_entity(ue->srb[srb_id - 1]);
ue->srb[srb_id - 1] = NULL;
}
else
LOG_E(PDCP, "Attempting to release SRB%d but it is not configured\n", srb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void nr_release_drb(ue_id_t ue_id, int drb_id)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
nr_pdcp_entity_t *drb = ue->drb[drb_id - 1];
if (drb) {
drb->release_entity(drb);
drb->delete_entity(drb);
ue->drb[drb_id - 1] = NULL;
}
else
LOG_E(PDCP, "Attempting to release DRB%d but it is not configured\n", drb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void nr_pdcp_reestablishment(ue_id_t ue_id) void nr_pdcp_reestablishment(ue_id_t ue_id)
{ {
// TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2 // TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2
......
...@@ -51,14 +51,34 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ...@@ -51,14 +51,34 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
NR_DRB_ToAddModList_t *const drb2add_list, NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP, const uint8_t security_modeP,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint, uint8_t *const kUPint);
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
void add_drb(int is_gnb,
ue_id_t rntiMaybeUEid,
struct NR_DRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid); void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid);
bool nr_pdcp_remove_UE(ue_id_t ue_id); bool nr_pdcp_remove_UE(ue_id_t ue_id);
void nr_pdcp_reestablishment(ue_id_t ue_id); void nr_pdcp_reestablishment(ue_id_t ue_id);
void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering);
void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering);
void nr_release_srb(ue_id_t ue_id, int srb_id);
void nr_release_drb(ue_id_t ue_id, int drb_id);
void add_srb(int is_gnb,
ue_id_t rntiMaybeUEid,
struct NR_SRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
void nr_pdcp_config_set_security(ue_id_t ue_id, void nr_pdcp_config_set_security(ue_id_t ue_id,
const rb_id_t rb_id, const rb_id_t rb_id,
const uint8_t security_modeP, const uint8_t security_modeP,
......
...@@ -66,8 +66,8 @@ int decode_t_poll_retransmit(int v) ...@@ -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,31 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ...@@ -243,3 +243,31 @@ 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,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ...@@ -176,4 +176,15 @@ 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_ */
...@@ -54,6 +54,35 @@ static uint64_t nr_rlc_current_time; ...@@ -54,6 +54,35 @@ static uint64_t nr_rlc_current_time;
static int nr_rlc_current_time_last_frame; static int nr_rlc_current_time_last_frame;
static int nr_rlc_current_time_last_subframe; static int nr_rlc_current_time_last_subframe;
static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id)
{
AssertFatal(channel_id != 0, "LCID = 0 shouldn't be handled here\n");
nr_rlc_rb_t *rb = &ue->lcid2rb[channel_id - 1];
if (rb->type == NR_RLC_NONE)
return;
if (rb->type == NR_RLC_SRB) {
int id = rb->choice.srb_id - 1;
AssertFatal(id > 0, "logic bug: impossible to have srb0 here\n");
if (ue->srb[id]) {
ue->srb[id]->delete_entity(ue->srb[id]);
ue->srb[id] = NULL;
}
else
LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id);
}
else {
AssertFatal(rb->type == NR_RLC_DRB,
"Invalid RB type\n");
int id = rb->choice.drb_id - 1;
if (ue->drb[id]) {
ue->drb[id]->delete_entity(ue->drb[id]);
ue->drb[id] = NULL;
}
else
LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id);
}
}
static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id) static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id)
{ {
if (channel_id == 0) if (channel_id == 0)
...@@ -71,6 +100,23 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i ...@@ -71,6 +100,23 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i
} }
} }
void nr_release_rlc_entity(int rnti, logical_chan_id_t channel_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 (channel_id == 0) {
if (ue->srb0 != NULL) {
free(ue->srb0->deliver_sdu_data);
ue->srb0->delete_entity(ue->srb0);
ue->srb0 = NULL;
} else
LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id);
} else {
release_rlc_entity_from_lcid(ue, channel_id);
}
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
void mac_rlc_data_ind(const module_id_t module_idP, void mac_rlc_data_ind(const module_id_t module_idP,
const rnti_t rntiP, const rnti_t rntiP,
const eNB_index_t eNB_index, const eNB_index_t eNB_index,
...@@ -582,6 +628,93 @@ rb_found: ...@@ -582,6 +628,93 @@ 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 < 2,
"LCG %ld not supported as per limitation when creating RBs\n",
*lc_Config->ul_SpecificParameters->logicalChannelGroup);
}
if (rlc_Config) {
AssertFatal(rb->stats.mode != NR_RLC_TM, "Cannot reconfigure TM mode\n");
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;
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 = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength);
sn_field_length = &_sn_field_length;
}
} 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;
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 = decode_sn_field_length_um(*um->dl_UM_RLC.sn_FieldLength);
sn_field_length = &_sn_field_length;
}
} 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 +733,10 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare ...@@ -600,7 +733,10 @@ 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 +744,29 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare ...@@ -608,26 +744,29 @@ 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 && r->present == NR_RLC_Config_PR_am) {
case 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; } else {
} // default values as in 9.2.1 of 38.331
default: t_reassembly = 35;
LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); t_status_prohibit = 0;
exit(1); 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 +781,6 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare ...@@ -642,14 +781,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,17 @@ struct NR_LogicalChannelConfig; ...@@ -44,12 +44,17 @@ 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_release_rlc_entity(int rnti, logical_chan_id_t channel_id);
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);
......
...@@ -154,8 +154,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, ...@@ -154,8 +154,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
DRB_configList, DRB_configList,
(UE->integrity_algorithm << 4) | UE->ciphering_algorithm, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm,
kUPenc, kUPenc,
kUPint, kUPint);
get_softmodem_params()->sa ? UE->masterCellGroup->rlc_BearerToAddModList : NULL);
return ret; return ret;
} }
......
...@@ -28,11 +28,12 @@ ...@@ -28,11 +28,12 @@
#define NR_RRC_HEADER_SIZE_MAX 64 #define NR_RRC_HEADER_SIZE_MAX 64
#define NR_RRC_BUFFER_SIZE_MAX 1024 #define NR_RRC_BUFFER_SIZE_MAX 1024
#define NR_NUM_SRB 4
typedef struct { typedef struct {
char Payload[NR_RRC_BUFFER_SIZE_MAX]; char Payload[NR_RRC_BUFFER_SIZE_MAX];
char Header[NR_RRC_HEADER_SIZE_MAX]; char Header[NR_RRC_HEADER_SIZE_MAX];
uint16_t payload_size; uint16_t payload_size;
} NR_RRC_BUFFER; } NR_RRC_BUFFER;
typedef enum UE_STATE_NR_e { typedef enum UE_STATE_NR_e {
...@@ -45,17 +46,17 @@ typedef enum UE_STATE_NR_e { ...@@ -45,17 +46,17 @@ typedef enum UE_STATE_NR_e {
} NR_UE_STATE_t; } NR_UE_STATE_t;
typedef struct { typedef struct {
unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */ unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */ unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */
unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/ unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/
unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/ unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/
uint8_t Delay_class; /*!< \brief Delay class offered by MAC layer scheduling*/ uint8_t Delay_class; /*!< \brief Delay class offered by MAC layer scheduling*/
uint8_t Target_bler; /*!< \brief Target Average Transport Block Error rate*/ uint8_t Target_bler; /*!< \brief Target Average Transport Block Error rate*/
uint8_t Lchan_t; /*!< \brief Logical Channel Type (BCCH,CCCH,DCCH,DTCH_B,DTCH,MRBCH)*/ uint8_t Lchan_t; /*!< \brief Logical Channel Type (BCCH,CCCH,DCCH,DTCH_B,DTCH,MRBCH)*/
} __attribute__ ((__packed__)) NR_LCHAN_DESC; } __attribute__ ((__packed__)) NR_LCHAN_DESC;
typedef struct RB_INFO_NR_s { typedef struct RB_INFO_NR_s {
uint16_t Rb_id; //=Lchan_id uint16_t Rb_id; //=Lchan_id
NR_LCHAN_DESC Lchan_desc[2]; NR_LCHAN_DESC Lchan_desc[2];
//MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT
} NR_RB_INFO; } NR_RB_INFO;
...@@ -66,8 +67,8 @@ typedef struct NR_SRB_INFO_s { ...@@ -66,8 +67,8 @@ typedef struct NR_SRB_INFO_s {
} NR_SRB_INFO; } NR_SRB_INFO;
typedef struct SRB_INFO_TABLE_ENTRY_NR_s { typedef struct SRB_INFO_TABLE_ENTRY_NR_s {
NR_SRB_INFO Srb_info; NR_SRB_INFO Srb_info;
uint8_t Active; uint8_t Active;
uint8_t status; uint8_t status;
} NR_SRB_INFO_TABLE_ENTRY; } NR_SRB_INFO_TABLE_ENTRY;
......
...@@ -155,8 +155,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ...@@ -155,8 +155,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
NR_DRB_ToAddModList_t *const drb2add_list, NR_DRB_ToAddModList_t *const drb2add_list,
const uint8_t security_modeP, const uint8_t security_modeP,
uint8_t *const kUPenc, uint8_t *const kUPenc,
uint8_t *const kUPint, uint8_t *const kUPint);
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id);
......
...@@ -938,8 +938,7 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co ...@@ -938,8 +938,7 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co
DRB_configList, DRB_configList,
(ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm,
kUPenc, kUPenc,
kUPint, kUPint);
get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL);
/* Loop through DRBs and establish if necessary */ /* Loop through DRBs and establish if necessary */
if (DRB_configList != NULL) { if (DRB_configList != NULL) {
......
...@@ -389,8 +389,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ...@@ -389,8 +389,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
ue_context_p->ue_context.rb_config->drb_ToAddModList, ue_context_p->ue_context.rb_config->drb_ToAddModList,
(ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
kUPenc, kUPenc,
kUPint, kUPint);
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
ctxt.rntiMaybeUEid = du_ue_id; ctxt.rntiMaybeUEid = du_ue_id;
// assume only a single bearer // assume only a single bearer
......
...@@ -133,14 +133,16 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, ...@@ -133,14 +133,16 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
switch(Srb_id) { switch(Srb_id) {
case CCCH: case CCCH:
LOG_D(NR_RRC,
LOG_D(NR_RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); "nr_mac_rrc_data_req_ue: Payload size = %i\n",
memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); NR_UE_rrc_inst[Mod_idP].Srb[gNB_id][0].srb_buffers.Tx_buffer.payload_size);
for(int i = 0; i<NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size; i++) { NR_UE_RRC_SRB_INFO_t *Srb0 = &NR_UE_rrc_inst[Mod_idP].Srb[gNB_id][0];
memcpy(buffer_pP, (uint8_t *)Srb0->srb_buffers.Tx_buffer.Payload, Srb0->srb_buffers.Tx_buffer.payload_size);
for (int i = 0; i < Srb0->srb_buffers.Tx_buffer.payload_size; i++) {
LOG_D(NR_RRC,"(%i): %i\n", i, buffer_pP[i]); LOG_D(NR_RRC,"(%i): %i\n", i, buffer_pP[i]);
} }
return NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size; return Srb0->srb_buffers.Tx_buffer.payload_size;
case DCCH: case DCCH:
AssertFatal(1==0, "SRB1 not implemented yet!\n"); AssertFatal(1==0, "SRB1 not implemented yet!\n");
......
...@@ -97,13 +97,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( ...@@ -97,13 +97,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
uint8_t gNB_index uint8_t gNB_index
); );
void
nr_rrc_ue_process_RadioBearerConfig(
const protocol_ctxt_t *const ctxt_pP,
const uint8_t gNB_index,
NR_RadioBearerConfig_t *const radioBearerConfig
);
uint8_t do_NR_RRCReconfigurationComplete( uint8_t do_NR_RRCReconfigurationComplete(
const protocol_ctxt_t *const ctxt_pP, const protocol_ctxt_t *const ctxt_pP,
uint8_t *buffer, uint8_t *buffer,
...@@ -120,70 +113,9 @@ nr_rrc_ue_generate_rrcReestablishmentComplete( ...@@ -120,70 +113,9 @@ nr_rrc_ue_generate_rrcReestablishmentComplete(
mui_t nr_rrc_mui=0; mui_t nr_rrc_mui=0;
static void nr_rrc_addmod_srbs(int rnti,
const NR_SRB_ToAddModList_t *srb_list,
const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list)
{
if (srb_list == NULL || bearer_list == NULL)
return;
for (int i = 0; i < srb_list->list.count; i++) {
const NR_SRB_ToAddMod_t *srb = srb_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_srb_Identity
&& srb->srb_Identity == bearer->servedRadioBearer->choice.srb_Identity) {
nr_rlc_add_srb(rnti, srb->srb_Identity, bearer);
}
}
}
}
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, NR_CellGroupConfig_t *cell_group_config)
const uint8_t *buffer, {
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
...@@ -197,8 +129,8 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, ...@@ -197,8 +129,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){
...@@ -212,16 +144,31 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR ...@@ -212,16 +144,31 @@ 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;
}
if(get_softmodem_params()->sa || get_softmodem_params()->nsa) { if (get_softmodem_params()->sa || get_softmodem_params()->nsa)
nr_rrc_manage_rlc_bearers(cellGroupConfig, &NR_UE_rrc_inst[module_id], 0, module_id, NR_UE_rrc_inst[module_id].rnti);
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 (get_softmodem_params()->sa || get_softmodem_params()->nsa) {
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);
} }
...@@ -241,11 +188,8 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR ...@@ -241,11 +188,8 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR
if (get_softmodem_params()->nsa) { if (get_softmodem_params()->nsa) {
nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig); nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig);
} }
} } else
else nr_rrc_ue_decode_secondary_cellgroup_config(module_id, cellGroupConfig);
nr_rrc_ue_decode_secondary_cellgroup_config(module_id,
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){
...@@ -272,15 +216,13 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR ...@@ -272,15 +216,13 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR
return 0; return 0;
} }
int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){ int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){
return 0; return 0;
} }
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len)
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message,int msg_len) { {
module_id_t module_id=0; // TODO module_id_t module_id=0; // TODO
switch (nsa_message_type) { switch (nsa_message_type) {
case nr_SecondaryCellGroupConfig_r15: case nr_SecondaryCellGroupConfig_r15:
...@@ -322,7 +264,6 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, ...@@ -322,7 +264,6 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, ENB_FLAG_YES, mac->crnti, 0, 0, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, ENB_FLAG_YES, mac->crnti, 0, 0, 0);
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)RadioBearerConfig);
LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig() at %d with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n", LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig() at %d with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n",
__LINE__, RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity, __LINE__, RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity,
RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity, RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity,
...@@ -341,7 +282,6 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, ...@@ -341,7 +282,6 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
AssertFatal(1==0,"Unknown message %d\n",nsa_message_type); AssertFatal(1==0,"Unknown message %d\n",nsa_message_type);
break; break;
} }
} }
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file) NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file)
...@@ -357,15 +297,21 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi ...@@ -357,15 +297,21 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi
rrc->ubwpd = NULL; rrc->ubwpd = NULL;
rrc->as_security_activated = false; rrc->as_security_activated = false;
for (int i = 0; i < NB_SIG_CNX_UE; i++) for (int i = 0; i < NB_CNX_UE; i++) {
memset((void *)&rrc->SInfo[i], 0, sizeof(rrc->SInfo[i])); memset((void *)&rrc->SInfo[i], 0, sizeof(rrc->SInfo[i]));
for (int j = 0; j < NR_NUM_SRB; j++)
memset((void *)&rrc->Srb[i][j], 0, sizeof(rrc->Srb[i][j]));
for (int j = 0; j < MAX_DRBS_PER_UE; j++)
rrc->active_DRBs[i][j] = false;
// SRB0 activated by default
rrc->Srb[i][0].status = RB_ESTABLISHED;
}
rrc->ra_trigger = RA_NOT_RUNNING; rrc->ra_trigger = RA_NOT_RUNNING;
} }
NR_UE_rrc_inst->uecap_file = uecap_file; NR_UE_rrc_inst->uecap_file = uecap_file;
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) { if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
// read in files for RRCReconfiguration and RBconfig // read in files for RRCReconfiguration and RBconfig
LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file); LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file);
...@@ -389,10 +335,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi ...@@ -389,10 +335,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi
strerror(errno)); strerror(errno));
msg_len=fread(buffer,1,1024,fd); msg_len=fread(buffer,1,1024,fd);
fclose(fd); fclose(fd);
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len);
} } else if (get_softmodem_params()->nsa) {
else if (get_softmodem_params()->nsa)
{
LOG_D(NR_RRC, "In NSA mode \n"); LOG_D(NR_RRC, "In NSA mode \n");
} }
...@@ -407,11 +351,6 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi ...@@ -407,11 +351,6 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi
return NR_UE_rrc_inst; return NR_UE_rrc_inst;
} }
int8_t nr_ue_process_rlc_bearer_list(NR_CellGroupConfig_t *cell_group_config){
return 0;
}
int8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){ int8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){
return 0; return 0;
...@@ -810,6 +749,47 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, ...@@ -810,6 +749,47 @@ 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,
module_id_t module_id,
int rnti)
{
if (cellGroupConfig->rlc_BearerToReleaseList != NULL) {
for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i];
AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n");
nr_release_rlc_entity(rnti, *lcid);
}
}
if (cellGroupConfig->rlc_BearerToAddModList != NULL) {
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);
}
}
}
}
nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id,
cellGroupConfig->rlc_BearerToAddModList,
cellGroupConfig->rlc_BearerToReleaseList);
}
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,
...@@ -833,20 +813,7 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, ...@@ -833,20 +813,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->module_id, 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)
...@@ -955,13 +922,11 @@ void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config) ...@@ -955,13 +922,11 @@ void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config)
} }
} }
/*--------------------------------------------------*/ static void rrc_ue_generate_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP,
static void rrc_ue_generate_RRCSetupComplete( const uint8_t gNB_index,
const protocol_ctxt_t *const ctxt_pP, const uint8_t Transaction_id,
const uint8_t gNB_index, uint8_t sel_plmn_id)
const uint8_t Transaction_id, {
uint8_t sel_plmn_id){
uint8_t buffer[100]; uint8_t buffer[100];
uint8_t size; uint8_t size;
const char *nas_msg; const char *nas_msg;
...@@ -980,47 +945,59 @@ static void rrc_ue_generate_RRCSetupComplete( ...@@ -980,47 +945,59 @@ static void rrc_ue_generate_RRCSetupComplete(
size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer), size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer),
Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); Transaction_id, sel_plmn_id, nas_msg_length, nas_msg);
LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", LOG_I(NR_RRC,
ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); "[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n",
ctxt_pP->module_id,
ctxt_pP->frame,
size,
gNB_index);
int srb_id = 1; // RRC setup complete on SRB1
LOG_D(NR_RRC, LOG_D(NR_RRC,
"[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB "
"%02d]\n",
ctxt_pP->frame, ctxt_pP->frame,
ctxt_pP->module_id, ctxt_pP->module_id,
size, size,
gNB_index, gNB_index,
nr_rrc_mui, nr_rrc_mui,
ctxt_pP->module_id + NB_eNB_INST, ctxt_pP->module_id + NB_eNB_INST,
DCCH); srb_id);
//for (int i=0;i<size;i++) printf("%02x ",buffer[i]); nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
//printf("\n");
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
} }
int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ) int8_t nr_rrc_ue_decode_ccch(const protocol_ctxt_t *const ctxt_pP, const NR_UE_RRC_SRB_INFO_t *Srb_info, const uint8_t gNB_index)
{ {
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
asn_dec_rval_t dec_rval; asn_dec_rval_t dec_rval;
int rval=0; int rval=0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
LOG_D(RRC,"[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n",ctxt_pP->module_id,Srb_info->Rx_buffer.payload_size, LOG_D(RRC,
"[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n",
ctxt_pP->module_id,
Srb_info->srb_buffers.Rx_buffer.payload_size,
rrc->nrRrcState); rrc->nrRrcState);
dec_rval = uper_decode(NULL, dec_rval = uper_decode(NULL,
&asn_DEF_NR_DL_CCCH_Message, &asn_DEF_NR_DL_CCCH_Message,
(void **)&dl_ccch_msg, (void **)&dl_ccch_msg,
(uint8_t *)Srb_info->Rx_buffer.Payload, (uint8_t *)Srb_info->srb_buffers.Rx_buffer.Payload,
Srb_info->Rx_buffer.payload_size,0,0); Srb_info->srb_buffers.Rx_buffer.payload_size,
0,
// if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { 0);
xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
// } // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)dl_ccch_msg);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { // }
LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
return -1; LOG_E(RRC,
"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",
ctxt_pP->module_id,
ctxt_pP->frame,
dec_rval.consumed);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
return -1;
} }
if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
...@@ -1159,7 +1136,7 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, ...@@ -1159,7 +1136,7 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP,
asn_enc_rval_t enc_rval; asn_enc_rval_t enc_rval;
NR_UL_DCCH_Message_t ul_dcch_msg; NR_UL_DCCH_Message_t ul_dcch_msg;
uint8_t buffer[200]; uint8_t buffer[200];
int i, securityMode; int securityMode;
LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index); ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index);
...@@ -1263,7 +1240,11 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, ...@@ -1263,7 +1240,11 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP,
if (securityMode != 0xff) { if (securityMode != 0xff) {
uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4); uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4);
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, security_mode, kRRCenc, kRRCint, kUPenc); // configure lower layers to apply SRB integrity protection and ciphering
for (int i = 1; i < NR_NUM_SRB; i++) {
if (ue_rrc->Srb[gNB_index][i].status == RB_ESTABLISHED)
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, i, security_mode, kRRCenc, kRRCint, kUPenc);
}
} else { } else {
LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
} }
...@@ -1290,7 +1271,7 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, ...@@ -1290,7 +1271,7 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP,
log_dump(NR_RRC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: "); log_dump(NR_RRC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: ");
LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) { for (int i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
LOG_T(NR_RRC, "%02x.", buffer[i]); LOG_T(NR_RRC, "%02x.", buffer[i]);
} }
LOG_T(NR_RRC, "\n"); LOG_T(NR_RRC, "\n");
...@@ -1298,122 +1279,52 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, ...@@ -1298,122 +1279,52 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP,
//TODO the SecurityModeCommand message needs to pass the integrity protection check //TODO the SecurityModeCommand message needs to pass the integrity protection check
// for the UE to declare AS security to be activated // for the UE to declare AS security to be activated
ue_rrc->as_security_activated = true; ue_rrc->as_security_activated = true;
int srb_id = 1; // SecurityModeComplete in SRB1
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid,
srb_id,
nr_rrc_mui++,
(enc_rval.encoded + 7) / 8,
buffer,
deliver_pdu_srb_rlc,
NULL);
} else } else
LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n",
securityModeCommand->criticalExtensions.present); securityModeCommand->criticalExtensions.present);
} }
//----------------------------------------------------------------------------- void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) {
uint8_t i=0,rv[6];
if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) {
// Get RRCConnectionRequest, fill random for now
// Generate random byte stream for contention resolution
for (i=0; i<6; i++) {
#ifdef SMBV
// if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
rv[i]=i;
#else
rv[i]=taus()&0xff;
#endif
LOG_T(NR_RRC,"%x.",rv[i]);
}
LOG_T(NR_RRC,"\n");
NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size =
do_RRCSetupRequest(
module_id,
(uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload,
sizeof(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload),
rv);
LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n",
module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
for (i=0; i<NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
//printf("%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
}
LOG_T(NR_RRC,"\n");
//printf("\n");
/*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff;
UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */
}
}
//-----------------------------------------------------------------------------
int32_t
nr_rrc_ue_establish_srb1(
module_id_t ue_mod_idP,
frame_t frameP,
uint8_t gNB_index,
NR_SRB_ToAddMod_t *SRB_config
)
//-----------------------------------------------------------------------------
{ {
// add descriptor from RRC PDU uint8_t rv[6];
NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Active = 1; NR_UE_RRC_SRB_INFO_t *Srb0 = &NR_UE_rrc_inst[module_id].Srb[gNB_index][0];
NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].status = RADIO_CONFIG_OK; // RADIO CFG if (Srb0->srb_buffers.Tx_buffer.payload_size == 0) {
LOG_I(NR_RRC, "[UE %d], CONFIG_SRB1 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH, gNB_index); // Get RRCConnectionRequest, fill random for now
return(0); // Generate random byte stream for contention resolution
} for (int i = 0; i < 6; i++) {
#ifdef SMBV
// if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
rv[i] = i;
#else
rv[i] = taus() & 0xff;
#endif
LOG_T(NR_RRC, "%x.", rv[i]);
}
int32_t nr_rrc_ue_establish_srb2(module_id_t ue_mod_idP, LOG_T(NR_RRC, "\n");
frame_t frameP, Srb0->srb_buffers.Tx_buffer.payload_size = do_RRCSetupRequest(module_id,
uint8_t gNB_index, (uint8_t *)Srb0->srb_buffers.Tx_buffer.Payload,
NR_SRB_ToAddMod_t *SRB_config) sizeof(Srb0->srb_buffers.Tx_buffer.Payload),
{ rv);
// add descriptor from RRC PDU LOG_I(NR_RRC,
NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Active = 1; "[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n",
NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].status = RADIO_CONFIG_OK; // RADIO CFG module_id,
LOG_I(NR_RRC, "[UE %d], CONFIG_SRB2 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH1, gNB_index); Srb0->srb_buffers.Tx_buffer.payload_size,
return(0); gNB_index);
}
for (int i = 0; i < Srb0->srb_buffers.Tx_buffer.payload_size; i++)
LOG_T(NR_RRC, "%x.", Srb0->srb_buffers.Tx_buffer.Payload[i]);
int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, LOG_T(NR_RRC, "\n");
frame_t frameP,
uint8_t gNB_index,
NR_DRB_ToAddMod_t *DRB_config)
{
// add descriptor from RRC PDU
int oip_ifup = 0, ip_addr_offset3 = 0, ip_addr_offset4 = 0;
/* avoid gcc warnings */
(void)oip_ifup;
(void)ip_addr_offset3;
(void)ip_addr_offset4;
LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n",
ue_mod_idP, frameP, DRB_config->drb_Identity);
if(!get_softmodem_params()->sa) {
ip_addr_offset3 = 0;
ip_addr_offset4 = 1;
LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1);
oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id
UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet
ip_addr_offset4+ue_mod_idP+1, // fourth_octet
"oip"); // interface suffix (when using kernel module)
if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n",
ue_mod_idP,
ip_addr_offset3+ue_mod_idP,
(long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity));
rb_conf_ipv4(0,//add
ue_mod_idP,//cx align with the UE index
ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
(gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb
0,//dscp
ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr
ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr
LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index);
}
} }
return(0);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -1540,35 +1451,33 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, ...@@ -1540,35 +1451,33 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
} }
} }
//----------------------------------------------------------------------------- void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP,
void const uint8_t gNB_index,
nr_rrc_ue_process_RadioBearerConfig( NR_RadioBearerConfig_t *const radioBearerConfig)
const protocol_ctxt_t *const ctxt_pP,
const uint8_t gNB_index,
NR_RadioBearerConfig_t *const radioBearerConfig
)
//-----------------------------------------------------------------------------
{ {
long SRB_id, DRB_id; if (LOG_DEBUGFLAG(DEBUG_ASN1))
int i, cnt; xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)radioBearerConfig);
if( radioBearerConfig->srb3_ToRelease != NULL){
if( *radioBearerConfig->srb3_ToRelease == true){
//TODO (release the PDCP entity and the srb-Identity of the SRB3.)
}
}
NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
if (radioBearerConfig->srb_ToAddModList != NULL) { if (radioBearerConfig->srb3_ToRelease)
nr_release_srb(ctxt_pP->rntiMaybeUEid, 3);
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
if (ue_rrc->as_security_activated) {
if (radioBearerConfig->securityConfig != NULL) { if (radioBearerConfig->securityConfig != NULL) {
if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) { // When the field is not included, continue to use the currently configured keyToUse
ue_rrc->cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; if (radioBearerConfig->securityConfig->keyToUse) {
ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; AssertFatal(*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master,
"Secondary key usage seems not to be implemented\n");
ue_rrc->keyToUse = *radioBearerConfig->securityConfig->keyToUse;
}
// When the field is not included, continue to use the currently configured security algorithm
if (radioBearerConfig->securityConfig->securityAlgorithmConfig) {
ue_rrc->cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm;
ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm;
} }
} }
uint8_t kRRCenc[16] = {0};
uint8_t kRRCint[16] = {0};
nr_derive_key(RRC_ENC_ALG, nr_derive_key(RRC_ENC_ALG,
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
...@@ -1577,137 +1486,65 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, ...@@ -1577,137 +1486,65 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
kRRCint); kRRCint);
}
// Refresh SRBs if (radioBearerConfig->srb_ToAddModList != NULL) {
nr_pdcp_add_srbs(ctxt_pP->enb_flag, for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
ctxt_pP->rntiMaybeUEid, struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt];
radioBearerConfig->srb_ToAddModList, NR_UE_RRC_SRB_INFO_t *Srb_info = &ue_rrc->Srb[gNB_index][srb->srb_Identity];
ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4), if (Srb_info->status == RB_NOT_PRESENT)
kRRCenc, add_srb(ctxt_pP->enb_flag,
kRRCint); ctxt_pP->rntiMaybeUEid,
// Refresh SRBs radioBearerConfig->srb_ToAddModList->list.array[cnt],
nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_rrc->cipheringAlgorithm,
radioBearerConfig->srb_ToAddModList, ue_rrc->integrityProtAlgorithm,
ue_rrc->cell_group_config->rlc_BearerToAddModList); kRRCenc,
kRRCint);
for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { else {
SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity; AssertFatal(srb->discardOnPDCP == NULL, "discardOnPDCP not yet implemented\n");
LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id); AssertFatal(srb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n");
if (SRB_id == 1) { if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering)
if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) { nr_pdcp_reconfigure_srb(ctxt_pP->rntiMaybeUEid, srb->srb_Identity, *srb->pdcp_Config->t_Reordering);
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index], }
radioBearerConfig->srb_ToAddModList->list.array[cnt], Srb_info->status = RB_ESTABLISHED;
sizeof(NR_SRB_ToAddMod_t));
} else {
NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
nr_rrc_ue_establish_srb1(ctxt_pP->module_id,
ctxt_pP->frame,
gNB_index,
radioBearerConfig->srb_ToAddModList->list.array[cnt]);
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,1,true); //todo handle mac_LogicalChannelConfig
// rrc_mac_config_req_ue
}
} else {
if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) {
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index],
radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t));
} else {
NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
nr_rrc_ue_establish_srb2(ctxt_pP->module_id,
ctxt_pP->frame,
gNB_index,
radioBearerConfig->srb_ToAddModList->list.array[cnt]);
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,2,true); //todo handle mac_LogicalChannelConfig
// rrc_mac_config_req_ue
}
} // srb2
} }
} // srb_ToAddModList }
// Establish DRBs if present if (radioBearerConfig->drb_ToReleaseList) {
if (radioBearerConfig->drb_ToAddModList != NULL) { for (int cnt = 0; cnt < radioBearerConfig->drb_ToReleaseList->list.count; cnt++) {
if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) && NR_DRB_Identity_t *DRB_id = radioBearerConfig->drb_ToReleaseList->list.array[cnt];
(radioBearerConfig->drb_ToAddModList->list.count >= 1)) { if (DRB_id)
NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t)); nr_release_drb(ctxt_pP->rntiMaybeUEid, *DRB_id);
*NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity;
} }
}
for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { // Establish DRBs if present
DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity; if (radioBearerConfig->drb_ToAddModList != NULL) {
if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) { for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1], struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt];
radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t)); int DRB_id = drb->drb_Identity;
if (ue_rrc->active_DRBs[gNB_index][DRB_id]) {
AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n");
AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n");
if (drb->pdcp_Config && drb->pdcp_Config->t_Reordering)
nr_pdcp_reconfigure_drb(ctxt_pP->rntiMaybeUEid, DRB_id, *drb->pdcp_Config->t_Reordering);
if (drb->cnAssociation)
AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n");
} else { } else {
//LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]); ue_rrc->active_DRBs[gNB_index][DRB_id] = true;
NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt]; add_drb(ctxt_pP->enb_flag,
int j; ctxt_pP->rntiMaybeUEid,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list = NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList; radioBearerConfig->drb_ToAddModList->list.array[cnt],
if (rlc_bearer2add_list != NULL) { ue_rrc->cipheringAlgorithm,
for(j = 0; j < rlc_bearer2add_list->list.count; j++){ ue_rrc->integrityProtAlgorithm,
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){ kRRCenc,
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){ kRRCint);
if(DRB_id == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB lcid %ld gNB %d) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, rlc_bearer2add_list->list.array[j]->logicalChannelIdentity, 0, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,rlc_bearer2add_list->list.array[j]->logicalChannelIdentity,true); //todo handle mac_LogicalChannelConfig
}
}
}
}
}
} }
} }
uint8_t kUPenc[16] = {0};
uint8_t kUPint[16] = {0};
nr_derive_key(UP_ENC_ALG,
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
kUPenc);
nr_derive_key(UP_INT_ALG,
NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
kUPint);
// Refresh DRBs
nr_pdcp_add_drbs(ctxt_pP->enb_flag,
ctxt_pP->rntiMaybeUEid,
radioBearerConfig->drb_ToAddModList,
ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4),
kUPenc,
kUPint,
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 //
if (radioBearerConfig->drb_ToReleaseList != NULL) {
for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) {
DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i];
free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]);
}
}
if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList != NULL) {
for (i = 0; i < NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.count; i++) {
NR_LogicalChannelIdentity_t lcid = *NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.array[i];
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (RB lcid %ld gNB %d release) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, lcid, 0, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,lcid,false); //todo handle mac_LogicalChannelConfig
}
}
NR_UE_rrc_inst[ctxt_pP->module_id].nrRrcState = RRC_STATE_CONNECTED_NR; NR_UE_rrc_inst[ctxt_pP->module_id].nrRrcState = RRC_STATE_CONNECTED_NR;
LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); LOG_I(NR_RRC, "[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -1763,53 +1600,54 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, ...@@ -1763,53 +1600,54 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
} }
} }
//----------------------------------------------------------------------------- void nr_rrc_ue_generate_RRCReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP,
void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t Transaction_id ) { const uint8_t gNB_index,
const int srb_id,
const uint8_t Transaction_id)
{
uint8_t buffer[32], size; uint8_t buffer[32], size;
size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id); size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id);
LOG_I(NR_RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n", LOG_I(NR_RRC,
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, gNB_index); PROTOCOL_RRC_CTXT_UE_FMT
" Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
size,
gNB_index);
AssertFatal(srb_id == 1 || srb_id == 3, "Invalid SRB ID %d\n", srb_id);
LOG_D(RLC, LOG_D(RLC,
"[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n", "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) "
ctxt_pP->frame, "--->][PDCP][INST %02d][RB %02d]\n",
UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), ctxt_pP->frame,
size, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
gNB_index, size,
nr_rrc_mui, gNB_index,
UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), nr_rrc_mui,
DCCH); UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL); srb_id);
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
} }
// from NR SRB1 int nr_rrc_ue_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
//----------------------------------------------------------------------------- const srb_id_t Srb_id,
int const uint8_t *const Buffer,
nr_rrc_ue_decode_dcch( size_t Buffer_size,
const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_indexP)
const srb_id_t Srb_id,
const uint8_t *const Buffer,
size_t Buffer_size,
const uint8_t gNB_indexP
)
//-----------------------------------------------------------------------------
{ {
asn_dec_rval_t dec_rval; asn_dec_rval_t dec_rval;
NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; NR_DL_DCCH_Message_t *dl_dcch_msg = NULL;
MessageDef *msg_p; MessageDef *msg_p;
if (Srb_id != 1 && Srb_id != 2) { if (Srb_id != 1 && Srb_id != 2) {
LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", LOG_E(NR_RRC,
ctxt_pP->module_id, ctxt_pP->frame, Srb_id); "[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
ctxt_pP->module_id,
ctxt_pP->frame,
Srb_id);
} }
LOG_D(NR_RRC, "Decoding DL-DCCH Message\n"); LOG_D(NR_RRC, "Decoding DL-DCCH Message\n");
dec_rval = uper_decode( NULL, dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_DCCH_Message, (void **)&dl_dcch_msg, Buffer, Buffer_size, 0, 0);
&asn_DEF_NR_DL_DCCH_Message,
(void **)&dl_dcch_msg,
Buffer,
Buffer_size,
0,
0);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed);
...@@ -1817,8 +1655,8 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, ...@@ -1817,8 +1655,8 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
return -1; return -1;
} }
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg); xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)dl_dcch_msg);
} }
if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) { if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) {
...@@ -1827,58 +1665,51 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, ...@@ -1827,58 +1665,51 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n"); LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n");
break; break;
case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: {
{ rrc_ue_process_rrcReconfiguration(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, gNB_indexP);
rrc_ue_process_rrcReconfiguration(ctxt_pP, nr_rrc_ue_generate_RRCReconfigurationComplete(
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, ctxt_pP,
gNB_indexP); gNB_indexP,
nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP, Srb_id,
gNB_indexP, dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
break; break;
} }
case NR_DL_DCCH_MessageType__c1_PR_rrcResume: case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n", LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n", ctxt_pP->module_id, gNB_indexP);
ctxt_pP->module_id, gNB_indexP);
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == if ((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present
NR_RRCRelease__criticalExtensions_PR_rrcRelease) && == NR_RRCRelease__criticalExtensions_PR_rrcRelease)
(dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)) { && (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)) {
dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; ->deprioritisationTimer = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; ->deprioritisationType = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
} }
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
break; break;
case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id,gNB_indexP); LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id, gNB_indexP);
nr_rrc_ue_process_ueCapabilityEnquiry( nr_rrc_ue_process_ueCapabilityEnquiry(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, gNB_indexP);
ctxt_pP,
dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry,
gNB_indexP);
break; break;
case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
LOG_I(NR_RRC, LOG_I(NR_RRC,
"[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n", "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n",
ctxt_pP->module_id, ctxt_pP->module_id,
ctxt_pP->frame); ctxt_pP->frame);
nr_rrc_ue_generate_rrcReestablishmentComplete( nr_rrc_ue_generate_rrcReestablishmentComplete(ctxt_pP,
ctxt_pP, dl_dcch_msg->message.choice.c1->choice.rrcReestablishment,
dl_dcch_msg->message.choice.c1->choice.rrcReestablishment, gNB_indexP);
gNB_indexP);
break; break;
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: {
{
NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer; NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer;
if (dlInformationTransfer->criticalExtensions.present if (dlInformationTransfer->criticalExtensions.present
== NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) { == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) {
/* This message hold a dedicated info NAS payload, forward it to NAS */ /* This message hold a dedicated info NAS payload, forward it to NAS */
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NR_DedicatedNAS_Message_t *dedicatedNAS_Message =
dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message; dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message;
...@@ -1890,8 +1721,7 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, ...@@ -1890,8 +1721,7 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf; NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf;
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
} }
} } break;
break;
case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
...@@ -1903,11 +1733,8 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, ...@@ -1903,11 +1733,8 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
case NR_DL_DCCH_MessageType__c1_PR_counterCheck: case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
break; break;
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", ctxt_pP->module_id, gNB_indexP);
ctxt_pP->module_id, gNB_indexP); nr_rrc_ue_process_securityModeCommand(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.securityModeCommand, gNB_indexP);
nr_rrc_ue_process_securityModeCommand(ctxt_pP,
dl_dcch_msg->message.choice.c1->choice.securityModeCommand,
gNB_indexP);
break; break;
} }
} }
...@@ -1932,7 +1759,6 @@ void *rrc_nrue_task(void *args_p) ...@@ -1932,7 +1759,6 @@ void *rrc_nrue_task(void *args_p)
instance_t instance; instance_t instance;
unsigned int ue_mod_id; unsigned int ue_mod_id;
int result; int result;
NR_SRB_INFO *srb_info_p;
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
itti_mark_task_ready(TASK_RRC_NRUE); itti_mark_task_ready(TASK_RRC_NRUE);
...@@ -2008,15 +1834,12 @@ void *rrc_nrue_task(void *args_p) ...@@ -2008,15 +1834,12 @@ void *rrc_nrue_task(void *args_p)
ITTI_MSG_NAME (msg_p), ITTI_MSG_NAME (msg_p),
NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame,
NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index]; NR_UE_RRC_SRB_INFO_t *srb0 = &NR_UE_rrc_inst[ue_mod_id].Srb[NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index][0];
memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu, memcpy(srb0->srb_buffers.Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size); srb0->srb_buffers.Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size;
srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
// PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
nr_rrc_ue_decode_ccch (&ctxt, nr_rrc_ue_decode_ccch(&ctxt, srb0, NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index);
srb_info_p,
NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
break; break;
/* PDCP messages */ /* PDCP messages */
...@@ -2077,8 +1900,8 @@ void *rrc_nrue_task(void *args_p) ...@@ -2077,8 +1900,8 @@ void *rrc_nrue_task(void *args_p)
length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data);
/* Transfer data to PDCP */ /* Transfer data to PDCP */
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0,0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0,0);
// check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) // check if SRB2 is created, if yes request data_req on SRB2
rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL ? DCCH : DCCH1; rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].Srb[0][2].status == RB_ESTABLISHED ? 2 : 1;
nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL); nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL);
break; break;
} }
...@@ -2115,14 +1938,9 @@ void nr_rrc_ue_process_sidelink_radioResourceConfig( ...@@ -2115,14 +1938,9 @@ void nr_rrc_ue_process_sidelink_radioResourceConfig(
} }
} }
//----------------------------------------------------------------------------- void nr_rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
void NR_UECapabilityEnquiry_t *UECapabilityEnquiry,
nr_rrc_ue_process_ueCapabilityEnquiry( uint8_t gNB_index)
const protocol_ctxt_t *const ctxt_pP,
NR_UECapabilityEnquiry_t *UECapabilityEnquiry,
uint8_t gNB_index
)
//-----------------------------------------------------------------------------
{ {
asn_enc_rval_t enc_rval; asn_enc_rval_t enc_rval;
asn_dec_rval_t dec_rval; asn_dec_rval_t dec_rval;
...@@ -2131,7 +1949,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( ...@@ -2131,7 +1949,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
char UE_NR_Capability_xer[65536]; char UE_NR_Capability_xer[65536];
size_t size; size_t size;
uint8_t buffer[500]; uint8_t buffer[500];
int i;
LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n", LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n",
ctxt_pP->module_id, ctxt_pP->module_id,
ctxt_pP->frame, ctxt_pP->frame,
...@@ -2139,10 +1956,10 @@ nr_rrc_ue_process_ueCapabilityEnquiry( ...@@ -2139,10 +1956,10 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t)); memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t));
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation;
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation)); ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation));
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr; ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
NR_UE_NR_Capability_t* UE_Capability_nr = NULL; NR_UE_NR_Capability_t* UE_Capability_nr = NULL;
...@@ -2193,8 +2010,9 @@ nr_rrc_ue_process_ueCapabilityEnquiry( ...@@ -2193,8 +2010,9 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
(const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability, (const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability,
NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size); NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size);
NR_UECapabilityEnquiry_IEs_t *ueCapabilityEnquiry_ie = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry;
if (get_softmodem_params()->nsa == 1) { if (get_softmodem_params()->nsa == 1) {
OCTET_STRING_t * requestedFreqBandsNR = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityEnquiryExt; OCTET_STRING_t *requestedFreqBandsNR = ueCapabilityEnquiry_ie->ue_CapabilityEnquiryExt;
nsa_sendmsg_to_lte_ue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_INFO); nsa_sendmsg_to_lte_ue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_INFO);
} }
// ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[ue_mod_idP].UECapability; // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[ue_mod_idP].UECapability;
...@@ -2203,27 +2021,34 @@ nr_rrc_ue_process_ueCapabilityEnquiry( ...@@ -2203,27 +2021,34 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
"UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n", "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n",
UECapabilityEnquiry->criticalExtensions.present,NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry); UECapabilityEnquiry->criticalExtensions.present,NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry);
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation; NR_UECapabilityInformation_t *ueCapabilityInformation = ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation;
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs)); ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation;
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList = CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList)); ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation =
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0; CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs));
ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList =
for (i=0; i<UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.count; i++) { CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList));
if (UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0;
== NR_RAT_Type_nr) {
asn1cSeqAdd( for (int i = 0; i < ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.count; i++) {
&ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list, if (ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type == NR_RAT_Type_nr) {
&ue_CapabilityRAT_Container); asn1cSeqAdd(&ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list,
&ue_CapabilityRAT_Container);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 500); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 500);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
enc_rval.failed_type->name, enc_rval.encoded); enc_rval.failed_type->name, enc_rval.encoded);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
} }
LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); int srb_id = 1; // UECapabilityInformation on SRB1
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid,
srb_id,
nr_rrc_mui++,
(enc_rval.encoded + 7) / 8,
buffer,
deliver_pdu_srb_rlc,
NULL);
} }
} }
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "platform_types.h" #include "platform_types.h"
#include "commonDef.h" #include "commonDef.h"
#include "common/platform_constants.h"
#include "NR_asn_constant.h" #include "NR_asn_constant.h"
#include "NR_MeasConfig.h" #include "NR_MeasConfig.h"
...@@ -56,11 +57,10 @@ ...@@ -56,11 +57,10 @@
#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
#define NB_SIG_CNX_UE 2 //MAX_MANAGED_RG_PER_MOBILE
#define MAX_MEAS_OBJ 7 #define MAX_MEAS_OBJ 7
#define MAX_MEAS_CONFIG 7 #define MAX_MEAS_CONFIG 7
#define MAX_MEAS_ID 7 #define MAX_MEAS_ID 7
...@@ -178,6 +178,13 @@ typedef enum { ...@@ -178,6 +178,13 @@ typedef enum {
IN_SYNC = 1 IN_SYNC = 1
} nr_sync_msg_t; } nr_sync_msg_t;
typedef enum { RB_NOT_PRESENT, RB_ESTABLISHED, RB_SUSPENDED } NR_RB_status_t;
typedef struct NR_UE_RRC_SRB_INFO_s {
NR_RB_status_t status;
NR_SRB_INFO srb_buffers;
} NR_UE_RRC_SRB_INFO_t;
typedef struct NR_UE_RRC_INST_s { typedef struct NR_UE_RRC_INST_s {
NR_MeasConfig_t *meas_config; NR_MeasConfig_t *meas_config;
NR_CellGroupConfig_t *cell_group_config; NR_CellGroupConfig_t *cell_group_config;
...@@ -191,17 +198,13 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -191,17 +198,13 @@ typedef struct NR_UE_RRC_INST_s {
NR_MeasIdToAddMod_t *MeasId[NB_CNX_UE][MAX_MEAS_ID]; NR_MeasIdToAddMod_t *MeasId[NB_CNX_UE][MAX_MEAS_ID];
NR_MeasGapConfig_t *measGapConfig[NB_CNX_UE]; NR_MeasGapConfig_t *measGapConfig[NB_CNX_UE];
NR_RSRP_Range_t s_measure; NR_RSRP_Range_t s_measure;
NR_SRB_ToAddMod_t *SRB1_config[NB_CNX_UE];
NR_SRB_ToAddMod_t *SRB2_config[NB_CNX_UE];
NR_DRB_ToAddMod_t *DRB_config[NB_CNX_UE][8];
rb_id_t *defaultDRB; // remember the ID of the default DRB
char *uecap_file; char *uecap_file;
rnti_t rnti; rnti_t rnti;
NR_SRB_INFO Srb0[NB_SIG_CNX_UE]; NR_UE_RRC_SRB_INFO_t Srb[NB_CNX_UE][NR_NUM_SRB];
NR_SRB_INFO_TABLE_ENTRY Srb1[NB_CNX_UE]; bool active_DRBs[NB_CNX_UE][MAX_DRBS_PER_UE];
NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE]; 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;
...@@ -213,7 +216,7 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -213,7 +216,7 @@ typedef struct NR_UE_RRC_INST_s {
plmn_t plmnID; plmn_t plmnID;
NR_UE_RRC_SI_INFO SInfo[NB_SIG_CNX_UE]; NR_UE_RRC_SI_INFO SInfo[NB_CNX_UE];
NR_MIB_t *mib; NR_MIB_t *mib;
...@@ -227,6 +230,7 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -227,6 +230,7 @@ typedef struct NR_UE_RRC_INST_s {
//RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list; //RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list;
NR_CipheringAlgorithm_t cipheringAlgorithm; NR_CipheringAlgorithm_t cipheringAlgorithm;
e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; e_NR_IntegrityProtAlgorithm integrityProtAlgorithm;
long keyToUse;
bool as_security_activated; bool as_security_activated;
long selected_plmn_identity; long selected_plmn_identity;
......
...@@ -65,14 +65,6 @@ NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *); ...@@ -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);
...@@ -81,9 +73,9 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR ...@@ -81,9 +73,9 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR
\param meas_config measurement configuration*/ \param meas_config measurement configuration*/
int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config); int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config);
/**\prief Process radio bearer config from NR RRC connection reconfiguration message void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP,
\param radio_bearer_config radio bearer configuration*/ const uint8_t gNB_index,
int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_bearer_config); NR_RadioBearerConfig_t *const radioBearerConfig);
/**\brief decode NR BCCH-BCH (MIB) message /**\brief decode NR BCCH-BCH (MIB) message
\param module_idP module id \param module_idP module id
...@@ -171,6 +163,12 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, ...@@ -171,6 +163,12 @@ 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,
module_id_t module_id,
int rnti);
int configure_NR_SL_Preconfig(int sync_source); int configure_NR_SL_Preconfig(int sync_source);
/** @}*/ /** @}*/
#endif #endif
......
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