applications,core,internet,lte: Reduce indent by returning early

This commit is contained in:
André Apitzsch
2024-10-30 09:41:02 +01:00
committed by Eduardo Almeida
parent 769ffe3ed0
commit 213fe52e5c
9 changed files with 1022 additions and 1056 deletions

View File

@@ -258,19 +258,16 @@ ThreeGppHttpClient::ConnectionSucceededCallback(Ptr<Socket> socket)
{
NS_LOG_FUNCTION(this << socket);
if (m_state == CONNECTING)
{
NS_ASSERT_MSG(m_socket == socket, "Invalid socket.");
m_connectionEstablishedTrace(this);
socket->SetRecvCallback(MakeCallback(&ThreeGppHttpClient::ReceivedDataCallback, this));
NS_ASSERT(m_embeddedObjectsToBeRequested == 0);
m_eventRequestMainObject =
Simulator::ScheduleNow(&ThreeGppHttpClient::RequestMainObject, this);
}
else
if (m_state != CONNECTING)
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ConnectionSucceeded().");
}
NS_ASSERT_MSG(m_socket == socket, "Invalid socket.");
m_connectionEstablishedTrace(this);
socket->SetRecvCallback(MakeCallback(&ThreeGppHttpClient::ReceivedDataCallback, this));
NS_ASSERT(m_embeddedObjectsToBeRequested == 0);
m_eventRequestMainObject = Simulator::ScheduleNow(&ThreeGppHttpClient::RequestMainObject, this);
}
void
@@ -280,8 +277,7 @@ ThreeGppHttpClient::ConnectionFailedCallback(Ptr<Socket> socket)
if (m_state == CONNECTING)
{
NS_LOG_ERROR("Client failed to connect"
<< " to remote address " << m_peer);
NS_LOG_ERROR("Client failed to connect to remote address " << m_peer);
}
else
{
@@ -378,72 +374,67 @@ ThreeGppHttpClient::OpenConnection()
{
NS_LOG_FUNCTION(this);
if (m_state == NOT_STARTED || m_state == EXPECTING_EMBEDDED_OBJECT ||
m_state == PARSING_MAIN_OBJECT || m_state == READING)
{
m_socket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());
NS_ABORT_MSG_IF(m_peer.IsInvalid(), "Remote address not properly set");
if (!m_local.IsInvalid())
{
NS_ABORT_MSG_IF((Inet6SocketAddress::IsMatchingType(m_peer) &&
InetSocketAddress::IsMatchingType(m_local)) ||
(InetSocketAddress::IsMatchingType(m_peer) &&
Inet6SocketAddress::IsMatchingType(m_local)),
"Incompatible peer and local address IP version");
}
if (InetSocketAddress::IsMatchingType(m_peer))
{
const auto ret [[maybe_unused]] =
m_local.IsInvalid() ? m_socket->Bind() : m_socket->Bind(m_local);
NS_LOG_DEBUG(this << " Bind() return value= " << ret
<< " GetErrNo= " << m_socket->GetErrno() << ".");
const auto ipv4 = InetSocketAddress::ConvertFrom(m_peer).GetIpv4();
const auto port = InetSocketAddress::ConvertFrom(m_peer).GetPort();
NS_LOG_INFO(this << " Connecting to " << ipv4 << " port " << port << " / " << m_peer
<< ".");
m_socket->SetIpTos(m_tos);
}
else if (Inet6SocketAddress::IsMatchingType(m_peer))
{
const auto ret [[maybe_unused]] =
m_local.IsInvalid() ? m_socket->Bind6() : m_socket->Bind(m_local);
NS_LOG_DEBUG(this << " Bind6() return value= " << ret
<< " GetErrNo= " << m_socket->GetErrno() << ".");
const auto ipv6 = Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6();
const auto port = Inet6SocketAddress::ConvertFrom(m_peer).GetPort();
NS_LOG_INFO(this << " Connecting to " << ipv6 << " port " << port << " / " << m_peer
<< ".");
}
else
{
NS_ASSERT_MSG(false, "Incompatible address type: " << m_peer);
}
const auto ret [[maybe_unused]] = m_socket->Connect(m_peer);
NS_LOG_DEBUG(this << " Connect() return value= " << ret
<< " GetErrNo= " << m_socket->GetErrno() << ".");
NS_ASSERT_MSG(m_socket, "Failed creating socket.");
SwitchToState(CONNECTING);
m_socket->SetConnectCallback(
MakeCallback(&ThreeGppHttpClient::ConnectionSucceededCallback, this),
MakeCallback(&ThreeGppHttpClient::ConnectionFailedCallback, this));
m_socket->SetCloseCallbacks(MakeCallback(&ThreeGppHttpClient::NormalCloseCallback, this),
MakeCallback(&ThreeGppHttpClient::ErrorCloseCallback, this));
m_socket->SetRecvCallback(MakeCallback(&ThreeGppHttpClient::ReceivedDataCallback, this));
m_socket->SetAttribute("MaxSegLifetime", DoubleValue(0.02)); // 20 ms.
} // end of `if (m_state == {NOT_STARTED, EXPECTING_EMBEDDED_OBJECT, PARSING_MAIN_OBJECT,
// READING})`
else
if (m_state != NOT_STARTED && m_state != EXPECTING_EMBEDDED_OBJECT &&
m_state != PARSING_MAIN_OBJECT && m_state != READING)
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for OpenConnection().");
}
m_socket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());
NS_ABORT_MSG_IF(m_peer.IsInvalid(), "Remote address not properly set");
if (!m_local.IsInvalid())
{
NS_ABORT_MSG_IF((Inet6SocketAddress::IsMatchingType(m_peer) &&
InetSocketAddress::IsMatchingType(m_local)) ||
(InetSocketAddress::IsMatchingType(m_peer) &&
Inet6SocketAddress::IsMatchingType(m_local)),
"Incompatible peer and local address IP version");
}
if (InetSocketAddress::IsMatchingType(m_peer))
{
const auto ret [[maybe_unused]] =
m_local.IsInvalid() ? m_socket->Bind() : m_socket->Bind(m_local);
NS_LOG_DEBUG(this << " Bind() return value= " << ret
<< " GetErrNo= " << m_socket->GetErrno() << ".");
const auto ipv4 = InetSocketAddress::ConvertFrom(m_peer).GetIpv4();
const auto port = InetSocketAddress::ConvertFrom(m_peer).GetPort();
NS_LOG_INFO(this << " Connecting to " << ipv4 << " port " << port << " / " << m_peer
<< ".");
m_socket->SetIpTos(m_tos);
}
else if (Inet6SocketAddress::IsMatchingType(m_peer))
{
const auto ret [[maybe_unused]] =
m_local.IsInvalid() ? m_socket->Bind6() : m_socket->Bind(m_local);
NS_LOG_DEBUG(this << " Bind6() return value= " << ret
<< " GetErrNo= " << m_socket->GetErrno() << ".");
const auto ipv6 = Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6();
const auto port = Inet6SocketAddress::ConvertFrom(m_peer).GetPort();
NS_LOG_INFO(this << " Connecting to " << ipv6 << " port " << port << " / " << m_peer
<< ".");
}
else
{
NS_ASSERT_MSG(false, "Incompatible address type: " << m_peer);
}
const auto ret [[maybe_unused]] = m_socket->Connect(m_peer);
NS_LOG_DEBUG(this << " Connect() return value= " << ret << " GetErrNo= " << m_socket->GetErrno()
<< ".");
NS_ASSERT_MSG(m_socket, "Failed creating socket.");
SwitchToState(CONNECTING);
m_socket->SetConnectCallback(
MakeCallback(&ThreeGppHttpClient::ConnectionSucceededCallback, this),
MakeCallback(&ThreeGppHttpClient::ConnectionFailedCallback, this));
m_socket->SetCloseCallbacks(MakeCallback(&ThreeGppHttpClient::NormalCloseCallback, this),
MakeCallback(&ThreeGppHttpClient::ErrorCloseCallback, this));
m_socket->SetRecvCallback(MakeCallback(&ThreeGppHttpClient::ReceivedDataCallback, this));
m_socket->SetAttribute("MaxSegLifetime", DoubleValue(0.02)); // 20 ms.
} // end of `void OpenConnection ()`
void
@@ -451,37 +442,35 @@ ThreeGppHttpClient::RequestMainObject()
{
NS_LOG_FUNCTION(this);
if (m_state == CONNECTING || m_state == READING)
if (m_state != CONNECTING && m_state != READING)
{
ThreeGppHttpHeader header;
header.SetContentLength(0); // Request does not need any content length.
header.SetContentType(ThreeGppHttpHeader::MAIN_OBJECT);
header.SetClientTs(Simulator::Now());
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestMainObject().");
}
const auto requestSize = m_httpVariables->GetRequestSize();
auto packet = Create<Packet>(requestSize);
packet->AddHeader(header);
const auto packetSize = packet->GetSize();
m_txMainObjectRequestTrace(packet);
m_txTrace(packet);
const auto actualBytes = m_socket->Send(packet);
NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packet->GetSize() << " bytes,"
<< " return value= " << actualBytes << ".");
if (actualBytes != static_cast<int>(packetSize))
{
NS_LOG_ERROR(this << " Failed to send request for embedded object,"
<< " GetErrNo= " << m_socket->GetErrno() << ","
<< " waiting for another Tx opportunity.");
}
else
{
SwitchToState(EXPECTING_MAIN_OBJECT);
m_pageLoadStartTs = Simulator::Now(); // start counting page loading time
}
ThreeGppHttpHeader header;
header.SetContentLength(0); // Request does not need any content length.
header.SetContentType(ThreeGppHttpHeader::MAIN_OBJECT);
header.SetClientTs(Simulator::Now());
const auto requestSize = m_httpVariables->GetRequestSize();
auto packet = Create<Packet>(requestSize);
packet->AddHeader(header);
const auto packetSize = packet->GetSize();
m_txMainObjectRequestTrace(packet);
m_txTrace(packet);
const auto actualBytes = m_socket->Send(packet);
NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packet->GetSize() << " bytes,"
<< " return value= " << actualBytes << ".");
if (actualBytes != static_cast<int>(packetSize))
{
NS_LOG_ERROR(this << " Failed to send request for embedded object,"
<< " GetErrNo= " << m_socket->GetErrno() << ","
<< " waiting for another Tx opportunity.");
}
else
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestMainObject().");
SwitchToState(EXPECTING_MAIN_OBJECT);
m_pageLoadStartTs = Simulator::Now(); // start counting page loading time
}
} // end of `void RequestMainObject ()`
@@ -491,47 +480,43 @@ ThreeGppHttpClient::RequestEmbeddedObject()
{
NS_LOG_FUNCTION(this);
if (m_state == CONNECTING || m_state == PARSING_MAIN_OBJECT ||
m_state == EXPECTING_EMBEDDED_OBJECT)
if (m_state != CONNECTING && m_state != PARSING_MAIN_OBJECT &&
m_state != EXPECTING_EMBEDDED_OBJECT)
{
if (m_embeddedObjectsToBeRequested > 0)
{
ThreeGppHttpHeader header;
header.SetContentLength(0); // Request does not need any content length.
header.SetContentType(ThreeGppHttpHeader::EMBEDDED_OBJECT);
header.SetClientTs(Simulator::Now());
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestEmbeddedObject().");
}
const auto requestSize = m_httpVariables->GetRequestSize();
auto packet = Create<Packet>(requestSize);
packet->AddHeader(header);
const auto packetSize = packet->GetSize();
m_txEmbeddedObjectRequestTrace(packet);
m_txTrace(packet);
const auto actualBytes = m_socket->Send(packet);
NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packet->GetSize()
<< " bytes,"
<< " return value= " << actualBytes << ".");
if (m_embeddedObjectsToBeRequested == 0)
{
NS_LOG_WARN(this << " No embedded object to be requested.");
return;
}
if (actualBytes != static_cast<int>(packetSize))
{
NS_LOG_ERROR(this << " Failed to send request for embedded object,"
<< " GetErrNo= " << m_socket->GetErrno() << ","
<< " waiting for another Tx opportunity.");
}
else
{
m_embeddedObjectsToBeRequested--;
SwitchToState(EXPECTING_EMBEDDED_OBJECT);
}
}
else
{
NS_LOG_WARN(this << " No embedded object to be requested.");
}
ThreeGppHttpHeader header;
header.SetContentLength(0); // Request does not need any content length.
header.SetContentType(ThreeGppHttpHeader::EMBEDDED_OBJECT);
header.SetClientTs(Simulator::Now());
const auto requestSize = m_httpVariables->GetRequestSize();
auto packet = Create<Packet>(requestSize);
packet->AddHeader(header);
const auto packetSize = packet->GetSize();
m_txEmbeddedObjectRequestTrace(packet);
m_txTrace(packet);
const auto actualBytes = m_socket->Send(packet);
NS_LOG_DEBUG(this << " Send() packet " << packet << " of " << packet->GetSize() << " bytes,"
<< " return value= " << actualBytes << ".");
if (actualBytes != static_cast<int>(packetSize))
{
NS_LOG_ERROR(this << " Failed to send request for embedded object,"
<< " GetErrNo= " << m_socket->GetErrno() << ","
<< " waiting for another Tx opportunity.");
}
else
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestEmbeddedObject().");
m_embeddedObjectsToBeRequested--;
SwitchToState(EXPECTING_EMBEDDED_OBJECT);
}
} // end of `void RequestEmbeddedObject ()`
@@ -541,59 +526,53 @@ ThreeGppHttpClient::ReceiveMainObject(Ptr<Packet> packet, const Address& from)
{
NS_LOG_FUNCTION(this << packet << from);
if (m_state == EXPECTING_MAIN_OBJECT)
{
/*
* In the following call to Receive(), #m_objectBytesToBeReceived *will*
* be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
* ThreeGppHttpHeader will be removed from the packet, if it is the first
* packet of the object to be received; the header will be available in
* #m_constructedPacketHeader.
* #m_constructedPacket will also be updated.
*/
Receive(packet);
m_rxMainObjectPacketTrace(packet);
if (m_objectBytesToBeReceived > 0)
{
/*
* There are more packets of this main object, so just stay still
* and wait until they arrive.
*/
NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)"
<< " remains from this chunk of main object.");
}
else
{
/*
* This is the last packet of this main object. Acknowledge the
* reception of a whole main object
*/
NS_LOG_INFO(this << " Finished receiving a main object.");
m_rxMainObjectTrace(this, m_constructedPacket);
if (!m_objectServerTs.IsZero())
{
m_rxDelayTrace(Simulator::Now() - m_objectServerTs, from);
m_objectServerTs = MilliSeconds(0); // Reset back to zero.
}
if (!m_objectClientTs.IsZero())
{
m_rxRttTrace(Simulator::Now() - m_objectClientTs, from);
m_objectClientTs = MilliSeconds(0); // Reset back to zero.
}
EnterParsingTime();
} // end of else of `if (m_objectBytesToBeReceived > 0)`
} // end of `if (m_state == EXPECTING_MAIN_OBJECT)`
else
if (m_state != EXPECTING_MAIN_OBJECT)
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ReceiveMainObject().");
}
/*
* In the following call to Receive(), #m_objectBytesToBeReceived *will*
* be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
* ThreeGppHttpHeader will be removed from the packet, if it is the first
* packet of the object to be received; the header will be available in
* #m_constructedPacketHeader.
* #m_constructedPacket will also be updated.
*/
Receive(packet);
m_rxMainObjectPacketTrace(packet);
if (m_objectBytesToBeReceived > 0)
{
/*
* There are more packets of this main object, so just stay still
* and wait until they arrive.
*/
NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)"
<< " remains from this chunk of main object.");
return;
}
/*
* This is the last packet of this main object. Acknowledge the
* reception of a whole main object
*/
NS_LOG_INFO(this << " Finished receiving a main object.");
m_rxMainObjectTrace(this, m_constructedPacket);
if (!m_objectServerTs.IsZero())
{
m_rxDelayTrace(Simulator::Now() - m_objectServerTs, from);
m_objectServerTs = MilliSeconds(0); // Reset back to zero.
}
if (!m_objectClientTs.IsZero())
{
m_rxRttTrace(Simulator::Now() - m_objectClientTs, from);
m_objectClientTs = MilliSeconds(0); // Reset back to zero.
}
EnterParsingTime();
} // end of `void ReceiveMainObject (Ptr<Packet> packet)`
void
@@ -601,75 +580,69 @@ ThreeGppHttpClient::ReceiveEmbeddedObject(Ptr<Packet> packet, const Address& fro
{
NS_LOG_FUNCTION(this << packet << from);
if (m_state == EXPECTING_EMBEDDED_OBJECT)
{
/*
* In the following call to Receive(), #m_objectBytesToBeReceived *will*
* be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
* ThreeGppHttpHeader will be removed from the packet, if it is the first
* packet of the object to be received; the header will be available in
* #m_constructedPacket, which will also be updated.
*/
Receive(packet);
m_rxEmbeddedObjectPacketTrace(packet);
if (m_objectBytesToBeReceived > 0)
{
/*
* There are more packets of this embedded object, so just stay
* still and wait until they arrive.
*/
NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)"
<< " remains from this chunk of embedded object");
}
else
{
/*
* This is the last packet of this embedded object. Acknowledge
* the reception of a whole embedded object
*/
NS_LOG_INFO(this << " Finished receiving an embedded object.");
m_rxEmbeddedObjectTrace(this, m_constructedPacket);
if (!m_objectServerTs.IsZero())
{
m_rxDelayTrace(Simulator::Now() - m_objectServerTs, from);
m_objectServerTs = MilliSeconds(0); // Reset back to zero.
}
if (!m_objectClientTs.IsZero())
{
m_rxRttTrace(Simulator::Now() - m_objectClientTs, from);
m_objectClientTs = MilliSeconds(0); // Reset back to zero.
}
if (m_embeddedObjectsToBeRequested > 0)
{
NS_LOG_INFO(this << " " << m_embeddedObjectsToBeRequested
<< " more embedded object(s) to be requested.");
// Immediately request another using the existing connection.
m_eventRequestEmbeddedObject =
Simulator::ScheduleNow(&ThreeGppHttpClient::RequestEmbeddedObject, this);
}
else
{
/*
* There is no more embedded object, the web page has been
* downloaded completely. Now is the time to read it.
*/
NS_LOG_INFO(this << " Finished receiving a web page.");
FinishReceivingPage(); // trigger callback for page loading time
EnterReadingTime();
}
} // end of else of `if (m_objectBytesToBeReceived > 0)`
} // end of `if (m_state == EXPECTING_EMBEDDED_OBJECT)`
else
if (m_state != EXPECTING_EMBEDDED_OBJECT)
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ReceiveEmbeddedObject().");
}
/*
* In the following call to Receive(), #m_objectBytesToBeReceived *will*
* be updated. #m_objectClientTs and #m_objectServerTs *may* be updated.
* ThreeGppHttpHeader will be removed from the packet, if it is the first
* packet of the object to be received; the header will be available in
* #m_constructedPacket, which will also be updated.
*/
Receive(packet);
m_rxEmbeddedObjectPacketTrace(packet);
if (m_objectBytesToBeReceived > 0)
{
/*
* There are more packets of this embedded object, so just stay
* still and wait until they arrive.
*/
NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)"
<< " remains from this chunk of embedded object");
return;
}
/*
* This is the last packet of this embedded object. Acknowledge
* the reception of a whole embedded object
*/
NS_LOG_INFO(this << " Finished receiving an embedded object.");
m_rxEmbeddedObjectTrace(this, m_constructedPacket);
if (!m_objectServerTs.IsZero())
{
m_rxDelayTrace(Simulator::Now() - m_objectServerTs, from);
m_objectServerTs = MilliSeconds(0); // Reset back to zero.
}
if (!m_objectClientTs.IsZero())
{
m_rxRttTrace(Simulator::Now() - m_objectClientTs, from);
m_objectClientTs = MilliSeconds(0); // Reset back to zero.
}
if (m_embeddedObjectsToBeRequested > 0)
{
NS_LOG_INFO(this << " " << m_embeddedObjectsToBeRequested
<< " more embedded object(s) to be requested.");
// Immediately request another using the existing connection.
m_eventRequestEmbeddedObject =
Simulator::ScheduleNow(&ThreeGppHttpClient::RequestEmbeddedObject, this);
}
else
{
/*
* There is no more embedded object, the web page has been
* downloaded completely. Now is the time to read it.
*/
NS_LOG_INFO(this << " Finished receiving a web page.");
FinishReceivingPage(); // trigger callback for page loading time
EnterReadingTime();
}
} // end of `void ReceiveEmbeddedObject (Ptr<Packet> packet)`
void
@@ -733,19 +706,17 @@ ThreeGppHttpClient::EnterParsingTime()
{
NS_LOG_FUNCTION(this);
if (m_state == EXPECTING_MAIN_OBJECT)
{
const auto parsingTime = m_httpVariables->GetParsingTime();
NS_LOG_INFO(this << " The parsing of this main object"
<< " will complete in " << parsingTime.As(Time::S) << ".");
m_eventParseMainObject =
Simulator::Schedule(parsingTime, &ThreeGppHttpClient::ParseMainObject, this);
SwitchToState(PARSING_MAIN_OBJECT);
}
else
if (m_state != EXPECTING_MAIN_OBJECT)
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for EnterParsingTime().");
}
const auto parsingTime = m_httpVariables->GetParsingTime();
NS_LOG_INFO(this << " The parsing of this main object will complete in "
<< parsingTime.As(Time::S) << ".");
m_eventParseMainObject =
Simulator::Schedule(parsingTime, &ThreeGppHttpClient::ParseMainObject, this);
SwitchToState(PARSING_MAIN_OBJECT);
}
void
@@ -753,37 +724,35 @@ ThreeGppHttpClient::ParseMainObject()
{
NS_LOG_FUNCTION(this);
if (m_state == PARSING_MAIN_OBJECT)
if (m_state != PARSING_MAIN_OBJECT)
{
m_embeddedObjectsToBeRequested = m_httpVariables->GetNumOfEmbeddedObjects();
// saving total number of embedded objects
m_numberEmbeddedObjectsRequested = m_embeddedObjectsToBeRequested;
NS_LOG_INFO(this << " Parsing has determined " << m_embeddedObjectsToBeRequested
<< " embedded object(s) in the main object.");
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ParseMainObject().");
}
if (m_embeddedObjectsToBeRequested > 0)
{
/*
* Immediately request the first embedded object using the
* existing connection.
*/
m_eventRequestEmbeddedObject =
Simulator::ScheduleNow(&ThreeGppHttpClient::RequestEmbeddedObject, this);
}
else
{
/*
* There is no embedded object in the main object. So sit back and
* enjoy the plain web page.
*/
NS_LOG_INFO(this << " Finished receiving a web page.");
FinishReceivingPage(); // trigger callback for page loading time
EnterReadingTime();
}
m_embeddedObjectsToBeRequested = m_httpVariables->GetNumOfEmbeddedObjects();
// saving total number of embedded objects
m_numberEmbeddedObjectsRequested = m_embeddedObjectsToBeRequested;
NS_LOG_INFO(this << " Parsing has determined " << m_embeddedObjectsToBeRequested
<< " embedded object(s) in the main object.");
if (m_embeddedObjectsToBeRequested > 0)
{
/*
* Immediately request the first embedded object using the
* existing connection.
*/
m_eventRequestEmbeddedObject =
Simulator::ScheduleNow(&ThreeGppHttpClient::RequestEmbeddedObject, this);
}
else
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ParseMainObject().");
/*
* There is no embedded object in the main object. So sit back and
* enjoy the plain web page.
*/
NS_LOG_INFO(this << " Finished receiving a web page.");
FinishReceivingPage(); // trigger callback for page loading time
EnterReadingTime();
}
} // end of `void ParseMainObject ()`
@@ -793,21 +762,19 @@ ThreeGppHttpClient::EnterReadingTime()
{
NS_LOG_FUNCTION(this);
if (m_state == EXPECTING_EMBEDDED_OBJECT || m_state == PARSING_MAIN_OBJECT)
{
const auto readingTime = m_httpVariables->GetReadingTime();
NS_LOG_INFO(this << " Client will finish reading this web page in "
<< readingTime.As(Time::S) << ".");
// Schedule a request of another main object once the reading time expires.
m_eventRequestMainObject =
Simulator::Schedule(readingTime, &ThreeGppHttpClient::RequestMainObject, this);
SwitchToState(READING);
}
else
if (m_state != EXPECTING_EMBEDDED_OBJECT && m_state != PARSING_MAIN_OBJECT)
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for EnterReadingTime().");
}
const auto readingTime = m_httpVariables->GetReadingTime();
NS_LOG_INFO(this << " Client will finish reading this web page in " << readingTime.As(Time::S)
<< ".");
// Schedule a request of another main object once the reading time expires.
m_eventRequestMainObject =
Simulator::Schedule(readingTime, &ThreeGppHttpClient::RequestMainObject, this);
SwitchToState(READING);
}
void

