diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 7c1827151..0f906b1b6 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -155,7 +155,6 @@ private: phy_common common; sync sfsync; scell::async_recv_vector scell_sync; - uint32_t scell_earfcn[SRSLTE_MAX_CARRIERS - 1] = {}; prach prach_buffer; srslte_prach_cfg_t prach_cfg = {}; diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index 94b3c0897..eb4c41302 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -78,7 +78,11 @@ public: uint32_t pcell_report_period; bool pcell_first_measurement; - /* SCell enable for Activation / Deactivation */ + // SCell EARFCN and PCI list + uint32_t scell_earfcn[SRSLTE_MAX_CARRIERS - 1] = {}; + uint32_t scell_pci[SRSLTE_MAX_CARRIERS - 1] = {}; + + // SCell enable for Activation / Deactivation bool scell_configured[SRSLTE_MAX_CARRIERS]; bool scell_enable[SRSLTE_MAX_CARRIERS]; /* Entry index 0 is reserved, do NOT use it for PCell */ bool multiple_csi_request_enabled; /* True means cross scheduling enabled */ diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index 927c57d2a..01ee285f5 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -661,6 +661,7 @@ private: void apply_rr_config_common(asn1::rrc::rr_cfg_common_s* config, bool send_lower_layers); bool apply_rr_config_dedicated(asn1::rrc::rr_cfg_ded_s* cnfg); + void apply_scell_config(asn1::rrc::rrc_conn_recfg_r8_ies_s* reconfig_r8); void apply_phy_config_dedicated(const asn1::rrc::phys_cfg_ded_s& phy_cnfg); void apply_mac_config_dedicated_default(); diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index b3303db30..65f08e2dc 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -479,7 +479,7 @@ void phy::set_config_scell(asn1::rrc::scell_to_add_mod_r10_s* scell_config) scell_sync.at(m->radio_idx - 1)->set_scell_cell(cc_idx, &cell, earfcn); } else { // Change frequency only if the earfcn was modified - if (scell_earfcn[cc_idx - 1] != earfcn) { + if (common.scell_earfcn[cc_idx - 1] != earfcn) { float dl_freq = srslte_band_fd(earfcn) * 1e6f; float ul_freq = srslte_band_fu(srslte_band_ul_earfcn(earfcn)) * 1e6f; for (uint32_t p = 0; p < common.args->nof_rx_ant; p++) { @@ -489,8 +489,9 @@ void phy::set_config_scell(asn1::rrc::scell_to_add_mod_r10_s* scell_config) } } - // Store SCell earfcn - scell_earfcn[cc_idx - 1] = earfcn; + // Store SCell earfcn and pci + common.scell_earfcn[cc_idx - 1] = earfcn; + common.scell_pci[cc_idx - 1] = cell.id; // Set SCell as configured common.scell_configured[cc_idx] = true; diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 625aaaac9..7d469903a 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -896,7 +896,7 @@ bool phy_common::is_mbsfn_sf(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) void phy_common::enable_scell(uint32_t cc_idx, bool enable) { - if (cc_idx < SRSLTE_MAX_RADIOS) { + if (cc_idx < SRSLTE_MAX_CARRIERS) { scell_enable[cc_idx] = enable; } } diff --git a/srsue/src/phy/sf_worker.cc b/srsue/src/phy/sf_worker.cc index caedf3160..7ab0e1df7 100644 --- a/srsue/src/phy/sf_worker.cc +++ b/srsue/src/phy/sf_worker.cc @@ -339,12 +339,25 @@ void sf_worker::update_measurements() // Run measurements in all carriers for (uint32_t cc_idx = 0; cc_idx < cc_workers.size(); cc_idx++) { + // Update measurement of the Component Carrier cc_workers[cc_idx]->update_measurements(); - } - // Send PCell measurement - if ((tti % phy->pcell_report_period) == phy->pcell_report_period - 1) { - phy->stack->new_phy_meas(phy->avg_rsrp_dbm[0], phy->avg_rsrq_db, tti); + // Send measurements + if ((tti % phy->pcell_report_period) == phy->pcell_report_period - 1) { + if (cc_idx == 0) { + // Send report for PCell + phy->stack->new_phy_meas(phy->avg_rsrp_dbm[0], phy->avg_rsrq_db, tti); + } else { + // Send report for SCell (if it they are enabled) + if (phy->scell_enable[cc_idx]) { + phy->stack->new_phy_meas(phy->avg_rsrp_dbm[cc_idx], + phy->avg_rsrq_db, + tti, + phy->scell_earfcn[cc_idx - 1], + phy->scell_pci[cc_idx - 1]); + } + } + } } // Check in-sync / out-sync conditions diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index c77b8a1af..733d73ff2 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -593,7 +593,11 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } phy_meas_t new_meas = {rsrp, rsrq, tti, earfcn, pci}; phy_meas_q.push(new_meas); - rrc_log->info("MEAS: New measurement pci=%d (%s), rsrp=%.1f dBm.\n", pci, pci_i < 0 ? "serving" : "neighbour", rsrp); + rrc_log->info("MEAS: New measurement earfcn=%d, pci=%d (%s), rsrp=%.1f dBm.\n", + earfcn_i, + pci, + pci_i < 0 ? "serving" : "neighbour", + rsrp); } /* Processes all pending PHY measurements in queue. Must be called from a mutexed function @@ -1497,6 +1501,9 @@ bool rrc::ho_prepare() apply_rr_config_dedicated(&mob_reconf_r8->rr_cfg_ded); } + // Extract and apply scell config if any + apply_scell_config(mob_reconf_r8); + if (!phy->cell_select(&neighbour_cells[target_cell_idx]->phy_cell)) { rrc_log->error("Could not synchronize with target cell pci=%d. Trying to return to source PCI\n", neighbour_cells[target_cell_idx]->get_pci()); @@ -1609,59 +1616,8 @@ bool rrc::con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig) return false; } } - if (reconfig_r8->non_crit_ext_present) { - rrc_conn_recfg_v890_ies_s* reconfig_r890 = &reconfig_r8->non_crit_ext; - if (reconfig_r890->non_crit_ext_present) { - rrc_conn_recfg_v920_ies_s* reconfig_r920 = &reconfig_r890->non_crit_ext; - if (reconfig_r920->non_crit_ext_present) { - rrc_conn_recfg_v1020_ies_s* reconfig_r1020 = &reconfig_r920->non_crit_ext; - // Handle Add/Modify SCell list - if (reconfig_r1020->s_cell_to_add_mod_list_r10_present) { - for (uint32_t i = 0; i < reconfig_r1020->s_cell_to_add_mod_list_r10.size(); i++) { - auto scell_config = &reconfig_r1020->s_cell_to_add_mod_list_r10[i]; - - // Limit enable64_qam, if the ue does not - // since the phy does not have information about the RRC category and release, the RRC shall limit the - if (scell_config->rr_cfg_common_scell_r10_present) { - // enable64_qam - auto rr_cfg_common_scell = &scell_config->rr_cfg_common_scell_r10; - if (rr_cfg_common_scell->ul_cfg_r10_present) { - auto ul_cfg = &rr_cfg_common_scell->ul_cfg_r10; - auto pusch_cfg_common = &ul_cfg->pusch_cfg_common_r10; - - // According to 3GPP 36.331 v12 UE-EUTRA-Capability field descriptions - // Allow 64QAM for: - // ue-Category 5 and 8 when enable64QAM (without suffix) - if (pusch_cfg_common->pusch_cfg_basic.enable64_qam) { - if (args.ue_category != 5 && args.ue_category != 8 && args.ue_category != 13) { - pusch_cfg_common->pusch_cfg_basic.enable64_qam = false; - } - } - } - } - - // Call mac reconfiguration - mac->reconfiguration(scell_config->s_cell_idx_r10, true); - - // Call phy reconfiguration - phy->set_config_scell(scell_config); - } - } - - // Handle Remove SCell list - if (reconfig_r1020->s_cell_to_release_list_r10_present) { - for (uint32_t i = 0; i < reconfig_r1020->s_cell_to_release_list_r10.size(); i++) { - // Call mac reconfiguration - mac->reconfiguration(reconfig_r1020->s_cell_to_release_list_r10[i], false); - - // Call phy reconfiguration - // TODO: Implement phy layer cell removal - } - } - } - } - } + apply_scell_config(reconfig_r8); // If first message after reestablishment, resume SRB2 and all DRB if (reestablishment_successful) { @@ -3058,6 +3014,66 @@ bool rrc::apply_rr_config_dedicated(rr_cfg_ded_s* cnfg) return true; } +/* + * Extracts and applies SCell configuration from an ASN.1 reconfiguration struct + */ +void rrc::apply_scell_config(asn1::rrc::rrc_conn_recfg_r8_ies_s* reconfig_r8) +{ + if (reconfig_r8->non_crit_ext_present) { + auto reconfig_r890 = &reconfig_r8->non_crit_ext; + if (reconfig_r890->non_crit_ext_present) { + rrc_conn_recfg_v920_ies_s* reconfig_r920 = &reconfig_r890->non_crit_ext; + if (reconfig_r920->non_crit_ext_present) { + rrc_conn_recfg_v1020_ies_s* reconfig_r1020 = &reconfig_r920->non_crit_ext; + + // Handle Add/Modify SCell list + if (reconfig_r1020->s_cell_to_add_mod_list_r10_present) { + for (uint32_t i = 0; i < reconfig_r1020->s_cell_to_add_mod_list_r10.size(); i++) { + auto scell_config = &reconfig_r1020->s_cell_to_add_mod_list_r10[i]; + + // Limit enable64_qam, if the ue does not + // since the phy does not have information about the RRC category and release, the RRC shall limit the + if (scell_config->rr_cfg_common_scell_r10_present) { + // enable64_qam + auto rr_cfg_common_scell = &scell_config->rr_cfg_common_scell_r10; + if (rr_cfg_common_scell->ul_cfg_r10_present) { + auto ul_cfg = &rr_cfg_common_scell->ul_cfg_r10; + auto pusch_cfg_common = &ul_cfg->pusch_cfg_common_r10; + + // According to 3GPP 36.331 v12 UE-EUTRA-Capability field descriptions + // Allow 64QAM for: + // ue-Category 5 and 8 when enable64QAM (without suffix) + if (pusch_cfg_common->pusch_cfg_basic.enable64_qam) { + if (args.ue_category != 5 && args.ue_category != 8 && args.ue_category != 13) { + pusch_cfg_common->pusch_cfg_basic.enable64_qam = false; + } + } + } + } + + // Call mac reconfiguration + mac->reconfiguration(scell_config->s_cell_idx_r10, true); + + // Call phy reconfiguration + phy->set_config_scell(scell_config); + } + } + + // Handle Remove SCell list + if (reconfig_r1020->s_cell_to_release_list_r10_present) { + for (uint32_t i = 0; i < reconfig_r1020->s_cell_to_release_list_r10.size(); i++) { + // Call mac reconfiguration + mac->reconfiguration(reconfig_r1020->s_cell_to_release_list_r10[i], false); + + // Call phy reconfiguration + // TODO: Implement phy layer cell removal + } + } + } + } + } +} + void rrc::handle_con_setup(rrc_conn_setup_s* setup) { // Apply the Radio Resource configuration