21 #include <ns3/fatal-error.h>
23 #include <ns3/object-map.h>
24 #include <ns3/object-factory.h>
25 #include <ns3/node-list.h>
27 #include <ns3/simulator.h>
98 "IDLE_CELL_SELECTION",
99 "IDLE_WAIT_SYSTEM_INFO",
100 "IDLE_CAMPED_NORMALLY",
101 "IDLE_RANDOM_ACCESS",
103 "CONNECTED_NORMALLY",
104 "CONNECTED_REESTABLISHING",
122 : m_cphySapProvider (0),
123 m_cmacSapProvider (0),
125 m_macSapProvider (0),
127 m_state (IDLE_CELL_SELECTION),
132 m_connectionPending (0),
168 .AddConstructor<LteUeRrc> ()
169 .AddAttribute (
"DataRadioBearerMap",
"List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
172 MakeObjectMapChecker<LteDataRadioBearerInfo> ())
173 .AddAttribute (
"Srb0",
"SignalingRadioBearerInfo for SRB0",
176 MakePointerChecker<LteSignalingRadioBearerInfo> ())
177 .AddAttribute (
"Srb1",
"SignalingRadioBearerInfo for SRB1",
180 MakePointerChecker<LteSignalingRadioBearerInfo> ())
181 .AddAttribute (
"CellId",
182 "Serving cell identifier",
185 MakeUintegerChecker<uint16_t> ())
186 .AddAttribute (
"C-RNTI",
187 "Cell Radio Network Temporary Identifier",
190 MakeUintegerChecker<uint16_t> ())
191 .AddTraceSource (
"StateTransition",
192 "trace fired upon every UE RRC state transition",
194 .AddTraceSource (
"RandomAccessSuccessful",
195 "trace fired upon successful completion of the random access procedure",
197 .AddTraceSource (
"ConnectionEstablished",
198 "trace fired upon successful RRC connection establishment",
200 .AddTraceSource (
"ConnectionReconfiguration",
201 "trace fired upon RRC connection reconfiguration",
203 .AddTraceSource (
"HandoverStart",
204 "trace fired upon start of a handover procedure",
206 .AddTraceSource (
"HandoverEndOk",
207 "trace fired upon successful termination of a handover procedure",
354 Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
359 m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
387 std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it =
m_drbMap.find (drbid);
393 params.lcid = it->second->m_logicalChannelIdentity;
395 NS_LOG_LOGIC (
this <<
" RNTI=" <<
m_rnti <<
" sending " << packet <<
"on DRBID " << (uint32_t) drbid <<
" (LCID" << params.lcid <<
")" <<
" (" << packet->
GetSize () <<
" bytes)");
396 it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
412 NS_LOG_INFO (
"aborting connection setup procedure");
555 NS_LOG_LOGIC (
this <<
" CellId " << newMeasIt->m_cellId <<
" RSRP " << newMeasIt->m_rsrp <<
" RSRQ " << newMeasIt->m_rsrq);
558 std::map<uint16_t, MeasValues>::iterator storedMeasIt =
m_storedMeasValues.find (newMeasIt->m_cellId);
563 v.
rsrp = newMeasIt->m_rsrp;
564 v.
rsrq = newMeasIt->m_rsrq;
565 std::pair<uint16_t, MeasValues> val (newMeasIt->m_cellId, v);
566 std::pair<std::map<uint16_t, MeasValues>::iterator,
bool>
568 NS_ASSERT_MSG (ret.second ==
true,
"element already existed");
569 storedMeasIt = ret.first;
584 for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
589 NS_ASSERT (measIdIt->first == measIdIt->second.measId);
590 uint8_t measId = measIdIt->first;
591 NS_LOG_LOGIC (
this <<
" considering measId " << (uint32_t) measId);
593 std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
598 std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
603 std::map<uint8_t, VarMeasReport>::iterator
610 "only triggerType == event is supported");
613 bool eventEntryCondApplicable =
false;
614 bool eventLeavingCondApplicable =
false;
616 std::list<uint16_t> concernedCellsEntry;
617 std::list<uint16_t> concernedCellsLeaving;
619 switch (reportConfigEutra.eventId)
625 double hys = (double) reportConfigEutra.hysteresis * 0.5;
626 switch (reportConfigEutra.triggerQuantity)
631 NS_ASSERT (reportConfigEutra.threshold1.choice
638 NS_ASSERT (reportConfigEutra.threshold1.choice
647 bool entryCond = ms + hys < thresh;
648 if (entryCond ==
true
651 && (measReportIt->second.cellsTriggeredList.find (
m_cellId)
652 == measReportIt->second.cellsTriggeredList.end ()))))
654 concernedCellsEntry.push_back (
m_cellId);
655 eventEntryCondApplicable =
true;
658 bool leavingCond = ms - hys > thresh;
661 && (measReportIt->second.cellsTriggeredList.find (
m_cellId)
662 != measReportIt->second.cellsTriggeredList.end ()))
664 concernedCellsLeaving.push_back (
m_cellId);
665 eventLeavingCondApplicable =
true;
667 NS_LOG_LOGIC (
"event A2: serving cell " <<
m_cellId <<
" ms=" << ms <<
" thresh=" << thresh <<
" entryCond=" << entryCond <<
" leavingCond=" << leavingCond);
673 for (std::map<uint16_t, MeasValues>::iterator storedMeasIt =
m_storedMeasValues.begin ();
677 uint16_t cellId = storedMeasIt->first;
682 double hys = (double) reportConfigEutra.hysteresis * 0.5;
683 switch (reportConfigEutra.triggerQuantity)
686 mn = storedMeasIt->second.rsrp;
688 NS_ASSERT (reportConfigEutra.threshold1.choice
693 mn = storedMeasIt->second.rsrq;
695 NS_ASSERT (reportConfigEutra.threshold1.choice
704 bool entryCond = mn + measObjectEutra.offsetFreq + 0.0 - hys > thresh;
705 if (entryCond ==
true
708 && (measReportIt->second.cellsTriggeredList.find (cellId)
709 == measReportIt->second.cellsTriggeredList.end ()))))
711 concernedCellsEntry.push_back (cellId);
712 eventEntryCondApplicable =
true;
715 bool leavingCond = mn + measObjectEutra.offsetFreq + 0.0 + hys < thresh;
718 && (measReportIt->second.cellsTriggeredList.find (cellId)
719 != measReportIt->second.cellsTriggeredList.end ()))
721 concernedCellsLeaving.push_back (cellId);
722 eventLeavingCondApplicable =
true;
725 NS_LOG_LOGIC (
"event A4: neighbor cell " << cellId <<
" mn=" << mn <<
" thresh=" << thresh <<
" entryCond=" << entryCond <<
" leavingCond=" << leavingCond);
732 NS_FATAL_ERROR (
"unsupported eventId " << reportConfigEutra.eventId);
737 NS_LOG_LOGIC (
"eventEntryCondApplicable=" << eventEntryCondApplicable
738 <<
" eventLeavingCondApplicable=" << eventLeavingCondApplicable);
740 bool initiateUeMeasurementReportingProcedure =
false;
742 if (eventEntryCondApplicable)
748 std::pair<uint8_t, VarMeasReport> val (measId, r);
749 std::pair<std::map<uint8_t, VarMeasReport>::iterator,
bool>
751 NS_ASSERT_MSG (ret.second ==
true,
"element already existed");
752 measReportIt = ret.first;
754 for (std::list<uint16_t>::iterator it = concernedCellsEntry.begin ();
755 it != concernedCellsEntry.end ();
758 measReportIt->second.cellsTriggeredList.insert (*it);
760 measReportIt->second.numberOfReportsSent = 0;
761 initiateUeMeasurementReportingProcedure =
true;
764 if (eventLeavingCondApplicable)
767 for (std::list<uint16_t>::iterator it = concernedCellsLeaving.begin ();
768 it != concernedCellsLeaving.end ();
771 measReportIt->second.cellsTriggeredList.erase (*it);
777 if (reportConfigEutra.reportOnLeave)
779 initiateUeMeasurementReportingProcedure =
true;
784 if (initiateUeMeasurementReportingProcedure)
790 && (measReportIt->second.cellsTriggeredList.empty ()))
792 measReportIt->second.periodicReportTimer.Cancel ();
1006 std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.
srbToAddModList.begin ();
1014 NS_ASSERT_MSG (stamIt->srbIdentity == 1,
"only SRB1 supported");
1016 const uint8_t lcid = 1;
1030 m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1041 lcConfig.
priority = stamIt->logicalChannelConfig.priority;
1058 NS_LOG_INFO (
"request to modify SRB1 (skipping as currently not implemented)");
1064 std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1069 NS_LOG_INFO (
this <<
" IMSI " <<
m_imsi <<
" adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity <<
" LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1070 NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2,
"LCID value " << dtamIt->logicalChannelIdentity <<
" is reserved for SRBs");
1072 std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt =
m_drbMap.find (dtamIt->drbIdentity);
1084 switch (dtamIt->rlcConfig.choice)
1105 rlc->
SetLcId (dtamIt->logicalChannelIdentity);
1108 drbInfo->
m_rlc = rlc;
1119 pdcp->
SetLcId (dtamIt->logicalChannelIdentity);
1132 lcConfig.
priority = dtamIt->logicalChannelConfig.priority;
1150 std::list<uint8_t>::iterator dtdmIt;
1155 uint8_t drbid = *dtdmIt;
1156 NS_LOG_INFO (
this <<
" IMSI " <<
m_imsi <<
" releasing DRB " << (uint32_t) drbid << drbid);
1157 std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it =
m_drbMap.find (drbid);
1177 uint8_t measObjectId = *it;
1178 NS_LOG_LOGIC (
this <<
" deleting measObjectId " << (uint32_t) measObjectId);
1183 if (measIdIt->second.measObjectId == measObjectId)
1185 uint8_t measId = measIdIt->second.measId;
1187 NS_LOG_LOGIC (
this <<
" deleting measId " << (uint32_t) measId <<
" because referring to measObjectId " << (uint32_t) measObjectId);
1190 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (measId);
1193 NS_LOG_LOGIC (
this <<
" deleting existing report for measId " << (uint32_t) measId <<
" because referring to measObjectId " << (uint32_t) measObjectId);
1194 measReportIt->second.periodicReportTimer.Cancel ();
1212 NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (),
"cellsToRemoveList not supported");
1213 NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (),
"cellsToAddModList not supported");
1214 NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (),
"blackCellsToRemoveList not supported");
1215 NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (),
"blackCellsToAddModList not supported");
1216 NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI ==
false ,
"cellForWhichToReportCGI is not supported");
1219 uint8_t measObjectId = it->measObjectId;
1223 NS_LOG_LOGIC (
"measObjectId " << (uint32_t) measObjectId <<
" exists, updating entry");
1224 measObjectIt->second = *it;
1225 for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1230 if (measIdIt->second.measObjectId == measObjectId)
1232 uint8_t measId = measIdIt->second.measId;
1233 NS_LOG_LOGIC (
this <<
" found measId " << (uint32_t) measId <<
" referring to measObjectId " << (uint32_t) measObjectId);
1234 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (measId);
1237 NS_LOG_LOGIC (
this <<
" deleting existing report for measId " << (uint32_t) measId <<
" because referring to measObjectId " << (uint32_t) measObjectId);
1238 measReportIt->second.periodicReportTimer.Cancel ();
1246 NS_LOG_LOGIC (
"measObjectId " << (uint32_t) measObjectId <<
" is new, adding entry");
1256 uint8_t reportConfigId = *it;
1257 NS_LOG_LOGIC (
this <<
" deleting reportConfigId " << (uint32_t) reportConfigId);
1262 if (measIdIt->second.reportConfigId == reportConfigId)
1264 uint8_t measId = measIdIt->second.measId;
1266 NS_LOG_LOGIC (
this <<
" deleting measId " << (uint32_t) measId <<
" because referring to reportConfigId " << (uint32_t) reportConfigId);
1269 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (measId);
1272 NS_LOG_LOGIC (
this <<
" deleting existing report for measId" << (uint32_t) measId <<
" because referring to reportConfigId " << (uint32_t) reportConfigId);
1273 measReportIt->second.periodicReportTimer.Cancel ();
1292 "only trigger type EVENT is supported");
1295 "only events A2 and A4 are supported");
1296 NS_ASSERT_MSG (it->reportConfigEutra.timeToTrigger == 0,
"timeToTrigger > 0 is not supported");
1298 uint8_t reportConfigId = it->reportConfigId;
1302 NS_LOG_LOGIC (
"reportConfigId " << (uint32_t) reportConfigId <<
" exists, updating entry");
1304 for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1309 if (measIdIt->second.reportConfigId == reportConfigId)
1311 uint8_t measId = measIdIt->second.measId;
1312 NS_LOG_LOGIC (
this <<
" found measId " << (uint32_t) measId <<
" referring to reportConfigId " << (uint32_t) reportConfigId);
1313 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (measId);
1316 NS_LOG_LOGIC (
this <<
" deleting existing report for measId " << (uint32_t) measId <<
" because referring to reportConfigId " << (uint32_t) reportConfigId);
1317 measReportIt->second.periodicReportTimer.Cancel ();
1325 NS_LOG_LOGIC (
"reportConfigId " << (uint32_t) reportConfigId <<
" is new, adding entry");
1339 uint8_t measId = measIdIt->second.measId;
1341 NS_LOG_LOGIC (
this <<
" deleting measId " << (uint32_t) measId);
1344 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (measId);
1347 NS_LOG_LOGIC (
this <<
" deleting existing report for measId" << (uint32_t) measId);
1348 measReportIt->second.periodicReportTimer.Cancel ();
1366 uint8_t measId = *it;
1367 NS_LOG_LOGIC (
this <<
" deleting measId " << (uint32_t) measId);
1369 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (measId);
1372 NS_LOG_LOGIC (
this <<
" deleting existing report for measId" << (uint32_t) measId);
1373 measReportIt->second.periodicReportTimer.Cancel ();
1379 for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.
measIdToAddModList.begin ();
1383 NS_LOG_LOGIC (
this <<
" measId " << (uint32_t) it->measId <<
" (measObjectId="
1384 << (uint32_t) it->measObjectId <<
", reportConfigId=" << (uint32_t) it->reportConfigId <<
")");
1390 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (it->measId);
1393 measReportIt->second.periodicReportTimer.Cancel ();
1423 std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
1427 std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1434 measResults.
measId = measId;
1441 "RSRP " << (uint32_t) measResults.
rsrpResult <<
" (" << servingMeasIt->second.rsrp <<
" dBm) "
1442 "RSRQ " << (uint32_t) measResults.
rsrqResult <<
" (" << servingMeasIt->second.rsrq <<
" dB)");
1444 std::map<uint8_t, VarMeasReport>::iterator measReportIt =
m_varMeasReportList.find (measId);
1447 NS_LOG_ERROR (
"no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
1451 if (!(measReportIt->second.cellsTriggeredList.empty ()))
1455 std::multimap<double, uint16_t> sortedNeighCells;
1456 for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
1457 cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
1460 uint16_t cellId = *cellsTriggeredIt;
1463 std::map<uint16_t, MeasValues>::iterator neighborMeasIt =
m_storedMeasValues.find (cellId);
1464 double triggerValue;
1465 switch (reportConfigEutra.triggerQuantity)
1468 triggerValue = neighborMeasIt->second.rsrp;
1471 triggerValue = neighborMeasIt->second.rsrq;
1477 sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
1481 std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
1483 for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
1484 sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
1485 ++sortedNeighCellsIt, ++count)
1487 uint16_t cellId = sortedNeighCellsIt->second;
1488 std::map<uint16_t, MeasValues>::iterator neighborMeasIt =
m_storedMeasValues.find (cellId);
1492 measResultEutra.haveCgiInfo =
false;
1493 measResultEutra.haveRsrpResult =
true;
1495 measResultEutra.haveRsrqResult =
true;
1497 NS_LOG_INFO (
this <<
" reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
1498 <<
" RSRP " << (uint32_t) measResultEutra.rsrpResult
1499 <<
" (" << neighborMeasIt->second.rsrp <<
" dBm) "
1500 <<
" RSRQ " << (uint32_t) measResultEutra.rsrqResult
1501 <<
" (" << neighborMeasIt->second.rsrq <<
" dB)");
1507 NS_LOG_WARN (
this <<
" cellsTriggeredList is empty");
1509 measReportIt->second.numberOfReportsSent++;
1510 measReportIt->second.periodicReportTimer.Cancel ();
1515 uint32_t intervalMs;
1516 switch (reportConfigEutra.reportInterval)
1526 measReportIt->second.periodicReportTimer
1551 std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
1572 std::map<uint8_t, uint8_t>::iterator it =
m_bid2DrbidMap.find (bid);