View File

@@ -221,76 +221,70 @@ ThreeGppHttpServer::StartApplication()
{
NS_LOG_FUNCTION(this);
if (m_state == NOT_STARTED)
{
m_httpVariables->Initialize();
if (!m_initialSocket)
{
// Find the current default MTU value of TCP sockets.
Ptr<const ns3::AttributeValue> previousSocketMtu;
const TypeId tcpSocketTid = TcpSocket::GetTypeId();
for (uint32_t i = 0; i < tcpSocketTid.GetAttributeN(); i++)
{
TypeId::AttributeInformation attrInfo = tcpSocketTid.GetAttribute(i);
if (attrInfo.name == "SegmentSize")
{
previousSocketMtu = attrInfo.initialValue;
}
}
// Creating a TCP socket to connect to the server.
m_initialSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());
m_initialSocket->SetAttribute("SegmentSize", UintegerValue(m_mtuSize));
NS_ABORT_MSG_IF(m_local.IsInvalid(), "Local address not properly set");
if (InetSocketAddress::IsMatchingType(m_local))
{
const auto ipv4 [[maybe_unused]] =
InetSocketAddress::ConvertFrom(m_local).GetIpv4();
m_initialSocket->SetIpTos(m_tos); // Affects only IPv4 sockets.
NS_LOG_INFO(this << " Binding on " << ipv4 << " port " << m_port << " / " << m_local
<< ".");
}
else if (Inet6SocketAddress::IsMatchingType(m_local))
{
const auto ipv6 [[maybe_unused]] =
Inet6SocketAddress::ConvertFrom(m_local).GetIpv6();
NS_LOG_INFO(this << " Binding on " << ipv6 << " port " << m_port << " / " << m_local
<< ".");
}
else
{
NS_ABORT_MSG("Incompatible local address");
}
auto ret [[maybe_unused]] = m_initialSocket->Bind(m_local);
NS_LOG_DEBUG(this << " Bind() return value= " << ret
<< " GetErrNo= " << m_initialSocket->GetErrno() << ".");
ret = m_initialSocket->Listen();
NS_LOG_DEBUG(this << " Listen () return value= " << ret
<< " GetErrNo= " << m_initialSocket->GetErrno() << ".");
NS_ASSERT_MSG(m_initialSocket, "Failed creating socket.");
m_initialSocket->SetAcceptCallback(
MakeCallback(&ThreeGppHttpServer::ConnectionRequestCallback, this),
MakeCallback(&ThreeGppHttpServer::NewConnectionCreatedCallback, this));
m_initialSocket->SetCloseCallbacks(
MakeCallback(&ThreeGppHttpServer::NormalCloseCallback, this),
MakeCallback(&ThreeGppHttpServer::ErrorCloseCallback, this));
m_initialSocket->SetRecvCallback(
MakeCallback(&ThreeGppHttpServer::ReceivedDataCallback, this));
m_initialSocket->SetSendCallback(MakeCallback(&ThreeGppHttpServer::SendCallback, this));
} // end of `if (m_initialSocket == 0)`
SwitchToState(STARTED);
} // end of `if (m_state == NOT_STARTED)`
else
if (m_state != NOT_STARTED)
{
NS_FATAL_ERROR("Invalid state " << GetStateString() << " for StartApplication().");
}
m_httpVariables->Initialize();
if (!m_initialSocket)
{
// Find the current default MTU value of TCP sockets.
Ptr<const ns3::AttributeValue> previousSocketMtu;
const TypeId tcpSocketTid = TcpSocket::GetTypeId();
for (uint32_t i = 0; i < tcpSocketTid.GetAttributeN(); i++)
{
TypeId::AttributeInformation attrInfo = tcpSocketTid.GetAttribute(i);
if (attrInfo.name == "SegmentSize")
{
previousSocketMtu = attrInfo.initialValue;
}
}
// Creating a TCP socket to connect to the server.
m_initialSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());
m_initialSocket->SetAttribute("SegmentSize", UintegerValue(m_mtuSize));
NS_ABORT_MSG_IF(m_local.IsInvalid(), "Local address not properly set");
if (InetSocketAddress::IsMatchingType(m_local))
{
const auto ipv4 [[maybe_unused]] = InetSocketAddress::ConvertFrom(m_local).GetIpv4();
m_initialSocket->SetIpTos(m_tos); // Affects only IPv4 sockets.
NS_LOG_INFO(this << " Binding on " << ipv4 << " port " << m_port << " / " << m_local
<< ".");
}
else if (Inet6SocketAddress::IsMatchingType(m_local))
{
const auto ipv6 [[maybe_unused]] = Inet6SocketAddress::ConvertFrom(m_local).GetIpv6();
NS_LOG_INFO(this << " Binding on " << ipv6 << " port " << m_port << " / " << m_local
<< ".");
}
else
{
NS_ABORT_MSG("Incompatible local address");
}
auto ret [[maybe_unused]] = m_initialSocket->Bind(m_local);
NS_LOG_DEBUG(this << " Bind() return value= " << ret
<< " GetErrNo= " << m_initialSocket->GetErrno() << ".");
ret = m_initialSocket->Listen();
NS_LOG_DEBUG(this << " Listen () return value= " << ret
<< " GetErrNo= " << m_initialSocket->GetErrno() << ".");
NS_ASSERT_MSG(m_initialSocket, "Failed creating socket.");
m_initialSocket->SetAcceptCallback(
MakeCallback(&ThreeGppHttpServer::ConnectionRequestCallback, this),
MakeCallback(&ThreeGppHttpServer::NewConnectionCreatedCallback, this));
m_initialSocket->SetCloseCallbacks(
MakeCallback(&ThreeGppHttpServer::NormalCloseCallback, this),
MakeCallback(&ThreeGppHttpServer::ErrorCloseCallback, this));
m_initialSocket->SetRecvCallback(
MakeCallback(&ThreeGppHttpServer::ReceivedDataCallback, this));
m_initialSocket->SetSendCallback(MakeCallback(&ThreeGppHttpServer::SendCallback, this));
} // end of `if (m_initialSocket == 0)`
SwitchToState(STARTED);
} // end of `void StartApplication ()`
void
@@ -485,49 +479,50 @@ ThreeGppHttpServer::SendCallback(Ptr<Socket> socket, uint32_t availableBufferSiz
{
NS_LOG_FUNCTION(this << socket << availableBufferSize);
if (!m_txBuffer->IsBufferEmpty(socket))
if (m_txBuffer->IsBufferEmpty(socket))
{
const auto txBufferSize [[maybe_unused]] = m_txBuffer->GetBufferSize(socket);
const auto actualSent [[maybe_unused]] = ServeFromTxBuffer(socket);
return;
}
const auto txBufferSize [[maybe_unused]] = m_txBuffer->GetBufferSize(socket);
const auto actualSent [[maybe_unused]] = ServeFromTxBuffer(socket);
#ifdef NS3_LOG_ENABLE
// Some log messages.
if (actualSent < txBufferSize)
// Some log messages.
if (actualSent < txBufferSize)
{
switch (m_txBuffer->GetBufferContentType(socket))
{
switch (m_txBuffer->GetBufferContentType(socket))
{
case ThreeGppHttpHeader::MAIN_OBJECT:
NS_LOG_INFO(this << " Transmission of main object is suspended"
<< " after " << actualSent << " bytes.");
break;
case ThreeGppHttpHeader::EMBEDDED_OBJECT:
NS_LOG_INFO(this << " Transmission of embedded object is suspended"
<< " after " << actualSent << " bytes.");
break;
default:
NS_FATAL_ERROR("Invalid Tx buffer content type.");
break;
}
case ThreeGppHttpHeader::MAIN_OBJECT:
NS_LOG_INFO(this << " Transmission of main object is suspended"
<< " after " << actualSent << " bytes.");
break;
case ThreeGppHttpHeader::EMBEDDED_OBJECT:
NS_LOG_INFO(this << " Transmission of embedded object is suspended"
<< " after " << actualSent << " bytes.");
break;
default:
NS_FATAL_ERROR("Invalid Tx buffer content type.");
break;
}
else
}
else
{
switch (m_txBuffer->GetBufferContentType(socket))
{
switch (m_txBuffer->GetBufferContentType(socket))
{
case ThreeGppHttpHeader::MAIN_OBJECT:
NS_LOG_INFO(this << " Finished sending a whole main object.");
break;
case ThreeGppHttpHeader::EMBEDDED_OBJECT:
NS_LOG_INFO(this << " Finished sending a whole embedded object.");
break;
default:
NS_FATAL_ERROR("Invalid Tx buffer content type.");
break;
}
case ThreeGppHttpHeader::MAIN_OBJECT:
NS_LOG_INFO(this << " Finished sending a whole main object.");
break;
case ThreeGppHttpHeader::EMBEDDED_OBJECT:
NS_LOG_INFO(this << " Finished sending a whole embedded object.");
break;
default:
NS_FATAL_ERROR("Invalid Tx buffer content type.");
break;
}
}
#endif /* NS3_LOG_ENABLE */
} // end of `if (m_txBuffer->IsBufferEmpty (socket))`
} // end of `void SendCallback (Ptr<Socket> socket, uint32_t availableBufferSize)`
void

