From 213fe52e5c86b52e90b23162c8308486c4e842af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Wed, 30 Oct 2024 09:41:02 +0100 Subject: [PATCH] applications,core,internet,lte: Reduce indent by returning early --- .../model/three-gpp-http-client.cc | 547 ++++++++---------- .../model/three-gpp-http-server.cc | 189 +++--- src/core/model/log.cc | 42 +- .../model/global-route-manager-impl.cc | 303 +++++----- src/lte/model/a3-rsrp-handover-algorithm.cc | 54 +- src/lte/model/fdmt-ff-mac-scheduler.cc | 199 ++++--- src/lte/model/lte-spectrum-phy.cc | 216 ++++--- src/lte/model/lte-ue-phy.cc | 85 +-- src/lte/test/lte-test-ue-measurements.cc | 405 ++++++------- 9 files changed, 1003 insertions(+), 1037 deletions(-) diff --git a/src/applications/model/three-gpp-http-client.cc b/src/applications/model/three-gpp-http-client.cc index 0a7580c32c..b6c0706311 100644 --- a/src/applications/model/three-gpp-http-client.cc +++ b/src/applications/model/three-gpp-http-client.cc @@ -258,19 +258,16 @@ ThreeGppHttpClient::ConnectionSucceededCallback(Ptr 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) 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) + 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); - } + NS_FATAL_ERROR("Invalid state " << GetStateString() << " for OpenConnection()."); + } - const auto ret [[maybe_unused]] = m_socket->Connect(m_peer); - NS_LOG_DEBUG(this << " Connect() return value= " << ret + 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() << "."); - 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. + 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() << "."); - } // end of `if (m_state == {NOT_STARTED, EXPECTING_EMBEDDED_OBJECT, PARSING_MAIN_OBJECT, - // READING})` + 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_FATAL_ERROR("Invalid state " << GetStateString() << " for OpenConnection()."); + 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) - { - 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(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(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 - } + if (m_state != CONNECTING && m_state != READING) + { + NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestMainObject()."); + } + + 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(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(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()); - - const auto requestSize = m_httpVariables->GetRequestSize(); - auto packet = Create(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(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."); - } + NS_FATAL_ERROR("Invalid state " << GetStateString() << " for RequestEmbeddedObject()."); + } + + if (m_embeddedObjectsToBeRequested == 0) + { + NS_LOG_WARN(this << " No embedded object to be requested."); + return; + } + + 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(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(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, const Address& from) { NS_LOG_FUNCTION(this << packet << from); - if (m_state == EXPECTING_MAIN_OBJECT) + 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) { /* - * 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. + * There are more packets of this main object, so just stay still + * and wait until they arrive. */ - Receive(packet); - m_rxMainObjectPacketTrace(packet); + NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)" + << " remains from this chunk of main object."); + return; + } - 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 + /* + * 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()) { - NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ReceiveMainObject()."); + 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)` void @@ -601,75 +580,69 @@ ThreeGppHttpClient::ReceiveEmbeddedObject(Ptr packet, const Address& fro { NS_LOG_FUNCTION(this << packet << from); - if (m_state == EXPECTING_EMBEDDED_OBJECT) + 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) { /* - * 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. + * There are more packets of this embedded object, so just stay + * still and wait until they arrive. */ - Receive(packet); - m_rxEmbeddedObjectPacketTrace(packet); + NS_LOG_INFO(this << " " << m_objectBytesToBeReceived << " byte(s)" + << " remains from this chunk of embedded object"); + return; + } - 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 + /* + * 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()) { - NS_FATAL_ERROR("Invalid state " << GetStateString() << " for ReceiveEmbeddedObject()."); + 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)` 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 diff --git a/src/applications/model/three-gpp-http-server.cc b/src/applications/model/three-gpp-http-server.cc index 4acc21b5f2..4b40327c71 100644 --- a/src/applications/model/three-gpp-http-server.cc +++ b/src/applications/model/three-gpp-http-server.cc @@ -221,76 +221,70 @@ ThreeGppHttpServer::StartApplication() { NS_LOG_FUNCTION(this); - if (m_state == NOT_STARTED) + if (m_state != NOT_STARTED) { - m_httpVariables->Initialize(); - if (!m_initialSocket) + NS_FATAL_ERROR("Invalid state " << GetStateString() << " for StartApplication()."); + } + + m_httpVariables->Initialize(); + if (!m_initialSocket) + { + // Find the current default MTU value of TCP sockets. + Ptr previousSocketMtu; + const TypeId tcpSocketTid = TcpSocket::GetTypeId(); + for (uint32_t i = 0; i < tcpSocketTid.GetAttributeN(); i++) { - // Find the current default MTU value of TCP sockets. - Ptr 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") { - TypeId::AttributeInformation attrInfo = tcpSocketTid.GetAttribute(i); - if (attrInfo.name == "SegmentSize") - { - previousSocketMtu = attrInfo.initialValue; - } + 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"); - } + // Creating a TCP socket to connect to the server. + m_initialSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId()); + m_initialSocket->SetAttribute("SegmentSize", UintegerValue(m_mtuSize)); - 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 - { - NS_FATAL_ERROR("Invalid state " << GetStateString() << " for StartApplication()."); - } + 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, 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, uint32_t availableBufferSize)` void diff --git a/src/core/model/log.cc b/src/core/model/log.cc index 41b427065b..ae9c29c7f7 100644 --- a/src/core/model/log.cc +++ b/src/core/model/log.cc @@ -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 diff --git a/src/internet/model/global-route-manager-impl.cc b/src/internet/model/global-route-manager-impl.cc index 3b86dc48e0..36e197be39 100644 --- a/src/internet/model/global-route-manager-impl.cc +++ b/src/internet/model/global-route-manager-impl.cc @@ -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 = node->GetObject(); - NS_ASSERT_MSG(ipv4, - "GlobalRouteManagerImpl::SPFIntraAddRouter (): " - "QI for 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 - // (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 has an m_rootOif (outbound interface index) to - // which the packets should be send for forwarding. - // - Ptr router = node->GetObject(); - 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 = node->GetObject(); + NS_ASSERT_MSG(ipv4, + "GlobalRouteManagerImpl::SPFIntraAddRouter (): " + "QI for 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 + // (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 has an m_rootOif (outbound interface index) to + // which the packets should be send for forwarding. + // + Ptr router = node->GetObject(); + if (!router) + { + continue; + } + Ptr 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 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) + { + continue; + } + + 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 = node->GetObject(); + NS_ASSERT_MSG(ipv4, + "GlobalRouteManagerImpl::SPFIntraAddRouter (): " + "GetObject for 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 . + // + 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) { - 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 = node->GetObject(); - NS_ASSERT_MSG(ipv4, - "GlobalRouteManagerImpl::SPFIntraAddRouter (): " - "GetObject for interface failed"); + // We are only concerned about point-to-point links // - // 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(); + GlobalRoutingLinkRecord* lr = lsa->GetLinkRecord(j); + if (lr->GetLinkType() != GlobalRoutingLinkRecord::PointToPoint) + { + continue; + } // - // 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 . + // 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 + // (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 has an m_rootOif (outbound interface index) to + // which the packets should be send for forwarding. // - 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) + Ptr router = node->GetObject(); + if (!router) { - // - // We are only concerned about point-to-point links - // - GlobalRoutingLinkRecord* lr = lsa->GetLinkRecord(j); - if (lr->GetLinkType() != GlobalRoutingLinkRecord::PointToPoint) + continue; + } + Ptr 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) { - continue; + 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); } - // - // 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 - // (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 has an m_rootOif (outbound interface index) to - // which the packets should be send for forwarding. - // - Ptr router = node->GetObject(); - if (!router) + else { - continue; + 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); } - Ptr 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; + } // for all routes from the root the vertex 'v' } + // + // Done adding the routes for the selected node. + // + return; } } diff --git a/src/lte/model/a3-rsrp-handover-algorithm.cc b/src/lte/model/a3-rsrp-handover-algorithm.cc index 1ae8391c5f..e33cafe6fa 100644 --- a/src/lte/model/a3-rsrp-handover-algorithm.cc +++ b/src/lte/model/a3-rsrp-handover-algorithm.cc @@ -119,45 +119,43 @@ A3RsrpHandoverAlgorithm::DoReportUeMeas(uint16_t rnti, LteRrcSap::MeasResults me return; } - if (measResults.haveMeasResultNeighCells && !measResults.measResultListEutra.empty()) + if (!measResults.haveMeasResultNeighCells || measResults.measResultListEutra.empty()) { - uint16_t bestNeighbourCellId = 0; - uint8_t bestNeighbourRsrp = 0; + NS_LOG_WARN( + this << " Event A3 received without measurement results from neighbouring cells"); + return; + } - for (auto it = measResults.measResultListEutra.begin(); - it != measResults.measResultListEutra.end(); - ++it) + uint16_t bestNeighbourCellId = 0; + uint8_t bestNeighbourRsrp = 0; + + for (auto it = measResults.measResultListEutra.begin(); + it != measResults.measResultListEutra.end(); + ++it) + { + if (it->haveRsrpResult) { - if (it->haveRsrpResult) - { - if ((bestNeighbourRsrp < it->rsrpResult) && IsValidNeighbour(it->physCellId)) - { - bestNeighbourCellId = it->physCellId; - bestNeighbourRsrp = it->rsrpResult; - } - } - else + if ((bestNeighbourRsrp < it->rsrpResult) && IsValidNeighbour(it->physCellId)) { - NS_LOG_WARN("RSRP measurement is missing from cell ID " << it->physCellId); + bestNeighbourCellId = it->physCellId; + bestNeighbourRsrp = it->rsrpResult; } } - - if (bestNeighbourCellId > 0) + else { - 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); + NS_LOG_WARN("RSRP measurement is missing from cell ID " << it->physCellId); } } - else + + if (bestNeighbourCellId > 0) { - NS_LOG_WARN( - this << " Event A3 received without measurement results from neighbouring cells"); - } + 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 diff --git a/src/lte/model/fdmt-ff-mac-scheduler.cc b/src/lte/model/fdmt-ff-mac-scheduler.cc index e997955125..a97b1b760d 100644 --- a/src/lte/model/fdmt-ff-mac-scheduler.cc +++ b/src/lte/model/fdmt-ff-mac-scheduler.cc @@ -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++) - { - 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()) - { - 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; - } + continue; + } - auto itCqi = m_a30CqiRxed.find(*it); - auto itTxMode = m_uesTxMode.find(*it); - if (itTxMode == m_uesTxMode.end()) - { - NS_FATAL_ERROR("No Transmission Mode info on user " << (*it)); - } - auto nLayer = TransmissionModesLayers::TxMode2LayerNum((*itTxMode).second); - std::vector sbCqi; - if (itCqi == m_a30CqiRxed.end()) - { - sbCqi = std::vector(nLayer, 1); // start with lowest value - } - else + 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)) + { + // UE already allocated for HARQ or without HARQ process available -> drop it + if (itRnti != rntiAllocated.end()) { - sbCqi = (*itCqi).second.m_higherLayerSelected.at(i).m_sbCqi; + NS_LOG_DEBUG(this << " RNTI discarded for HARQ tx" << (uint16_t)(*it)); } - uint8_t cqi1 = sbCqi.at(0); - uint8_t cqi2 = 0; - if (sbCqi.size() > 1) + if (!HarqProcessAvailability(*it)) { - cqi2 = sbCqi.at(1); + NS_LOG_DEBUG(this << " RNTI discarded for HARQ id" << (uint16_t)(*it)); } - if ((cqi1 > 0) || - (cqi2 > 0)) // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213) + continue; + } + + auto itCqi = m_a30CqiRxed.find(*it); + auto itTxMode = m_uesTxMode.find(*it); + if (itTxMode == m_uesTxMode.end()) + { + NS_FATAL_ERROR("No Transmission Mode info on user " << (*it)); + } + auto nLayer = TransmissionModesLayers::TxMode2LayerNum((*itTxMode).second); + std::vector sbCqi; + if (itCqi == m_a30CqiRxed.end()) + { + sbCqi = std::vector(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) { - 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++) { - // 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) { - 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 + mcs = m_amc->GetMcsFromCqi(sbCqi.at(k)); } - - double rcqi = achievableRate; - NS_LOG_INFO(this << " RNTI " << (*it) << " MCS " << (uint32_t)mcs - << " achievableRate " << achievableRate << " RCQI " - << rcqi); - - if (rcqi > rcqiMax) + else { - rcqiMax = rcqi; - itMax = it; + // no info on this subband -> worst MCS + mcs = 0; } + achievableRate += ((m_amc->GetDlTbSizeFromMcs(mcs, rbgSize) / 8) / + 0.001); // = TB size / TTI } - } // end if cqi - } // end for m_rlcBufferReq + 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()) + 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()) { - // no UE available for this RB - NS_LOG_INFO(this << " any UE found"); + // insert new element + std::vector tempMap; + tempMap.push_back(i); + allocationMap[*itMax] = tempMap; } else { - rbgMap.at(i) = true; - auto itMap = allocationMap.find(*itMax); - if (itMap == allocationMap.end()) - { - // insert new element - std::vector tempMap; - tempMap.push_back(i); - allocationMap[*itMax] = tempMap; - } - else - { - (*itMap).second.push_back(i); - } - NS_LOG_INFO(this << " UE assigned " << (*itMax)); + (*itMap).second.push_back(i); } - } // end for RBG free - } // end for RBGs + 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 diff --git a/src/lte/model/lte-spectrum-phy.cc b/src/lte/model/lte-spectrum-phy.cc index 0566c77b4e..b53511b12f 100644 --- a/src/lte/model/lte-spectrum-phy.cc +++ b/src/lte/model/lte-spectrum-phy.cc @@ -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) + continue; + } + + if (!(*itTb).second.corrupt) + { + m_phyRxEndOkTrace(*j); + + if (!m_ltePhyRxDataEndOkCallback.IsNull()) { - m_phyRxEndOkTrace(*j); + m_ltePhyRxDataEndOkCallback(*j); + } + } + else + { + // TB received with errors + m_phyRxEndErrorTrace(*j); + } - if (!m_ltePhyRxDataEndOkCallback.IsNull()) - { - m_ltePhyRxDataEndOkCallback(*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(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(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 } } diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index f2a9c6a9f6..c45308d53b 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -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; + } + + // measure instantaneous RSRQ now + NS_ASSERT_MSG(m_rsInterferencePowerUpdated, " RS interference power info obsolete"); - auto itPss = m_pssList.begin(); - while (itPss != m_pssList.end()) + 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; - - auto itIntN = m_rsInterferencePower.ConstValuesBegin(); - auto itPj = m_rsReceivedPower.ConstValuesBegin(); - for (itPj = m_rsReceivedPower.ConstValuesBegin(); - itPj != m_rsReceivedPower.ConstValuesEnd(); - itIntN++, itPj++) - { - 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); + 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); - NS_ASSERT(rbNum == (*itPss).nRB); - double rsrq_dB = 10 * log10((*itPss).pssPsdSum / rssiSum); + NS_ASSERT(rbNum == (*itPss).nRB); + double rsrq_dB = 10 * log10((*itPss).pssPsdSum / rssiSum); - if (rsrq_dB > m_pssReceptionThreshold) + 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()) { - 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"); - } + (*itMeasMap).second.rsrqSum += rsrq_dB; + (*itMeasMap).second.rsrqNum++; } + else + { + NS_LOG_WARN("race condition of bug 2091 occurred"); + } + } - itPss++; - - } // end of while (itPss != m_pssList.end ()) + itPss++; - m_pssList.clear(); + } // end of while (itPss != m_pssList.end ()) - } // end of if (m_pssReceived) + m_pssList.clear(); } // end of void LteUePhy::GenerateCtrlCqiReport (const SpectrumValue& sinr) diff --git a/src/lte/test/lte-test-ue-measurements.cc b/src/lte/test/lte-test-ue-measurements.cc index 8260b17a2e..1b57939ce6 100644 --- a/src/lte/test/lte-test-ue-measurements.cc +++ b/src/lte/test/lte-test-ue-measurements.cc @@ -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)"); - - // 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)"); - - } // end of else of if (measResults.measResultListEutra.size () == 0) + return; + } - // verifying the report timing - bool hasEnded = m_itExpectedTime == m_expectedTime.end(); - NS_TEST_ASSERT_MSG_EQ(hasEnded, + // 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)"); + + // 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); - - // using milliseconds to avoid floating-point comparison - uint64_t timeNowMs = Simulator::Now().GetMilliSeconds(); - uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds(); - m_itExpectedTime++; + "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)"); + + } // 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, + false, + "Reporting should not have occurred at " << Simulator::Now().As(Time::S)); + if (hasEnded) + { + return; + } - uint16_t observedRsrp = measResults.measResultPCell.rsrpResult; - uint16_t referenceRsrp = *m_itExpectedRsrp; - m_itExpectedRsrp++; + hasEnded = m_itExpectedRsrp == m_expectedRsrp.end(); + NS_ASSERT(!hasEnded); - 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"); + // using milliseconds to avoid floating-point comparison + uint64_t timeNowMs = Simulator::Now().GetMilliSeconds(); + uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds(); + m_itExpectedTime++; - } // end of if (!hasEnded) + uint16_t observedRsrp = measResults.measResultPCell.rsrpResult; + uint16_t referenceRsrp = *m_itExpectedRsrp; + m_itExpectedRsrp++; - } // end of if (report.measResults.measId == m_expectedMeasId) + 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()) + // 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)"); + + // 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_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells, + NS_ASSERT(it.physCellId == 2 || it.physCellId == 3); + NS_TEST_ASSERT_MSG_EQ(it.haveCgiInfo, false, - "Unexpected report content"); - } - else - { - NS_TEST_ASSERT_MSG_EQ(measResults.haveMeasResultNeighCells, + "Report contains cgi-info, which is not supported"); + NS_TEST_ASSERT_MSG_EQ(it.haveRsrpResult, 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)"); - } - - } // 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, - false, - "Reporting should not have occurred at " - << Simulator::Now().GetSeconds() << "s"); - if (!hasEnded) - { - // using milliseconds to avoid floating-point comparison - uint64_t timeNowMs = Simulator::Now().GetMilliSeconds(); - uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds(); - m_itExpectedTime++; + "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; + } + + // 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) + 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)"); - - // 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)"); - - } // end of else of if (measResults.measResultListEutra.size () == 0) + return; + } - // verifying the report timing - bool hasEnded = m_itExpectedTime == m_expectedTime.end(); - NS_TEST_ASSERT_MSG_EQ(hasEnded, + // 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)"); + + // 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); - - // using milliseconds to avoid floating-point comparison - uint64_t timeNowMs = Simulator::Now().GetMilliSeconds(); - uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds(); - m_itExpectedTime++; - - 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 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()); + 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)"); + + } // 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, + false, + "Reporting should not have occurred at " << Simulator::Now().As(Time::S)); + if (hasEnded) + { + return; + } - } // end of if (report.measResults.measId == correctMeasId) + hasEnded = m_itExpectedRsrp == m_expectedRsrp.end(); + NS_ASSERT(!hasEnded); + + // using milliseconds to avoid floating-point comparison + uint64_t timeNowMs = Simulator::Now().GetMilliSeconds(); + uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds(); + m_itExpectedTime++; + + 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