Commit de27eb68 authored by aligungr's avatar aligungr

RRC developments

parent 5e0d35c6
...@@ -57,9 +57,11 @@ class NasMm ...@@ -57,9 +57,11 @@ class NasMm
// Network feature support information // Network feature support information
nas::IE5gsNetworkFeatureSupport m_nwFeatureSupport{}; nas::IE5gsNetworkFeatureSupport m_nwFeatureSupport{};
// Last time Service Request needed indication for Data // Last time Service Request needed indication for Data
long m_lastTimeServiceReqNeededIndForData{}; int64_t m_lastTimeServiceReqNeededIndForData{};
// Number of times the network failing the authentication check // Number of times the network failing the authentication check
int m_nwConsecutiveAuthFailure{}; int m_nwConsecutiveAuthFailure{};
// Last time PLMN search failure logged
int64_t m_lastTimePlmnSearchFailureLogged{};
friend class UeCmdHandler; friend class UeCmdHandler;
......
...@@ -7,18 +7,75 @@ ...@@ -7,18 +7,75 @@
// //
#include "mm.hpp" #include "mm.hpp"
#include <algorithm> #include <algorithm>
#include <lib/nas/utils.hpp> #include <lib/nas/utils.hpp>
#include <ue/app/task.hpp> #include <ue/app/task.hpp>
#include <ue/nas/sm/sm.hpp> #include <ue/nas/sm/sm.hpp>
#include <ue/rrc/task.hpp> #include <ue/rrc/task.hpp>
#include <utils/common.hpp>
namespace nr::ue namespace nr::ue
{ {
void NasMm::performPlmnSelection() void NasMm::performPlmnSelection()
{ {
// TODO int64_t currentTime = utils::CurrentTimeMillis();
bool logFailures = currentTime - m_lastTimePlmnSearchFailureLogged >= 10'000;
Plmn lastSelectedPlmn = m_base->shCtx.selectedPlmn.get();
std::unordered_set<Plmn> plmns = m_base->shCtx.availablePlmns.get();
if (!m_usim->isValid() || plmns.empty())
{
if (logFailures)
{
if (!m_usim->isValid())
m_logger->warn("No PLMN can be selected, USIM is invalid");
else
m_logger->err("PLMN selection failure, no cells in coverage");
m_lastTimePlmnSearchFailureLogged = currentTime;
}
m_base->shCtx.selectedPlmn.set({});
return;
}
std::vector<Plmn> candidates;
for (auto &plmn : plmns)
if (plmn == m_base->config->hplmn)
candidates.push_back(plmn);
for (auto &plmn : plmns)
{
if (plmn == m_base->config->hplmn)
continue;
if (nas::utils::PlmnListContains(m_usim->m_forbiddenPlmnList, plmn))
continue;
if (nas::utils::ServiceAreaListForbidsPlmn(m_usim->m_serviceAreaList, nas::utils::PlmnFrom(plmn)))
continue;
if (nas::utils::PlmnListContains(m_usim->m_equivalentPlmnList, plmn))
candidates.push_back(plmn);
}
Plmn selected = candidates.empty() ? Plmn{} : candidates[0];
if (!selected.hasValue())
{
if (logFailures)
{
m_logger->err("No PLMN could be selected among [%d] PLMNs", static_cast<int>(plmns.size()));
m_lastTimePlmnSearchFailureLogged = currentTime;
}
}
else if (lastSelectedPlmn != selected)
m_logger->info("Selected PLMN[%s]", ToJson(selected).str().c_str());
m_base->shCtx.selectedPlmn.set(selected);
} }
void NasMm::handleServingCellChange(const UeCellInfo &servingCell) void NasMm::handleServingCellChange(const UeCellInfo &servingCell)
......
...@@ -140,7 +140,8 @@ struct UeConfig ...@@ -140,7 +140,8 @@ struct UeConfig
struct UeSharedContext struct UeSharedContext
{ {
Locked<std::unordered_set<Plmn>> availablePlmns{}; Locked<std::unordered_set<Plmn>> availablePlmns;
Locked<Plmn> selectedPlmn;
}; };
struct TaskBase struct TaskBase
......
...@@ -96,6 +96,11 @@ bool operator==(const Plmn &lhs, const Plmn &rhs) ...@@ -96,6 +96,11 @@ bool operator==(const Plmn &lhs, const Plmn &rhs)
return lhs.isLongMnc == rhs.isLongMnc; return lhs.isLongMnc == rhs.isLongMnc;
} }
bool operator!=(const Plmn &lhs, const Plmn &rhs)
{
return !(lhs == rhs);
}
bool operator==(const GlobalNci &lhs, const GlobalNci &rhs) bool operator==(const GlobalNci &lhs, const GlobalNci &rhs)
{ {
return lhs.plmn == rhs.plmn && lhs.nci == rhs.nci; return lhs.plmn == rhs.plmn && lhs.nci == rhs.nci;
...@@ -123,3 +128,8 @@ std::size_t std::hash<GlobalNci>::operator()(const GlobalNci &v) const noexcept ...@@ -123,3 +128,8 @@ std::size_t std::hash<GlobalNci>::operator()(const GlobalNci &v) const noexcept
utils::HashCombine(h, v.nci); utils::HashCombine(h, v.nci);
return h; return h;
} }
bool Plmn::hasValue() const
{
return this->mcc != 0;
}
...@@ -30,6 +30,8 @@ struct Plmn ...@@ -30,6 +30,8 @@ struct Plmn
int mcc{}; int mcc{};
int mnc{}; int mnc{};
bool isLongMnc{}; bool isLongMnc{};
[[nodiscard]] bool hasValue() const;
}; };
struct SingleSlice struct SingleSlice
...@@ -197,6 +199,7 @@ struct UacAiBarringSet ...@@ -197,6 +199,7 @@ struct UacAiBarringSet
bool operator==(const SingleSlice &lhs, const SingleSlice &rhs); bool operator==(const SingleSlice &lhs, const SingleSlice &rhs);
bool operator==(const Plmn &lhs, const Plmn &rhs); bool operator==(const Plmn &lhs, const Plmn &rhs);
bool operator!=(const Plmn &lhs, const Plmn &rhs);
bool operator==(const GlobalNci &lhs, const GlobalNci &rhs); bool operator==(const GlobalNci &lhs, const GlobalNci &rhs);
Json ToJson(const Supi &v); Json ToJson(const Supi &v);
......
...@@ -24,6 +24,8 @@ class Locked ...@@ -24,6 +24,8 @@ class Locked
{ {
} }
static_assert(!std::is_reference<T>::value);
Locked(const T &) = delete; Locked(const T &) = delete;
Locked(T &&) = delete; Locked(T &&) = delete;
...@@ -43,4 +45,16 @@ class Locked ...@@ -43,4 +45,16 @@ class Locked
std::lock_guard lk(m_mutex); std::lock_guard lk(m_mutex);
fun(m_value); fun(m_value);
} }
inline T get()
{
T copy{};
access([&copy](auto &value) { copy = value; });
return copy;
}
inline void set(const T &value)
{
mutate([&value](auto &v) { v = 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