init-version-3.27

This commit is contained in:
lai
2025-08-12 14:15:27 +08:00
parent 85f22d2098
commit a2d7a353d8
4264 changed files with 625612 additions and 1 deletions

201
src/gnb/rls/udp_task.cpp Normal file
View File

@@ -0,0 +1,201 @@
//
// This file is a part of UERANSIM project.
// Copyright (c) 2023 ALİ GÜNGÖR.
//
// https://github.com/aligungr/UERANSIM/
// See README, LICENSE, and CONTRIBUTING files for licensing details.
//
#include "udp_task.hpp"
#include <cmath>
#include <cstdint>
#include <cstring>
#include <set>
#include <gnb/nts.hpp>
#include <utils/common.hpp>
#include <utils/constants.hpp>
#include <utils/libc_error.hpp>
static constexpr const int BUFFER_SIZE = 16384;
static constexpr const int LOOP_PERIOD = 1000;
static constexpr const int RECEIVE_TIMEOUT = 200;
static constexpr const int HEARTBEAT_THRESHOLD = 2000; // (LOOP_PERIOD + RECEIVE_TIMEOUT)'dan büyük olmalı
static constexpr const int MIN_ALLOWED_DBM = -120;
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));
if (distance == 0)
return -1; // 0 may be confusing for people
return -distance;
}
namespace nr::gnb
{
RlsUdpTask::RlsUdpTask(TaskBase *base, uint64_t sti, Vector3 phyLocation)
: m_server{}, m_ctlTask{}, m_sti{sti}, m_phyLocation{phyLocation}, m_lastLoop{}, m_stiToUe{}, m_ueMap{}, m_newIdCounter{}
{
m_logger = base->logBase->makeUniqueLogger("rls-udp");
try
{
m_server = new udp::UdpServer(base->config->linkIp, cons::RadioLinkPort);
}
catch (const LibError &e)
{
m_logger->err("RLS failure [%s]", e.what());
quit();
return;
}
}
void RlsUdpTask::onStart()
{
}
void RlsUdpTask::onLoop()
{
auto current = utils::CurrentTimeMillis();
if (current - m_lastLoop > LOOP_PERIOD)
{
m_lastLoop = current;
heartbeatCycle(current);
}
uint8_t buffer[BUFFER_SIZE];
InetAddress peerAddress;
int size = m_server->Receive(buffer, BUFFER_SIZE, RECEIVE_TIMEOUT, peerAddress);
if (size > 0)
{
auto rlsMsg = rls::DecodeRlsMessage(OctetView{buffer, static_cast<size_t>(size)});
if (rlsMsg == nullptr)
m_logger->err("Unable to decode RLS message");
else
receiveRlsPdu(peerAddress, std::move(rlsMsg));
}
}
void RlsUdpTask::onQuit()
{
delete m_server;
}
void RlsUdpTask::receiveRlsPdu(const InetAddress &addr, std::unique_ptr<rls::RlsMessage> &&msg)
{
if (msg->msgType == rls::EMessageType::HEARTBEAT)
{
int dbm = EstimateSimulatedDbm(m_phyLocation, ((const rls::RlsHeartBeat &)*msg).simPos);
if (dbm < MIN_ALLOWED_DBM)
{
// if the simulated signal strength is such low, then ignore this message
return;
}
if (m_stiToUe.count(msg->sti))
{
int ueId = m_stiToUe[msg->sti];
m_ueMap[ueId].address = addr;
m_ueMap[ueId].lastSeen = utils::CurrentTimeMillis();
}
else
{
int ueId = ++m_newIdCounter;
m_stiToUe[msg->sti] = ueId;
m_ueMap[ueId].address = addr;
m_ueMap[ueId].lastSeen = utils::CurrentTimeMillis();
auto w = std::make_unique<NmGnbRlsToRls>(NmGnbRlsToRls::SIGNAL_DETECTED);
w->ueId = ueId;
m_ctlTask->push(std::move(w));
}
rls::RlsHeartBeatAck ack{m_sti};
ack.dbm = dbm;
sendRlsPdu(addr, ack);
return;
}
if (!m_stiToUe.count(msg->sti))
{
// if no HB received yet, and the message is not HB, then ignore the message
return;
}
auto w = std::make_unique<NmGnbRlsToRls>(NmGnbRlsToRls::RECEIVE_RLS_MESSAGE);
w->ueId = m_stiToUe[msg->sti];
w->msg = std::move(msg);
m_ctlTask->push(std::move(w));
}
void RlsUdpTask::sendRlsPdu(const InetAddress &addr, const rls::RlsMessage &msg)
{
OctetString stream;
rls::EncodeRlsMessage(msg, stream);
m_server->Send(addr, stream.data(), static_cast<size_t>(stream.length()));
}
void RlsUdpTask::heartbeatCycle(int64_t time)
{
std::set<int> lostUeId{};
std::set<uint64_t> lostSti{};
for (auto &item : m_ueMap)
{
if (time - item.second.lastSeen > HEARTBEAT_THRESHOLD)
{
lostUeId.insert(item.first);
lostSti.insert(item.second.sti);
}
}
for (uint64_t sti : lostSti)
m_stiToUe.erase(sti);
for (int ueId : lostUeId)
m_ueMap.erase(ueId);
for (int ueId : lostUeId)
{
auto w = std::make_unique<NmGnbRlsToRls>(NmGnbRlsToRls::SIGNAL_LOST);
w->ueId = ueId;
m_ctlTask->push(std::move(w));
}
}
void RlsUdpTask::initialize(NtsTask *ctlTask)
{
m_ctlTask = ctlTask;
}
void RlsUdpTask::send(int ueId, const rls::RlsMessage &msg)
{
if (ueId == 0)
{
for (auto &ue : m_ueMap)
send(ue.first, msg);
return;
}
if (!m_ueMap.count(ueId))
{
// ignore the message
return;
}
sendRlsPdu(m_ueMap[ueId].address, msg);
}
} // namespace nr::gnb