Commit a7c632b8 authored by aligungr's avatar aligungr

RRC developments

parent fd300697
...@@ -25,20 +25,31 @@ void UeRrcTask::performCellSelection() ...@@ -25,20 +25,31 @@ void UeRrcTask::performCellSelection()
int lastCell = m_base->shCtx.currentCell.get<int>([](auto &value) { return value.cellId; }); int lastCell = m_base->shCtx.currentCell.get<int>([](auto &value) { return value.cellId; });
CurrentCellInfo cellInfo; CurrentCellInfo cellInfo;
CellSelectionReport report;
if (!lookForSuitableCell(cellInfo)) if (!lookForSuitableCell(cellInfo, report))
{ {
lookForAcceptableCell(cellInfo); m_logger->warn(
"Suitable cell selection failed in [%d] cells. [%d] out of PLMN, [%d] no SI, [%d] reserved, [%d] barred",
static_cast<int>(m_cellDesc.size()), report.outOfPlmnCells, report.sib1MissingCells, report.reservedCells,
report.barredCells);
report = {};
if (!lookForAcceptableCell(cellInfo, report))
{
m_logger->warn("Acceptable cell selection failed in [%d] cells. [%d] no SI, [%d] reserved, [%d] barred",
static_cast<int>(m_cellDesc.size()), report.sib1MissingCells, report.reservedCells,
report.barredCells);
m_logger->err("Cell selection failure, no suitable or acceptable cell found");
}
} }
int selectedCell = cellInfo.cellId; int selectedCell = cellInfo.cellId;
m_base->shCtx.currentCell.set(cellInfo); m_base->shCtx.currentCell.set(cellInfo);
if (selectedCell != 0 && selectedCell != lastCell) if (selectedCell != 0 && selectedCell != lastCell)
{
m_logger->info("Selected cell id[%d] category[%s]", selectedCell, ToJson(cellInfo.category).str().c_str()); m_logger->info("Selected cell id[%d] category[%s]", selectedCell, ToJson(cellInfo.category).str().c_str());
}
if (selectedCell != lastCell) if (selectedCell != lastCell)
{ {
...@@ -50,17 +61,12 @@ void UeRrcTask::performCellSelection() ...@@ -50,17 +61,12 @@ void UeRrcTask::performCellSelection()
} }
} }
bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo) bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo, CellSelectionReport &report)
{ {
Plmn selectedPlmn = m_base->shCtx.selectedPlmn.get(); Plmn selectedPlmn = m_base->shCtx.selectedPlmn.get();
if (!selectedPlmn.hasValue()) if (!selectedPlmn.hasValue())
return false; return false;
int outOfPlmnCells = 0;
int sib1MissingCells = 0;
int barredCells = 0;
int reservedCells = 0;
std::vector<int> candidates; std::vector<int> candidates;
for (auto &item : m_cellDesc) for (auto &item : m_cellDesc)
...@@ -69,13 +75,13 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo) ...@@ -69,13 +75,13 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo)
if (!cell.sib1.hasSib1) if (!cell.sib1.hasSib1)
{ {
sib1MissingCells++; report.sib1MissingCells++;
continue; continue;
} }
if (cell.sib1.plmn != selectedPlmn) if (cell.sib1.plmn != selectedPlmn)
{ {
outOfPlmnCells++; report.outOfPlmnCells++;
continue; continue;
} }
...@@ -83,14 +89,14 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo) ...@@ -83,14 +89,14 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo)
{ {
if (cell.mib.isBarred) if (cell.mib.isBarred)
{ {
barredCells++; report.barredCells++;
continue; continue;
} }
} }
if (cell.sib1.isReserved) if (cell.sib1.isReserved)
{ {
reservedCells++; report.reservedCells++;
continue; continue;
} }
...@@ -102,12 +108,7 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo) ...@@ -102,12 +108,7 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo)
} }
if (candidates.empty()) if (candidates.empty())
{
m_logger->err("Cell selection failed in [%d] cells. [%d] out of PLMN, [%d] no SI, [%d] reserved, [%d] barred",
static_cast<int>(m_cellDesc.size()), outOfPlmnCells, sib1MissingCells, reservedCells,
barredCells);
return false; return false;
}
// Order candidates by signal strength // Order candidates by signal strength
std::sort(candidates.begin(), candidates.end(), [this](int a, int b) { std::sort(candidates.begin(), candidates.end(), [this](int a, int b) {
...@@ -128,10 +129,78 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo) ...@@ -128,10 +129,78 @@ bool UeRrcTask::lookForSuitableCell(CurrentCellInfo &cellInfo)
return true; return true;
} }
bool UeRrcTask::lookForAcceptableCell(CurrentCellInfo &cellInfo) bool UeRrcTask::lookForAcceptableCell(CurrentCellInfo &cellInfo, CellSelectionReport &report)
{ {
// TODO std::vector<int> candidates;
for (auto &item : m_cellDesc)
{
auto &cell = item.second;
if (!cell.sib1.hasSib1)
{
report.sib1MissingCells++;
continue;
}
if (cell.mib.hasMib)
{
if (cell.mib.isBarred)
{
report.barredCells++;
continue;
}
}
if (cell.sib1.isReserved)
{
report.reservedCells++;
continue;
}
// TODO: Check TAI if forbidden by service area or forbidden list
// TODO: Do we need to check by access identity?
// It seems acceptable
candidates.push_back(item.first);
}
if (candidates.empty())
return false; return false;
// Order candidates by signal strength first
std::sort(candidates.begin(), candidates.end(), [this](int a, int b) {
auto &cellA = m_cellDesc[a];
auto &cellB = m_cellDesc[b];
return cellB.dbm < cellA.dbm;
});
// Then order candidates by PLMN priority if we have a selected PLMN
Plmn selectedPlmn = m_base->shCtx.selectedPlmn.get();
if (selectedPlmn.hasValue())
{
// Using stable-sort here
std::stable_sort(candidates.begin(), candidates.end(), [this, &selectedPlmn](int a, int b) {
auto &cellA = m_cellDesc[a];
auto &cellB = m_cellDesc[b];
bool matchesA = cellA.sib1.hasSib1 && cellA.sib1.plmn == selectedPlmn;
bool matchesB = cellB.sib1.hasSib1 && cellB.sib1.plmn == selectedPlmn;
return matchesB < matchesA;
});
}
auto &selectedId = candidates[0];
auto &selectedCell = m_cellDesc[selectedId];
cellInfo = {};
cellInfo.cellId = selectedId;
cellInfo.plmn = selectedCell.sib1.plmn;
cellInfo.tac = selectedCell.sib1.tac;
cellInfo.category = ECellCategory::ACCEPTABLE_CELL;
return true;
} }
} // namespace nr::ue } // namespace nr::ue
\ No newline at end of file
...@@ -104,8 +104,8 @@ class UeRrcTask : public NtsTask ...@@ -104,8 +104,8 @@ class UeRrcTask : public NtsTask
/* Idle Mode Operations */ /* Idle Mode Operations */
void performCellSelection(); void performCellSelection();
bool lookForSuitableCell(CurrentCellInfo &cellInfo); bool lookForSuitableCell(CurrentCellInfo &cellInfo, CellSelectionReport &report);
bool lookForAcceptableCell(CurrentCellInfo &cellInfo); bool lookForAcceptableCell(CurrentCellInfo &cellInfo, CellSelectionReport &report);
/* Cell Management */ /* Cell Management */
void handleCellSignalChange(int cellId, int dbm); void handleCellSignalChange(int cellId, int dbm);
......
...@@ -138,6 +138,14 @@ struct UeConfig ...@@ -138,6 +138,14 @@ struct UeConfig
} }
}; };
struct CellSelectionReport
{
int outOfPlmnCells{};
int sib1MissingCells{};
int reservedCells{};
int barredCells{};
};
struct CurrentCellInfo struct CurrentCellInfo
{ {
int cellId{}; int cellId{};
......
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