View File

@@ -453,28 +453,30 @@ CheckEnvironmentVariables()
<< "\" in env variable NS_LOG, see above for a list of valid components");
}
// We have a valid component or wildcard, check the flags
if (!value.empty())
// No valid component or wildcard
if (value.empty())
{
// Check the flags present in value
StringVector flags = SplitString(value, "|");
for (const auto& flag : flags)
continue;
}
// We have a valid component or wildcard, check the flags present in value
StringVector flags = SplitString(value, "|");
for (const auto& flag : flags)
{
// Handle wild cards
if (flag == "*" || flag == "**")
{
// Handle wild cards
if (flag == "*" || flag == "**")
{
continue;
}
bool ok = LOG_LABEL_LEVELS.find(flag) != LOG_LABEL_LEVELS.end();
if (!ok)
{
NS_FATAL_ERROR("Invalid log level \""
<< flag << "\" in env variable NS_LOG for component name "
<< component);
}
} // for flag
} // !value.empty
} // for component
continue;
}
bool ok = LOG_LABEL_LEVELS.find(flag) != LOG_LABEL_LEVELS.end();
if (!ok)
{
NS_FATAL_ERROR("Invalid log level \""
<< flag << "\" in env variable NS_LOG for component name "
<< component);
}
} // for flag
} // for component
}
void

