Merge remote-tracking branch 'origin/oai-ue-fix-rsrp-mapping' into integration_2025_w42 (!3701)
OAI UE: add shared RSRP Table 10.1.6.1-1 mapping function to helpers and adopt it RRC UE - Add to common/utils/nr/nr_common remove from NR_MAC_UE/nr_ue_procedures.c - Adopt in asn1_msg.c for MeasurementReport: this solves the following possible assert: Assertion (enc_rval.encoded > 0) failed! In do_nrMeasurementReport_SA() /oai-ran/openair2/RRC/NR/MESSAGES/asn1_msg.c:898 ASN1 message encoding failed (MeasResultServMOList, 18446744073709551615)! Motivation: unify RSRP-to-index mapping across layers and fix NR RRC MeasurementReport encoding failures due to out-of-range values by reusing the validated mapping. Note: NR_RSRP-Range.c constraint: /* (0..127) */ Also refactored MeasurementReport to improve the code.
This commit is contained in:
@@ -152,6 +152,17 @@ void reverse_bits_u8(uint8_t const* in, size_t sz, uint8_t* out)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief 3GPP TS 38.133 Table 10.1.6.1-1 mapping from dBm to RSRP index */
|
||||||
|
uint8_t get_rsrp_index(int rsrp_dBm)
|
||||||
|
{
|
||||||
|
int index = rsrp_dBm + 157;
|
||||||
|
if (rsrp_dBm > -44)
|
||||||
|
index = 113;
|
||||||
|
if (rsrp_dBm < -140)
|
||||||
|
index = 16;
|
||||||
|
return (uint8_t)index;
|
||||||
|
}
|
||||||
|
|
||||||
// Reverse bits implementation based on http://graphics.stanford.edu/~seander/bithacks.html
|
// Reverse bits implementation based on http://graphics.stanford.edu/~seander/bithacks.html
|
||||||
uint64_t reverse_bits(uint64_t in, int n_bits)
|
uint64_t reverse_bits(uint64_t in, int n_bits)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ typedef struct meas_s {
|
|||||||
val_init_t csi_rsrp_dBm;
|
val_init_t csi_rsrp_dBm;
|
||||||
} meas_t;
|
} meas_t;
|
||||||
|
|
||||||
|
/** @brief Returns NR RSRP index per 3GPP TS 38.133 Table 10.1.6.1-1 */
|
||||||
|
uint8_t get_rsrp_index(int rsrp_dBm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief To start a timer
|
* @brief To start a timer
|
||||||
* @param timer Timer to be started
|
* @param timer Timer to be started
|
||||||
|
|||||||
@@ -2908,17 +2908,6 @@ static int compare_ssb_rsrp(const void *a, const void *b)
|
|||||||
return mb->ssb_rsrp_dBm - ma->ssb_rsrp_dBm;
|
return mb->ssb_rsrp_dBm - ma->ssb_rsrp_dBm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns index from RSRP
|
|
||||||
// according to Table 10.1.6.1-1 in 38.133
|
|
||||||
static uint8_t get_rsrp_index(int rsrp)
|
|
||||||
{
|
|
||||||
int index = rsrp + 157;
|
|
||||||
if (rsrp > -44)
|
|
||||||
index = 113;
|
|
||||||
if (rsrp < -140)
|
|
||||||
index = 16;
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||||
struct NR_CSI_ReportConfig *csi_reportconfig,
|
struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||||
|
|||||||
@@ -850,50 +850,45 @@ int do_RRCSetupComplete(uint8_t *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This function is only implemented for event A2
|
// TODO: This function is only implemented for event A2
|
||||||
int do_nrMeasurementReport_SA(NR_MeasurementReport_t *measurementReport,
|
int do_nrMeasurementReport_SA(long trigger_to_measid,
|
||||||
long trigger_to_measid,
|
|
||||||
long trigger_quantity,
|
long trigger_quantity,
|
||||||
long rs_type,
|
long rs_type,
|
||||||
uint16_t Nid_cell,
|
uint16_t Nid_cell,
|
||||||
int rsrp_dBm,
|
int rsrp_index,
|
||||||
uint8_t *buffer,
|
uint8_t *buffer,
|
||||||
size_t buffer_size)
|
size_t buffer_size)
|
||||||
{
|
{
|
||||||
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 = {0};
|
||||||
memset((void *)&ul_dcch_msg, 0, sizeof(NR_UL_DCCH_Message_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));
|
asn1cCalloc(ul_dcch_msg.message.choice.c1, c1);
|
||||||
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_measurementReport;
|
c1->present = NR_UL_DCCH_MessageType__c1_PR_measurementReport;
|
||||||
|
|
||||||
memset(measurementReport, 0, sizeof(struct NR_MeasurementReport));
|
asn1cCalloc(c1->choice.measurementReport, measurementReport);
|
||||||
ul_dcch_msg.message.choice.c1->choice.measurementReport = measurementReport;
|
|
||||||
measurementReport->criticalExtensions.present = NR_MeasurementReport__criticalExtensions_PR_measurementReport;
|
measurementReport->criticalExtensions.present = NR_MeasurementReport__criticalExtensions_PR_measurementReport;
|
||||||
|
|
||||||
NR_MeasurementReport_IEs_t *measurementReport_ie = CALLOC(1, sizeof(struct NR_MeasurementReport_IEs));
|
asn1cCalloc(measurementReport->criticalExtensions.choice.measurementReport, mrIE);
|
||||||
measurementReport->criticalExtensions.choice.measurementReport = measurementReport_ie;
|
mrIE->measResults.measId = trigger_to_measid;
|
||||||
measurementReport_ie->measResults.measId = trigger_to_measid;
|
|
||||||
|
|
||||||
NR_MeasResultServMO_t *measResultServMo = CALLOC(1, sizeof(struct NR_MeasResultServMO));
|
NR_MeasResultServMO_t *measResultServMo = calloc_or_fail(1, sizeof(*measResultServMo));
|
||||||
|
|
||||||
NR_MeasResultNR_t *measResultServingCell = &measResultServMo->measResultServingCell;
|
NR_MeasResultNR_t *measResultServingCell = &measResultServMo->measResultServingCell;
|
||||||
measResultServingCell->physCellId = CALLOC(1, sizeof(NR_PhysCellId_t));
|
asn1cCalloc(measResultServingCell->physCellId, pci);
|
||||||
*measResultServingCell->physCellId = Nid_cell;
|
*pci = Nid_cell;
|
||||||
|
|
||||||
struct NR_MeasQuantityResults *active_mq_res = CALLOC(1, sizeof(struct NR_MeasQuantityResults));
|
|
||||||
|
|
||||||
|
struct NR_MeasQuantityResults *active_mq_res = calloc_or_fail(1, sizeof(*active_mq_res));
|
||||||
if (trigger_quantity == NR_MeasTriggerQuantityOffset_PR_rsrp) {
|
if (trigger_quantity == NR_MeasTriggerQuantityOffset_PR_rsrp) {
|
||||||
active_mq_res->rsrp = CALLOC(1, sizeof(NR_RSRP_Range_t));
|
asn1cCalloc(active_mq_res->rsrp, rsrp);
|
||||||
|
// Assign precomputed RSRP index
|
||||||
*active_mq_res->rsrp = rsrp_dBm + 157;
|
*rsrp = rsrp_index;
|
||||||
if (rs_type == NR_NR_RS_Type_ssb)
|
if (rs_type == NR_NR_RS_Type_ssb)
|
||||||
measResultServingCell->measResult.cellResults.resultsSSB_Cell = active_mq_res;
|
measResultServingCell->measResult.cellResults.resultsSSB_Cell = active_mq_res;
|
||||||
else
|
else
|
||||||
measResultServingCell->measResult.cellResults.resultsCSI_RS_Cell = active_mq_res;
|
measResultServingCell->measResult.cellResults.resultsCSI_RS_Cell = active_mq_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN_SEQUENCE_ADD(&measurementReport_ie->measResults.measResultServingMOList.list, measResultServMo);
|
ASN_SEQUENCE_ADD(&mrIE->measResults.measResultServingMOList.list, measResultServMo);
|
||||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, buffer_size);
|
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, buffer_size);
|
||||||
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
|
||||||
|
|
||||||
|
|||||||
@@ -125,12 +125,11 @@ int do_NR_MeasurementTimingConfiguration(const NR_MeasurementTimingConfiguration
|
|||||||
|
|
||||||
int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_t fiveG_S_TMSI_part1);
|
int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_t fiveG_S_TMSI_part1);
|
||||||
|
|
||||||
int do_nrMeasurementReport_SA(NR_MeasurementReport_t *measurementReport,
|
int do_nrMeasurementReport_SA(long trigger_to_measid,
|
||||||
long trigger_to_measid,
|
|
||||||
long trigger_quantity,
|
long trigger_quantity,
|
||||||
long rs_type,
|
long rs_type,
|
||||||
uint16_t Nid_cell,
|
uint16_t Nid_cell,
|
||||||
int rsrp_dBm,
|
int rsrp_index,
|
||||||
uint8_t *buffer,
|
uint8_t *buffer,
|
||||||
size_t buffer_size);
|
size_t buffer_size);
|
||||||
|
|
||||||
|
|||||||
@@ -3057,15 +3057,14 @@ void nr_rrc_set_mac_queue(instance_t instance, notifiedFIFO_t *mac_input_nf)
|
|||||||
void rrc_ue_generate_measurementReport(rrcPerNB_t *rrc, instance_t ue_id)
|
void rrc_ue_generate_measurementReport(rrcPerNB_t *rrc, instance_t ue_id)
|
||||||
{
|
{
|
||||||
uint8_t buffer[NR_RRC_BUF_SIZE];
|
uint8_t buffer[NR_RRC_BUF_SIZE];
|
||||||
NR_MeasurementReport_t measurementReport = {0};
|
|
||||||
l3_measurements_t *l3m = &rrc->l3_measurements;
|
l3_measurements_t *l3m = &rrc->l3_measurements;
|
||||||
int rsrp_dBm = l3m->rs_type == NR_NR_RS_Type_ssb ? l3m->serving_cell.ss_rsrp_dBm.val : l3m->serving_cell.csi_rsrp_dBm.val;
|
int rsrp_dBm = l3m->rs_type == NR_NR_RS_Type_ssb ? l3m->serving_cell.ss_rsrp_dBm.val : l3m->serving_cell.csi_rsrp_dBm.val;
|
||||||
uint8_t size = do_nrMeasurementReport_SA(&measurementReport,
|
int rsrp_index = get_rsrp_index(rsrp_dBm);
|
||||||
l3m->trigger_to_measid,
|
uint8_t size = do_nrMeasurementReport_SA(l3m->trigger_to_measid,
|
||||||
l3m->trigger_quantity,
|
l3m->trigger_quantity,
|
||||||
l3m->rs_type,
|
l3m->rs_type,
|
||||||
l3m->serving_cell.Nid_cell,
|
l3m->serving_cell.Nid_cell,
|
||||||
rsrp_dBm,
|
rsrp_index,
|
||||||
buffer,
|
buffer,
|
||||||
sizeof(buffer));
|
sizeof(buffer));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user