Commit 14fe33e5 authored by aligungr's avatar aligungr

UE SAS dev.

parent 53548ab1
......@@ -12,6 +12,7 @@
#include "mr/task.hpp"
#include "ngap/task.hpp"
#include "rrc/task.hpp"
#include "sas/task.hpp"
#include "sctp/task.hpp"
#include <app/cli_base.hpp>
......@@ -34,6 +35,7 @@ GNodeB::GNodeB(GnbConfig *config, app::INodeListener *nodeListener, NtsTask *cli
base->rrcTask = new GnbRrcTask(base);
base->gtpTask = new GtpTask(base);
base->mrTask = new GnbMrTask(base);
base->sasTask = new GnbSasTask(base);
taskBase = base;
}
......@@ -46,6 +48,7 @@ GNodeB::~GNodeB()
taskBase->rrcTask->quit();
taskBase->gtpTask->quit();
taskBase->mrTask->quit();
taskBase->sasTask->quit();
delete taskBase->appTask;
delete taskBase->sctpTask;
......@@ -53,6 +56,7 @@ GNodeB::~GNodeB()
delete taskBase->rrcTask;
delete taskBase->gtpTask;
delete taskBase->mrTask;
delete taskBase->sasTask;
delete taskBase->logBase;
......@@ -65,6 +69,7 @@ void GNodeB::start()
taskBase->sctpTask->start();
taskBase->ngapTask->start();
taskBase->rrcTask->start();
taskBase->sasTask->start();
taskBase->mrTask->start();
taskBase->gtpTask->start();
}
......
//
// 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 <cmath>
static int EstimateSimulatedDbm(const Vector3 &myPos, const Vector3 &uePos)
{
int deltaX = myPos.x - uePos.x;
int deltaY = myPos.y - uePos.y;
int deltaZ = myPos.z - uePos.z;
int distance = static_cast<int>(std::sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ));
return -distance;
}
namespace nr::gnb
{
void GnbSasTask::handleCellInfoRequest(const InetAddress &addr, const sas::SasCellInfoRequest &msg)
{
sas::SasCellInfoResponse resp{};
resp.cellId.nci = m_base->config->nci;
resp.cellId.plmn = m_base->config->plmn;
resp.tac = m_base->config->tac;
resp.dbm = EstimateSimulatedDbm(m_base->config->phyLocation, msg.simPos);
sendSasMessage(addr, resp);
}
} // namespace nr::gnb
//
// 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 <gnb/gtp/task.hpp>
#include <gnb/nts.hpp>
#include <gnb/rrc/task.hpp>
#include <utils/constants.hpp>
#include <utils/libc_error.hpp>
namespace nr::gnb
{
GnbSasTask::GnbSasTask(TaskBase *base) : m_base{base}, m_udpTask{}
{
m_logger = m_base->logBase->makeUniqueLogger("sas");
}
void GnbSasTask::onStart()
{
try
{
m_udpTask = new udp::UdpServerTask(m_base->config->portalIp, cons::PortalPort, this);
m_udpTask->start();
}
catch (const LibError &e)
{
m_logger->err("SAS failure [%s]", e.what());
quit();
return;
}
}
void GnbSasTask::onLoop()
{
NtsMessage *msg = take();
if (!msg)
return;
switch (msg->msgType)
{
case NtsMessageType::UDP_SERVER_RECEIVE: {
auto *w = dynamic_cast<udp::NwUdpServerReceive *>(msg);
auto sasMsg = sas::DecodeSasMessage(OctetView{w->packet});
if (sasMsg == nullptr)
{
m_logger->err("Unable to decode SAS message");
break;
}
receiveSasMessage(w->fromAddress, *sasMsg);
break;
}
default:
m_logger->unhandledNts(msg);
break;
}
delete msg;
}
void GnbSasTask::onQuit()
{
if (m_udpTask != nullptr)
m_udpTask->quit();
delete m_udpTask;
}
} // namespace nr::gnb
//
// 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.
//
#pragma once
#include <gnb/nts.hpp>
#include <gnb/types.hpp>
#include <memory>
#include <thread>
#include <udp/server_task.hpp>
#include <unordered_map>
#include <urs/rls/gnb_entity.hpp>
#include <urs/sas_pdu.hpp>
#include <utils/logger.hpp>
#include <utils/nts.hpp>
#include <vector>
namespace nr::gnb
{
class GnbSasTask : public NtsTask
{
private:
TaskBase *m_base;
std::unique_ptr<Logger> m_logger;
udp::UdpServerTask *m_udpTask;
friend class GnbCmdHandler;
public:
explicit GnbSasTask(TaskBase *base);
~GnbSasTask() override = default;
protected:
void onStart() override;
void onLoop() override;
void onQuit() override;
private: /* Transport */
void receiveSasMessage(const InetAddress &addr, const sas::SasMessage &msg);
void sendSasMessage(const InetAddress &addr, const sas::SasMessage &msg);
private: /* Handler */
void handleCellInfoRequest(const InetAddress &addr, const sas::SasCellInfoRequest &msg);
};
} // namespace nr::gnb
\ No newline at end of file
//
// 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"
namespace nr::gnb
{
void GnbSasTask::receiveSasMessage(const InetAddress &addr, const sas::SasMessage &msg)
{
switch (msg.msgType)
{
case sas::SasMessageType::CELL_INFO_REQUEST:
handleCellInfoRequest(addr, (const sas::SasCellInfoRequest &)msg);
break;
default:
m_logger->err("Unhandled SAS message received with type[%d]", static_cast<int>(msg.msgType));
break;
}
}
void GnbSasTask::sendSasMessage(const InetAddress &addr, const sas::SasMessage &msg)
{
OctetString stream{};
sas::EncodeSasMessage(msg, stream);
m_udpTask->send(addr, stream);
}
} // namespace nr::gnb
......@@ -26,6 +26,7 @@ class GtpTask;
class GnbMrTask;
class NgapTask;
class GnbRrcTask;
class GnbSasTask;
class SctpTask;
enum class EAmfState
......@@ -299,6 +300,7 @@ struct GnbConfig
/* Assigned by program */
std::string name{};
EPagingDrx pagingDrx{};
Vector3 phyLocation{};
[[nodiscard]] inline uint32_t getGnbId() const
{
......@@ -324,6 +326,7 @@ struct TaskBase
NgapTask *ngapTask{};
GnbRrcTask *rrcTask{};
SctpTask *sctpTask{};
GnbSasTask *sasTask{};
};
struct MrUeContext
......
......@@ -22,23 +22,23 @@ void UeSasTask::onMeasurement()
// compare active and pending measurements
for (auto &m : m_activeMeasurements)
{
bool newStrong = m.second.dbm >= DBM_STRONG_STRENGTH_THRESHOLD;
bool oldStrong = m.second.dbm >= DBM_STRONG_STRENGTH_THRESHOLD;
if (m_pendingMeasurements.count(m.first))
{
bool oldStrong = m_pendingMeasurements[m.first].dbm >= DBM_STRONG_STRENGTH_THRESHOLD;
bool newStrong = m_pendingMeasurements[m.first].dbm >= DBM_STRONG_STRENGTH_THRESHOLD;
if (newStrong ^ oldStrong)
(newStrong ? entered : exited).push_back(m.first);
}
else if (newStrong)
entered.push_back(m.first);
else if (oldStrong)
exited.push_back(m.first);
}
for (auto &m : m_pendingMeasurements)
{
bool oldStrong = m_pendingMeasurements[m.first].dbm >= DBM_STRONG_STRENGTH_THRESHOLD;
if (!m_activeMeasurements.count(m.first) && oldStrong)
exited.push_back(m.first);
bool newStrong = m_pendingMeasurements[m.first].dbm >= DBM_STRONG_STRENGTH_THRESHOLD;
if (!m_activeMeasurements.count(m.first) && newStrong)
entered.push_back(m.first);
}
if (!entered.empty() && !exited.empty())
if (!entered.empty() || !exited.empty())
onCoverageChange(entered, exited);
// copy from pending to active measurements
......@@ -46,7 +46,7 @@ void UeSasTask::onMeasurement()
// clear pending measurements
m_pendingMeasurements = {};
// Issue another cell info request for search space
// Issue another cell info request for each address in the search space
for (auto &ip : m_cellSearchSpace)
{
sas::SasCellInfoRequest req{};
......@@ -67,10 +67,8 @@ void UeSasTask::receiveCellInfoResponse(const sas::SasCellInfoResponse &msg)
void UeSasTask::onCoverageChange(const std::vector<GlobalNci> &entered, const std::vector<GlobalNci> &exited)
{
m_logger->debug("Coverage change detected. [%d] cell entered, [%d] exited to/from coverage",
static_cast<int>(entered.size()), static_cast<int>(exited.size()));
// TODO
m_logger->debug("Coverage change detected. [%d] cell entered, [%d] cell exited", static_cast<int>(entered.size()),
static_cast<int>(exited.size()));
}
} // namespace nr::ue
......@@ -53,7 +53,9 @@ void EncodeSasMessage(const SasMessage &msg, OctetString &stream)
if (msg.msgType == SasMessageType::CELL_INFO_REQUEST)
{
auto m = (const SasCellInfoRequest &)msg;
stream.appendOctet4(m.simPos);
stream.appendOctet4(m.simPos.x);
stream.appendOctet4(m.simPos.y);
stream.appendOctet4(m.simPos.z);
}
else if (msg.msgType == SasMessageType::CELL_INFO_RESPONSE)
{
......@@ -81,7 +83,9 @@ std::unique_ptr<SasMessage> DecodeSasMessage(const OctetView &stream)
if (msgType == SasMessageType::CELL_INFO_REQUEST)
{
auto res = std::make_unique<SasCellInfoRequest>();
res->simPos = stream.read4I();
res->simPos.x = stream.read4I();
res->simPos.y = stream.read4I();
res->simPos.z = stream.read4I();
return res;
}
else if (msgType == SasMessageType::CELL_INFO_RESPONSE)
......
......@@ -35,7 +35,7 @@ struct SasMessage
struct SasCellInfoRequest : SasMessage
{
int32_t simPos{};
Vector3 simPos{};
SasCellInfoRequest() : SasMessage(SasMessageType::CELL_INFO_REQUEST)
{
......@@ -45,8 +45,8 @@ struct SasCellInfoRequest : SasMessage
struct SasCellInfoResponse : SasMessage
{
GlobalNci cellId{};
int32_t tac{};
int32_t dbm{};
int tac{};
int dbm{};
SasCellInfoResponse() : SasMessage(SasMessageType::CELL_INFO_RESPONSE)
{
......
......@@ -119,13 +119,6 @@ enum class EDeregCause
ECALL_INACTIVITY,
};
Json ToJson(const Supi &v);
Json ToJson(const Plmn &v);
Json ToJson(const SingleSlice &v);
Json ToJson(const NetworkSlice &v);
Json ToJson(const PlmnSupport &v);
Json ToJson(const EDeregCause &v);
struct GlobalNci
{
Plmn plmn{};
......@@ -146,10 +139,30 @@ struct UeCellMeasurement
uint64_t time{};
};
struct Vector3
{
int x{};
int y{};
int z{};
Vector3() = default;
Vector3(int x, int y, int z) : x(x), y(y), z(z)
{
}
};
bool operator==(const SingleSlice &lhs, const SingleSlice &rhs);
bool operator==(const Plmn &lhs, const Plmn &rhs);
bool operator==(const GlobalNci &lhs, const GlobalNci &rhs);
Json ToJson(const Supi &v);
Json ToJson(const Plmn &v);
Json ToJson(const SingleSlice &v);
Json ToJson(const NetworkSlice &v);
Json ToJson(const PlmnSupport &v);
Json ToJson(const EDeregCause &v);
namespace std
{
......
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