View File

@@ -1559,77 +1559,79 @@ GlobalRouteManagerImpl::SPFAddASExternal(GlobalRoutingLSA* extlsa, SPFVertex* v)
//
NS_LOG_LOGIC("Considering router " << rtr->GetRouterId());
if (rtr->GetRouterId() == routerId)
if (rtr->GetRouterId() != routerId)
{
NS_LOG_LOGIC("Setting routes for node " << node->GetId());
//
// Routing information is updated using the Ipv4 interface. We need to QI
// for that interface. If the node is acting as an IP version 4 router, it
// should absolutely have an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
NS_ASSERT_MSG(ipv4,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"QI for <Ipv4> interface failed");
//
// Get the Global Router Link State Advertisement from the vertex we're
// adding the routes to. The LSA will have a number of attached Global Router
// Link Records corresponding to links off of that vertex / node. We're going
// to be interested in the records corresponding to point-to-point links.
//
NS_ASSERT_MSG(v->GetLSA(),
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"Expected valid LSA in SPFVertex* v");
Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask();
Ipv4Address tempip = extlsa->GetLinkStateId();
tempip = tempip.CombineMask(tempmask);
continue;
}
//
// Here's why we did all of that work. We're going to add a host route to the
// host address found in the m_linkData field of the point-to-point link
// record. In the case of a point-to-point link, this is the local IP address
// of the node connected to the link. Each of these point-to-point links
// will correspond to a local interface that has an IP address to which
// the node at the root of the SPF tree can send packets. The vertex <v>
// (corresponding to the node that has these links and interfaces) has
// an m_nextHop address precalculated for us that is the address to which the
// root node should send packets to be forwarded to these IP addresses.
// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
// which the packets should be send for forwarding.
//
Ptr<GlobalRouter> router = node->GetObject<GlobalRouter>();
if (!router)
NS_LOG_LOGIC("Setting routes for node " << node->GetId());
//
// Routing information is updated using the Ipv4 interface. We need to QI
// for that interface. If the node is acting as an IP version 4 router, it
// should absolutely have an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
NS_ASSERT_MSG(ipv4,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"QI for <Ipv4> interface failed");
//
// Get the Global Router Link State Advertisement from the vertex we're
// adding the routes to. The LSA will have a number of attached Global Router
// Link Records corresponding to links off of that vertex / node. We're going
// to be interested in the records corresponding to point-to-point links.
//
NS_ASSERT_MSG(v->GetLSA(),
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"Expected valid LSA in SPFVertex* v");
Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask();
Ipv4Address tempip = extlsa->GetLinkStateId();
tempip = tempip.CombineMask(tempmask);
//
// Here's why we did all of that work. We're going to add a host route to the
// host address found in the m_linkData field of the point-to-point link
// record. In the case of a point-to-point link, this is the local IP address
// of the node connected to the link. Each of these point-to-point links
// will correspond to a local interface that has an IP address to which
// the node at the root of the SPF tree can send packets. The vertex <v>
// (corresponding to the node that has these links and interfaces) has
// an m_nextHop address precalculated for us that is the address to which the
// root node should send packets to be forwarded to these IP addresses.
// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
// which the packets should be send for forwarding.
//
Ptr<GlobalRouter> router = node->GetObject<GlobalRouter>();
if (!router)
{
continue;
}
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all next-hop-IPs and out-going-interfaces for reaching
// the stub network gateway 'v' from the root node
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
continue;
gr->AddASExternalRouteTo(tempip, tempmask, nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " add external network route to " << tempip
<< " using next hop " << nextHop << " via interface "
<< outIf);
}
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all next-hop-IPs and out-going-interfaces for reaching
// the stub network gateway 'v' from the root node
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
else
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
gr->AddASExternalRouteTo(tempip, tempmask, nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " add external network route to " << tempip
<< " using next hop " << nextHop << " via interface "
<< outIf);
}
else
{
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add network route to " << tempip
<< " using next hop " << nextHop
<< " since outgoing interface id is negative");
}
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add network route to " << tempip
<< " using next hop " << nextHop
<< " since outgoing interface id is negative");
}
return;
} // if
} // for
}
return;
} // for
}
// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
@@ -1930,102 +1932,103 @@ GlobalRouteManagerImpl::SPFIntraAddRouter(SPFVertex* v)
//
NS_LOG_LOGIC("Considering router " << rtr->GetRouterId());
if (rtr->GetRouterId() == routerId)
if (rtr->GetRouterId() != routerId)
{
NS_LOG_LOGIC("Setting routes for node " << node->GetId());
//
// Routing information is updated using the Ipv4 interface. We need to
// GetObject for that interface. If the node is acting as an IP version 4
// router, it should absolutely have an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
NS_ASSERT_MSG(ipv4,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"GetObject for <Ipv4> interface failed");
//
// Get the Global Router Link State Advertisement from the vertex we're
// adding the routes to. The LSA will have a number of attached Global Router
// Link Records corresponding to links off of that vertex / node. We're going
// to be interested in the records corresponding to point-to-point links.
//
GlobalRoutingLSA* lsa = v->GetLSA();
NS_ASSERT_MSG(lsa,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"Expected valid LSA in SPFVertex* v");
continue;
}
uint32_t nLinkRecords = lsa->GetNLinkRecords();
NS_LOG_LOGIC("Setting routes for node " << node->GetId());
//
// Routing information is updated using the Ipv4 interface. We need to
// GetObject for that interface. If the node is acting as an IP version 4
// router, it should absolutely have an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
NS_ASSERT_MSG(ipv4,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"GetObject for <Ipv4> interface failed");
//
// Get the Global Router Link State Advertisement from the vertex we're
// adding the routes to. The LSA will have a number of attached Global Router
// Link Records corresponding to links off of that vertex / node. We're going
// to be interested in the records corresponding to point-to-point links.
//
GlobalRoutingLSA* lsa = v->GetLSA();
NS_ASSERT_MSG(lsa,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"Expected valid LSA in SPFVertex* v");
uint32_t nLinkRecords = lsa->GetNLinkRecords();
//
// Iterate through the link records on the vertex to which we're going to add
// routes. To make sure we're being clear, we're going to add routing table
// entries to the tables on the node corresponding to the root of the SPF tree.
// These entries will have routes to the IP addresses we find from looking at
// the local side of the point-to-point links found on the node described by
// the vertex <v>.
//
NS_LOG_LOGIC(" Node " << node->GetId() << " found " << nLinkRecords
<< " link records in LSA " << lsa << "with LinkStateId "
<< lsa->GetLinkStateId());
for (uint32_t j = 0; j < nLinkRecords; ++j)
{
//
// Iterate through the link records on the vertex to which we're going to add
// routes. To make sure we're being clear, we're going to add routing table
// entries to the tables on the node corresponding to the root of the SPF tree.
// These entries will have routes to the IP addresses we find from looking at
// the local side of the point-to-point links found on the node described by
// the vertex <v>.
// We are only concerned about point-to-point links
//
NS_LOG_LOGIC(" Node " << node->GetId() << " found " << nLinkRecords
<< " link records in LSA " << lsa << "with LinkStateId "
<< lsa->GetLinkStateId());
for (uint32_t j = 0; j < nLinkRecords; ++j)
GlobalRoutingLinkRecord* lr = lsa->GetLinkRecord(j);
if (lr->GetLinkType() != GlobalRoutingLinkRecord::PointToPoint)
{
//
// We are only concerned about point-to-point links
//
GlobalRoutingLinkRecord* lr = lsa->GetLinkRecord(j);
if (lr->GetLinkType() != GlobalRoutingLinkRecord::PointToPoint)
{
continue;
}
//
// Here's why we did all of that work. We're going to add a host route to the
// host address found in the m_linkData field of the point-to-point link
// record. In the case of a point-to-point link, this is the local IP address
// of the node connected to the link. Each of these point-to-point links
// will correspond to a local interface that has an IP address to which
// the node at the root of the SPF tree can send packets. The vertex <v>
// (corresponding to the node that has these links and interfaces) has
// an m_nextHop address precalculated for us that is the address to which the
// root node should send packets to be forwarded to these IP addresses.
// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
// which the packets should be send for forwarding.
//
Ptr<GlobalRouter> router = node->GetObject<GlobalRouter>();
if (!router)
{
continue;
}
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all available exit directions due to ECMP,
// and add host route for each of the exit direction toward
// the vertex 'v'
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
gr->AddHostRouteTo(lr->GetLinkData(), nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " adding host route to " << lr->GetLinkData()
<< " using next hop " << nextHop
<< " and outgoing interface " << outIf);
}
else
{
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add host route to "
<< lr->GetLinkData() << " using next hop " << nextHop
<< " since outgoing interface id is negative "
<< outIf);
}
} // for all routes from the root the vertex 'v'
continue;
}
//
// Done adding the routes for the selected node.
// Here's why we did all of that work. We're going to add a host route to the
// host address found in the m_linkData field of the point-to-point link
// record. In the case of a point-to-point link, this is the local IP address
// of the node connected to the link. Each of these point-to-point links
// will correspond to a local interface that has an IP address to which
// the node at the root of the SPF tree can send packets. The vertex <v>
// (corresponding to the node that has these links and interfaces) has
// an m_nextHop address precalculated for us that is the address to which the
// root node should send packets to be forwarded to these IP addresses.
// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
// which the packets should be send for forwarding.
//
return;
Ptr<GlobalRouter> router = node->GetObject<GlobalRouter>();
if (!router)
{
continue;
}
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all available exit directions due to ECMP,
// and add host route for each of the exit direction toward
// the vertex 'v'
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
gr->AddHostRouteTo(lr->GetLinkData(), nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " adding host route to " << lr->GetLinkData()
<< " using next hop " << nextHop
<< " and outgoing interface " << outIf);
}
else
{
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add host route to " << lr->GetLinkData()
<< " using next hop " << nextHop
<< " since outgoing interface id is negative " << outIf);
}
} // for all routes from the root the vertex 'v'
}
//
// Done adding the routes for the selected node.
//
return;
}
}

View File

@@ -119,45 +119,43 @@ A3RsrpHandoverAlgorithm::DoReportUeMeas(uint16_t rnti, LteRrcSap::MeasResults me
return;
}
if (measResults.haveMeasResultNeighCells && !measResults.measResultListEutra.empty())
{
uint16_t bestNeighbourCellId = 0;
uint8_t bestNeighbourRsrp = 0;
for (auto it = measResults.measResultListEutra.begin();
it != measResults.measResultListEutra.end();
++it)
{
if (it->haveRsrpResult)
{
if ((bestNeighbourRsrp < it->rsrpResult) && IsValidNeighbour(it->physCellId))
{
bestNeighbourCellId = it->physCellId;
bestNeighbourRsrp = it->rsrpResult;
}
}
else
{
NS_LOG_WARN("RSRP measurement is missing from cell ID " << it->physCellId);
}
}
if (bestNeighbourCellId > 0)
{
NS_LOG_LOGIC("Trigger Handover to cellId " << bestNeighbourCellId);
NS_LOG_LOGIC("target cell RSRP " << (uint16_t)bestNeighbourRsrp);
NS_LOG_LOGIC("serving cell RSRP " << (uint16_t)measResults.measResultPCell.rsrpResult);
// Inform eNodeB RRC about handover
m_handoverManagementSapUser->TriggerHandover(rnti, bestNeighbourCellId);
}
}
else
if (!measResults.haveMeasResultNeighCells || measResults.measResultListEutra.empty())
{
NS_LOG_WARN(
this << " Event A3 received without measurement results from neighbouring cells");
return;
}
uint16_t bestNeighbourCellId = 0;
uint8_t bestNeighbourRsrp = 0;
for (auto it = measResults.measResultListEutra.begin();
it != measResults.measResultListEutra.end();
++it)
{
if (it->haveRsrpResult)
{
if ((bestNeighbourRsrp < it->rsrpResult) && IsValidNeighbour(it->physCellId))
{
bestNeighbourCellId = it->physCellId;
bestNeighbourRsrp = it->rsrpResult;
}
}
else
{
NS_LOG_WARN("RSRP measurement is missing from cell ID " << it->physCellId);
}
}
if (bestNeighbourCellId > 0)
{
NS_LOG_LOGIC("Trigger Handover to cellId " << bestNeighbourCellId);
NS_LOG_LOGIC("target cell RSRP " << (uint16_t)bestNeighbourRsrp);
NS_LOG_LOGIC("serving cell RSRP " << (uint16_t)measResults.measResultPCell.rsrpResult);
// Inform eNodeB RRC about handover
m_handoverManagementSapUser->TriggerHandover(rnti, bestNeighbourCellId);
}
} // end of DoReportUeMeas
bool

View File

@@ -843,111 +843,112 @@ FdMtFfMacScheduler::DoSchedDlTriggerReq(
for (int i = 0; i < rbgNum; i++)
{
NS_LOG_INFO(this << " ALLOCATION for RBG " << i << " of " << rbgNum);
if (!rbgMap.at(i))
if (rbgMap.at(i))
{
auto itMax = m_flowStatsDl.end();
double rcqiMax = 0.0;
for (auto it = m_flowStatsDl.begin(); it != m_flowStatsDl.end(); it++)
continue;
}
auto itMax = m_flowStatsDl.end();
double rcqiMax = 0.0;
for (auto it = m_flowStatsDl.begin(); it != m_flowStatsDl.end(); it++)
{
auto itRnti = rntiAllocated.find(*it);
if (itRnti != rntiAllocated.end() || !HarqProcessAvailability(*it))
{
auto itRnti = rntiAllocated.find(*it);
if (itRnti != rntiAllocated.end() || !HarqProcessAvailability(*it))
// UE already allocated for HARQ or without HARQ process available -> drop it
if (itRnti != rntiAllocated.end())
{
// UE already allocated for HARQ or without HARQ process available -> drop it
if (itRnti != rntiAllocated.end())
{
NS_LOG_DEBUG(this << " RNTI discarded for HARQ tx" << (uint16_t)(*it));
}
if (!HarqProcessAvailability(*it))
{
NS_LOG_DEBUG(this << " RNTI discarded for HARQ id" << (uint16_t)(*it));
}
continue;
NS_LOG_DEBUG(this << " RNTI discarded for HARQ tx" << (uint16_t)(*it));
}
auto itCqi = m_a30CqiRxed.find(*it);
auto itTxMode = m_uesTxMode.find(*it);
if (itTxMode == m_uesTxMode.end())
if (!HarqProcessAvailability(*it))
{
NS_FATAL_ERROR("No Transmission Mode info on user " << (*it));
NS_LOG_DEBUG(this << " RNTI discarded for HARQ id" << (uint16_t)(*it));
}
auto nLayer = TransmissionModesLayers::TxMode2LayerNum((*itTxMode).second);
std::vector<uint8_t> sbCqi;
if (itCqi == m_a30CqiRxed.end())
{
sbCqi = std::vector<uint8_t>(nLayer, 1); // start with lowest value
}
else
{
sbCqi = (*itCqi).second.m_higherLayerSelected.at(i).m_sbCqi;
}
uint8_t cqi1 = sbCqi.at(0);
uint8_t cqi2 = 0;
if (sbCqi.size() > 1)
{
cqi2 = sbCqi.at(1);
}
if ((cqi1 > 0) ||
(cqi2 > 0)) // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213)
{
if (LcActivePerFlow(*it) > 0)
{
// this UE has data to transmit
double achievableRate = 0.0;
uint8_t mcs = 0;
for (uint8_t k = 0; k < nLayer; k++)
{
if (sbCqi.size() > k)
{
mcs = m_amc->GetMcsFromCqi(sbCqi.at(k));
}
else
{
// no info on this subband -> worst MCS
mcs = 0;
}
achievableRate += ((m_amc->GetDlTbSizeFromMcs(mcs, rbgSize) / 8) /
0.001); // = TB size / TTI
}
continue;
}
double rcqi = achievableRate;
NS_LOG_INFO(this << " RNTI " << (*it) << " MCS " << (uint32_t)mcs
<< " achievableRate " << achievableRate << " RCQI "
<< rcqi);
if (rcqi > rcqiMax)
{
rcqiMax = rcqi;
itMax = it;
}
}
} // end if cqi
} // end for m_rlcBufferReq
if (itMax == m_flowStatsDl.end())
auto itCqi = m_a30CqiRxed.find(*it);
auto itTxMode = m_uesTxMode.find(*it);
if (itTxMode == m_uesTxMode.end())
{
// no UE available for this RB
NS_LOG_INFO(this << " any UE found");
NS_FATAL_ERROR("No Transmission Mode info on user " << (*it));
}
auto nLayer = TransmissionModesLayers::TxMode2LayerNum((*itTxMode).second);
std::vector<uint8_t> sbCqi;
if (itCqi == m_a30CqiRxed.end())
{
sbCqi = std::vector<uint8_t>(nLayer, 1); // start with lowest value
}
else
{
rbgMap.at(i) = true;
auto itMap = allocationMap.find(*itMax);
if (itMap == allocationMap.end())
{
// insert new element
std::vector<uint16_t> tempMap;
tempMap.push_back(i);
allocationMap[*itMax] = tempMap;
}
else
{
(*itMap).second.push_back(i);
}
NS_LOG_INFO(this << " UE assigned " << (*itMax));
sbCqi = (*itCqi).second.m_higherLayerSelected.at(i).m_sbCqi;
}
} // end for RBG free
} // end for RBGs
uint8_t cqi1 = sbCqi.at(0);
uint8_t cqi2 = 0;
if (sbCqi.size() > 1)
{
cqi2 = sbCqi.at(1);
}
if ((cqi1 > 0) ||
(cqi2 > 0)) // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213)
{
if (LcActivePerFlow(*it) > 0)
{
// this UE has data to transmit
double achievableRate = 0.0;
uint8_t mcs = 0;
for (uint8_t k = 0; k < nLayer; k++)
{
if (sbCqi.size() > k)
{
mcs = m_amc->GetMcsFromCqi(sbCqi.at(k));
}
else
{
// no info on this subband -> worst MCS
mcs = 0;
}
achievableRate += ((m_amc->GetDlTbSizeFromMcs(mcs, rbgSize) / 8) /
0.001); // = TB size / TTI
}
double rcqi = achievableRate;
NS_LOG_INFO(this << " RNTI " << (*it) << " MCS " << (uint32_t)mcs
<< " achievableRate " << achievableRate << " RCQI " << rcqi);
if (rcqi > rcqiMax)
{
rcqiMax = rcqi;
itMax = it;
}
}
} // end if cqi
} // end for m_rlcBufferReq
if (itMax == m_flowStatsDl.end())
{
// no UE available for this RB
NS_LOG_INFO(this << " any UE found");
}
else
{
rbgMap.at(i) = true;
auto itMap = allocationMap.find(*itMax);
if (itMap == allocationMap.end())
{
// insert new element
std::vector<uint16_t> tempMap;
tempMap.push_back(i);
allocationMap[*itMax] = tempMap;
}
else
{
(*itMap).second.push_back(i);
}
NS_LOG_INFO(this << " UE assigned " << (*itMax));
}
} // end for RBGs
// generate the transmission opportunities by grouping the RBGs of the same RNTI and
// creating the correspondent DCIs
@@ -1207,25 +1208,23 @@ FdMtFfMacScheduler::EstimateUlSinr(uint16_t rnti, uint16_t rb)
// no cqi info about this UE
return NO_SINR;
}
else
// take the average SINR value among the available
double sinrSum = 0;
unsigned int sinrNum = 0;
for (uint32_t i = 0; i < m_cschedCellConfig.m_ulBandwidth; i++)
{
// take the average SINR value among the available
double sinrSum = 0;
unsigned int sinrNum = 0;
for (uint32_t i = 0; i < m_cschedCellConfig.m_ulBandwidth; i++)
double sinr = (*itCqi).second.at(i);
if (sinr != NO_SINR)
{
double sinr = (*itCqi).second.at(i);
if (sinr != NO_SINR)
{
sinrSum += sinr;
sinrNum++;
}
sinrSum += sinr;
sinrNum++;
}
double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at(rb) = estimatedSinr;
return estimatedSinr;
}
double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at(rb) = estimatedSinr;
return estimatedSinr;
}
void

View File

