Commit 2ab318fe authored by aligungr's avatar aligungr

UE SAS dev.

parent 3a1d5581
...@@ -41,6 +41,7 @@ void GnbSasTask::handleCellInfoRequest(const InetAddress &addr, const sas::SasCe ...@@ -41,6 +41,7 @@ void GnbSasTask::handleCellInfoRequest(const InetAddress &addr, const sas::SasCe
resp.tac = m_base->config->tac; resp.tac = m_base->config->tac;
resp.dbm = dbm; resp.dbm = dbm;
resp.gnbName = m_base->config->name; resp.gnbName = m_base->config->name;
resp.linkIp = m_base->config->portalIp;
sendSasMessage(addr, resp); sendSasMessage(addr, resp);
} }
......
...@@ -40,6 +40,9 @@ void NasMm::handleRrcEvent(const NwUeRrcToNas &msg) ...@@ -40,6 +40,9 @@ void NasMm::handleRrcEvent(const NwUeRrcToNas &msg)
handleRadioLinkFailure(); handleRadioLinkFailure();
break; break;
} }
case NwUeRrcToNas::SERVING_CELL_CHANGE: {
handleServingCellChange(msg.servingCell);
}
} }
} }
......
...@@ -145,6 +145,7 @@ class NasMm ...@@ -145,6 +145,7 @@ class NasMm
void handlePlmnSearchResponse(const std::vector<UeCellMeasurement> &measures); void handlePlmnSearchResponse(const std::vector<UeCellMeasurement> &measures);
void handleRrcConnectionSetup(); void handleRrcConnectionSetup();
void handleRrcConnectionRelease(); void handleRrcConnectionRelease();
void handleServingCellChange(const UeCellInfo &servingCell);
void handleRadioLinkFailure(); void handleRadioLinkFailure();
private: /* Access Control */ private: /* Access Control */
......
...@@ -151,6 +151,36 @@ void NasMm::handlePlmnSearchResponse(const std::vector<UeCellMeasurement> &measu ...@@ -151,6 +151,36 @@ void NasMm::handlePlmnSearchResponse(const std::vector<UeCellMeasurement> &measu
} }
} }
void NasMm::handleServingCellChange(const UeCellInfo &servingCell)
{
if (m_cmState == ECmState::CM_CONNECTED)
{
m_logger->err("Serving cell change in CM-CONNECTED");
return;
}
if (servingCell.cellCategory != ECellCategory::ACCEPTABLE_CELL &&
servingCell.cellCategory != ECellCategory::SUITABLE_CELL)
{
m_logger->err("Serving cell change with unhandled cell category");
return;
}
m_logger->info("Serving cell determined [%s]", servingCell.gnbName.c_str());
if (m_mmState == EMmState::MM_REGISTERED || m_mmState == EMmState::MM_DEREGISTERED)
{
bool isSuitable = servingCell.cellCategory == ECellCategory::SUITABLE_CELL;
if (m_mmState == EMmState::MM_REGISTERED)
switchMmState(EMmState::MM_REGISTERED, isSuitable ? EMmSubState::MM_REGISTERED_NORMAL_SERVICE
: EMmSubState::MM_REGISTERED_LIMITED_SERVICE);
else
switchMmState(EMmState::MM_DEREGISTERED, isSuitable ? EMmSubState::MM_DEREGISTERED_NORMAL_SERVICE
: EMmSubState::MM_DEREGISTERED_LIMITED_SERVICE);
}
}
void NasMm::handleRrcConnectionSetup() void NasMm::handleRrcConnectionSetup()
{ {
switchCmState(ECmState::CM_CONNECTED); switchCmState(ECmState::CM_CONNECTED);
......
...@@ -153,6 +153,7 @@ struct NwUeRrcToNas : NtsMessage ...@@ -153,6 +153,7 @@ struct NwUeRrcToNas : NtsMessage
RRC_CONNECTION_SETUP, RRC_CONNECTION_SETUP,
RRC_CONNECTION_RELEASE, RRC_CONNECTION_RELEASE,
RADIO_LINK_FAILURE, RADIO_LINK_FAILURE,
SERVING_CELL_CHANGE,
} present; } present;
// NAS_DELIVERY // NAS_DELIVERY
...@@ -161,6 +162,9 @@ struct NwUeRrcToNas : NtsMessage ...@@ -161,6 +162,9 @@ struct NwUeRrcToNas : NtsMessage
// PLMN_SEARCH_RESPONSE // PLMN_SEARCH_RESPONSE
std::vector<UeCellMeasurement> measurements{}; std::vector<UeCellMeasurement> measurements{};
// SERVING_CELL_CHANGE
UeCellInfo servingCell{};
explicit NwUeRrcToNas(PR present) : NtsMessage(NtsMessageType::UE_RRC_TO_NAS), present(present) explicit NwUeRrcToNas(PR present) : NtsMessage(NtsMessageType::UE_RRC_TO_NAS), present(present)
{ {
} }
...@@ -236,11 +240,15 @@ struct NwUeSasToRrc : NtsMessage ...@@ -236,11 +240,15 @@ struct NwUeSasToRrc : NtsMessage
enum PR enum PR
{ {
PLMN_SEARCH_RESPONSE, PLMN_SEARCH_RESPONSE,
SERVING_CELL_CHANGE
} present; } present;
// PLMN_SEARCH_RESPONSE // PLMN_SEARCH_RESPONSE
std::vector<UeCellMeasurement> measurements{}; std::vector<UeCellMeasurement> measurements{};
// SERVING_CELL_CHANGE
UeCellInfo servingCell{};
explicit NwUeSasToRrc(PR present) : NtsMessage(NtsMessageType::UE_SAS_TO_RRC), present(present) explicit NwUeSasToRrc(PR present) : NtsMessage(NtsMessageType::UE_SAS_TO_RRC), present(present)
{ {
} }
......
...@@ -106,6 +106,12 @@ void UeRrcTask::onLoop() ...@@ -106,6 +106,12 @@ void UeRrcTask::onLoop()
m_base->nasTask->push(wr); m_base->nasTask->push(wr);
break; break;
} }
case NwUeSasToRrc::SERVING_CELL_CHANGE: {
auto *wr = new NwUeRrcToNas(NwUeRrcToNas::SERVING_CELL_CHANGE);
wr->servingCell = w->servingCell;
m_base->nasTask->push(wr);
break;
}
} }
break; break;
} }
......
...@@ -16,8 +16,24 @@ namespace nr::ue ...@@ -16,8 +16,24 @@ namespace nr::ue
void UeSasTask::handleCellSelectionCommand(const GlobalNci &cellId, bool isSuitable) void UeSasTask::handleCellSelectionCommand(const GlobalNci &cellId, bool isSuitable)
{ {
m_logger->err("TODO"); // TODO perform camp if (!m_activeMeasurements.count(cellId))
} {
m_logger->err("Selected cell is no longer available for camping");
return;
}
auto &measurement = m_activeMeasurements[cellId];
m_servingCell = UeCellInfo{};
m_servingCell->cellId = measurement.cellId;
m_servingCell->tac = measurement.tac;
m_servingCell->gnbName = measurement.gnbName;
m_servingCell->linkIp = measurement.linkIp;
m_servingCell->cellCategory = isSuitable ? ECellCategory::SUITABLE_CELL : ECellCategory::ACCEPTABLE_CELL;
auto *w = new NwUeSasToRrc(NwUeSasToRrc::SERVING_CELL_CHANGE);
w->servingCell = *m_servingCell;
m_base->rrcTask->push(w);
}
} // namespace nr::ue } // namespace nr::ue
...@@ -53,7 +53,7 @@ void UeSasTask::receiveCellInfoResponse(const sas::SasCellInfoResponse &msg) ...@@ -53,7 +53,7 @@ void UeSasTask::receiveCellInfoResponse(const sas::SasCellInfoResponse &msg)
meas.tac = msg.tac; meas.tac = msg.tac;
meas.dbm = msg.dbm; meas.dbm = msg.dbm;
meas.gnbName = msg.gnbName; meas.gnbName = msg.gnbName;
meas.time = utils::CurrentTimeMillis(); meas.linkIp = msg.linkIp;
m_pendingMeasurements[meas.cellId] = meas; m_pendingMeasurements[meas.cellId] = meas;
} }
......
...@@ -17,7 +17,7 @@ namespace nr::ue ...@@ -17,7 +17,7 @@ namespace nr::ue
{ {
UeSasTask::UeSasTask(TaskBase *base) UeSasTask::UeSasTask(TaskBase *base)
: m_base{base}, m_udpTask{}, m_cellSearchSpace{}, m_pendingMeasurements{}, m_activeMeasurements{} : m_base{base}, m_udpTask{}, m_cellSearchSpace{}, m_pendingMeasurements{}, m_activeMeasurements{}, m_servingCell{}
{ {
m_logger = m_base->logBase->makeUniqueLogger(m_base->config->getLoggerPrefix() + "sas"); m_logger = m_base->logBase->makeUniqueLogger(m_base->config->getLoggerPrefix() + "sas");
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <optional>
#include <thread> #include <thread>
#include <udp/server_task.hpp> #include <udp/server_task.hpp>
#include <ue/types.hpp> #include <ue/types.hpp>
...@@ -33,6 +34,8 @@ class UeSasTask : public NtsTask ...@@ -33,6 +34,8 @@ class UeSasTask : public NtsTask
std::unordered_map<GlobalNci, UeCellMeasurement> m_pendingMeasurements; std::unordered_map<GlobalNci, UeCellMeasurement> m_pendingMeasurements;
std::unordered_map<GlobalNci, UeCellMeasurement> m_activeMeasurements; std::unordered_map<GlobalNci, UeCellMeasurement> m_activeMeasurements;
std::optional<UeCellInfo> m_servingCell;
friend class UeCmdHandler; friend class UeCmdHandler;
public: public:
......
...@@ -65,6 +65,8 @@ void EncodeSasMessage(const SasMessage &msg, OctetString &stream) ...@@ -65,6 +65,8 @@ void EncodeSasMessage(const SasMessage &msg, OctetString &stream)
stream.appendOctet4(m.dbm); stream.appendOctet4(m.dbm);
stream.appendOctet4(static_cast<int>(m.gnbName.size())); stream.appendOctet4(static_cast<int>(m.gnbName.size()));
stream.appendUtf8(m.gnbName); stream.appendUtf8(m.gnbName);
stream.appendOctet4(static_cast<int>(m.linkIp.size()));
stream.appendUtf8(m.linkIp);
} }
} }
...@@ -97,6 +99,7 @@ std::unique_ptr<SasMessage> DecodeSasMessage(const OctetView &stream) ...@@ -97,6 +99,7 @@ std::unique_ptr<SasMessage> DecodeSasMessage(const OctetView &stream)
res->tac = stream.read4I(); res->tac = stream.read4I();
res->dbm = stream.read4I(); res->dbm = stream.read4I();
res->gnbName = stream.readUtf8String(stream.read4I()); res->gnbName = stream.readUtf8String(stream.read4I());
res->linkIp = stream.readUtf8String(stream.read4I());
return res; return res;
} }
......
...@@ -48,6 +48,7 @@ struct SasCellInfoResponse : SasMessage ...@@ -48,6 +48,7 @@ struct SasCellInfoResponse : SasMessage
int tac{}; int tac{};
int dbm{}; int dbm{};
std::string gnbName{}; std::string gnbName{};
std::string linkIp{};
SasCellInfoResponse() : SasMessage(SasMessageType::CELL_INFO_RESPONSE) SasCellInfoResponse() : SasMessage(SasMessageType::CELL_INFO_RESPONSE)
{ {
......
...@@ -131,13 +131,31 @@ struct GlobalNci ...@@ -131,13 +131,31 @@ struct GlobalNci
} }
}; };
enum class ECellCategory
{
UNDEFINED,
ACCEPTABLE_CELL,
SUITABLE_CELL,
BARRED_CELL,
RESERVED_CELL,
};
struct UeCellMeasurement struct UeCellMeasurement
{ {
GlobalNci cellId{}; GlobalNci cellId{};
int tac{}; int tac{};
int dbm{}; int dbm{};
std::string gnbName{}; std::string gnbName{};
uint64_t time{}; std::string linkIp{};
};
struct UeCellInfo
{
GlobalNci cellId{};
int tac{};
ECellCategory cellCategory{};
std::string gnbName{};
std::string linkIp{};
}; };
struct Vector3 struct Vector3
......
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