Commit 9dfe831f authored by aligungr's avatar aligungr

RRC developments

parent 510cbb63
//
// This file is a part of UERANSIM open source project.
// Copyright (c) 2021 ALİ GÜNGÖR.
//
// The software and all associated files are licensed under GPL-3.0
// and subject to the terms and conditions defined in LICENSE file.
//
#include "task.hpp"
#include <algorithm>
#include <lib/asn/rrc.hpp>
#include <lib/asn/utils.hpp>
#include <lib/rrc/encode.hpp>
#include <ue/nas/task.hpp>
namespace nr::ue
{
void UeRrcTask::performCellSelection()
{
if (m_state == ERrcState::RRC_CONNECTED)
return;
if (!lookForSuitableCell())
lookForAcceptableCell();
}
bool UeRrcTask::lookForSuitableCell()
{
Plmn selectedPlmn = m_base->shCtx.selectedPlmn.get();
if (!selectedPlmn.hasValue())
return false;
int lastCell = m_base->shCtx.currentCell.get<int>([](auto &value) { return value.cellId; });
int outOfPlmnCells = 0;
int sib1MissingCells = 0;
int barredCells = 0;
int reservedCells = 0;
std::vector<int> candidates;
for (auto &item : m_cellDesc)
{
auto &cell = item.second;
if (!cell.sib1.hasSib1)
{
sib1MissingCells++;
continue;
}
if (cell.sib1.plmn != selectedPlmn)
{
outOfPlmnCells++;
continue;
}
if (cell.mib.hasMib)
{
if (cell.mib.isBarred)
{
barredCells++;
continue;
}
}
if (cell.sib1.isReserved)
{
reservedCells++;
continue;
}
// TODO: Check TAI if forbidden by service area or forbidden list
// TODO: Do we need to check by access identity
// It seems suitable
candidates.push_back(item.first);
}
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;
}
// Order candidates by signal strength
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;
});
auto &selectedId = candidates[0];
auto &selectedCell = m_cellDesc[selectedId];
CurrentCellInfo cellInfo;
cellInfo.cellId = selectedId;
cellInfo.plmn = selectedCell.sib1.plmn;
cellInfo.tac = selectedCell.sib1.tac;
cellInfo.category = ECellCategory::SUITABLE_CELL;
m_base->shCtx.currentCell.set(cellInfo);
if (lastCell != selectedId)
{
m_logger->info("Selected cell id[%d] category[SUITABLE]", selectedId);
// TODO: Notify RLS
m_base->nasTask->push(new NwUeRrcToNas(NwUeRrcToNas::NAS_NOTIFY));
}
return true;
}
bool UeRrcTask::lookForAcceptableCell()
{
// TODO
return false;
}
} // namespace nr::ue
\ No newline at end of file
...@@ -18,8 +18,17 @@ namespace nr::ue ...@@ -18,8 +18,17 @@ namespace nr::ue
void UeRrcTask::performCycle() void UeRrcTask::performCycle()
{ {
// TODO if (m_state == ERrcState::RRC_CONNECTED)
{
}
else if (m_state == ERrcState::RRC_IDLE)
{
performCellSelection();
}
else if (m_state == ERrcState::RRC_INACTIVE)
{
performCellSelection();
}
} }
} // namespace nr::ue } // namespace nr::ue
\ No newline at end of file
...@@ -100,6 +100,11 @@ class UeRrcTask : public NtsTask ...@@ -100,6 +100,11 @@ class UeRrcTask : public NtsTask
/* State Management */ /* State Management */
void performCycle(); void performCycle();
/* Idle Mode Operations */
void performCellSelection();
bool lookForSuitableCell();
bool lookForAcceptableCell();
/* Cell Management */ /* Cell Management */
void handleCellSignalChange(int cellId, int dbm); void handleCellSignalChange(int cellId, int dbm);
void notifyCellDetected(int cellId, int dbm); void notifyCellDetected(int cellId, int dbm);
......
...@@ -274,4 +274,9 @@ Json ToJson(const EServiceReqCause &v) ...@@ -274,4 +274,9 @@ Json ToJson(const EServiceReqCause &v)
} }
} }
bool CurrentCellInfo::hasValue() const
{
return cellId != 0;
}
} // namespace nr::ue } // namespace nr::ue
...@@ -138,10 +138,21 @@ struct UeConfig ...@@ -138,10 +138,21 @@ struct UeConfig
} }
}; };
struct CurrentCellInfo
{
int cellId{};
ECellCategory category{};
Plmn plmn{};
int tac{};
[[nodiscard]] bool hasValue() const;
};
struct UeSharedContext struct UeSharedContext
{ {
Locked<std::unordered_set<Plmn>> availablePlmns; Locked<std::unordered_set<Plmn>> availablePlmns;
Locked<Plmn> selectedPlmn; Locked<Plmn> selectedPlmn;
Locked<CurrentCellInfo> currentCell;
}; };
struct TaskBase struct TaskBase
......
...@@ -146,11 +146,10 @@ struct GlobalNci ...@@ -146,11 +146,10 @@ struct GlobalNci
enum class ECellCategory enum class ECellCategory
{ {
UNDEFINED,
ACCEPTABLE_CELL,
SUITABLE_CELL,
BARRED_CELL, BARRED_CELL,
RESERVED_CELL, RESERVED_CELL,
ACCEPTABLE_CELL,
SUITABLE_CELL,
}; };
struct UeCellMeasurement struct UeCellMeasurement
......
...@@ -33,14 +33,14 @@ class Locked ...@@ -33,14 +33,14 @@ class Locked
Locked &operator=(Locked &&) = delete; Locked &operator=(Locked &&) = delete;
template <typename Func> template <typename Func>
inline void access(Func&& fun) inline void access(Func &&fun)
{ {
// Şimdilik access ve mutate aynı, optimizasyon adına read-write lock kullanılabilir // Şimdilik access ve mutate aynı, optimizasyon adına read-write lock kullanılabilir
mutate(fun); mutate(fun);
} }
template <typename Func> template <typename Func>
inline void mutate(Func&& fun) inline void mutate(Func &&fun)
{ {
std::lock_guard lk(m_mutex); std::lock_guard lk(m_mutex);
fun(m_value); fun(m_value);
...@@ -53,8 +53,21 @@ class Locked ...@@ -53,8 +53,21 @@ class Locked
return copy; return copy;
} }
template <typename U, typename Func>
inline U get(Func &&fun)
{
U copy{};
access([&copy, &fun](auto &value) { copy = fun(value); });
return copy;
}
inline void set(const T &value) inline void set(const T &value)
{ {
mutate([&value](auto &v) { v = value; }); mutate([&value](auto &v) { v = value; });
} }
inline void set(T &&value)
{
mutate([&value](auto &v) { v = std::move(value); });
}
}; };
\ No newline at end of file
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