@@ -1029,127 +1029,125 @@ LteSpectrumPhy::EndRxData()
itTb = m_expectedTbs.find(tbId);
NS_LOG_INFO(this << " Packet of " << tbId.m_rnti << " layer "
<< (uint16_t)tag.GetLayer());
if (itTb != m_expectedTbs.end())
if (itTb == m_expectedTbs.end())
{
if (!(*itTb).second.corrupt)
{
m_phyRxEndOkTrace(*j);
continue;
}
if (!m_ltePhyRxDataEndOkCallback.IsNull())
{
m_ltePhyRxDataEndOkCallback(*j);
}
if (!(*itTb).second.corrupt)
{
m_phyRxEndOkTrace(*j);
if (!m_ltePhyRxDataEndOkCallback.IsNull())
{
m_ltePhyRxDataEndOkCallback(*j);
}
}
else
{
// TB received with errors
m_phyRxEndErrorTrace(*j);
}
// send HARQ feedback (if not already done for this TB)
if ((*itTb).second.harqFeedbackSent)
{
continue;
}
(*itTb).second.harqFeedbackSent = true;
if (!(*itTb).second.downlink)
{
UlInfoListElement_s harqUlInfo;
harqUlInfo.m_rnti = tbId.m_rnti;
harqUlInfo.m_tpc = 0;
if ((*itTb).second.corrupt)
{
harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
m_harqPhyModule->UpdateUlHarqProcessStatus(
tbId.m_rnti,
(*itTb).second.mi,
(*itTb).second.size,
(*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
}
else
{
// TB received with errors
m_phyRxEndErrorTrace(*j);
harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
m_harqPhyModule->ResetUlHarqProcessStatus(tbId.m_rnti,
(*itTb).second.harqProcessId);
}
// send HARQ feedback (if not already done for this TB)
if (!(*itTb).second.harqFeedbackSent)
if (!m_ltePhyUlHarqFeedbackCallback.IsNull())
{
(*itTb).second.harqFeedbackSent = true;
if (!(*itTb).second.downlink)
m_ltePhyUlHarqFeedbackCallback(harqUlInfo);
}
}
else
{
auto itHarq = harqDlInfoMap.find(tbId.m_rnti);
if (itHarq == harqDlInfoMap.end())
{
DlInfoListElement_s harqDlInfo;
harqDlInfo.m_harqStatus.resize(m_layersNum, DlInfoListElement_s::ACK);
harqDlInfo.m_rnti = tbId.m_rnti;
harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
if ((*itTb).second.corrupt)
{
UlInfoListElement_s harqUlInfo;
harqUlInfo.m_rnti = tbId.m_rnti;
harqUlInfo.m_tpc = 0;
if ((*itTb).second.corrupt)
{
harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
m_harqPhyModule->UpdateUlHarqProcessStatus(
tbId.m_rnti,
(*itTb).second.mi,
(*itTb).second.size,
(*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
}
else
{
harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
m_harqPhyModule->ResetUlHarqProcessStatus(tbId.m_rnti,
(*itTb).second.harqProcessId);
}
if (!m_ltePhyUlHarqFeedbackCallback.IsNull())
{
m_ltePhyUlHarqFeedbackCallback(harqUlInfo);
}
harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::NACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId << " layer "
<< (uint16_t)tbId.m_layer << " send DL-HARQ-NACK");
m_harqPhyModule->UpdateDlHarqProcessStatus(
(*itTb).second.harqProcessId,
tbId.m_layer,
(*itTb).second.mi,
(*itTb).second.size,
(*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
}
else
{
auto itHarq = harqDlInfoMap.find(tbId.m_rnti);
if (itHarq == harqDlInfoMap.end())
{
DlInfoListElement_s harqDlInfo;
harqDlInfo.m_harqStatus.resize(m_layersNum, DlInfoListElement_s::ACK);
harqDlInfo.m_rnti = tbId.m_rnti;
harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
if ((*itTb).second.corrupt)
{
harqDlInfo.m_harqStatus.at(tbId.m_layer) =
DlInfoListElement_s::NACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId
<< " layer " << (uint16_t)tbId.m_layer
<< " send DL-HARQ-NACK");
m_harqPhyModule->UpdateDlHarqProcessStatus(
(*itTb).second.harqProcessId,
tbId.m_layer,
(*itTb).second.mi,
(*itTb).second.size,
(*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
}
else
{
harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId
<< " layer " << (uint16_t)tbId.m_layer << " size "
<< (*itTb).second.size << " send DL-HARQ-ACK");
m_harqPhyModule->ResetDlHarqProcessStatus(
(*itTb).second.harqProcessId);
}
harqDlInfoMap.insert(
std::pair<uint16_t, DlInfoListElement_s>(tbId.m_rnti, harqDlInfo));
}
else
{
if ((*itTb).second.corrupt)
{
(*itHarq).second.m_harqStatus.at(tbId.m_layer) =
DlInfoListElement_s::NACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId
<< " layer " << (uint16_t)tbId.m_layer << " size "
<< (*itHarq).second.m_harqStatus.size()
<< " send DL-HARQ-NACK");
m_harqPhyModule->UpdateDlHarqProcessStatus(
(*itTb).second.harqProcessId,
tbId.m_layer,
(*itTb).second.mi,
(*itTb).second.size,
(*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
}
else
{
NS_ASSERT_MSG(tbId.m_layer < (*itHarq).second.m_harqStatus.size(),
" layer " << (uint16_t)tbId.m_layer);
(*itHarq).second.m_harqStatus.at(tbId.m_layer) =
DlInfoListElement_s::ACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId
<< " layer " << (uint16_t)tbId.m_layer << " size "
<< (*itHarq).second.m_harqStatus.size()
<< " send DL-HARQ-ACK");
m_harqPhyModule->ResetDlHarqProcessStatus(
(*itTb).second.harqProcessId);
}
}
} // end if ((*itTb).second.downlink) HARQ
} // end if (!(*itTb).second.harqFeedbackSent)
}
harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId << " layer "
<< (uint16_t)tbId.m_layer << " size "
<< (*itTb).second.size << " send DL-HARQ-ACK");
m_harqPhyModule->ResetDlHarqProcessStatus((*itTb).second.harqProcessId);
}
harqDlInfoMap.insert(
std::pair<uint16_t, DlInfoListElement_s>(tbId.m_rnti, harqDlInfo));
}
else
{
if ((*itTb).second.corrupt)
{
(*itHarq).second.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::NACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId << " layer "
<< (uint16_t)tbId.m_layer << " size "
<< (*itHarq).second.m_harqStatus.size()
<< " send DL-HARQ-NACK");
m_harqPhyModule->UpdateDlHarqProcessStatus(
(*itTb).second.harqProcessId,
tbId.m_layer,
(*itTb).second.mi,
(*itTb).second.size,
(*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
}
else
{
NS_ASSERT_MSG(tbId.m_layer < (*itHarq).second.m_harqStatus.size(),
" layer " << (uint16_t)tbId.m_layer);
(*itHarq).second.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
<< (uint16_t)(*itTb).second.harqProcessId << " layer "
<< (uint16_t)tbId.m_layer << " size "
<< (*itHarq).second.m_harqStatus.size()
<< " send DL-HARQ-ACK");
m_harqPhyModule->ResetDlHarqProcessStatus((*itTb).second.harqProcessId);
}
}
} // end if ((*itTb).second.downlink) HARQ
}
}

View File

@@ -630,58 +630,59 @@ LteUePhy::GenerateCqiRsrpRsrq(const SpectrumValue& sinr)
m_rsrpSinrSampleCounter = 0;
}
if (m_pssReceived)
if (!m_pssReceived)
{
// measure instantaneous RSRQ now
NS_ASSERT_MSG(m_rsInterferencePowerUpdated, " RS interference power info obsolete");
return;
}
auto itPss = m_pssList.begin();
while (itPss != m_pssList.end())
// measure instantaneous RSRQ now
NS_ASSERT_MSG(m_rsInterferencePowerUpdated, " RS interference power info obsolete");
auto itPss = m_pssList.begin();
while (itPss != m_pssList.end())
{
uint16_t rbNum = 0;
double rssiSum = 0.0;
auto itIntN = m_rsInterferencePower.ConstValuesBegin();
auto itPj = m_rsReceivedPower.ConstValuesBegin();
for (itPj = m_rsReceivedPower.ConstValuesBegin();
itPj != m_rsReceivedPower.ConstValuesEnd();
itIntN++, itPj++)
{
uint16_t rbNum = 0;
double rssiSum = 0.0;
rbNum++;
// convert PSD [W/Hz] to linear power [W] for the single RE
double interfPlusNoisePowerTxW = (*itIntN);
double signalPowerTxW = (*itPj);
rssiSum += (2 * (interfPlusNoisePowerTxW + signalPowerTxW));
}
rssiSum *= (180000.0 / 12.0);
auto itIntN = m_rsInterferencePower.ConstValuesBegin();
auto itPj = m_rsReceivedPower.ConstValuesBegin();
for (itPj = m_rsReceivedPower.ConstValuesBegin();
itPj != m_rsReceivedPower.ConstValuesEnd();
itIntN++, itPj++)
NS_ASSERT(rbNum == (*itPss).nRB);
double rsrq_dB = 10 * log10((*itPss).pssPsdSum / rssiSum);
if (rsrq_dB > m_pssReceptionThreshold)
{
NS_LOG_INFO(this << " PSS RNTI " << m_rnti << " cellId " << m_cellId << " has RSRQ "
<< rsrq_dB << " and RBnum " << rbNum);
// store measurements
auto itMeasMap = m_ueMeasurementsMap.find((*itPss).cellId);
if (itMeasMap != m_ueMeasurementsMap.end())
{
rbNum++;
// convert PSD [W/Hz] to linear power [W] for the single RE
double interfPlusNoisePowerTxW = (*itIntN);
double signalPowerTxW = (*itPj);
rssiSum += (2 * (interfPlusNoisePowerTxW + signalPowerTxW));
(*itMeasMap).second.rsrqSum += rsrq_dB;
(*itMeasMap).second.rsrqNum++;
}
rssiSum *= (180000.0 / 12.0);
NS_ASSERT(rbNum == (*itPss).nRB);
double rsrq_dB = 10 * log10((*itPss).pssPsdSum / rssiSum);
if (rsrq_dB > m_pssReceptionThreshold)
else
{
NS_LOG_INFO(this << " PSS RNTI " << m_rnti << " cellId " << m_cellId << " has RSRQ "
<< rsrq_dB << " and RBnum " << rbNum);
// store measurements
auto itMeasMap = m_ueMeasurementsMap.find((*itPss).cellId);
if (itMeasMap != m_ueMeasurementsMap.end())
{
(*itMeasMap).second.rsrqSum += rsrq_dB;
(*itMeasMap).second.rsrqNum++;
}
else
{
NS_LOG_WARN("race condition of bug 2091 occurred");
}
NS_LOG_WARN("race condition of bug 2091 occurred");
}
}
itPss++;
itPss++;
} // end of while (itPss != m_pssList.end ())
} // end of while (itPss != m_pssList.end ())
m_pssList.clear();
} // end of if (m_pssReceived)
m_pssList.clear();
} // end of void LteUePhy::GenerateCtrlCqiReport (const SpectrumValue& sinr)

View File

