diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 2c136467f6..1d332e3bc8 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -357,7 +357,7 @@ static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_inf AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - uint8_t nr_prach = nr_ue_get_rach(prach_resources, + uint8_t nr_prach = nr_ue_get_rach_nsa(prach_resources, prach_pdu, ul_info->module_id, ul_info->cc_id, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index a9632fb330..b02aa10cc8 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -415,6 +415,16 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t gNB_id, int nr_slot_tx); +uint8_t nr_ue_get_rach_nsa(NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, + module_id_t mod_id, + int CC_id, + frame_t frame, + uint8_t gNB_id, + int nr_slot_tx); + + + /* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321). @param module_idP Index of UE instance @param CC_id Component Carrier Index diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index c30d808b99..6714750a3c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -657,7 +657,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot * @gNB_id gNB ID * @nr_slot_tx current UL TX slot */ -uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, +uint8_t nr_ue_get_rach_nsa(NR_PRACH_RESOURCES_t *prach_resources, fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, int CC_id, @@ -848,6 +848,209 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } + +/** + * Function: handles Random Access Preamble Initialization (5.1.1 TS 38.321) + * handles Random Access Response reception (5.1.4 TS 38.321) + * Note: In SA mode the Msg3 contains a CCCH SDU, therefore no C-RNTI MAC CE is transmitted. + * + * @prach_resources pointer to PRACH resources + * @prach_pdu pointer to FAPI UL PRACH PDU + * @mod_id module ID + * @CC_id CC ID + * @frame current UL TX frame + * @gNB_id gNB ID + * @nr_slot_tx current UL TX slot + */ +uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, + module_id_t mod_id, + int CC_id, + frame_t frame, + uint8_t gNB_id, + int nr_slot_tx){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; + NR_RACH_ConfigCommon_t *setup; + if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + else setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; + AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated; + + // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side + if (!prach_resources->init_msg1) { + if ( (mac->common_configuration_complete>0 || get_softmodem_params()->do_ra==1) && ((MAX_FRAME_NUMBER+frame-prach_resources->sync_frame)%MAX_FRAME_NUMBER)>150 ){ + prach_resources->init_msg1 = 1; + } else { + LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame); + return 0; + } + } + + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: init_msg1 %d, ra_state %d, RA_active %d\n", + __FUNCTION__, + mod_id, + frame, + nr_slot_tx, + prach_resources->init_msg1, + ra->ra_state, + ra->RA_active); + + if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) { + + if (ra->RA_active == 0) { + /* RA not active - checking if RRC is ready to initiate the RA procedure */ + + LOG_D(NR_MAC, "In %s: RA not active. Checking for data to transmit from upper layers...\n", __FUNCTION__); + + const uint8_t lcid = UL_SCH_LCID_CCCH; + const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_FIXED); + const uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // Note: unclear the reason behind the selection of such TBS_max + int8_t size_sdu = 0; + uint8_t mac_ce[16] = {0}; + uint8_t *pdu = get_softmodem_params()->sa ? mac->CCCH_pdu.payload : mac_ce; + uint8_t *payload = pdu; + + // Concerning the C-RNTI MAC CE, it has to be included if the UL transmission (Msg3) is not being made for the CCCH logical channel. + // Therefore it has been assumed that this event only occurs only when RA is done and it is not SA mode. + if (get_softmodem_params()->sa) { + + NR_MAC_SUBHEADER_FIXED *header = (NR_MAC_SUBHEADER_FIXED *) pdu; + pdu += sh_size; + + // initialisation by RRC + nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id); + + // CCCH PDU + size_sdu = nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, pdu); + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: Requested RRCConnectionRequest, got %d bytes for LCID 0x%02x \n", __FUNCTION__, mod_id, frame, nr_slot_tx, size_sdu, lcid); + + if (size_sdu > 0) { + + // UE Contention Resolution Identity + // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the + // Random Access Procedure has been successful after reception of Msg4 + memcpy(ra->cont_res_id, pdu, sizeof(uint8_t) * 6); + + pdu += size_sdu; + ra->Msg3_size = size_sdu + sh_size; + + // Build header + header->R = 0; + header->LCID = lcid; + + } else { + pdu -= sh_size; + } + + } else { + + size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL); + pdu += size_sdu; + ra->Msg3_size = size_sdu; + + } + + if (size_sdu > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) { + + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx); + AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); + + // Init RA procedure + init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated); + nr_get_RA_window(mac); + // Fill in preamble and PRACH resources + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + + // Padding: fill remainder with 0 + if (TBS_max - ra->Msg3_size > 0) { + LOG_D(NR_MAC, "In %s: remaining %d bytes, filling with padding\n", __FUNCTION__, TBS_max - ra->Msg3_size); + ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; + pdu += sizeof(NR_MAC_SUBHEADER_FIXED); + for (int j = 0; j < TBS_max - ra->Msg3_size - sizeof(NR_MAC_SUBHEADER_FIXED); j++) { + pdu[j] = 0; + } + } + + // Dumping ULSCH payload + LOG_D(NR_MAC, "In %s: dumping UL Msg3 MAC PDU with length %d: \n", __FUNCTION__, TBS_max); + for(int k = 0; k < TBS_max; k++) { + LOG_D(NR_MAC,"(%i): %i\n", k, payload[k]); + } + + // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after + // receiving Msg2 (which contains the Msg3 resource reserve). + // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s. + mac->ulsch_pdu.Pdu_size = TBS_max; + memcpy(mac->ulsch_pdu.payload, payload, TBS_max); + + } else { + return 0; + } + } else if (ra->RA_window_cnt != -1) { // RACH is active + + LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt); + + if (ra->RA_BI_found){ + prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * ra->RA_backoff_indicator; + } else { + prach_resources->RA_PREAMBLE_BACKOFF = 0; + } + + if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) { + + if(ra->cfra) { + // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213) + nr_ra_succeeded(mod_id, frame, nr_slot_tx); + } else { + ra->generate_nr_prach = GENERATE_IDLE; + } + + } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) { + + LOG_I(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx); + + nr_ra_failed(mod_id, CC_id, prach_resources, frame, nr_slot_tx); + + } else if (ra->RA_window_cnt > 0) { + + LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA window count %d) \n", mod_id, frame, nr_slot_tx, ra->RA_window_cnt); + + // Fill in preamble and PRACH resources + ra->RA_window_cnt--; + if (ra->generate_nr_prach == GENERATE_PREAMBLE) { + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + } + } else if (ra->RA_backoff_cnt > 0) { + + LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA backoff count %d) \n", mod_id, frame, nr_slot_tx, ra->RA_backoff_cnt); + + ra->RA_backoff_cnt--; + + if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) { + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + } + + } + } + } + + if (ra->RA_contention_resolution_timer_active){ + nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources); + } + + LOG_D(MAC,"ra->generate_nr_prach %d ra->ra_state %d (GENERATE_IDLE %d)\n",ra->generate_nr_prach,ra->ra_state,GENERATE_IDLE); + if(ra->generate_nr_prach != GENERATE_IDLE) { + return ra->generate_nr_prach; + } else { + return ra->ra_state; + } + +} + void nr_get_RA_window(NR_UE_MAC_INST_t *mac){ uint8_t mu, ra_ResponseWindow; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index a1056a2f71..c3aaf87844 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -259,9 +259,6 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl //NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; NR_BWP_DownlinkDedicated_t *bwpd = (bwp_id>0) ? mac->DLbwp[bwp_id-1]->bwp_Dedicated : mac->cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP; NR_BWP_DownlinkCommon_t *bwp_Common = (bwp_id>0) ? mac->DLbwp[bwp_id-1]->bwp_Common : &mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP; - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; - NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; - struct NR_PhysicalCellGroupConfig *phy_cgc = (mac->cg) ? mac->cg->physicalCellGroupConfig : NULL; LOG_D(NR_MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &ra->ra_rnti, ra->ra_rnti, &mac->crnti, mac->crnti, &ra->t_crnti, ra->t_crnti); @@ -270,6 +267,9 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[bwp_id][coreset_id - 1][ss_id] != NULL; ss_id++){ LOG_D(NR_MAC, "[DCI_CONFIG] ss_id %d\n",ss_id); NR_SearchSpace_t *ss = mac->SSpace[bwp_id][coreset_id - 1][ss_id]; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; + NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; + struct NR_PhysicalCellGroupConfig *phy_cgc = mac->cg->physicalCellGroupConfig; switch (ss->searchSpaceType->present){ case NR_SearchSpace__searchSpaceType_PR_common: // this is for CSSs, we use BWP common and pdcch_ConfigCommon @@ -414,6 +414,8 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl } // Search space 0, CORESET ID 0 + NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; + if (pdcch_ConfigCommon && pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 && !get_softmodem_params()->nsa) { diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 50d1bd6c92..f5a7e8b0cd 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -153,15 +153,13 @@ void handle_nr_uci(NR_UL_IND_t *UL_info) switch (uci_list[i].pdu_type) { case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: if (uci_list[i].pucch_pdu_format_0_1.harq) { - free(uci_list[i].pucch_pdu_format_0_1.harq->harq_list); - uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL; + free(uci_list[i].pucch_pdu_format_0_1.harq->harq_list); + uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL; + } free(uci_list[i].pucch_pdu_format_0_1.harq); uci_list[i].pucch_pdu_format_0_1.harq = NULL; - } - if (uci_list[i].pucch_pdu_format_0_1.sr) { - free(uci_list[i].pucch_pdu_format_0_1.sr); - uci_list[i].pucch_pdu_format_0_1.sr = NULL; - } + free(uci_list[i].pucch_pdu_format_0_1.sr); + uci_list[i].pucch_pdu_format_0_1.sr = NULL; break; case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 0a8e799a06..1cdd38b503 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -811,14 +811,9 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea ul_tti_request->SFN, ul_tti_request->Slot); if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) { - LOG_D(NR_PHY, "put_queue failed for nr_ul_tti_req_queue.\n"); - reset_queue(&nr_ul_tti_req_queue); - if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) - { - LOG_E(NR_PHY, "put_queue failed for ul_tti_request.\n"); - free(ul_tti_request); - ul_tti_request = NULL; - } + LOG_E(NR_PHY, "put_queue failed for ul_tti_request.\n"); + free(ul_tti_request); + ul_tti_request = NULL; } } /* TODO: This indicates that dl_tti_req was late or never arrived. If there are @@ -828,21 +823,11 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea mitigate proxy timing issues. */ else if (nr_uci_ind_queue.num_items == 0) { - LOG_D(NR_MAC, "We added UL_TTI_REQ to wait queue for sfn slot %d %d\n", + LOG_D(NR_MAC, "We added UL_TTI_REQ to queue for sfn slot %d %d\n", ul_tti_request->SFN, ul_tti_request->Slot); - if (!put_queue(&nr_wait_ul_tti_req_queue, ul_tti_request)) - { - LOG_D(NR_PHY, "put_queue failed for nr_wait_ul_tti_req_queue.\n"); - reset_queue(&nr_wait_ul_tti_req_queue); - if (!put_queue(&nr_wait_ul_tti_req_queue, ul_tti_request)) - { - LOG_E(NR_PHY, "put_queue failed for nr_wait_ul_tti_req_queue.\n"); - free(ul_tti_request); - ul_tti_request = NULL; - } - } + nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_wait_ul_tti_req_queue, ul_tti_request); + free(evicted_ul_tti_req); } - break; } diff --git a/openair2/PHY_INTERFACE/queue.c b/openair2/PHY_INTERFACE/queue.c index c6e1fb6d2f..d837857ac7 100644 --- a/openair2/PHY_INTERFACE/queue.c +++ b/openair2/PHY_INTERFACE/queue.c @@ -25,6 +25,34 @@ void reset_queue(queue_t *q) } } +void *put_queue_replace(queue_t *q, void *item) +{ + assert(item != NULL); + if (pthread_mutex_lock(&q->mutex) != 0) + { + LOG_ERROR("put_queue: mutex_lock failed"); + return false; + } + + void *evicted = NULL; + if (q->num_items >= MAX_QUEUE_SIZE) + { + evicted = q->items[q->read_index]; + assert(evicted != NULL); + q->items[q->read_index] = NULL; + q->read_index = (q->read_index + 1) % MAX_QUEUE_SIZE; + q->num_items--; + } + assert(q->items[q->write_index] == NULL); + q->items[q->write_index] = item; + q->write_index = (q->write_index + 1) % MAX_QUEUE_SIZE; + q->num_items++; + + pthread_mutex_unlock(&q->mutex); + return evicted; +} + + bool put_queue(queue_t *q, void *item) { assert(item != NULL); diff --git a/openair2/PHY_INTERFACE/queue.h b/openair2/PHY_INTERFACE/queue.h index d274f7b0cd..4678e31030 100644 --- a/openair2/PHY_INTERFACE/queue.h +++ b/openair2/PHY_INTERFACE/queue.h @@ -42,6 +42,7 @@ typedef struct queue_t void init_queue(queue_t *q); void reset_queue(queue_t *q); +void *put_queue_replace(queue_t *q, void *item); bool put_queue(queue_t *q, void *item); void *get_queue(queue_t *q); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 13cb2b7f78..0626906c5b 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -337,8 +337,10 @@ int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupCon }else{ // maintain list if(cell_group_config->spCellConfig != NULL){ + if (get_softmodem_params()->nsa) { nr_rrc_mac_config_req_ue(0, 0, 0, NULL, NULL, cell_group_config, NULL); LOG_D(NR_RRC, "Filled scc now \n"); + } if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ // process element of list to be add by RRC message if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ @@ -514,8 +516,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ errno, strerror(errno)); int msg_len=fread(buffer,1,1024,fd); - process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); fclose(fd); + process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); if (rrc_config_path) sprintf(filename,"%s/rbconfig.raw",rrc_config_path); else @@ -527,9 +529,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ errno, strerror(errno)); msg_len=fread(buffer,1,1024,fd); - process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); fclose(fd); - + process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); } else if (get_softmodem_params()->nsa) { @@ -2686,8 +2687,11 @@ nr_rrc_ue_process_ueCapabilityEnquiry( OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, (const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability, NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size); - OCTET_STRING_t * requestedFreqBandsNR = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityEnquiryExt; - nsa_sendmsg_to_lte_ue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_INFO); + + if (get_softmodem_params()->nsa == 1) { + OCTET_STRING_t * requestedFreqBandsNR = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityEnquiryExt; + 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.size = UE_rrc_inst[ue_mod_idP].UECapability_size; AssertFatal(UECapabilityEnquiry->criticalExtensions.present == NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry,