Commit 3993c337 authored by aligungr's avatar aligungr

UE RRC release and radio link failure handling

parent b9d0ede3
...@@ -234,35 +234,6 @@ void NasMm::onSwitchUState(E5UState oldState, E5UState newState) ...@@ -234,35 +234,6 @@ void NasMm::onSwitchUState(E5UState oldState, E5UState newState)
{ {
} }
void NasMm::receivePlmnSearchResponse(const std::string &gnbName)
{
if (m_base->nodeListener)
m_base->nodeListener->onConnected(app::NodeType::UE, m_base->config->getNodeName(), app::NodeType::GNB,
gnbName);
m_logger->info("UE connected to gNB");
if (m_mmSubState == EMmSubState::MM_REGISTERED_PLMN_SEARCH ||
m_mmSubState == EMmSubState::MM_REGISTERED_NO_CELL_AVAILABLE)
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_NORMAL_SERVICE);
else if (m_mmSubState == EMmSubState::MM_DEREGISTERED_PLMN_SEARCH ||
m_mmSubState == EMmSubState::MM_DEREGISTERED_NO_CELL_AVAILABLE)
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NORMAL_SERVICE);
}
void NasMm::receivePlmnSearchFailure()
{
if (m_mmSubState == EMmSubState::MM_REGISTERED_PLMN_SEARCH)
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_NO_CELL_AVAILABLE);
else if (m_mmSubState == EMmSubState::MM_DEREGISTERED_PLMN_SEARCH)
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NO_CELL_AVAILABLE);
}
void NasMm::receiveRrcConnectionSetup()
{
switchCmState(ECmState::CM_CONNECTED);
}
void NasMm::onTimerExpire(nas::NasTimer &timer) void NasMm::onTimerExpire(nas::NasTimer &timer)
{ {
switch (timer.getCode()) switch (timer.getCode())
......
...@@ -66,9 +66,13 @@ class NasMm ...@@ -66,9 +66,13 @@ class NasMm
void triggerMmCycle(); void triggerMmCycle();
void performMmCycle(); void performMmCycle();
void onTimerExpire(nas::NasTimer &timer); void onTimerExpire(nas::NasTimer &timer);
void receivePlmnSearchResponse(const std::string &gnbName);
void receivePlmnSearchFailure(); /* Radio resource control */
void receiveRrcConnectionSetup(); void handlePlmnSearchResponse(const std::string &gnbName);
void handlePlmnSearchFailure();
void handleRrcConnectionSetup();
void handleRrcConnectionRelease();
void handleRadioLinkFailure();
/* Transport */ /* Transport */
void sendNasMessage(const nas::PlainMmMessage &msg); void sendNasMessage(const nas::PlainMmMessage &msg);
......
//
// 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 "mm.hpp"
#include <nas/utils.hpp>
#include <ue/app/task.hpp>
#include <ue/sm/sm.hpp>
namespace nr::ue
{
void NasMm::handlePlmnSearchResponse(const std::string &gnbName)
{
if (m_base->nodeListener)
m_base->nodeListener->onConnected(app::NodeType::UE, m_base->config->getNodeName(), app::NodeType::GNB,
gnbName);
m_logger->info("UE connected to gNB");
if (m_mmSubState == EMmSubState::MM_REGISTERED_PLMN_SEARCH ||
m_mmSubState == EMmSubState::MM_REGISTERED_NO_CELL_AVAILABLE)
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_NORMAL_SERVICE);
else if (m_mmSubState == EMmSubState::MM_DEREGISTERED_PLMN_SEARCH ||
m_mmSubState == EMmSubState::MM_DEREGISTERED_NO_CELL_AVAILABLE)
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NORMAL_SERVICE);
}
void NasMm::handlePlmnSearchFailure()
{
if (m_mmSubState == EMmSubState::MM_REGISTERED_PLMN_SEARCH)
switchMmState(EMmState::MM_REGISTERED, EMmSubState::MM_REGISTERED_NO_CELL_AVAILABLE);
else if (m_mmSubState == EMmSubState::MM_DEREGISTERED_PLMN_SEARCH)
switchMmState(EMmState::MM_DEREGISTERED, EMmSubState::MM_DEREGISTERED_NO_CELL_AVAILABLE);
}
void NasMm::handleRrcConnectionSetup()
{
switchCmState(ECmState::CM_CONNECTED);
}
void NasMm::handleRrcConnectionRelease()
{
m_logger->err("TODO: handle RRC connection release");
}
void NasMm::handleRadioLinkFailure()
{
m_logger->debug("Radio link failure detected");
handleRrcConnectionRelease();
}
}
\ No newline at end of file
...@@ -68,7 +68,15 @@ void UeMrTask::onLoop() ...@@ -68,7 +68,15 @@ void UeMrTask::onLoop()
break; break;
} }
case NwUeMrToMr::RLS_RELEASED: { case NwUeMrToMr::RLS_RELEASED: {
m_logger->warn("UE disconnected from gNB, RLS released [%s]", rls::CauseToString(w->cause)); if (rls::IsRlf(w->cause))
{
m_logger->err("Radio link failure with cause[%s]", rls::CauseToString(w->cause));
m_base->rrcTask->push(new NwUeMrToRrc(NwUeMrToRrc::RADIO_LINK_FAILURE));
}
else
{
m_logger->debug("UE disconnected from gNB [%s]", rls::CauseToString(w->cause));
}
break; break;
} }
case NwUeMrToMr::RLS_SEARCH_FAILURE: { case NwUeMrToMr::RLS_SEARCH_FAILURE: {
...@@ -113,6 +121,10 @@ void UeMrTask::onLoop() ...@@ -113,6 +121,10 @@ void UeMrTask::onLoop()
m_rlsEntity->onUplinkDelivery(rls::EPayloadType::RRC, std::move(stream)); m_rlsEntity->onUplinkDelivery(rls::EPayloadType::RRC, std::move(stream));
break; break;
} }
case NwUeRrcToMr::RRC_CONNECTION_RELEASE: {
m_rlsEntity->localReleaseConnection(rls::ECause::RRC_RELEASE);
break;
}
} }
break; break;
} }
......
...@@ -60,15 +60,15 @@ void NasTask::onLoop() ...@@ -60,15 +60,15 @@ void NasTask::onLoop()
switch (w->present) switch (w->present)
{ {
case NwUeRrcToNas::RRC_CONNECTION_SETUP: { case NwUeRrcToNas::RRC_CONNECTION_SETUP: {
mm->receiveRrcConnectionSetup(); mm->handleRrcConnectionSetup();
break; break;
} }
case NwUeRrcToNas::PLMN_SEARCH_RESPONSE: { case NwUeRrcToNas::PLMN_SEARCH_RESPONSE: {
mm->receivePlmnSearchResponse(w->gnbName); mm->handlePlmnSearchResponse(w->gnbName);
break; break;
} }
case NwUeRrcToNas::PLMN_SEARCH_FAILURE: { case NwUeRrcToNas::PLMN_SEARCH_FAILURE: {
mm->receivePlmnSearchFailure(); mm->handlePlmnSearchFailure();
break; break;
} }
case NwUeRrcToNas::NAS_DELIVERY: { case NwUeRrcToNas::NAS_DELIVERY: {
...@@ -78,6 +78,14 @@ void NasTask::onLoop() ...@@ -78,6 +78,14 @@ void NasTask::onLoop()
mm->receiveNasMessage(*nasMessage); mm->receiveNasMessage(*nasMessage);
break; break;
} }
case NwUeRrcToNas::RRC_CONNECTION_RELEASE: {
mm->handleRrcConnectionRelease();
break;
}
case NwUeRrcToNas::RADIO_LINK_FAILURE: {
mm->handleRadioLinkFailure();
break;
}
} }
break; break;
} }
......
...@@ -66,6 +66,7 @@ struct NwUeMrToRrc : NtsMessage ...@@ -66,6 +66,7 @@ struct NwUeMrToRrc : NtsMessage
PLMN_SEARCH_RESPONSE, PLMN_SEARCH_RESPONSE,
PLMN_SEARCH_FAILURE, PLMN_SEARCH_FAILURE,
RRC_PDU_DELIVERY, RRC_PDU_DELIVERY,
RADIO_LINK_FAILURE
} present; } present;
// PLMN_SEARCH_RESPONSE // PLMN_SEARCH_RESPONSE
...@@ -156,6 +157,8 @@ struct NwUeRrcToNas : NtsMessage ...@@ -156,6 +157,8 @@ struct NwUeRrcToNas : NtsMessage
PLMN_SEARCH_RESPONSE, PLMN_SEARCH_RESPONSE,
PLMN_SEARCH_FAILURE, PLMN_SEARCH_FAILURE,
RRC_CONNECTION_SETUP, RRC_CONNECTION_SETUP,
RRC_CONNECTION_RELEASE,
RADIO_LINK_FAILURE,
} present; } present;
// NAS_DELIVERY // NAS_DELIVERY
...@@ -195,7 +198,8 @@ struct NwUeRrcToMr : NtsMessage ...@@ -195,7 +198,8 @@ struct NwUeRrcToMr : NtsMessage
enum PR enum PR
{ {
PLMN_SEARCH_REQUEST, PLMN_SEARCH_REQUEST,
RRC_PDU_DELIVERY RRC_PDU_DELIVERY,
RRC_CONNECTION_RELEASE,
} present; } present;
// RRC_PDU_DELIVERY // RRC_PDU_DELIVERY
......
...@@ -255,13 +255,15 @@ void UeRrcTask::receiveRrcMessage(ASN_RRC_DL_DCCH_Message *msg) ...@@ -255,13 +255,15 @@ void UeRrcTask::receiveRrcMessage(ASN_RRC_DL_DCCH_Message *msg)
auto &c1 = msg->message.choice.c1; auto &c1 = msg->message.choice.c1;
switch (c1->present) switch (c1->present)
{ {
case ASN_RRC_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { case ASN_RRC_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
receiveDownlinkInformationTransfer(*c1->choice.dlInformationTransfer); receiveDownlinkInformationTransfer(*c1->choice.dlInformationTransfer);
break; break;
case ASN_RRC_DL_DCCH_MessageType__c1_PR_rrcRelease:
receiveRrcRelease(*c1->choice.rrcRelease);
break;
default: default:
break; break;
} }
}
} }
void UeRrcTask::receiveRrcMessage(ASN_RRC_PCCH_Message *msg) void UeRrcTask::receiveRrcMessage(ASN_RRC_PCCH_Message *msg)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "task.hpp" #include "task.hpp"
#include <asn/utils/utils.hpp> #include <asn/utils/utils.hpp>
#include <rrc/encode.hpp> #include <rrc/encode.hpp>
#include <ue/mr/task.hpp>
#include <ue/nas/task.hpp> #include <ue/nas/task.hpp>
#include <ue/nts.hpp> #include <ue/nts.hpp>
#include <utils/common.hpp> #include <utils/common.hpp>
...@@ -124,4 +125,13 @@ void UeRrcTask::receiveDownlinkInformationTransfer(const ASN_RRC_DLInformationTr ...@@ -124,4 +125,13 @@ void UeRrcTask::receiveDownlinkInformationTransfer(const ASN_RRC_DLInformationTr
m_base->nasTask->push(nw); m_base->nasTask->push(nw);
} }
void UeRrcTask::receiveRrcRelease(const ASN_RRC_RRCRelease &msg)
{
m_logger->debug("RRC Release received");
m_state = ERrcState::RRC_IDLE;
m_base->mrTask->push(new NwUeRrcToMr(NwUeRrcToMr::RRC_CONNECTION_RELEASE));
m_base->nasTask->push(new NwUeRrcToNas(NwUeRrcToNas::RRC_CONNECTION_RELEASE));
}
} // namespace nr::ue } // namespace nr::ue
\ No newline at end of file
...@@ -63,6 +63,10 @@ void UeRrcTask::onLoop() ...@@ -63,6 +63,10 @@ void UeRrcTask::onLoop()
handleDownlinkRrc(w->channel, w->pdu); handleDownlinkRrc(w->channel, w->pdu);
break; break;
} }
case NwUeMrToRrc::RADIO_LINK_FAILURE: {
handleRadioLinkFailure();
break;
}
} }
break; break;
} }
...@@ -91,4 +95,9 @@ void UeRrcTask::onLoop() ...@@ -91,4 +95,9 @@ void UeRrcTask::onLoop()
delete msg; delete msg;
} }
void UeRrcTask::handleRadioLinkFailure()
{
m_base->nasTask->push(new NwUeRrcToNas(NwUeRrcToNas::RADIO_LINK_FAILURE));
}
} // namespace nr::ue } // namespace nr::ue
\ No newline at end of file
...@@ -34,6 +34,7 @@ extern "C" ...@@ -34,6 +34,7 @@ extern "C"
struct ASN_RRC_ULInformationTransfer; struct ASN_RRC_ULInformationTransfer;
struct ASN_RRC_RRCSetup; struct ASN_RRC_RRCSetup;
struct ASN_RRC_RRCReject; struct ASN_RRC_RRCReject;
struct ASN_RRC_RRCRelease;
} }
namespace nr::ue namespace nr::ue
...@@ -64,14 +65,17 @@ class UeRrcTask : public NtsTask ...@@ -64,14 +65,17 @@ class UeRrcTask : public NtsTask
private: private:
/* Handlers */ /* Handlers */
void handleDownlinkRrc(rrc::RrcChannel channel, const OctetString& pdu); void handleDownlinkRrc(rrc::RrcChannel channel, const OctetString &pdu);
void deliverInitialNas(OctetString &&nasPdu, long establishmentCause); void deliverInitialNas(OctetString &&nasPdu, long establishmentCause);
void deliverUplinkNas(OctetString &&nasPdu); void deliverUplinkNas(OctetString &&nasPdu);
void receiveRrcSetup(const ASN_RRC_RRCSetup &msg); void receiveRrcSetup(const ASN_RRC_RRCSetup &msg);
void receiveRrcReject(const ASN_RRC_RRCReject &msg); void receiveRrcReject(const ASN_RRC_RRCReject &msg);
void receiveRrcRelease(const ASN_RRC_RRCRelease &msg);
void receiveDownlinkInformationTransfer(const ASN_RRC_DLInformationTransfer &msg); void receiveDownlinkInformationTransfer(const ASN_RRC_DLInformationTransfer &msg);
void handleRadioLinkFailure();
/* RRC channel send message */ /* RRC channel send message */
void sendRrcMessage(ASN_RRC_BCCH_BCH_Message *msg); void sendRrcMessage(ASN_RRC_BCCH_BCH_Message *msg);
void sendRrcMessage(ASN_RRC_BCCH_DL_SCH_Message *msg); void sendRrcMessage(ASN_RRC_BCCH_DL_SCH_Message *msg);
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
#include "ue_entity.hpp" #include "ue_entity.hpp"
#include <utility>
#include <utils/common.hpp> #include <utils/common.hpp>
#include <utils/constants.hpp> #include <utils/constants.hpp>
#include <utility>
static const octet3 AppVersion = octet3{cons::Major, cons::Minor, cons::Patch}; static const octet3 AppVersion = octet3{cons::Major, cons::Minor, cons::Patch};
...@@ -226,13 +226,7 @@ void RlsUeEntity::onReceive(const InetAddress &address, const OctetString &pdu) ...@@ -226,13 +226,7 @@ void RlsUeEntity::onReceive(const InetAddress &address, const OctetString &pdu)
void RlsUeEntity::releaseConnection(ECause cause) void RlsUeEntity::releaseConnection(ECause cause)
{ {
sendReleaseIndication(cause); sendReleaseIndication(cause);
state = EUeState::RELEASED; localReleaseConnection(cause);
nextSearch = 0;
ueToken = 0;
gnbToken = 0;
lastGnbHeartbeat = 0;
lastError = ECause::UNSPECIFIED;
onRelease(cause);
} }
void RlsUeEntity::resetEntity() void RlsUeEntity::resetEntity()
...@@ -293,4 +287,15 @@ void RlsUeEntity::sendRlsMessage(const InetAddress &address, const RlsMessage &m ...@@ -293,4 +287,15 @@ void RlsUeEntity::sendRlsMessage(const InetAddress &address, const RlsMessage &m
sendRlsPdu(address, std::move(stream)); sendRlsPdu(address, std::move(stream));
} }
void RlsUeEntity::localReleaseConnection(ECause cause)
{
state = EUeState::RELEASED;
nextSearch = 0;
ueToken = 0;
gnbToken = 0;
lastGnbHeartbeat = 0;
lastError = ECause::UNSPECIFIED;
onRelease(cause);
}
} // namespace rls } // namespace rls
\ No newline at end of file
...@@ -51,6 +51,7 @@ class RlsUeEntity ...@@ -51,6 +51,7 @@ class RlsUeEntity
void onUplinkDelivery(EPayloadType type, OctetString &&payload); void onUplinkDelivery(EPayloadType type, OctetString &&payload);
void startGnbSearch(); void startGnbSearch();
void releaseConnection(ECause cause); void releaseConnection(ECause cause);
void localReleaseConnection(ECause cause);
void resetEntity(); void resetEntity();
private: private:
......
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