@@ -1571,81 +1571,82 @@ LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback(
NS_ASSERT(rnti == 1);
NS_ASSERT(cellId == 1);
if (report.measResults.measId == m_expectedMeasId)
if (report.measResults.measId != m_expectedMeasId)
{
// verifying the report completeness
LteRrcSap::MeasResults measResults = report.measResults;
NS_LOG_DEBUG(
this << " Serving cellId=" << cellId
<< " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
<< " dBm)"
<< " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
<< " dB)");
return;
}
// verifying reported best cells
if (measResults.measResultListEutra.empty())
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
false,
"Unexpected report content");
}
else
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
true,
"Unexpected report content");
auto it = measResults.measResultListEutra.begin();
NS_ASSERT(it != measResults.measResultListEutra.end());
NS_ASSERT(it->physCellId == 2);
NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
false,
"Report contains cgi-info, which is not supported");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
true,
"Report does not contain measured RSRP result");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
true,
"Report does not contain measured RSRQ result");
NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
<< " rsrp=" << (uint16_t)it->rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
<< " rsrq=" << (uint16_t)it->rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
// verifying the report completeness
LteRrcSap::MeasResults measResults = report.measResults;
NS_LOG_DEBUG(
this << " Serving cellId=" << cellId
<< " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
<< " dBm)"
<< " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
<< " dB)");
} // end of else of if (measResults.measResultListEutra.size () == 0)
// verifying the report timing
bool hasEnded = m_itExpectedTime == m_expectedTime.end();
NS_TEST_ASSERT_MSG_EQ(hasEnded,
// verifying reported best cells
if (measResults.measResultListEutra.empty())
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
false,
"Reporting should not have occurred at "
<< Simulator::Now().As(Time::S));
if (!hasEnded)
{
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
NS_ASSERT(!hasEnded);
"Unexpected report content");
}
else
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
true,
"Unexpected report content");
auto it = measResults.measResultListEutra.begin();
NS_ASSERT(it != measResults.measResultListEutra.end());
NS_ASSERT(it->physCellId == 2);
NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
false,
"Report contains cgi-info, which is not supported");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
true,
"Report does not contain measured RSRP result");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
true,
"Report does not contain measured RSRQ result");
NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
<< " rsrp=" << (uint16_t)it->rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
<< " rsrq=" << (uint16_t)it->rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
// using milliseconds to avoid floating-point comparison
uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
m_itExpectedTime++;
} // end of else of if (measResults.measResultListEutra.size () == 0)
uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
uint16_t referenceRsrp = *m_itExpectedRsrp;
m_itExpectedRsrp++;
// verifying the report timing
bool hasEnded = m_itExpectedTime == m_expectedTime.end();
NS_TEST_ASSERT_MSG_EQ(hasEnded,
false,
"Reporting should not have occurred at " << Simulator::Now().As(Time::S));
if (hasEnded)
{
return;
}
NS_TEST_ASSERT_MSG_EQ(timeNowMs,
timeExpectedMs,
"Reporting should not have occurred at this time");
NS_TEST_ASSERT_MSG_EQ(observedRsrp,
referenceRsrp,
"The RSRP observed differs with the reference RSRP");
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
NS_ASSERT(!hasEnded);
} // end of if (!hasEnded)
// using milliseconds to avoid floating-point comparison
uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
m_itExpectedTime++;
} // end of if (report.measResults.measId == m_expectedMeasId)
uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
uint16_t referenceRsrp = *m_itExpectedRsrp;
m_itExpectedRsrp++;
NS_TEST_ASSERT_MSG_EQ(timeNowMs,
timeExpectedMs,
"Reporting should not have occurred at this time");
NS_TEST_ASSERT_MSG_EQ(observedRsrp,
referenceRsrp,
"The RSRP observed differs with the reference RSRP");
} // end of void LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback
@@ -1863,75 +1864,76 @@ LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback(
NS_ASSERT(rnti == 1);
NS_ASSERT(cellId == 1);
if (report.measResults.measId == m_expectedMeasId)
if (report.measResults.measId != m_expectedMeasId)
{
// verifying the report completeness
LteRrcSap::MeasResults measResults = report.measResults;
NS_LOG_DEBUG(
this << " Serving cellId=" << cellId
<< " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
<< " dBm)"
<< " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
<< " dB)");
return;
}
// verifying reported best cells
if (measResults.measResultListEutra.empty())
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
false,
"Unexpected report content");
}
else
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
true,
"Unexpected report content");
auto it = measResults.measResultListEutra.begin();
NS_ASSERT(it != measResults.measResultListEutra.end());
for (const auto& it : measResults.measResultListEutra)
{
NS_ASSERT(it.physCellId == 2 || it.physCellId == 3);
NS_TEST_ASSERT_MSG_EQ(it.haveCgiInfo,
false,
"Report contains cgi-info, which is not supported");
NS_TEST_ASSERT_MSG_EQ(it.haveRsrpResult,
true,
"Report does not contain measured RSRP result");
NS_TEST_ASSERT_MSG_EQ(it.haveRsrqResult,
true,
"Report does not contain measured RSRQ result");
NS_LOG_DEBUG(
this << " Neighbour cellId=" << it.physCellId
<< " rsrp=" << (uint16_t)it.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(it.rsrpResult) << " dBm)"
<< " rsrq=" << (uint16_t)it.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(it.rsrqResult) << " dB)");
}
// verifying the report completeness
LteRrcSap::MeasResults measResults = report.measResults;
NS_LOG_DEBUG(
this << " Serving cellId=" << cellId
<< " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
<< " dBm)"
<< " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
<< " dB)");
} // end of else of if (measResults.measResultListEutra.size () == 0)
// verifying the report timing
bool hasEnded = m_itExpectedTime == m_expectedTime.end();
NS_TEST_ASSERT_MSG_EQ(hasEnded,
// verifying reported best cells
if (measResults.measResultListEutra.empty())
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
false,
"Reporting should not have occurred at "
<< Simulator::Now().GetSeconds() << "s");
if (!hasEnded)
"Unexpected report content");
}
else
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
true,
"Unexpected report content");
auto it = measResults.measResultListEutra.begin();
NS_ASSERT(it != measResults.measResultListEutra.end());
for (const auto& it : measResults.measResultListEutra)
{
// using milliseconds to avoid floating-point comparison
uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
m_itExpectedTime++;
NS_ASSERT(it.physCellId == 2 || it.physCellId == 3);
NS_TEST_ASSERT_MSG_EQ(it.haveCgiInfo,
false,
"Report contains cgi-info, which is not supported");
NS_TEST_ASSERT_MSG_EQ(it.haveRsrpResult,
true,
"Report does not contain measured RSRP result");
NS_TEST_ASSERT_MSG_EQ(it.haveRsrqResult,
true,
"Report does not contain measured RSRQ result");
NS_LOG_DEBUG(this << " Neighbour cellId=" << it.physCellId
<< " rsrp=" << (uint16_t)it.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(it.rsrpResult) << " dBm)"
<< " rsrq=" << (uint16_t)it.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(it.rsrqResult) << " dB)");
}
NS_TEST_ASSERT_MSG_EQ(timeNowMs,
timeExpectedMs,
"Reporting should not have occurred at this time");
} // end of else of if (measResults.measResultListEutra.size () == 0)
} // end of if (!hasEnded)
// verifying the report timing
bool hasEnded = m_itExpectedTime == m_expectedTime.end();
NS_TEST_ASSERT_MSG_EQ(hasEnded,
false,
"Reporting should not have occurred at " << Simulator::Now().GetSeconds()
<< "s");
if (hasEnded)
{
return;
}
} // end of if (report.measResults.measId == m_expectedMeasId)
// using milliseconds to avoid floating-point comparison
uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
m_itExpectedTime++;
NS_TEST_ASSERT_MSG_EQ(timeNowMs,
timeExpectedMs,
"Reporting should not have occurred at this time");
} // end of void LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback
@@ -2491,81 +2493,82 @@ LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback(
NS_FATAL_ERROR("Invalid cell ID " << cellId);
}
if (isCorrectMeasId)
if (!isCorrectMeasId)
{
// verifying the report completeness
LteRrcSap::MeasResults measResults = report.measResults;
NS_LOG_DEBUG(
this << " Serving cellId=" << cellId
<< " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
<< " dBm)"
<< " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
<< " dB)");
return;
}
// verifying reported best cells
if (measResults.measResultListEutra.empty())
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
false,
"Unexpected report content");
}
else
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
true,
"Unexpected report content");
auto it = measResults.measResultListEutra.begin();
NS_ASSERT(it != measResults.measResultListEutra.end());
NS_ASSERT(it->physCellId != cellId);
NS_ASSERT(it->physCellId <= 2);
NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
false,
"Report contains cgi-info, which is not supported");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
true,
"Report does not contain measured RSRP result");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
true,
"Report does not contain measured RSRQ result");
NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
<< " rsrp=" << (uint16_t)it->rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
<< " rsrq=" << (uint16_t)it->rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
// verifying the report completeness
LteRrcSap::MeasResults measResults = report.measResults;
NS_LOG_DEBUG(
this << " Serving cellId=" << cellId
<< " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
<< " dBm)"
<< " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
<< " dB)");
} // end of else of if (measResults.measResultListEutra.size () == 0)
// verifying the report timing
bool hasEnded = m_itExpectedTime == m_expectedTime.end();
NS_TEST_ASSERT_MSG_EQ(hasEnded,
// verifying reported best cells
if (measResults.measResultListEutra.empty())
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
false,
"Reporting should not have occurred at "
<< Simulator::Now().As(Time::S));
if (!hasEnded)
{
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
NS_ASSERT(!hasEnded);
"Unexpected report content");
}
else
{
NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells,
true,
"Unexpected report content");
auto it = measResults.measResultListEutra.begin();
NS_ASSERT(it != measResults.measResultListEutra.end());
NS_ASSERT(it->physCellId != cellId);
NS_ASSERT(it->physCellId <= 2);
NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
false,
"Report contains cgi-info, which is not supported");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
true,
"Report does not contain measured RSRP result");
NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
true,
"Report does not contain measured RSRQ result");
NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
<< " rsrp=" << (uint16_t)it->rsrpResult << " ("
<< EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
<< " rsrq=" << (uint16_t)it->rsrqResult << " ("
<< EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
// using milliseconds to avoid floating-point comparison
uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
m_itExpectedTime++;
} // end of else of if (measResults.measResultListEutra.size () == 0)
uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
uint16_t referenceRsrp = *m_itExpectedRsrp;
m_itExpectedRsrp++;
// verifying the report timing
bool hasEnded = m_itExpectedTime == m_expectedTime.end();
NS_TEST_ASSERT_MSG_EQ(hasEnded,
false,
"Reporting should not have occurred at " << Simulator::Now().As(Time::S));
if (hasEnded)
{
return;
}
NS_TEST_ASSERT_MSG_EQ(timeNowMs,
timeExpectedMs,
"Reporting should not have occurred at this time");
NS_TEST_ASSERT_MSG_EQ(observedRsrp,
referenceRsrp,
"The RSRP observed differs with the reference RSRP");
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
NS_ASSERT(!hasEnded);
} // end of if (!hasEnded)
// using milliseconds to avoid floating-point comparison
uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
m_itExpectedTime++;
} // end of if (report.measResults.measId == correctMeasId)
uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
uint16_t referenceRsrp = *m_itExpectedRsrp;
m_itExpectedRsrp++;
NS_TEST_ASSERT_MSG_EQ(timeNowMs,
timeExpectedMs,
"Reporting should not have occurred at this time");
NS_TEST_ASSERT_MSG_EQ(observedRsrp,
referenceRsrp,
"The RSRP observed differs with the reference RSRP");
} // end of void LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback