remove gNB structure dependency from get_MeasConfig in asn1_msg.c
This commit is contained in:
@@ -1095,172 +1095,28 @@ int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t r
|
|||||||
return((enc_rval.encoded+7)/8);
|
return((enc_rval.encoded+7)/8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NR_ReportConfigToAddMod_t *prepare_periodic_event_report(const nr_per_event_t *per_event)
|
|
||||||
{
|
|
||||||
NR_ReportConfigToAddMod_t *rc = calloc(1, sizeof(*rc));
|
|
||||||
rc->reportConfigId = 1;
|
|
||||||
rc->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
|
||||||
|
|
||||||
NR_PeriodicalReportConfig_t *prc = calloc(1, sizeof(*prc));
|
|
||||||
prc->rsType = NR_NR_RS_Type_ssb;
|
|
||||||
prc->reportInterval = NR_ReportInterval_ms1024;
|
|
||||||
prc->reportAmount = NR_PeriodicalReportConfig__reportAmount_infinity;
|
|
||||||
prc->reportQuantityCell.rsrp = true;
|
|
||||||
prc->reportQuantityCell.rsrq = true;
|
|
||||||
prc->reportQuantityCell.sinr = true;
|
|
||||||
prc->reportQuantityRS_Indexes = calloc(1, sizeof(*prc->reportQuantityRS_Indexes));
|
|
||||||
prc->reportQuantityRS_Indexes->rsrp = true;
|
|
||||||
prc->reportQuantityRS_Indexes->rsrq = true;
|
|
||||||
prc->reportQuantityRS_Indexes->sinr = true;
|
|
||||||
asn1cCallocOne(prc->maxNrofRS_IndexesToReport, per_event->maxReportCells);
|
|
||||||
prc->maxReportCells = per_event->maxReportCells;
|
|
||||||
prc->includeBeamMeasurements = per_event->includeBeamMeasurements;
|
|
||||||
|
|
||||||
NR_ReportConfigNR_t *rcnr = calloc(1, sizeof(*rcnr));
|
|
||||||
rcnr->reportType.present = NR_ReportConfigNR__reportType_PR_periodical;
|
|
||||||
rcnr->reportType.choice.periodical = prc;
|
|
||||||
|
|
||||||
rc->reportConfig.choice.reportConfigNR = rcnr;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NR_ReportConfigToAddMod_t *prepare_a2_event_report(const nr_a2_event_t *a2_event)
|
|
||||||
{
|
|
||||||
NR_ReportConfigToAddMod_t *rc_A2 = calloc(1, sizeof(*rc_A2));
|
|
||||||
rc_A2->reportConfigId = 2;
|
|
||||||
rc_A2->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
|
||||||
NR_EventTriggerConfig_t *etrc_A2 = calloc(1, sizeof(*etrc_A2));
|
|
||||||
etrc_A2->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA2;
|
|
||||||
etrc_A2->eventId.choice.eventA2 = calloc(1, sizeof(*etrc_A2->eventId.choice.eventA2));
|
|
||||||
etrc_A2->eventId.choice.eventA2->a2_Threshold.present = NR_MeasTriggerQuantity_PR_rsrp;
|
|
||||||
etrc_A2->eventId.choice.eventA2->a2_Threshold.choice.rsrp = a2_event->threshold_RSRP;
|
|
||||||
etrc_A2->eventId.choice.eventA2->reportOnLeave = false;
|
|
||||||
etrc_A2->eventId.choice.eventA2->hysteresis = 0;
|
|
||||||
etrc_A2->eventId.choice.eventA2->timeToTrigger = a2_event->timeToTrigger;
|
|
||||||
etrc_A2->rsType = NR_NR_RS_Type_ssb;
|
|
||||||
etrc_A2->reportInterval = NR_ReportInterval_ms480;
|
|
||||||
etrc_A2->reportAmount = NR_EventTriggerConfig__reportAmount_r4;
|
|
||||||
etrc_A2->reportQuantityCell.rsrp = true;
|
|
||||||
etrc_A2->reportQuantityCell.rsrq = true;
|
|
||||||
etrc_A2->reportQuantityCell.sinr = true;
|
|
||||||
asn1cCallocOne(etrc_A2->maxNrofRS_IndexesToReport, 4);
|
|
||||||
etrc_A2->maxReportCells = 1;
|
|
||||||
etrc_A2->includeBeamMeasurements = false;
|
|
||||||
NR_ReportConfigNR_t *rcnr_A2 = calloc(1, sizeof(*rcnr_A2));
|
|
||||||
rcnr_A2->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
|
|
||||||
rcnr_A2->reportType.choice.eventTriggered = etrc_A2;
|
|
||||||
rc_A2->reportConfig.choice.reportConfigNR = rcnr_A2;
|
|
||||||
|
|
||||||
return rc_A2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NR_ReportConfigToAddMod_t *prepare_a3_event_report(const nr_a3_event_t *a3_event)
|
|
||||||
{
|
|
||||||
NR_ReportConfigToAddMod_t *rc_A3 = calloc(1, sizeof(*rc_A3));
|
|
||||||
// 3 is default A3 Report Config ID. So cellId(0) specific Report Config ID
|
|
||||||
// starts from 4
|
|
||||||
rc_A3->reportConfigId = a3_event->pci == -1 ? 3 : a3_event->pci + 4;
|
|
||||||
rc_A3->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
|
||||||
NR_EventTriggerConfig_t *etrc_A3 = calloc(1, sizeof(*etrc_A3));
|
|
||||||
etrc_A3->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA3;
|
|
||||||
etrc_A3->eventId.choice.eventA3 = calloc(1, sizeof(*etrc_A3->eventId.choice.eventA3));
|
|
||||||
etrc_A3->eventId.choice.eventA3->a3_Offset.present = NR_MeasTriggerQuantityOffset_PR_rsrp;
|
|
||||||
etrc_A3->eventId.choice.eventA3->a3_Offset.choice.rsrp = a3_event->a3_offset;
|
|
||||||
etrc_A3->eventId.choice.eventA3->reportOnLeave = true;
|
|
||||||
etrc_A3->eventId.choice.eventA3->hysteresis = a3_event->hysteresis;
|
|
||||||
etrc_A3->eventId.choice.eventA3->timeToTrigger = a3_event->timeToTrigger;
|
|
||||||
etrc_A3->rsType = NR_NR_RS_Type_ssb;
|
|
||||||
etrc_A3->reportInterval = NR_ReportInterval_ms1024;
|
|
||||||
etrc_A3->reportAmount = NR_EventTriggerConfig__reportAmount_r4;
|
|
||||||
etrc_A3->reportQuantityCell.rsrp = true;
|
|
||||||
etrc_A3->reportQuantityCell.rsrq = true;
|
|
||||||
etrc_A3->reportQuantityCell.sinr = true;
|
|
||||||
asn1cCallocOne(etrc_A3->maxNrofRS_IndexesToReport, 4);
|
|
||||||
etrc_A3->maxReportCells = 4;
|
|
||||||
etrc_A3->includeBeamMeasurements = false;
|
|
||||||
NR_ReportConfigNR_t *rcnr_A3 = calloc(1, sizeof(*rcnr_A3));
|
|
||||||
rcnr_A3->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
|
|
||||||
rcnr_A3->reportType.choice.eventTriggered = etrc_A3;
|
|
||||||
rc_A3->reportConfig.choice.reportConfigNR = rcnr_A3;
|
|
||||||
return rc_A3;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nr_a3_event_t *get_a3_configuration(int pci)
|
|
||||||
{
|
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
|
||||||
nr_measurement_configuration_t *measurementConfiguration = &rrc->measurementConfiguration;
|
|
||||||
if (!measurementConfiguration->a3_event_list)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < measurementConfiguration->a3_event_list->size; i++) {
|
|
||||||
nr_a3_event_t *a3_event = (nr_a3_event_t *)seq_arr_at(measurementConfiguration->a3_event_list, i);
|
|
||||||
if (a3_event->pci == pci)
|
|
||||||
return a3_event;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (measurementConfiguration->is_default_a3_configuration_exists)
|
|
||||||
return get_a3_configuration(-1);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
||||||
int band,
|
int band,
|
||||||
int scs,
|
int scs,
|
||||||
const nr_measurement_configuration_t *const measurementConfiguration,
|
NR_ReportConfigToAddMod_t *rc_PER,
|
||||||
const seq_arr_t *const neighbourConfiguration)
|
NR_ReportConfigToAddMod_t *rc_A2,
|
||||||
|
seq_arr_t *rc_A3_seq,
|
||||||
|
seq_arr_t *pci_seq)
|
||||||
{
|
{
|
||||||
if (!measurementConfiguration)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!measurementConfiguration->a2_event && !measurementConfiguration->per_event && !measurementConfiguration->a3_event_list) {
|
|
||||||
LOG_D(NR_RRC, "NR Measurements are not configured in the conf file\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!measurementConfiguration->a2_event && !measurementConfiguration->per_event && measurementConfiguration->a3_event_list
|
|
||||||
&& !neighbourConfiguration) {
|
|
||||||
LOG_I(NR_RRC, "A2 and Periodical Events are off. A3 Can not be prepared without neighbours!\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_MeasConfig_t *mc = calloc(1, sizeof(*mc));
|
NR_MeasConfig_t *mc = calloc(1, sizeof(*mc));
|
||||||
mc->measObjectToAddModList = calloc(1, sizeof(*mc->measObjectToAddModList));
|
mc->measObjectToAddModList = calloc(1, sizeof(*mc->measObjectToAddModList));
|
||||||
mc->reportConfigToAddModList = calloc(1, sizeof(*mc->reportConfigToAddModList));
|
mc->reportConfigToAddModList = calloc(1, sizeof(*mc->reportConfigToAddModList));
|
||||||
mc->measIdToAddModList = calloc(1, sizeof(*mc->measIdToAddModList));
|
mc->measIdToAddModList = calloc(1, sizeof(*mc->measIdToAddModList));
|
||||||
|
|
||||||
if (measurementConfiguration->per_event) {
|
if (rc_PER)
|
||||||
NR_ReportConfigToAddMod_t *rc_PER = prepare_periodic_event_report(measurementConfiguration->per_event);
|
|
||||||
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_PER);
|
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_PER);
|
||||||
}
|
|
||||||
|
|
||||||
if (measurementConfiguration->a2_event) {
|
if (rc_A2)
|
||||||
LOG_D(NR_RRC, "HO LOG: Preparing A2 Event Measurement Configuration!\n");
|
|
||||||
NR_ReportConfigToAddMod_t *rc_A2 = prepare_a2_event_report(measurementConfiguration->a2_event);
|
|
||||||
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_A2);
|
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_A2);
|
||||||
}
|
|
||||||
|
|
||||||
if (neighbourConfiguration && measurementConfiguration->a3_event_list && measurementConfiguration->a3_event_list->size > 0) {
|
if (rc_A3_seq) {
|
||||||
/* Loop through neighbours and find related A3 configuration
|
for (int i = 0; i < rc_A3_seq->size; i++) {
|
||||||
If no related A3 but there is default add the default one.
|
NR_ReportConfigToAddMod_t *rc_A3 = (NR_ReportConfigToAddMod_t *)seq_arr_at(rc_A3_seq, i);
|
||||||
If default one added once as a report, no need to add it again && duplication.
|
|
||||||
*/
|
|
||||||
LOG_D(NR_RRC, "HO LOG: Preparing A3 Event Measurement Configuration!\n");
|
|
||||||
bool is_default_a3_added = false;
|
|
||||||
for (uint8_t neighbourIdx = 0; neighbourIdx < neighbourConfiguration->size; neighbourIdx++) {
|
|
||||||
const nr_neighbour_gnb_configuration_t *neighbourCell =
|
|
||||||
(const nr_neighbour_gnb_configuration_t *)seq_arr_at(neighbourConfiguration, neighbourIdx);
|
|
||||||
if (!neighbourCell->isIntraFrequencyNeighbour)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const nr_a3_event_t *a3Event = get_a3_configuration(neighbourCell->physicalCellId);
|
|
||||||
if (!a3Event || is_default_a3_added)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (a3Event->pci == -1)
|
|
||||||
is_default_a3_added = true;
|
|
||||||
|
|
||||||
NR_ReportConfigToAddMod_t *rc_A3 = prepare_a3_event_report(a3Event);
|
|
||||||
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_A3);
|
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_A3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1289,19 +1145,15 @@ NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
|||||||
monr1->ext1 = calloc(1, sizeof(*monr1->ext1));
|
monr1->ext1 = calloc(1, sizeof(*monr1->ext1));
|
||||||
asn1cCallocOne(monr1->ext1->freqBandIndicatorNR, band);
|
asn1cCallocOne(monr1->ext1->freqBandIndicatorNR, band);
|
||||||
|
|
||||||
if (neighbourConfiguration && measurementConfiguration->a3_event_list) {
|
if (pci_seq) {
|
||||||
for (uint8_t nCell = 0; nCell < neighbourConfiguration->size; nCell++) {
|
for (int i = 0; i < pci_seq->size; i++) {
|
||||||
const nr_neighbour_gnb_configuration_t *neighbourCell =
|
|
||||||
(const nr_neighbour_gnb_configuration_t *)seq_arr_at(neighbourConfiguration, nCell);
|
|
||||||
if (!neighbourCell->isIntraFrequencyNeighbour)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (monr1->cellsToAddModList == NULL) {
|
if (monr1->cellsToAddModList == NULL) {
|
||||||
monr1->cellsToAddModList = calloc(1, sizeof(*monr1->cellsToAddModList));
|
monr1->cellsToAddModList = calloc(1, sizeof(*monr1->cellsToAddModList));
|
||||||
}
|
}
|
||||||
|
|
||||||
NR_CellsToAddMod_t *cell = calloc(1, sizeof(*cell));
|
NR_CellsToAddMod_t *cell = calloc(1, sizeof(*cell));
|
||||||
cell->physCellId = neighbourCell->physicalCellId;
|
int *pci = (int *)seq_arr_at(pci_seq, i);
|
||||||
|
cell->physCellId = *pci;
|
||||||
ASN_SEQUENCE_ADD(&monr1->cellsToAddModList->list, cell);
|
ASN_SEQUENCE_ADD(&monr1->cellsToAddModList->list, cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,12 +151,13 @@ int do_RRCReestablishment(int8_t nh_ncc, uint8_t *const buffer, size_t buffer_si
|
|||||||
|
|
||||||
int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier);
|
int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier);
|
||||||
|
|
||||||
const nr_a3_event_t *get_a3_configuration(int pci);
|
|
||||||
NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
||||||
int band,
|
int band,
|
||||||
int scs,
|
int scs,
|
||||||
const nr_measurement_configuration_t *const measurementConfiguration,
|
NR_ReportConfigToAddMod_t *rc_PER,
|
||||||
const seq_arr_t *const neighbourConfiguration);
|
NR_ReportConfigToAddMod_t *rc_A2,
|
||||||
|
seq_arr_t *rc_A3_seq,
|
||||||
|
seq_arr_t *pci_seq);
|
||||||
void free_MeasConfig(NR_MeasConfig_t *mc);
|
void free_MeasConfig(NR_MeasConfig_t *mc);
|
||||||
int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
|
int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
|
||||||
|
|
||||||
|
|||||||
+152
-6
@@ -471,6 +471,114 @@ static void rrc_gNB_process_RRCSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE
|
|||||||
rrc_gNB_send_NGAP_NAS_FIRST_REQ(rrc, UE, rrcSetupComplete);
|
rrc_gNB_send_NGAP_NAS_FIRST_REQ(rrc, UE, rrcSetupComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nr_a3_event_t *get_a3_configuration(gNB_RRC_INST *rrc, int pci)
|
||||||
|
{
|
||||||
|
nr_measurement_configuration_t *measurementConfiguration = &rrc->measurementConfiguration;
|
||||||
|
if (!measurementConfiguration->a3_event_list)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < measurementConfiguration->a3_event_list->size; i++) {
|
||||||
|
nr_a3_event_t *a3_event = (nr_a3_event_t *)seq_arr_at(measurementConfiguration->a3_event_list, i);
|
||||||
|
if (a3_event->pci == pci)
|
||||||
|
return a3_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (measurementConfiguration->is_default_a3_configuration_exists)
|
||||||
|
return get_a3_configuration(rrc, -1);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NR_ReportConfigToAddMod_t *prepare_periodic_event_report(const nr_per_event_t *per_event)
|
||||||
|
{
|
||||||
|
NR_ReportConfigToAddMod_t *rc = calloc(1, sizeof(*rc));
|
||||||
|
rc->reportConfigId = 1;
|
||||||
|
rc->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
||||||
|
|
||||||
|
NR_PeriodicalReportConfig_t *prc = calloc(1, sizeof(*prc));
|
||||||
|
prc->rsType = NR_NR_RS_Type_ssb;
|
||||||
|
prc->reportInterval = NR_ReportInterval_ms1024;
|
||||||
|
prc->reportAmount = NR_PeriodicalReportConfig__reportAmount_infinity;
|
||||||
|
prc->reportQuantityCell.rsrp = true;
|
||||||
|
prc->reportQuantityCell.rsrq = true;
|
||||||
|
prc->reportQuantityCell.sinr = true;
|
||||||
|
prc->reportQuantityRS_Indexes = calloc(1, sizeof(*prc->reportQuantityRS_Indexes));
|
||||||
|
prc->reportQuantityRS_Indexes->rsrp = true;
|
||||||
|
prc->reportQuantityRS_Indexes->rsrq = true;
|
||||||
|
prc->reportQuantityRS_Indexes->sinr = true;
|
||||||
|
asn1cCallocOne(prc->maxNrofRS_IndexesToReport, per_event->maxReportCells);
|
||||||
|
prc->maxReportCells = per_event->maxReportCells;
|
||||||
|
prc->includeBeamMeasurements = per_event->includeBeamMeasurements;
|
||||||
|
|
||||||
|
NR_ReportConfigNR_t *rcnr = calloc(1, sizeof(*rcnr));
|
||||||
|
rcnr->reportType.present = NR_ReportConfigNR__reportType_PR_periodical;
|
||||||
|
rcnr->reportType.choice.periodical = prc;
|
||||||
|
|
||||||
|
rc->reportConfig.choice.reportConfigNR = rcnr;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NR_ReportConfigToAddMod_t *prepare_a2_event_report(const nr_a2_event_t *a2_event)
|
||||||
|
{
|
||||||
|
NR_ReportConfigToAddMod_t *rc_A2 = calloc(1, sizeof(*rc_A2));
|
||||||
|
rc_A2->reportConfigId = 2;
|
||||||
|
rc_A2->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
||||||
|
NR_EventTriggerConfig_t *etrc_A2 = calloc(1, sizeof(*etrc_A2));
|
||||||
|
etrc_A2->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA2;
|
||||||
|
etrc_A2->eventId.choice.eventA2 = calloc(1, sizeof(*etrc_A2->eventId.choice.eventA2));
|
||||||
|
etrc_A2->eventId.choice.eventA2->a2_Threshold.present = NR_MeasTriggerQuantity_PR_rsrp;
|
||||||
|
etrc_A2->eventId.choice.eventA2->a2_Threshold.choice.rsrp = a2_event->threshold_RSRP;
|
||||||
|
etrc_A2->eventId.choice.eventA2->reportOnLeave = false;
|
||||||
|
etrc_A2->eventId.choice.eventA2->hysteresis = 0;
|
||||||
|
etrc_A2->eventId.choice.eventA2->timeToTrigger = a2_event->timeToTrigger;
|
||||||
|
etrc_A2->rsType = NR_NR_RS_Type_ssb;
|
||||||
|
etrc_A2->reportInterval = NR_ReportInterval_ms480;
|
||||||
|
etrc_A2->reportAmount = NR_EventTriggerConfig__reportAmount_r4;
|
||||||
|
etrc_A2->reportQuantityCell.rsrp = true;
|
||||||
|
etrc_A2->reportQuantityCell.rsrq = true;
|
||||||
|
etrc_A2->reportQuantityCell.sinr = true;
|
||||||
|
asn1cCallocOne(etrc_A2->maxNrofRS_IndexesToReport, 4);
|
||||||
|
etrc_A2->maxReportCells = 1;
|
||||||
|
etrc_A2->includeBeamMeasurements = false;
|
||||||
|
NR_ReportConfigNR_t *rcnr_A2 = calloc(1, sizeof(*rcnr_A2));
|
||||||
|
rcnr_A2->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
|
||||||
|
rcnr_A2->reportType.choice.eventTriggered = etrc_A2;
|
||||||
|
rc_A2->reportConfig.choice.reportConfigNR = rcnr_A2;
|
||||||
|
|
||||||
|
return rc_A2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NR_ReportConfigToAddMod_t *prepare_a3_event_report(const nr_a3_event_t *a3_event)
|
||||||
|
{
|
||||||
|
NR_ReportConfigToAddMod_t *rc_A3 = calloc(1, sizeof(*rc_A3));
|
||||||
|
// 3 is default A3 Report Config ID. So cellId(0) specific Report Config ID
|
||||||
|
// starts from 4
|
||||||
|
rc_A3->reportConfigId = a3_event->pci == -1 ? 3 : a3_event->pci + 4;
|
||||||
|
rc_A3->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
|
||||||
|
NR_EventTriggerConfig_t *etrc_A3 = calloc(1, sizeof(*etrc_A3));
|
||||||
|
etrc_A3->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA3;
|
||||||
|
etrc_A3->eventId.choice.eventA3 = calloc(1, sizeof(*etrc_A3->eventId.choice.eventA3));
|
||||||
|
etrc_A3->eventId.choice.eventA3->a3_Offset.present = NR_MeasTriggerQuantityOffset_PR_rsrp;
|
||||||
|
etrc_A3->eventId.choice.eventA3->a3_Offset.choice.rsrp = a3_event->a3_offset;
|
||||||
|
etrc_A3->eventId.choice.eventA3->reportOnLeave = true;
|
||||||
|
etrc_A3->eventId.choice.eventA3->hysteresis = a3_event->hysteresis;
|
||||||
|
etrc_A3->eventId.choice.eventA3->timeToTrigger = a3_event->timeToTrigger;
|
||||||
|
etrc_A3->rsType = NR_NR_RS_Type_ssb;
|
||||||
|
etrc_A3->reportInterval = NR_ReportInterval_ms1024;
|
||||||
|
etrc_A3->reportAmount = NR_EventTriggerConfig__reportAmount_r4;
|
||||||
|
etrc_A3->reportQuantityCell.rsrp = true;
|
||||||
|
etrc_A3->reportQuantityCell.rsrq = true;
|
||||||
|
etrc_A3->reportQuantityCell.sinr = true;
|
||||||
|
asn1cCallocOne(etrc_A3->maxNrofRS_IndexesToReport, 4);
|
||||||
|
etrc_A3->maxReportCells = 4;
|
||||||
|
etrc_A3->includeBeamMeasurements = false;
|
||||||
|
NR_ReportConfigNR_t *rcnr_A3 = calloc(1, sizeof(*rcnr_A3));
|
||||||
|
rcnr_A3->reportType.present = NR_ReportConfigNR__reportType_PR_eventTriggered;
|
||||||
|
rcnr_A3->reportType.choice.eventTriggered = etrc_A3;
|
||||||
|
rc_A3->reportConfig.choice.reportConfigNR = rcnr_A3;
|
||||||
|
return rc_A3;
|
||||||
|
}
|
||||||
|
|
||||||
static int rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc,
|
static int rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc,
|
||||||
gNB_RRC_UE_t *UE,
|
gNB_RRC_UE_t *UE,
|
||||||
uint8_t xid,
|
uint8_t xid,
|
||||||
@@ -484,6 +592,10 @@ static int rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc,
|
|||||||
DevAssert(du != NULL);
|
DevAssert(du != NULL);
|
||||||
f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info;
|
f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info;
|
||||||
NR_MeasConfig_t *measconfig = NULL;
|
NR_MeasConfig_t *measconfig = NULL;
|
||||||
|
NR_ReportConfigToAddMod_t *rc_PER = NULL;
|
||||||
|
NR_ReportConfigToAddMod_t *rc_A2 = NULL;
|
||||||
|
seq_arr_t *rc_A3_seq = NULL;
|
||||||
|
seq_arr_t *pci_seq = NULL;
|
||||||
if (du->mtc != NULL) {
|
if (du->mtc != NULL) {
|
||||||
int scs = get_ssb_scs(cell_info);
|
int scs = get_ssb_scs(cell_info);
|
||||||
int band = get_dl_band(cell_info);
|
int band = get_dl_band(cell_info);
|
||||||
@@ -494,7 +606,38 @@ static int rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc,
|
|||||||
if (neighbour_config)
|
if (neighbour_config)
|
||||||
neighbour_cells = neighbour_config->neighbour_cells;
|
neighbour_cells = neighbour_config->neighbour_cells;
|
||||||
|
|
||||||
measconfig = get_MeasConfig(mt, band, scs, &rrc->measurementConfiguration, neighbour_cells);
|
if (neighbour_cells
|
||||||
|
&& rrc->measurementConfiguration.a3_event_list
|
||||||
|
&& rrc->measurementConfiguration.a3_event_list->size > 0) {
|
||||||
|
/* Loop through neighbours and find related A3 configuration
|
||||||
|
If no related A3 but there is default add the default one.
|
||||||
|
If default one added once as a report, no need to add it again && duplication.
|
||||||
|
*/
|
||||||
|
rc_A3_seq = malloc(sizeof(seq_arr_t));
|
||||||
|
pci_seq = malloc(sizeof(seq_arr_t));
|
||||||
|
seq_arr_init(rc_A3_seq, sizeof(NR_ReportConfigToAddMod_t));
|
||||||
|
seq_arr_init(pci_seq, sizeof(int));
|
||||||
|
LOG_D(NR_RRC, "HO LOG: Preparing A3 Event Measurement Configuration!\n");
|
||||||
|
bool is_default_a3_added = false;
|
||||||
|
for (int i = 0; i < neighbour_cells->size; i++) {
|
||||||
|
nr_neighbour_gnb_configuration_t *neighbourCell = (nr_neighbour_gnb_configuration_t *)seq_arr_at(neighbour_cells, i);
|
||||||
|
if (!neighbourCell->isIntraFrequencyNeighbour)
|
||||||
|
continue;
|
||||||
|
seq_arr_push_back(pci_seq, &neighbourCell->physicalCellId, sizeof(int));
|
||||||
|
const nr_a3_event_t *a3Event = get_a3_configuration(rrc, neighbourCell->physicalCellId);
|
||||||
|
if (!a3Event || is_default_a3_added)
|
||||||
|
continue;
|
||||||
|
if (a3Event->pci == -1)
|
||||||
|
is_default_a3_added = true;
|
||||||
|
seq_arr_push_back(rc_A3_seq, prepare_a3_event_report(a3Event), sizeof(NR_ReportConfigToAddMod_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rrc->measurementConfiguration.per_event)
|
||||||
|
rc_PER = prepare_periodic_event_report(rrc->measurementConfiguration.per_event);
|
||||||
|
if (rrc->measurementConfiguration.a2_event)
|
||||||
|
rc_A2 = prepare_a2_event_report(rrc->measurementConfiguration.a2_event);
|
||||||
|
|
||||||
|
measconfig = get_MeasConfig(mt, band, scs, rc_PER, rc_A2, rc_A3_seq, pci_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UE->measConfig)
|
if (UE->measConfig)
|
||||||
@@ -1279,7 +1422,10 @@ static void process_Periodical_Measurement_Report(gNB_RRC_UE_t *ue_ctxt, NR_Meas
|
|||||||
measurementReport->criticalExtensions.choice.measurementReport = NULL;
|
measurementReport->criticalExtensions.choice.measurementReport = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_Event_Based_Measurement_Report(gNB_RRC_UE_t *ue, NR_ReportConfigNR_t *report, NR_MeasurementReport_t *measurementReport)
|
static void process_Event_Based_Measurement_Report(gNB_RRC_INST *rrc,
|
||||||
|
gNB_RRC_UE_t *ue,
|
||||||
|
NR_ReportConfigNR_t *report,
|
||||||
|
NR_MeasurementReport_t *measurementReport)
|
||||||
{
|
{
|
||||||
NR_EventTriggerConfig_t *event_triggered = report->reportType.choice.eventTriggered;
|
NR_EventTriggerConfig_t *event_triggered = report->reportType.choice.eventTriggered;
|
||||||
|
|
||||||
@@ -1344,7 +1490,7 @@ static void process_Event_Based_Measurement_Report(gNB_RRC_UE_t *ue, NR_ReportCo
|
|||||||
// neighbour.
|
// neighbour.
|
||||||
if (!neigh_cell && neighbour) {
|
if (!neigh_cell && neighbour) {
|
||||||
// No F1 connection but static neighbour configuration is available
|
// No F1 connection but static neighbour configuration is available
|
||||||
const nr_a3_event_t *a3_event_configuration = get_a3_configuration(neighbour->physicalCellId);
|
const nr_a3_event_t *a3_event_configuration = get_a3_configuration(rrc, neighbour->physicalCellId);
|
||||||
// Additional check - This part can be modified according to additional cell specific Handover Margin
|
// Additional check - This part can be modified according to additional cell specific Handover Margin
|
||||||
if (a3_event_configuration
|
if (a3_event_configuration
|
||||||
&& ((a3_event_configuration->a3_offset + a3_event_configuration->hysteresis)
|
&& ((a3_event_configuration->a3_offset + a3_event_configuration->hysteresis)
|
||||||
@@ -1370,7 +1516,7 @@ static void process_Event_Based_Measurement_Report(gNB_RRC_UE_t *ue, NR_ReportCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rrc_gNB_process_MeasurementReport(gNB_RRC_UE_t *UE, NR_MeasurementReport_t *measurementReport)
|
static void rrc_gNB_process_MeasurementReport(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_MeasurementReport_t *measurementReport)
|
||||||
{
|
{
|
||||||
NR_MeasurementReport__criticalExtensions_PR p = measurementReport->criticalExtensions.present;
|
NR_MeasurementReport__criticalExtensions_PR p = measurementReport->criticalExtensions.present;
|
||||||
if (p != NR_MeasurementReport__criticalExtensions_PR_measurementReport
|
if (p != NR_MeasurementReport__criticalExtensions_PR_measurementReport
|
||||||
@@ -1422,7 +1568,7 @@ static void rrc_gNB_process_MeasurementReport(gNB_RRC_UE_t *UE, NR_MeasurementRe
|
|||||||
return process_Periodical_Measurement_Report(UE, measurementReport);
|
return process_Periodical_Measurement_Report(UE, measurementReport);
|
||||||
|
|
||||||
if (report_config->choice.reportConfigNR->reportType.present == NR_ReportConfigNR__reportType_PR_eventTriggered)
|
if (report_config->choice.reportConfigNR->reportType.present == NR_ReportConfigNR__reportType_PR_eventTriggered)
|
||||||
return process_Event_Based_Measurement_Report(UE, report_config->choice.reportConfigNR, measurementReport);
|
return process_Event_Based_Measurement_Report(rrc, UE, report_config->choice.reportConfigNR, measurementReport);
|
||||||
|
|
||||||
LOG_E(NR_RRC, "Incoming Report Type: %d is not supported! \n", report_config->choice.reportConfigNR->reportType.present);
|
LOG_E(NR_RRC, "Incoming Report Type: %d is not supported! \n", report_config->choice.reportConfigNR->reportType.present);
|
||||||
}
|
}
|
||||||
@@ -1781,7 +1927,7 @@ static int rrc_gNB_decode_dcch(gNB_RRC_INST *rrc, const f1ap_ul_rrc_message_t *m
|
|||||||
|
|
||||||
case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
|
case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
|
||||||
if (ul_dcch_msg->message.choice.c1->choice.measurementReport != NULL) {
|
if (ul_dcch_msg->message.choice.c1->choice.measurementReport != NULL) {
|
||||||
rrc_gNB_process_MeasurementReport(UE, ul_dcch_msg->message.choice.c1->choice.measurementReport);
|
rrc_gNB_process_MeasurementReport(rrc, UE, ul_dcch_msg->message.choice.c1->choice.measurementReport);
|
||||||
} else {
|
} else {
|
||||||
LOG_E(NR_RRC, "UE %d: No measurementReport CHOICE is given\n", ue_context_p->ue_context.rrc_ue_id);
|
LOG_E(NR_RRC, "UE %d: No measurementReport CHOICE is given\n", ue_context_p->ue_context.rrc_ue_id);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user