--- a/src/lte/doc/Makefile Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/doc/Makefile Thu Dec 13 12:22:43 2012 +0100
@@ -1,6 +1,7 @@
EPSTOPDF = epstopdf
DIA = dia
SEQDIAG = seqdiag
+DOT = dot
CONVERT = convert -density 250
@@ -10,6 +11,7 @@
# specify dia figures from which .png and .pdf figures need to be built
IMAGES_DIA = \
+ $(FIGURES)/epc-ctrl-arch.dia \
$(FIGURES)/epc-data-flow-dl.dia \
$(FIGURES)/epc-data-flow-ul.dia \
$(FIGURES)/epc-profiling-scenario.dia \
@@ -18,8 +20,10 @@
$(FIGURES)/eutran-profiling-scenario.dia \
$(FIGURES)/ff-example.dia \
$(FIGURES)/ff-mac-saps.dia \
- $(FIGURES)/lte-arch-enb.dia \
- $(FIGURES)/lte-arch-ue.dia \
+ $(FIGURES)/lte-arch-enb-data.dia \
+ $(FIGURES)/lte-arch-enb-ctrl.dia \
+ $(FIGURES)/lte-arch-ue-data.dia \
+ $(FIGURES)/lte-arch-ue-ctrl.dia \
$(FIGURES)/lte-enb-phy.dia \
$(FIGURES)/lte-ue-phy.dia \
$(FIGURES)/lte-epc-e2e-data-protocol-stack.dia \
@@ -55,28 +59,41 @@
# rescale pdf figures as necessary
$(FIGURES)/lte-interference-test-scenario.pdf_width = 3in
+$(FIGURES)/epc-ctrl-arch.pdf_width = 8cm
$(FIGURES)/epc-topology.pdf_width = 4in
$(FIGURES)/epc-topology-x2-enhanced.pdf_width = 14cm
$(FIGURES)/lte-arch-data-rrc-pdcp-rlc.pdf_width = 3in
$(FIGURES)/lte-epc-e2e-data-protocol-stack.pdf_width = 15cm
$(FIGURES)/ff-mac-saps.pdf_width = 5in
$(FIGURES)/ff-example.pdf_width = 5in
+$(FIGURES)/lte-arch-enb-data.pdf_width = 6cm
+$(FIGURES)/lte-arch-enb-ctrl.pdf_width = 10cm
+$(FIGURES)/lte-arch-ue-data.pdf_width = 6cm
+$(FIGURES)/lte-arch-ue-ctrl.pdf_width = 10cm
$(FIGURES)/lte-rlc-implementation-model.pdf_width = 20in
$(FIGURES)/lte-rlc-data-txon-dl.pdf_width = 10cm
$(FIGURES)/lte-rlc-data-txon-ul.pdf_width = 10cm
$(FIGURES)/lte-rlc-data-retx-ul.pdf_width = 10cm
$(FIGURES)/lte-phy-interference.pdf_width = 12cm
$(FIGURES)/lte-subframe-structure.pdf_width = 2in
-
+$(FIGURES)/mac-random-access-contention.pdf_width = 10cm
+$(FIGURES)/mac-random-access-noncontention.pdf_width = 15cm
+$(FIGURES)/lte-ue-rrc-states.pdf_width = 7cm
+$(FIGURES)/helpers.pdf_width = 8cm
IMAGES_SEQDIAG = \
$(FIGURES)/lte-phy-interference.seqdiag \
$(FIGURES)/helpers.seqdiag \
+ $(FIGURES)/mac-random-access-contention.seqdiag \
+ $(FIGURES)/mac-random-access-noncontention.seqdiag \
$(FIGURES)/rrc-connection-establishment.seqdiag \
$(FIGURES)/rrc-connection-reconfiguration.seqdiag \
$(FIGURES)/rrc-connection-reconfiguration-handover.seqdiag \
- $(FIGURES)/nas-attach.seqdiag \
- $(FIGURES)/nas-activate-dedicated-bearer.seqdiag \
+ $(FIGURES)/nas-attach.seqdiag
+
+IMAGES_DOT = \
+ $(FIGURES)/lte-enb-rrc-states.dot \
+ $(FIGURES)/lte-ue-rrc-states.dot
IMAGES_NOBUILD = $(FIGURES)/fading_pedestrian.png \
$(FIGURES)/fading_vehicular.png \
@@ -113,7 +130,10 @@
$(FIGURES)/miesm_scheme.pdf \
$(FIGURES)/miesm_scheme.png \
${IMAGES_SEQDIAG:.seqdiag=.png} \
- ${IMAGES_SEQDIAG:.seqdiag=.pdf}
+ ${IMAGES_SEQDIAG:.seqdiag=.pdf} \
+ ${IMAGES_DOT:.dot=.png} \
+ ${IMAGES_DOT:.dot=.pdf} \
+
IMAGES_BUILD = \
${IMAGES_DIA:.dia=.eps} \
@@ -129,10 +149,14 @@
%.eps : %.dia; $(DIA) -t eps $< -e $@
%.png : %.dia; $(DIA) -t png $< -e $@
%.png : %.seqdiag; $(SEQDIAG) -Tpng --no-transparency -o $@ $<
+%.png : %.dot; $(DOT) -Tpng -o$@ $<
%.png : %.eps; $(CONVERT) $< $@
%.pdf : %.seqdiag
$(SEQDIAG) -Tpdf -o $@ $<
if test x$($@_width) != x; then ./rescale-pdf.sh $($@_width) $@ ; fi
+%.pdf : %.dot
+ $(DOT) -Tpdf -o $@ $<
+ if test x$($@_width) != x; then ./rescale-pdf.sh $($@_width) $@ ; fi
%.pdf : %.eps
$(EPSTOPDF) $< -o=$@
if test x$($@_width) != x; ./rescale-pdf.sh $($@_width) $@ ; fi
@@ -179,6 +203,9 @@
-rm -rf $(BUILDDIR)/*
-rm -f $(IMAGES_BUILD)
+
+images: $(IMAGES_NOBUILD) $(IMAGES_BUILD)
+
frag: pickle
@if test ! -d $(BUILDDIR)/frag; then mkdir $(BUILDDIR)/frag; fi
pushd $(BUILDDIR)/frag && ../../pickle-to-xml.py ../pickle/index.fpickle > navigation.xml && popd
--- a/src/lte/doc/source/conf.py Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/doc/source/conf.py Thu Dec 13 12:22:43 2012 +0100
@@ -50,7 +50,7 @@
# The short X.Y version.
version = 'lena-dev'
# The full version, including alpha/beta/rc tags.
-release = 'lena-dev'
+release = 'M5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Binary file src/lte/doc/source/figures/epc-ctrl-arch.dia has changed
Binary file src/lte/doc/source/figures/epc-topology.dia has changed
Binary file src/lte/doc/source/figures/helpers.pdf has changed
Binary file src/lte/doc/source/figures/helpers.png has changed
--- a/src/lte/doc/source/figures/helpers.seqdiag Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/doc/source/figures/helpers.seqdiag Thu Dec 13 12:22:43 2012 +0100
@@ -2,26 +2,23 @@
diagram {
-LteHelper => EpcHelper [label="AddEnb"] {
- EpcHelper -> EpcHelper [label="create EpcEnbApplication"];
- EpcHelper -> EpcHelper [label="Setup S1 link"];
- EpcHelper => EpcSgwPgwApplication [label="AddEnb (enbIpv4Address)"];
-}
-
-
-LteHelper => LteUeRrc [label="GetRnti", return="RNTI"]
-LteHelper => LteEnbRrc [label="SetupRadioBearer", return="LCID"]
+SimProgram; LteHelper; EpcHelper;
-LteHelper => EpcHelper [label="ActivateEpsBearer(UE IP, eNB IP, TFT, RNTI, LCID)"] {
- EpcHelper => EpcSgwPgwApplication [label="ActivateS1Bearer (UE IP, eNB IP, TFT)", return="TEID"] {
- EpcSgwPgwApplication => EpcSgwPgwApplication [label="Store UE IP<->eNB IP mapping"];
- EpcSgwPgwApplication => EpcSgwPgwApplication [label="Create GTP-U tunnel endpoint"];
- }
- EpcHelper => EpcEnbApplication [label="ErabSetupRequest(TEID, RNTI, LCID )"] {
- EpcEnbApplication -> EpcEnbApplication [label="Create GTP-U tunnel endpoint (TEID)"];
- EpcEnbApplication -> EpcEnbApplication [label="store TEID<->(RNTI,LCID) mapping"]
- }
-}
-
+SimProgram ->> LteHelper [label="create"]
+SimProgram ->> EpcHelper [label="create"]
+EpcHelper ->> EpcHelper [label="create MME and SGW/PGW"]
+SimProgram ->> LteHelper [label="InstallEnbDevice"]
+LteHelper ->> LteHelper [label="install protocol stack on eNB"]
+LteHelper ->> EpcHelper [label="AddEnb"]
+EpcHelper ->> EpcHelper [label="setup S1-U, S1-AP and S11"]
+SimProgram ->> LteHelper [label="InstallUeDevice"]
+LteHelper ->> LteHelper [label="install protocol stack on UE"]
+SimProgram ->> LteHelper [label="Attach (UE, eNB)"]
+LteHelper ->> LteHelper [label="tell UE NAS to start connection"]
+LteHelper ->> EpcHelper [label="ActivateEpsBearer (default)"]
+EpcHelper ->> EpcHelper [label="tell MME to activate bearer when UE connects"]
+SimProgram ->> LteHelper [label="ActivateDedicatedEpsBearer"]
+LteHelper ->> EpcHelper [label="ActivateEpsBearer"]
+EpcHelper ->> EpcHelper [label="tell MME to activate bearer when UE connects"]
}
\ No newline at end of file
Binary file src/lte/doc/source/figures/lte-arch-enb-ctrl.dia has changed
Binary file src/lte/doc/source/figures/lte-arch-enb-data.dia has changed
Binary file src/lte/doc/source/figures/lte-arch-enb.dia has changed
Binary file src/lte/doc/source/figures/lte-arch-ue-ctrl.dia has changed
Binary file src/lte/doc/source/figures/lte-arch-ue-data.dia has changed
Binary file src/lte/doc/source/figures/lte-arch-ue.dia has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/doc/source/figures/lte-enb-rrc-states.dot Thu Dec 13 12:22:43 2012 +0100
@@ -0,0 +1,31 @@
+digraph LteEnbRrcStates {
+
+size="20,20"
+
+
+NO_CONTEXT [shape="ellipse", label="no context"]
+INITIAL_RANDOM_ACCESS [shape="box",width=5]
+CONNECTION_SETUP [shape="box",width=5]
+CONNECTED_NORMALLY [shape="box",width=5]
+CONNECTION_RECONFIGURATION [shape="box",width=5]
+HANDOVER_PREPARATION [shape="box",width=5]
+HANDOVER_JOINING [shape="box",width=5]
+HANDOVER_PATH_SWITCH [shape="box",width=5]
+HANDOVER_LEAVING [shape="box",width=5]
+CONTEXT_DESTROYED [shape="ellipse", label="context destroyed"]
+
+NO_CONTEXT -> INITIAL_RANDOM_ACCESS [label="rx RA preamble",labeldistance=0]
+INITIAL_RANDOM_ACCESS -> CONNECTION_SETUP [label="rx RRC CONNECTION SETUP"]
+CONNECTION_SETUP -> CONNECTED_NORMALLY [label="rx RRC CONNECTION SETUP COMPLETED"]
+CONNECTED_NORMALLY -> CONNECTION_RECONFIGURATION [label="reconfiguration trigger"]
+CONNECTION_RECONFIGURATION -> CONNECTED_NORMALLY [label="rx RRC CONN RECONF COMPLETED"]
+CONNECTED_NORMALLY -> HANDOVER_PREPARATION [label="handover trigger"]
+HANDOVER_PREPARATION -> CONNECTED_NORMALLY [label="rx X2 HO PREP FAILURE"]
+HANDOVER_PREPARATION -> HANDOVER_LEAVING [label="rx X2 HO REQUEST ACK"]
+HANDOVER_LEAVING -> CONTEXT_DESTROYED [label="rx X2 UE CONTEXT RELEASE"]
+NO_CONTEXT -> HANDOVER_JOINING [label="rx & admit X2 HANDOVER REQUEST"]
+HANDOVER_JOINING -> HANDOVER_PATH_SWITCH [label="RRC CONN RECONF COMPLETED"]
+HANDOVER_PATH_SWITCH -> CONNECTED_NORMALLY [label="rx S1 PATH SWITCH REQUEST ACK"]
+
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/doc/source/figures/lte-ue-rrc-states.dot Thu Dec 13 12:22:43 2012 +0100
@@ -0,0 +1,22 @@
+digraph LteRrcStates {
+
+
+IDLE_CELL_SELECTION [shape="box",width=5]
+IDLE_WAIT_SYSTEM_INFO [shape="box",width=5]
+IDLE_CAMPED_NORMALLY [shape="box",width=5]
+IDLE_RANDOM_ACCESS [shape="box",width=5]
+IDLE_CONNECTING [shape="box",width=5]
+CONNECTED_NORMALLY [shape="box",width=5]
+CONNECTED_HANDOVER [shape="box",width=5]
+
+
+IDLE_CELL_SELECTION -> IDLE_WAIT_SYSTEM_INFO [label="eNB CellId enforced by upper layers"]
+IDLE_WAIT_SYSTEM_INFO -> IDLE_CAMPED_NORMALLY [label="rx MIB + SIB2"]
+IDLE_CAMPED_NORMALLY -> IDLE_RANDOM_ACCESS [label="connection request by upper layers"]
+IDLE_RANDOM_ACCESS -> IDLE_CONNECTING [label="random access successful"]
+IDLE_RANDOM_ACCESS -> IDLE_CAMPED_NORMALLY [label="random access failure"]
+IDLE_CONNECTING -> CONNECTED_NORMALLY [label="rx RRC CONN SETUP"]
+CONNECTED_NORMALLY -> CONNECTED_HANDOVER [label="rx RRC CONN RECONF with MobilityCltrInfo"]
+CONNECTED_HANDOVER -> CONNECTED_NORMALLY [label="random access successful"]
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/doc/source/figures/mac-random-access-contention.seqdiag Thu Dec 13 12:22:43 2012 +0100
@@ -0,0 +1,44 @@
+
+diagram {
+ UeRrc; UeMac; UePhy; EnbRrc; EnbPhy; EnbMac; FfSched;
+
+ UeRrc ->> UeMac [label="StartContentionBasedRandomAccessProcedure"]
+ UeMac ->> UeMac [label="Select random preamble in 0,1,...,63-Ncf"]
+ UeMac ->> UeMac [label="start RAR timeout"]
+ UeMac ->> UePhy [label="SendRachPreamble"]
+ UePhy ->> EnbPhy [label="RachPreambleLteControlMessage"]
+ EnbPhy ->> EnbMac [label="ReceiveRachPreamble (this UE)"]
+ EnbMac ->> EnbMac [label="add to list of received Rach preamble"]
+ EnbPhy ->> EnbMac [label="ReceiveRachPreamble (other UE colliding)"]
+ EnbMac ->> EnbMac [label="add to list of received Rach preamble"]
+ EnbPhy ->> EnbMac [label="SubframeIndication"]
+ EnbMac ->> EnbMac [label="discard collided preambles"]
+ UeMac ->> UeMac [label="RAR timeout expires"]
+ UeMac ->> UeMac [label="Select random preamble in 0,1,...,63-Ncf"]
+ UeMac ->> UeMac [label="start RAR timeout"]
+ UeMac ->> UePhy [label="SendRachPreamble"]
+ UePhy ->> EnbPhy [label="RachPreambleLteControlMessage"]
+ EnbPhy ->> EnbMac [label="ReceiveRachPreamble (this UE)"]
+ EnbMac ->> EnbMac [label="add to list of received Rach preamble"]
+ EnbPhy ->> EnbMac [label="SubframeIndication"]
+ EnbMac ->> EnbRrc [label="AllocateTemporaryCellRnti"]
+ EnbRrc ->> EnbRrc [label="AddUe"]
+ EnbMac <<- EnbRrc [label="ConfigureUe (C-RNTI = T-C-RNTI)"]
+ EnbMac ->> FfSched [label="CSCHED_UE_CONFIG_REQ"]
+ EnbMac <<- FfSched [label="CSCHED_UE_CONFIG_CNF"]
+ EnbMac ->> FfSched [label="CSCHED_LC_CONFIG_REQ (SRB1)"]
+ EnbMac <<- FfSched [label="CSCHED_LC_CONFIG_CNF"]
+ EnbMac <<- EnbRrc [label="T-C-RNTI"]
+ EnbMac ->> FfSched [label="SCHED_DL_RACH_INFO_REQ (T-C-RNTI list)"]
+ EnbMac ->> FfSched [label="SCHED_DL_TRIGGER_REQ"]
+ EnbMac <<- FfSched [label="SCHED_DL_CONFIG_IND (RAR list with UL grant per RNTI)"]
+ EnbMac ->> EnbMac [label="build RARs"]
+ EnbPhy <<- EnbMac [label="SendLteControlMessage (RARs)"]
+ UePhy <<- EnbPhy [label="RARs as RarLteControlMessage"]
+ UeMac <<- UePhy [label="ReceiveLteControlMessage (RARs)"]
+ UeMac ->> UeMac [label="RecvRaResponse"]
+ UeRrc <<- UeMac [label="NotifyRandomAccessSuccessful"]
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/doc/source/figures/mac-random-access-noncontention.seqdiag Thu Dec 13 12:22:43 2012 +0100
@@ -0,0 +1,34 @@
+
+diagram {
+ UeRrc; UeMac; UePhy; EnbRrc; EnbPhy; EnbMac; FfSched;
+
+ EnbRrc ->> EnbRrc [label="AddUe"]
+ EnbRrc ->> EnbMac [label="ConfigureUe (C-RNTI = T-C-RNTI)"]
+ EnbMac ->> FfSched [label="CSCHED_UE_CONFIG_REQ"]
+ EnbMac <<- FfSched [label="CSCHED_UE_CONFIG_CNF"]
+ EnbMac ->> FfSched [label="CSCHED_LC_CONFIG_REQ (SRB1)"]
+ EnbMac <<- FfSched [label="CSCHED_LC_CONFIG_CNF"]
+ EnbMac <<- EnbRrc [label=" AllocateNcRaPreamble (T-C-RNTI)"]
+ EnbMac ->> EnbRrc [label="rach preamble id"]
+ UeRrc <<- EnbRrc [label="rach preamble id (e.g., within handoverCommand inside X2 HO REQ ACK"]
+ UeRrc ->> UeMac [label="StartNonContentionBasedRandomAccessProcedure"]
+ UeMac ->> UeMac [label="start RAR timeout"]
+ UeMac ->> UePhy [label="SendRachPreamble"]
+ UePhy ->> EnbPhy [label="RachPreambleLteControlMessage"]
+ EnbPhy ->> EnbMac [label="ReceiveRachPreamble (this UE)"]
+ EnbMac ->> EnbMac [label="add to list of received Rach preamble"]
+ EnbPhy ->> EnbMac [label="SubframeIndication"]
+ EnbMac ->> EnbMac [label="preamble matches known T-C-RNTI"]
+ EnbMac ->> FfSched [label="SCHED_DL_RACH_INFO_REQ (T-C-RNTI list)"]
+ EnbMac ->> FfSched [label="SCHED_DL_TRIGGER_REQ"]
+ EnbMac <<- FfSched [label="SCHED_DL_CONFIG_IND (RAR list with UL grant per RNTI)"]
+ EnbMac ->> EnbMac [label="build RARs"]
+ EnbPhy <<- EnbMac [label="SendLteControlMessage (RARs)"]
+ UePhy <<- EnbPhy [label="RARs as RarLteControlMessage"]
+ UeMac <<- UePhy [label="ReceiveLteControlMessage (RARs)"]
+ UeMac ->> UeMac [label="RecvRaResponse"]
+ UeRrc <<- UeMac [label="NotifyRandomAccessSuccessful"]
+}
+
+
+
--- a/src/lte/doc/source/figures/nas-activate-dedicated-bearer.seqdiag Thu Dec 13 12:10:31 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-
-diagram {
- LteHelper; LteUeNetDevice; EpcUeNas; LteUeRrc; LteEnbRrc; EpcEnbApplication; EpcSgwPgwApplication; EpcHelper;
-
- LteHelper => LteUeNetDevice [label="ActivateDedicatedEpsBearer(Tft)"] {
- LteUeNetDevice => EpcUeNas [label="ActivateDedicatedEpsBearer(Tft)"] {
- EpcUeNas => EpcHelper [label="ActivateEpsBearer(UeDevice, EnbDevice, Tft)"] {
- EpcHelper => EpcSgwPgwApplication [label="ActivateS1Bearer (UE IP, eNB IP, IMSI, Tft)", return="TEID"] {
- EpcSgwPgwApplication => EpcSgwPgwApplication [label="Store UE IP<->eNB IP mapping"];
- EpcSgwPgwApplication => EpcSgwPgwApplication [label="Create GTP-U tunnel endpoint"];
- }
- EpcHelper => EpcEnbApplication [label="ErabSetupRequest(TEID, IMSI)"] {
- EpcEnbApplication => LteEnbRrc [label="RadioBearerSetupRequest (IMSI)", return="S1BearerSetupRequest (RNTI, LCID)"] {
- LteEnbRrc => LteUeRrc [label="RRC connection reconfiguration"];
- }
- EpcEnbApplication -> EpcEnbApplication [label="Create GTP-U tunnel endpoint (TEID)"];
- EpcEnbApplication -> EpcEnbApplication [label="store TEID<->(RNTI,LCID) mapping"];
- }
-
- }
- }
- }
-}
-
--- a/src/lte/doc/source/figures/nas-attach.seqdiag Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/doc/source/figures/nas-attach.seqdiag Thu Dec 13 12:22:43 2012 +0100
@@ -3,28 +3,22 @@
EpcUeNas; LteUeRrc; LteEnbRrc; EpcEnbApplication; EpcSgwPgwApplication; EpcMme;
- EpcUeNas -> LteUeRrc [label="ForceCampedOnEnb (CellID)"];
- EpcUeNas => LteUeRrc [label="Connect (S-TMSI, InitialNasMessage = EMM ATTACH REQUEST + ESM PDN CONNECTIVITY REQUEST)"] {
- LteUeRrc -> LteEnbRrc [label="RRC Connection Request (S-TMSI + InitialNasMessage)"]
- === RRC connection establishment ===
- LteUeRrc <- LteEnbRrc [label="RNTI"]
- LteEnbRrc -> EpcEnbApplication [label="UL NAS fwd (initial UE message)"]
- EpcEnbApplication -> EpcMme [label="S1-AP INITIAL UE MESSAGE (eNB UE S1 id = RNTI, S-TMSI, EGCI, NAS PDU)" return="InitialContextSetup (IMSI, RNTI, ERABs to be setup)"]
- EpcMme -> EpcMme [label="store IMSI->eNB UE id (RNTI) mapping"]
- EpcMme -> EpcSgwPgwApplication [label="CreateSessionRequest (IMSI, EGCI, BearerContext)"] {
- EpcSgwPgwApplication => EpcSgwPgwApplication [label="Store UE IP<->eNB IP mapping"];
- EpcSgwPgwApplication => EpcSgwPgwApplication [label="Create GTP-U tunnel endpoint"];
- }
- EpcMme <- EpcSgwPgwApplication [label="CreateSessionResponse (SGW-FQ-CSID, BearerContext)"]
- EpcMme => EpcEnbApplication [label="InitialContextSetupRequest(TEID, IMSI, RNTI, ERABs to be setup (incl. TEIDs))"] {
- EpcEnbApplication -> EpcEnbApplication [label="Create GTP-U tunnel endpoint (TEID)"];
- EpcEnbApplication -> EpcEnbApplication [label="store TEID<->(RNTI,LCID) mapping"];
- EpcEnbApplication => LteEnbRrc [label="RadioBearerSetupRequest (RNTI, QoS params, EBIs)", return="S1BearerSetupRequest (RNTI, LCID)"] {
- LteEnbRrc -> LteUeRrc [label="RRC connection reconfiguration"];
- }
- }
- }
- EpcUeNas <- EpcMme [label="EMM ATTACH COMPLETE + ESM ACTIVATE DEFAULT EPS BEARER REQUEST"]
- EpcUeNas -> EpcMme [label="ESM ACTIVATE DEFAULT EPS BEARER RESPONSE"]
+ EpcUeNas ->> LteUeRrc [label="ForceCampedOnEnb (CellId)"];
+ EpcUeNas ->> LteUeRrc [label="Connect"]
+ LteUeRrc ->> LteEnbRrc [label="RRC Connection Request"]
+ LteEnbRrc ->> EpcEnbApplication [label="initial UE message"]
+ EpcEnbApplication ->> EpcMme [label="S1-AP INITIAL UE MESSAGE"]
+ EpcMme ->> EpcMme [label="store IMSI->eNB UE id (RNTI) mapping"]
+ EpcMme ->> EpcSgwPgwApplication [label="S11 CREATE SESSION"]
+ EpcSgwPgwApplication ->> EpcSgwPgwApplication [label="setup S1-U bearers"]
+ EpcMme <<- EpcSgwPgwApplication [label="S11 CREATE SESSION RESPONSE"]
+ EpcEnbApplication <<- EpcMme [label="S1-AP INITIAL CONTEXT SETUP (bearers to be created)"]
+ EpcEnbApplication ->> EpcMme [label="S1-AP INITIAL CONTEXT SETUP RESPONSE"]
+ EpcEnbApplication ->> EpcEnbApplication [label="setup S1-U bearers"]
+ LteEnbRrc <<- EpcEnbApplication [label="DataRadioBearerSetupRequest"]
+ LteEnbRrc ->> LteEnbRrc [label="setup data radio bearers"]
+ LteUeRrc <<- LteEnbRrc [label="RRC Connection Reconfiguration"]
+ LteUeRrc ->> LteUeRrc [label="setup data radio bearers"]
+ LteUeRrc ->> LteEnbRrc [label="RRC Connection Reconfiguration Completed"]
}
--- a/src/lte/doc/source/figures/rrc-connection-establishment.seqdiag Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/doc/source/figures/rrc-connection-establishment.seqdiag Thu Dec 13 12:22:43 2012 +0100
@@ -1,53 +1,19 @@
+
diagram {
- UeRrc; UeMac; UePhy; EnbPhy; EnbMac; FfSched; EnbRrc;
-
- UeRrc ->> UeMac [label="SendOverCcch (RrcConnectionRequest)"]
- === start contention based MAC Random Access Procedure ===
- UeMac ->> UeMac [label="Select PRACH ID in 0,1,...,63-Ncf"]
- UeMac ->> UePhy [label="SendRachPreamble (PRACH ID)"]
- UePhy ->> EnbPhy [label="RachPreamble over RACH"]
- EnbPhy ->> EnbMac [label="NotifyRxRachPreamble (PRACH ID)"]
- EnbMac ->> EnbRrc [label="Allocate T-C-RNTI"]
- EnbMac <<- EnbRrc [label="T-C-RNTI"]
- EnbMac ->> FfSched [label="SCHED_DL_RACH_INFO_REQ (RNTI list)"]
- EnbPhy ->> EnbMac [label="SubframeIndication"]
- EnbMac ->> FfSched [label="SCHED_DL_TRIGGER_REQ"]
- EnbMac <<- FfSched [label="SCHED_DL_CONFIG_IND (RAR list with UL grant per RNTI)"]
- EnbMac ->> EnbMac [label="determine RA-RNTI from PRACH ID"]
- EnbPhy <<- EnbMac [label="Send RAR with RA-RNTI identifying preambleId"]
- UePhy <<- EnbPhy [label="RAR over PDSCH"]
- UeMac <<- UePhy [label="Rx"]
- UeMac ->> UePhy [label="SendOverUlsch (RrcConnectionRequest)"]
- UePhy ->> EnbPhy [label="TX over PUSCH with T-C-RNTI"]
- EnbPhy ->> EnbMac [label="RxOverUlsch"]
- EnbMac ->> EnbRrc [label="RxOverCcch (RrcConnectionRequest, T-C-RNTI)"]
- EnbMac <<- EnbRrc [label="ConfigureUe (C-RNTI = T-C-RNTI)"]
- EnbMac ->> FfSched [label="CSCHED_UE_CONFIG_REQ"]
- EnbMac <<- FfSched [label="CSCHED_UE_CONFIG_CNF"]
- EnbMac ->> FfSched [label="CSCHED_LC_CONFIG_REQ (SRB1)"]
- EnbMac <<- FfSched [label="CSCHED_LC_CONFIG_CNF"]
- EnbMac <<- EnbRrc [label="ResolveContentionAfterMessage3 (UE Identity)"]
- EnbMac ->> FfSched [label="SCHED_DL_MAC_BUFFER_REQ"]
- EnbPhy ->> EnbMac [label="SubframeIndication"]
- EnbMac ->> FfSched [label="SCHED_DL_TRIGGER_REQ"]
- EnbMac <<- FfSched [label="SCHED_DL_CONFIG_IND (MAC CR CE)"]
- EnbPhy <<- EnbMac [label="SendOverDlsch (CR with UE identity CE)"]
- UePhy <<- EnbPhy [label="CR over PD-SCH"]
- UeMac <<- UePhy [label="Rx"]
- UeMac <<- UeMac [label="C-RNTI = T-C-RNTI"]
- UeRrc <<- UeMac [label="NotifyRandomAccessProcedureEndOk (C-RNTI)"]
- === end contention based MAC Random Access Procedure ===
- EnbMac <<- EnbRrc [label="SendOverCcch (RrcConnectionSetup)"]
- EnbMac ->> FfSched [label="SCHED_DL_RLC_BUFFER_REQ"]
- EnbPhy ->> EnbMac [label="SubframeIndication"]
- EnbMac ->> FfSched [label="SCHED_DL_TRIGGER_REQ"]
- EnbMac <<- FfSched [label="SCHED_DL_CONFIG_IND (DATA list)"]
- EnbPhy <<- EnbMac [label="Send PDU"]
- UePhy <<- EnbPhy [label="PDU over DL-SCH"]
- UeMac <<- UePhy [label="Rx PDU"]
- UeRrc <<- UeMac [label="RxOverCcch (RrcConnectionSetup)"]
- UeRrc ->> EnbRrc [label="RrcConnectionSetupCompleted over SRB1)"]
+ AsSap; UeRrc; CmacSap; RrcSap; EnbRrc;
+
+
+ AsSap ->> UeRrc [label="Connect"]
+ UeRrc ->> CmacSap [label="StartContentionBasedRandomAccessProcedure"]
+ === UE sends RA preamble and receives RAR with T-C-RNTI ===
+ UeRrc <<- CmacSap [label="SetTemporaryCellRnti"]
+ UeRrc ->> RrcSap [label="send RRC CONNECTION REQUEST"]
+ RrcSap ->> EnbRrc [label="recv RRC CONNECTION REQUEST"]
+ RrcSap <<- EnbRrc [label="send RRC CONNECTION SETUP"]
+ UeRrc <<- RrcSap [label="recv RRC CONNECTION SETUP"]
+ UeRrc ->> RrcSap [label="send RRC CONNECTION SETUP COMPLETED"]
+ RrcSap ->> EnbRrc [label="recv RRC CONNECTION SETUP COMPLETED"]
}
--- a/src/lte/doc/source/lte-design.rst Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/doc/source/lte-design.rst Thu Dec 13 12:22:43 2012 +0100
@@ -6,50 +6,44 @@
++++++++++++++++++++++++++
-.. _overall-architecture:
-
------------------------
-Overall Architecture
------------------------
-
-The overall architecture of the LENA simulation model is depicted in
+---------
+Overview
+---------
+
+
+An overview of the LTE-EPC simulation model is depicted in
the figure :ref:`fig-epc-topology`. There are two main components:
* the LTE Model. This model includes the LTE Radio Protocol
stack (RRC, PDCP, RLC, MAC, PHY). These entities reside entirely within the
UE and the eNB nodes.
-* the EPC Model. This models includes core network
- interfaces, protocols and entities. These entities and protocols
- reside within the SGW, PGW and MME nodes, and partially within the
- eNB nodes.
+ * the EPC Model. This models includes core network
+ interfaces, protocols and entities. These entities and protocols
+ reside within the SGW, PGW and MME nodes, and partially within the
+ eNB nodes.
Each component of the overall architecture is explained in detail in
the following subsections.
-
-
.. _fig-epc-topology:
.. figure:: figures/epc-topology.*
:align: center
- Overall architecture of the LTE-EPC simulation model
-
-
-
-
-
-
----------------
-LTE Model
----------------
-
-
+ Overview of the LTE-EPC simulation model
+
+
+.. _sec-design-criteria:
+
+-----------------------
Design Criteria
-+++++++++++++++
-
+-----------------------
+
+
+LTE Model
++++++++++
The LTE model has been designed to support the evaluation of the following aspects of LTE systems:
@@ -116,81 +110,16 @@
should be modeled accurately.
-
-Architecture
-++++++++++++
-
-For the sake of an easier explanation, we consider separately the architecture of the UE and eNB nodes.
-
-
-UE architecture
----------------
-
-The architecture of the LTE radio protocol stack model of the UE is represented in the figure :ref:`fig-lte-arch-ue`.
-
-
-.. _fig-lte-arch-ue:
-
-.. figure:: figures/lte-arch-ue.*
- :align: center
-
- LTE radio protocol stack architecture for the UE
-
-The architecture of the PHY/channel model of the UE is represented in figure :ref:`fig-lte-ue-phy`.
-
-
-.. _fig-lte-ue-phy:
-
-.. figure:: figures/lte-ue-phy.*
- :align: center
-
- PHY and channel model architecture for the UE
-
-
-
-
-eNB architecture
----------------
-
-The architecture of the LTE radio protocol stack model of the eNB is represented in the figure :ref:`fig-lte-arch-enb`.
-
-
-.. _fig-lte-arch-enb:
-
-.. figure:: figures/lte-arch-enb.*
- :align: center
-
- LTE radio protocol stack architecture for the eNB
-
-The architecture of the PHY/channel model of the eNB is represented in figure :ref:`fig-lte-enb-phy`.
-
-
-.. _fig-lte-enb-phy:
-
-.. figure:: figures/lte-enb-phy.*
- :align: center
-
- PHY and channel model architecture for the eNB
-
-
-
-
-----------------
EPC Model
-----------------
-
-
-
-The EPC model provides means for the simulation of end-to-end IP
-connectivity over the LTE model. In particular, it supports for the
++++++++++
+
+
+The main objective of the EPC model is to provides means for the
+simulation of end-to-end IP connectivity over the LTE model.
+To this aim, it supports for the
interconnection of multiple UEs to the internet, via a radio access
-network of multiple eNBs connected to a single SGW/PGW node. This
-network topology is depicted in Figure :ref:`fig-epc-topology`.
-
-
-
-Design Criteria
-+++++++++++++++
+network of multiple eNBs connected to a single SGW/PGW node, as shown
+in Figure :ref:`fig-epc-topology`.
The following design choices have been made for the EPC model:
@@ -225,23 +154,115 @@
connected mode. Hence, all the functionality that is only relevant
for ECM idle mode (in particular, tracking area update and paging)
are not modeled at all.
- #. While handover support is not a current requirement, it is
- planned to be considered in the near future. Hence, the management
- of EPS bearers by the eNBs and the SGW/PGW should be implemented in such
- a way that it can be re-used when handover support is eventually
- added.
-
-
-
+ #. The model should allow the possibility to perform an X2-based
+ handover between two eNBs.
+
+
+
+
+.. _overall-architecture:
+
+-----------------------
Architecture
-++++++++++++
-
-The focus of the EPC model is currently on the EPC data plane. To
-understand the architecture of this model, we first look at Figure
-:ref:`fig-lte-epc-e2e-data-protocol-stack`, where we represent the
-end-to-end LTE-EPC protocol stack as it is
-implemented in the simulator. From the figure, it is evident that the
-biggest simplification introduced in the EPC model for the data plane
+-----------------------
+
+
+
+
+
+LTE Model
+++++++++++
+
+
+
+UE architecture
+---------------
+
+The architecture of the LTE radio protocol stack model of the UE is
+represented in the figures :ref:`fig-lte-arch-ue-data` and
+:ref:`fig-lte-arch-ue-ctrl` which highlight respectively the data
+plane and the control plane.
+
+
+.. _fig-lte-arch-ue-data:
+
+.. figure:: figures/lte-arch-ue-data.*
+ :align: center
+
+ LTE radio protocol stack architecture for the UE on the data plane
+
+
+.. _fig-lte-arch-ue-ctrl:
+
+.. figure:: figures/lte-arch-ue-ctrl.*
+ :align: center
+
+ LTE radio protocol stack architecture for the UE on the control plane
+
+
+The architecture of the PHY/channel model of the UE is represented in figure :ref:`fig-lte-ue-phy`.
+
+
+.. _fig-lte-ue-phy:
+
+.. figure:: figures/lte-ue-phy.*
+ :align: center
+
+ PHY and channel model architecture for the UE
+
+
+
+
+eNB architecture
+----------------
+
+The architecture of the LTE radio protocol stack model of the eNB is
+represented in the figures :ref:`fig-lte-arch-enb-data` and
+:ref:`fig-lte-arch-enb-ctrl` which highlight respectively the data plane
+and the control plane.
+
+
+.. _fig-lte-arch-enb-data:
+
+.. figure:: figures/lte-arch-enb-data.*
+ :align: center
+
+ LTE radio protocol stack architecture for the eNB on the data plane
+
+
+.. _fig-lte-arch-enb-ctrl:
+
+.. figure:: figures/lte-arch-enb-ctrl.*
+ :align: center
+
+ LTE radio protocol stack architecture for the eNB on the control plane
+
+
+The architecture of the PHY/channel model of the eNB is represented in figure :ref:`fig-lte-enb-phy`.
+
+
+.. _fig-lte-enb-phy:
+
+.. figure:: figures/lte-enb-phy.*
+ :align: center
+
+ PHY and channel model architecture for the eNB
+
+
+
+
+EPC Model
++++++++++
+
+
+
+EPC data plane
+--------------
+
+In Figure :ref:`fig-lte-epc-e2e-data-protocol-stack`, we represent the
+end-to-end LTE-EPC data plane protocol stack as it is modeled in the
+simulator. From the figure, it is evident that the
+biggest simplification introduced in the data plane model
is the inclusion of the SGW and PGW functionality within a single
SGW/PGW node, which removes the need for the S5 or S8 interfaces
specified by 3GPP. On the other hand, for both the S1-U protocol stack and
@@ -257,1053 +278,34 @@
LTE-EPC data plane protocol stack
-As shown in the figure, there are two different layers of
-IP networking. The first one is the end-to-end layer, which provides end-to-end
-connectivity to the users; this layers involves the UEs, the PGW and
-the remote host (including eventual internet routers and hosts in
-between), but does not involve the eNB. By default, UEs are assigned a public IPv4 address in the 7.0.0.0/8
-network, and the PGW gets the address 7.0.0.1, which is used by all
-UEs as the gateway to reach the internet.
-
-The second layer of IP networking is the EPC local area network. This
-involves all eNB nodes and the SGW/PGW node. This network is
-implemented as a set of point-to-point links which connect each eNB
-with the SGW/PGW node; thus, the SGW/PGW has a set of point-to-point
-devices, each providing connectivity to a different eNB. By default, a
-10.x.y.z/30 subnet is assigned to each point-to-point link (a /30
-subnet is the smallest subnet that allows for two distinct host
-addresses).
-
-As specified by 3GPP, the end-to-end IP
-communications is tunneled over the local EPC IP network using
-GTP/UDP/IP. In the following, we explain how this tunneling is
-implemented in the EPC model. The explanation is done by discussing the
-end-to-end flow of data packets.
-
-.. _fig-epc-data-flow-dl:
-
-.. figure:: figures/epc-data-flow-dl.*
- :align: center
-
- Data flow in the downlink between the internet and the UE
-
-To begin with, we consider the case of the downlink, which is depicted
-in Figure :ref:`fig-epc-data-flow-dl`.
-Downlink Ipv4 packets are generated from a generic remote host, and
-addressed to one of the UE device. Internet routing will take care of
-forwarding the packet to the generic NetDevice of the SGW/PGW node
-which is connected to the internet (this is the Gi interface according
-to 3GPP terminology). The SGW/PGW has a VirtualNetDevice which is
-assigned the gateway IP address of the UE subnet; hence, static
-routing rules will cause the incoming packet from the internet to be
-routed through this VirtualNetDevice. Such device starts the
-GTP/UDP/IP tunneling procedure, by forwarding the packet to a
-dedicated application in the SGW/PGW node which is called
-EpcSgwPgwApplication. This application does the following operations:
-
- #. it determines the eNB node to which the UE is attached, by looking
- at the IP destination address (which is the address of the UE);
- #. it classifies the packet using Traffic Flow Templates (TFTs) to
- identify to which EPS Bearer it belongs. EPS bearers have a
- one-to-one mapping to S1-U Bearers, so this operation returns the
- GTP-U Tunnel Endpoint Identifier (TEID) to which the packet
- belongs;
- #. it adds the corresponding GTP-U protocol header to the packet;
- #. finally, it sends the packet over an UDP socket to the S1-U
- point-to-point NetDevice, addressed to the eNB to which the UE is
- attached.
-
-As a consequence, the end-to-end IP packet with newly added IP, UDP
-and GTP headers is sent through one of the S1 links to the eNB, where
-it is received and delivered locally (as the destination address of
-the outmost IP header matches the eNB IP address). The local delivery
-process will forward the packet, via an UDP socket, to a dedicated
-application called EpcEnbApplication. This application then performs
-the following operations:
-
- #. it removes the GTP header and retrieves the TEID which is
- contained in it;
- #. leveraging on the one-to-one mapping between S1-U bearers and
- Radio Bearers (which is a 3GPP requirement), it determines the Radio
- Bearer ID (RBID) to which the packet belongs;
- #. it records the RBID in a dedicated tag called LteRadioBearerTag,
- which is added to the packet;
- #. it forwards the packet to the LteEnbNetDevice of the eNB node via
- a raw packet socket
-
-Note that, at this point, the outmost header of the packet is the
-end-to-end IP header, since the IP/UDP/GTP headers of the S1 protocol
-stack have already been stripped. Upon reception of
-the packet from the EpcEnbApplication, the LteEnbNetDevice will
-retrieve the RBID from the LteRadioBearerTag, and based on the RBID
-will determine the Radio Bearer instance (and the corresponding PDCP
-and RLC protocol instances) which are then used to forward the packet
-to the UE over the LTE radio interface. Finally, the LteUeNetDevice of
-the UE will receive the packet, and delivery it locally to the IP
-protocol stack, which will in turn delivery it to the application of
-the UE, which is the end point of the downlink communication.
-
-
-
-.. _fig-epc-data-flow-ul:
-
-.. figure:: figures/epc-data-flow-ul.*
- :align: center
-
- Data flow in the uplink between the UE and the internet
-
-
-The case of the uplink is depicted in Figure :ref:`fig-epc-data-flow-ul`.
-Uplink IP packets are generated by a generic application inside the UE,
-and forwarded by the local TCP/IP stack to the LteUeNetDevice of the
-UE. The LteUeNetDevice then performs the following operations:
-
- #. it classifies the packet using TFTs and determines the
- Radio Bearer to which the packet belongs (and the corresponding
- RBID);
- #. it identifies the corresponding PDCP protocol instance, which is
- the entry point of the LTE Radio Protocol stack for this packet;
- #. it sends the packet to the eNB over the LTE Radio Protocol stack.
-
-The eNB receives the packet via its LteEnbNetDevice. Since there is a
-single PDCP and RLC protocol instance for each Radio Bearer, the
-LteEnbNetDevice is able to determine the RBID of the packet. This RBID
-is then recorded onto an LteRadioBearerTag, which is added to the
-packet. The LteEnbNetDevice then forwards the packet to the
-EpcEnbApplication via a raw packet socket.
-
-Upon receiving the packet, the EpcEnbApplication performs the
-following operations:
-
- #. it retrieves the RBID from the LteRadioBearerTag in the packet;
- #. it determines the corresponding EPS Bearer instance and GTP-U TEID by
- leveraging on the one-to-one mapping between S1-U bearers and Radio
- Bearers;
- #. it adds a GTP-U header on the packet, including the TEID
- determined previously;
- #. it sends the packet to the SGW/PGW node via the UDP socket
- connected to the S1-U point-to-point net device.
-
-At this point, the packet contains the S1-U IP, UDP and GTP headers in
-addition to the original end-to-end IP header. When the packet is
-received by the corresponding S1-U point-to-point NetDevice of the
-SGW/PGW node, it is delivered locally (as the destination address of
-the outmost IP header matches the address of the point-to-point net
-device). The local delivery process will forward the packet to the
-EpcSgwPgwApplication via the correponding UDP socket. The
-EpcSgwPgwApplication then removes the GTP header and forwards the
-packet to the VirtualNetDevice. At this point, the outmost header
-of the packet is the end-to-end IP header. Hence, if the destination
-address within this header is a remote host on the internet, the
-packet is sent to the internet via the corresponding NetDevice of the
-SGW/PGW. In the event that the packet is addressed to another UE, the
-IP stack of the SGW/PGW will redirect the packet again to the
-VirtualNetDevice, and the packet will go through the dowlink delivery
-process in order to reach its destination UE.
-
-
-
------------------------------------------
-Detailed description of protocol elements
------------------------------------------
-
-
-
-
-MAC
-+++
-
-
-The FemtoForum MAC Scheduler Interface
---------------------------------------
-
-This section describes the ns-3 specific version of the LTE MAC
-Scheduler Interface Specification published by the FemtoForum [FFAPI]_.
-
-We implemented the ns-3 specific version of the FemtoForum MAC Scheduler
-Interface [FFAPI]_ as a set of C++ abstract
-classes; in particular, each primitive is translated to a C++ method of a
-given class. The term *implemented* here is used with the same
-meaning adopted in [FFAPI]_, and hence refers to the process of translating
-the logical interface specification to a particular programming language.
-The primitives in [FFAPI]_ are grouped in two groups: the CSCHED
-primitives, which deal with scheduler configuration, and the SCHED primitives,
-which deal with the execution of the scheduler. Furthermore, [FFAPI]_
-defines primitives of two different kinds: those of type REQ go from the MAC to
-the Scheduler, and those of type IND/CNF go from the scheduler to the MAC. To
-translate these characteristics into C++, we define the following abstract
-classes that implement Service Access Points (SAPs) to be used to issue the
-primitives:
-
- * the ``FfMacSchedSapProvider`` class defines all the C++ methods that
- correspond to SCHED primitives of type REQ;
- * the ``FfMacSchedSapUser`` class defines all the C++ methods that
- correspond to SCHED primitives of type CNF/IND;
- * the ``FfMacCschedSapProvider`` class defines all the C++ methods that
- correspond to CSCHED primitives of type REQ;
- * the ``FfMacCschedSapUser`` class defines all the C++ methods that
- correspond to CSCHED primitives of type CNF/IND;
-
-
-There are 3 blocks involved in the MAC Scheduler interface: Control block,
-Subframe block and Scheduler block. Each of these blocks provide one part of the
-MAC Scheduler interface. The figure below shows the relationship
-between the blocks and the SAPs defined in our implementation of the MAC
-Scheduler Interface.
-
-.. figure:: figures/ff-mac-saps.*
- :align: center
-
-In addition to the above principles, the following design choices have been
-taken:
-
- * The definition of the MAC Scheduler interface classes follows the naming
- conventions of the |ns3| Coding Style. In particular, we follow the
- CamelCase convention for the primitive names. For example, the primitive
- ``CSCHED_CELL_CONFIG_REQ`` is translated to ``CschedCellConfigReq``
- in the |ns3| code.
- * The same naming conventions are followed for the primitive parameters. As
- the primitive parameters are member variables of classes, they are also prefixed
- with a ``m_``.
- * regarding the use of vectors and lists in data structures, we note
- that [FFAPI]_ is a pretty much C-oriented API. However, considered that
- C++ is used in ns-3, and that the use of C arrays is discouraged, we used STL
- vectors (``std::vector``) for the implementation of the MAC Scheduler
- Interface, instead of using C arrays as implicitly suggested by the
- way [FFAPI]_ is written.
- * In C++, members with constructors and destructors are not allow in
- ``unions``. Hence all those data structures that are said to be
- ``unions`` in [FFAPI]_ have been defined as ``structs`` in our code.
-
-The figure below shows how the MAC Scheduler Interface is
-used within the eNB.
-
-.. figure:: figures/ff-example.*
- :align: center
-
-
-The User side of both the CSCHED SAP and the SCHED SAP are
-implemented within the eNB MAC, i.e., in the file ``lte-enb-mac.cc``.
-The eNB MAC can be used with different scheduler implementations without
-modifications. The same figure also shows, as an example, how the Round Robin
-Scheduler is implemented: to interact with the MAC of the eNB, the Round Robin
-scheduler implements the Provider side of the SCHED SAP and CSCHED
-SAP interfaces. A similar approach can be used to implement other schedulers as
-well. A description of all the scheduler implementations that we provide as
-part of our LTE simulation module will be given in
-the following.
-
-
-Resource Allocation Model
--------------------------
-
-
-We now briefly describe how resource allocation is handled in LTE,
-clarifying how it is implemented in the simulator. The scheduler is in
-charge of generating specific structures calles Data Control Indication (DCI)
-which are then transmitted by the PHY of the eNB to the connected UEs, in order
-to inform them of the resource allocation on a per subframe basis. In doing this
-in the downlink direction, the scheduler has to fill some specific fields of the
-DCI structure with all the information, such as: the Modulation and Coding
-Scheme (MCS) to be used, the MAC Transport Block (TB) size, and the allocation
-bitmap which identifies which RBs will contain the data
-transmitted by the eNB to each user.
-
-For the mapping of resources to
-physical RBs, we adopt a *localized mapping* approach
-(see [Sesia2009]_, Section 9.2.2.1);
-hence in a given subframe each RB is always allocated to the same user in both
-slots.
-The allocation bitmap can be coded in
-different formats; in this implementation, we considered the *Allocation
-Type 0* defined in [TS36213]_, according to which the RBs are grouped in
-Resource Block Groups (RBG) of different size determined as a function of the
-Transmission Bandwidth Configuration in use.
-
-For certain bandwidth
-values not all the RBs are usable, since the
-group size is not a common divisor of the group. This is for instance the case
-when the bandwidth is equal to 25 RBs, which results in a RBG size of 2 RBs, and
-therefore 1 RB will result not addressable.
-In uplink the format of the DCIs is different, since only adjacent RBs
-can be used because of the SC-FDMA modulation. As a consequence, all
-RBs can be allocated by the eNB regardless of the bandwidth
-configuration.
-
-.. _sec-lte-amc:
-
-Adaptive Modulation and Coding
-------------------------------
-
-The simulator provides two Adaptive Modulation and Coding (AMC) models: one based on the GSoC model [Piro2011]_ and one based on the physical error model (described in the following sections).
-
-The former model is a modified version of the model described in [Piro2011]_,
-which in turn is inspired from [Seo2004]_. Our version is described in the
-following. Let :math:`i` denote the
-generic user, and let :math:`\gamma_i` be its SINR. We get the spectral efficiency
-:math:`\eta_i` of user :math:`i` using the following equations:
-
-.. math::
-
- \mathrm{BER} = 0.00005
-
- \Gamma = \frac{ -\ln{ (5 * \mathrm{BER}) } }{ 1.5}
-
- \eta_i = \log_2 { \left( 1 + \frac{ {\gamma}_i }{ \Gamma } \right)}
-
-The procedure described in [R1-081483]_ is used to get
-the corresponding MCS scheme. The spectral efficiency is quantized based on the
-channel quality indicator (CQI), rounding to the lowest value, and is mapped to the corresponding MCS
-scheme.
-
-Finally, we note that there are some discrepancies between the MCS index
-in [R1-081483]_
-and that indicated by the standard: [TS36213]_ Table
-7.1.7.1-1 says that the MCS index goes from 0 to 31, and 0 appears to be a valid
-MCS scheme (TB size is not 0) but in [R1-081483]_ the first useful MCS
-index
-is 1. Hence to get the value as intended by the standard we need to subtract 1
-from the index reported in [R1-081483]_.
-
-The alternative model is based on the physical error model developed for this simulator and explained in the following subsections. This scheme is able to adapt the MCS selection to the actual PHY layer performance according to the specific CQI report. According to their definition, a CQI index is assigned when a single PDSCH TB with the modulation coding scheme and code rate correspondent to that CQI index in table 7.2.3-1 of [TS36213]_ can be received with an error probability less than 0.1. In case of wideband CQIs, the reference TB includes all the RBGs available in order to have a reference based on the whole available resources; while, for subband CQIs, the reference TB is sized as the RBGs.
-
-
-.. only:: latex
-
- .. raw:: latex
-
- \clearpage
-
-Round Robin (RR) Scheduler
---------------------------
-
-The Round Robin (RR) scheduler is probably the simplest scheduler found in the literature. It works by dividing the
-available resources among the active flows, i.e., those logical channels which have a non-empty RLC queue. If the number of RBGs is greater than the number of active flows, all the flows can be allocated in the same subframe. Otherwise, if the number of active flows is greater than the number of RBGs, not all the flows can be scheduled in a given subframe; then, in the next subframe the allocation will start from the last flow that was not allocated. The MCS to be adopted for each user is done according to the received wideband CQIs.
-
-For what concern the HARQ, RR implements the non adaptive version, which implies that in allocating the retransmission attempts RR uses the same allocation configuration of the original block, which means maintaining the same RBGs and MCS. UEs that are allocated for HARQ retransmissions are not considered for the transmission of new data in case they have a transmission opportunity available in the same TTI. Finally, HARQ can be disabled with ns3 attribute system for maintaining backward compatibility with old test cases and code, in detail::
-
- Config::SetDefault ("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue (false));
-
-
-.. only:: latex
-
- .. raw:: latex
-
- \clearpage
-
-Proportional Fair (PF) Scheduler
---------------------------------
-
-The Proportional Fair (PF) scheduler [Sesia2009]_ works by scheduling a user
-when its
-instantaneous channel quality is high relative to its own average channel
-condition over time. Let :math:`i,j` denote generic users; let :math:`t` be the
-subframe index, and :math:`k` be the resource block index; let :math:`M_{i,k}(t)` be MCS
-usable by user :math:`i` on resource block :math:`k` according to what reported by the AMC
-model (see `Adaptive Modulation and Coding`_); finally, let :math:`S(M, B)` be the TB
-size in bits as defined in [TS36213]_ for the case where a number :math:`B` of
-resource blocks is used. The achievable rate :math:`R_{i}(k,t)` in bit/s for user :math:`i`
-on resource block group :math:`k` at subframe :math:`t` is defined as
-
-.. math::
-
- R_{i}(k,t) = \frac{S\left( M_{i,k}(t), 1\right)}{\tau}
-
-where :math:`\tau` is the TTI duration.
-At the start of each subframe :math:`t`, each RBG is assigned to a certain user.
-In detail, the index :math:`\widehat{i}_{k}(t)` to which RBG :math:`k` is assigned at time
-:math:`t` is determined as
-
-.. math::
-
- \widehat{i}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
- \left( \frac{ R_{j}(k,t) }{ T_\mathrm{j}(t) } \right)
-
-where :math:`T_{j}(t)` is the past througput performance perceived by the
-user :math:`j`.
-According to the above scheduling algorithm, a user can be allocated to
-different RBGs, which can be either adjacent or not, depending on the current
-condition of the channel and the past throughput performance :math:`T_{j}(t)`. The
-latter is determined at the end of the subframe :math:`t` using the following
-exponential moving average approach:
-
-.. math::
-
- T_{j}(t) =
- (1-\frac{1}{\alpha})T_{j}(t-1)
- +\frac{1}{\alpha} \widehat{T}_{j}(t)
-
-where :math:`\alpha` is the time constant (in number of subframes) of
-the exponential moving average, and :math:`\widehat{T}_{j}(t)` is the actual
-throughput achieved by the user :math:`i` in the subframe :math:`t`. :math:`\widehat{T}_{j}(t)`
-is measured according to the following procedure. First we
-determine the MCS :math:`\widehat{M}_j(t)` actually used by user
-:math:`j`:
-
-.. math::
-
- \widehat{M}_j(t) = \min_{k: \widehat{i}_{k}(t) = j}{M_{j,k}(t)}
-
-then we determine the total number :math:`\widehat{B}_j(t)` of RBGs allocated to user
-:math:`j`:
-
-.. math::
-
- \widehat{B}_j(t) = \left| \{ k : \widehat{i}_{k}(t) = j \} \right|
-
-where :math:`|\cdot|` indicates the cardinality of the set; finally,
-
-.. math::
-
- \widehat{T}_{j}(t) = \frac{S\left( \widehat{M}_j(t), \widehat{B}_j(t)
- \right)}{\tau}
+
+
+EPC control plane
+-----------------
+
+The architecture of the implementation of the control plane model is
+shown in figure :ref:`fig-epc-ctrl-arch`. The control interfaces that are
+modeled explicitly are the S1-AP, the X2-AP and the S11 interfaces.
+
+We note that the S1-AP and the S11 interfaces are modeled in a simplified
+fashion, by using just one pair of interface classes to model the
+interaction between entities that reside on different nodes (the eNB
+and the MME for the S1-AP interface, and the MME and the SGW for the
+S11 interface). In practice, this means that the primitives of these
+interfaces are mapped to a direct function call between the two
+objects. On the other hand, the X2-AP interface is being modeled using
+protocol data units sent over an X2 link (modeled as a point-to-point
+link); for this reason, the X2-AP interface model is more realistic.
+
+
+
+
+.. _fig-epc-ctrl-arch:
-
-For what concern the HARQ, PF implements the non adaptive version, which implies that in allocating the retransmission attempts the scheduler uses the same allocation configuration of the original block, which means maintaining the same RBGs and MCS. UEs that are allocated for HARQ retransmissions are not considered for the transmission of new data in case they have a transmission opportunity available in the same TTI. Finally, HARQ can be disabled with ns3 attribute system for maintaining backward compatibility with old test cases and code, in detail::
-
- Config::SetDefault ("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue (false));
-
-Transport Blocks
-----------------
-
-The implementation of the MAC Transport Blocks (TBs) is simplified with
-respect to the 3GPP specifications. In particular, a simulator-specific class (PacketBurst) is used to aggregate
-MAC SDUs in order to achieve the simulator's equivalent of a TB,
-without the corresponding implementation complexity.
-The multiplexing of different logical channels to and from the RLC
-layer is performed using a dedicated packet tag (LteRadioBearerTag), which
-performs a functionality which is partially equivalent to that of the
-MAC headers specified by 3GPP.
-
-
-
-
-
-RLC and PDCP
-++++++++++++
-
-
-
-
-Overview
---------
-
-The RLC entity is specified in the 3GPP technical specification
-[TS36322]_, and comprises three different types of RLC: Transparent
-Mode (TM), Unacknowledge Mode (UM) and Acknowledged Mode (AM). We
-implement only the UM and the AM RLC entities.
-
-The RLC entities provide the RLC service interface to the upper PDCP layer and the MAC service interface
-to the lower MAC layer. The RLC entities use the PDCP service interface from the upper PDCP layer and
-the MAC service interface from the lower MAC layer.
-
-Figure :ref:`fig-lte-rlc-implementation-model` shows the
-implementation model of the RLC entities and its relationship
-with all the other entities and services in the protocol stack.
-
-
-.. _fig-lte-rlc-implementation-model:
-
-.. figure:: figures/lte-rlc-implementation-model.*
- :width: 800px
-
- Implementation Model of PDCP, RLC and MAC entities and SAPs
-
-
-
-Service Interfaces
-------------------
-
-PDCP Service Interface
-^^^^^^^^^^^^^^^^^^^^^^
-
-The PDCP service interface is divided into two parts:
-
- * the ``PdcpSapProvider`` part is provided by the PDCP layer and used by the upper layer and
- * the ``PdcpSapUser`` part is provided by the upper layer and used by the PDCP layer.
-
-PDCP Service Primitives
-"""""""""""""""""""""""
-
-The following list specifies which service primitives are provided by the PDCP service interfaces:
-
- * ``PdcpSapProvider::TransmitRrcPdu``
-
- * The RRC entity uses this primitive to send an RRC PDU to the lower PDCP entity
- in the transmitter peer
-
- * ``PdcpSapUser::ReceiveRrcPdu``
-
- * The PDCP entity uses this primitive to send an RRC PDU to the upper RRC entity
- in the receiver peer
-
-RLC Service Interface
-^^^^^^^^^^^^^^^^^^^^^
-
-The RLC service interface is divided into two parts:
-
- * the ``RlcSapProvider`` part is provided by the RLC layer and used by the upper PDCP layer and
- * the ``RlcSapUser`` part is provided by the upper PDCP layer and used by the RLC layer.
-
-Both the UM and the AM RLC entities provide the same RLC service interface to the upper PDCP layer.
-
-RLC Service Primitives
-""""""""""""""""""""""
-
-The following list specifies which service primitives are provided by the RLC service interfaces:
-
- * ``RlcSapProvider::TransmitPdcpPdu``
-
- * The PDCP entity uses this primitive to send a PDCP PDU to the lower RLC entity
- in the transmitter peer
-
- * ``RlcSapUser::ReceivePdcpPdu``
-
- * The RLC entity uses this primitive to send a PDCP PDU to the upper PDCP entity
- in the receiver peer
-
-MAC Service Interface
-^^^^^^^^^^^^^^^^^^^^^
-
-The MAC service interface is divided into two parts:
-
- * the ``MacSapProvider`` part is provided by the MAC layer and used by the upper RLC layer and
- * the ``MacSapUser`` part is provided by the upper RLC layer and used by the MAC layer.
-
-MAC Service Primitives
-""""""""""""""""""""""
-
-The following list specifies which service primitives are provided by the MAC service interfaces:
-
- * ``MacSapProvider::TransmitPdu``
-
- * The RLC entity uses this primitive to send a RLC PDU to the lower MAC entity
- in the transmitter peer
-
- * ``MacSapProvider::ReportBufferStatus``
-
- * The RLC entity uses this primitive to report the MAC entity the size of pending buffers
- in the transmitter peer
-
- * ``MacSapUser::NotifyTxOpportunity``
-
- * The MAC entity uses this primitive to nofify the RLC entity a transmission opportunity
-
- * ``MacSapUser::ReceivePdu``
-
- * The MAC entity uses this primitive to send an RLC PDU to the upper RLC entity
- in the receiver peer
-
-
-Interactions between entities and services
-------------------------------------------
-
-Transmit operations in downlink
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following sequence diagram shows the interactions between the
-different entities (RRC, PDCP, AM RLC, MAC and MAC scheduler) of the
-eNB in the downlink to perform data communications.
-
-Figure :ref:`fig-lte-rlc-data-txon-dl` shows how the upper layers send
-data PDUs and how the data flow is processed by the different
-entities/services of the LTE protocol stack. We will explain in detail
-only the processing related to the AM RLC entity, which is the most
-complex.
-
-.. _fig-lte-rlc-data-txon-dl:
-
-.. figure:: figures/lte-rlc-data-txon-dl.*
- :width: 800px
-
- Sequence diagram of data PDU transmission in downlink
-
-
-The PDCP entity calls the ``Transmit_PDCP_PDU service primitive`` in
-order to send a data PDU. The AM RLC entity processes this service
-primitive according to the AM data transfer procedures defined in
-section 5.1.3 of [TS36322]_.
-
-When the ``Transmit_PDCP_PDU`` service primitive is called, the AM RLC
-entity performs the following operations:
-
- * Put the data SDU in the Transmission Buffer.
- * Compute the size of the buffers (how the size of buffers is
- computed will be explained afterwards).
- * Call the ``Report_Buffer_Status`` service primitive of the eNB
- MAC entity in order to notify to the eNB MAC
- entity the sizes of the buffers of the AM RLC entity. Then, the
- eNB MAC entity updates the buffer status in the MAC scheduler
- using the SchedDlRlcBufferReq service primitive of the FF MAC
- Scheduler API.
-
-Afterwards, when the MAC scheduler decides that some data can be sent,
-the MAC entity notifies it to the RLC entity, i.e. it calls the
-``Notify_Tx_Opportunity`` service primitive, then the AM RLC entity
-does the following:
-
- * Create a single data PDU by segmenting and/or concatenating the
- SDUs in the Transmission Buffer.
- * Move the data PDU from the Transmission Buffer to the
- Transmitted PDUs Buffer.
- * Update state variables according section 5.1.3.1.1 of
- [TS36322]_.
- * Call the ``Transmit_PDU`` primitive in order to send the data
- PDU to the MAC entity.
-
-Retransmission in downlink
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The sequence diagram of Figure :ref:`fig-lte-rlc-data-retx-dl` shows
-the interactions between the different entities (AM RLC, MAC and MAC
-scheduler) of the eNB in downlink when data PDUs must be retransmitted
-by the AM RLC entity.
-
-.. _fig-lte-rlc-data-retx-dl:
-
-.. figure:: figures/lte-rlc-data-retx-dl.*
- :width: 500px
-
- Sequence diagram of data PDU retransmission in downlink
-
-
-The transmitting AM RLC entity can receive STATUS PDUs from the peer AM RLC entity. STATUS PDUs are
-sent according section 5.3.2 of [TS36322]_ and the processing of reception is made according
-section 5.2.1 of [TS36322]_.
-
-When a data PDUs is retransmitted from the Transmitted PDUs Buffer, it is also moved to the
-Retransmission Buffer.
-
-Transmit operations in uplink
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The sequence diagram of Figure :ref:`fig-lte-rlc-data-txon-ul` shows
-the interactions between the different entities of the UE (RRC, PDCP,
-RLC and MAC) and the eNB (MAC and Scheduler) in uplink when data PDUs
-are sent by the upper layers.
-
-.. _fig-lte-rlc-data-txon-ul:
-
-.. figure:: figures/lte-rlc-data-txon-ul.*
- :width: 800px
-
- Sequence diagram of data PDU transmission in uplink
-
-
-It is similar to the sequence diagram in downlink; the main difference
-is that in this case the Report_Buffer_Status is sent from the UE MAC
-to the MAC Scheduler in the eNB over the air using the control
-channel.
-
-Retransmission in uplink
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The sequence diagram of Figure :ref:`fig-lte-rlc-data-retx-ul` shows
-the interactions between the different entities of the UE (AM RLC and
-MAC) and the eNB (MAC) in uplink when data PDUs must be retransmitted
-by the AM RLC entity.
-
-.. _fig-lte-rlc-data-retx-ul:
-
-.. figure:: figures/lte-rlc-data-retx-ul.*
- :width: 500px
-
- Sequence diagram of data PDU retransmission in uplink
-
-
-.. _am_data_transfer:
-
-AM data transfer
-----------------
-
-The processing of the data transfer in the AM RLC entity is explained in section 5.1.3 of [TS36322]_.
-In this section we describe some details of the implementation of the RLC entity.
-
-Management of buffers in transmit operations
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The AM RLC entity manages 3 buffers:
-
- * **Transmission Buffer**: it is the RLC SDU queue.
- When the AM RLC entity receives a SDU in the TransmitPdcpPdu service primitive from the
- upper PDCP entity, it enqueues it in the Transmission Buffer. We
- put a limit on the RLC buffer size and just silently drop SDUs
- when the buffer is full.
-
- * **Transmitted PDUs Buffer**: it is the queue of transmitted RLC PDUs for which an ACK/NACK has not
- been received yet. When the AM RLC entity sends a PDU to the MAC
- entity, it also puts a copy of the transmitted PDU in the Transmitted PDUs Buffer.
-
- * **Retransmission Buffer**: it is the queue of RLC PDUs which are considered for retransmission
- (i.e., they have been NACKed). The AM RLC entity moves this PDU to the Retransmission Buffer,
- when it retransmits a PDU from the Transmitted Buffer.
-
-
-Calculation of the buffer size
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The Transmission Buffer contains RLC SDUs. A RLC PDU is one or more SDU segments plus an RLC header.
-The size of the RLC header of one RLC PDU depends on the number of SDU segments the PDU contains.
-
-The 3GPP standard (section 6.1.3.1 of [TS36321]_) says clearly that,
-for the uplink, the RLC and MAC headers are not considered in the
-buffer size that is to be report as part of the Buffer Status Report.
-For the downlink, the behavior is not specified. Neither [FFAPI]_ specifies
-how to do it. Our RLC model works by assuming that the calculation of
-the buffer size in the downlink is done exactly as in the uplink,
-i.e., not considering the RLC and MAC header size.
-
-We note that this choice affects the interoperation with the
-MAC scheduler, since, in response to the
-``Notify_Tx_Opportunity`` service primitive, the RLC is expected to
-create a PDU of no more than the size requested by the MAC, including
-RLC overhead. Hence, unneeded fragmentation can occur if (for example)
-the MAC notifies a transmission exactly equal to the buffer size
-previously reported by the RLC. We assume that it is left to the Scheduler
-to implement smart strategies for the selection of the size of the
-transmission opportunity, in order to eventually avoid the inefficiency
-of unneeded fragmentation.
-
-
-
-Concatenation and Segmentation
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The AM RLC entity generates and sends exactly one RLC PDU for each transmission opportunity even
-if it is smaller than the size reported by the transmission opportunity. So for instance, if a
-STATUS PDU is to be sent, then only this PDU will be sent in that transmission opportunity.
-
-The segmentation and concatenation for the SDU queue of the AM RLC entity follows the same philosophy
-as the same procedures of the UM RLC entity but there are new state variables (see section 7.1) only
-present in the AM RLC entity.
-
-It is noted that, according to the 3GPP specs, there is no concatenation for the Retransmission Buffer.
-
-Re-segmentation
-^^^^^^^^^^^^^^^
-
-The current model of the AM RLC entity does not support the
-re-segmentation of the retransmission buffer. Rather, the AM RLC
-entity just expects to receive a big enough transmission
-opportunity. An assertion fails if a too small transmission opportunity is
-received.
-
-
-Unsupported features
-^^^^^^^^^^^^^^^^^^^^
-
-We do not support the following procedures of [TS36322]_ :
-
- * “Send an indication of successful delivery of RLC SDU” (See section 5.1.3.1.1)
- * “Indicate to upper layers that max retransmission has been reached” (See section 5.2.1)
- * “SDU discard procedures” (See section 5.3)
- * “Re-establishment procedure” (See section 5.4)
-
-We do not support any of the additional primitives of RLC SAP for AM RLC entity. In particular:
-
- * no SDU discard notified by PDCP
- * no notification of successful / failed delivery by AM RLC entity to PDCP entity
-
-
-
-
-RLC/SM
-------
-
-In addition to the full-fledged RLC/UM and RLC/AM implementations,
-a simplified RLC model is provided, which is denoted RLC/SM. This RLC model does not accepts
-PDUs from any above layer (such as PDCP); rather, RLC/SM takes care of the
-generation of RLC PDUs in response to
-the notification of transmission opportunities notified by the MAC.
-In other words, RLC/SM simulates saturation conditions, i.e., it
-assumes that the RLC buffer is always full and can generate a new PDU
-whenever notified by the scheduler. In fact, the "SM" in the name of
-the model stands for "Saturation Mode".
-
-RLC/SM is used for simplified simulation scenarios in which only the
-LTE Radio model is used, without the EPC and hence without any IP
-networking support. We note that, although RLC/SM is an
-unrealistic traffic model, it still allows for the correct simulation
-of scenarios with multiple flows belonging to different (non real-time)
-QoS classes, in order to test the QoS performance obtained by different
-schedulers. This can be
-done since it is the task of the Scheduler to assign transmission
-resources based on the characteristics of each Radio Bearer which are
-specified upon the creation of each Bearer at the start of the
-simulation.
-
-As for schedulers designed to work with real-time QoS
-traffic that has delay constraints, RLC/SM is probably not an appropriate choice.
-This is because the absence of actual RLC SDUs (replaced by the artificial
-generation of Buffer Status Reports) makes it not possible to provide
-the Scheduler with meaningful head-of-line-delay information, which is
-normally the metric of choice for the implementation of scheduling
-policies for real-time traffic flows. For the simulation and testing
-of such schedulers, it is advisable to use one of the realistic RLC
-implementations (RLC/UM or RLC/AM).
-
-
-
-PDCP
-----
-
-The reference document for the specification of the PDCP entity is
-[TS36323]_. With respect to this specification, the PDCP model
-implemented in the simulator supports only the following features:
-
- * transfer of data (user plane or control plane);
- * maintenance of PDCP SNs;
-
-The following features are currently not supported:
-
- * header compression and decompression of IP data flows using the ROHC protocol;
- * in-sequence delivery of upper layer PDUs at re-establishment of lower layers;
- * duplicate elimination of lower layer SDUs at re-establishment of lower layers for radio bearers mapped on RLC AM;
- * ciphering and deciphering of user plane data and control plane data;
- * integrity protection and integrity verification of control plane data;
- * timer based discard;
- * duplicate discarding.
-
-
-
-.. only:: latex
-
- .. raw:: latex
-
- \clearpage
-
-
-
-Radio Resource Control (RRC)
-++++++++++++++++++++++++++++
-
-The RRC model implemented in the simulator provides the following functionality:
-
- - generation (at the eNB) and interpretation (at the UE) of the Master Information Block and System Information Block Type 1 (including in particular PLMN identity, CSG-indication and CSG-identity)
- - RRC connection establishment procedure
- - RRC reconfiguration procedure, supporting the following use cases:
- + reconfiguration of the PHY TX mode (MIMO)
- + data radio bearer setup
- + handover
- - RRC connection re-establishment, supporting the following use
- cases:
- + handover
-
-
-Radio Bearer Configuration
---------------------------
-
-Some implementation choices have been made in the RRC regarding the setup of radio bearers:
-
- - three Logical Channel Groups (out of four available) are used, according to the following policy:
- + LCG 0 is for signaling radio bearers
- + LCG 1 is for GBR data radio bearers
- + LCG 2 is for Non-GBR data radio bearers
-
-
-RRC connection establishment
-----------------------------
-
-Figure :ref:`fig-rrc-connection-establishment` shows how the RRC
-Connection Establishment procedure is modeled, highlighting the role
-of the RRC layer at both the UE and the eNB, as well as the
-interaction with the lower layers. The figure highlights the different
-type of control messages involved and the interactions with the
-scheduler to allocate the radio resources needed for their transmission.
-
-.. _fig-rrc-connection-establishment:
-
-.. figure:: figures/rrc-connection-establishment.*
+.. figure:: figures/epc-ctrl-arch.*
:align: center
- Sequence diagram of the RRC Connection Establishment procedure
-
-
-
-RRC connection reconfiguration
-------------------------------
-
-Figure :ref:`fig-rrc-connection-reconfiguration` shows how the RRC
-Connection Reconfiguration procedure is modeled for the case where
-MobilityControlInfo is not provided, i.e., handover is not
-performed. In this case, only RRC messages sent over SRB1/DCCH1 are
-involved. The allocation of radio resources to send these messages
-follows the usual procedure of RLC AM described in section
-:ref:`am_data_transfer`, which is therefore omitted from the figure
-for simplicity.
-
-
-.. _fig-rrc-connection-reconfiguration:
-
-.. figure:: figures/rrc-connection-reconfiguration.*
- :align: center
-
- Sequence diagram of the RRC Connection Reconfiguration procedure
-
-
-
-Figure :ref:`fig-rrc-connection-reconf-handover` shows how the RRC
-Connection Reconfiguration procedure is modeled for the case where
-MobilityControlInfo is provided, i.e., handover is to be performed.
-As specified in [TS36331]_, *After receiving the handover message,
-the UE attempts to access the target cell at the first available RACH
-occasion according to Random Access resource selection defined in [TS36321]_,
-i.e. the handover is asynchronous. Consequently, when
-allocating a dedicated preamble for the random access in the target
-cell, E-UTRA shall ensure it is available from the first RACH occasion
-the UE may use. Upon successful completion of the handover, the UE
-sends a message used to confirm the handover.* Note that the random
-access procedure in this case is non-contention based, hence in a real
-LTE system it differs slightly from the one used in RRC connection
-established. Also note that the RA Preamble ID is signalled via RRC
-using the RACH-ConfigDedicated IE which is part of MobilityControlInfo.
-
-
-.. _fig-rrc-connection-reconf-handover:
-
-.. figure:: figures/rrc-connection-reconfiguration-handover.*
- :align: center
-
- Sequence diagram of the RRC Connection Reconfiguration procedure
- for the handover case
-
-
-
-Connection Setup Signaling implementation
------------------------------------------
-
-As can be observed from the sequence diagrams of the RRC procedures
-reported in the previous subsection, RRC procedures involve control
-messages of several kinds at various layers (especially for the random
-access procedure). In the following, we describe how they are
-implemented in the simulator.
-
-
- * **MAC** messages:
-
- - **Random Access (RA) preamble**: in real LTE systems this
- corresponds to a Zadoff-Chu (ZC)
- sequence using one of several formats available and sent in the
- PRACH slots which could in principle overlap with PUSCH. Since an
- accurate modeling of the random access procedure is not a
- requirement of the simulator, the RA preamble will be modeled by
- an apposite ideal control message, without consuming any radio
- resources and without any associated error model.
-
- - **Random Access Response (RAR)**: in real LTE systems, this is a
- special MAC PDU sent on the DL-SCH. Since MAC PDUs are not
- accurately modeled in the simulator (only RLC and above PDUs
- are), the RAR is modeled as an ideal control message, without any
- associated error model. Still, the consumption of Radio
- Resources for sending the RAR is modeled by interaction with
- the scheduler using the FF MAC Scheduler primitive
- SCHED_DL_RACH_INFO_REQ.
-
- - **Contention Resolution (CR)**: in real LTE system, the CR is
- sent as a regular MAC PDU with a special LCID and a CR MAC CE sent on the
- DL-SCH. In the simulator, it is implemented as an
- ideal control message without any associated error model, but still
- modeling the associated consumption of scheduler resources by
- using the FF MAC Scheduler primitive SCHED_DL_MAC_BUFFER_REQ.
-
- * **SRB0** messages (over CCCH):
-
- - **RrcConnectionRequest**: in real LTE systems, this is an RLC TM
- SDU sent over resources specified in the UL Grant in the RAR (not
- in UL DCIs); the reason is that C-RNTI is not known yet at this
- stage. In the simulator, this is modeled as a real RLC TM RLC PDU
- whose UL resources are allocated by the sched upon call to
- SCHED_DL_RACH_INFO_REQ.
-
- - **RrcConnectionSetup**: in the simulator this is implemented as in
- real LTE systems, i.e., with an RLC TM SDU sent over resources
- indicated by a regular UL DCI, allocated with
- SCHED_DL_RLC_BUFFER_REQ triggered by the RLC TM instance that is
- mapped to LCID 0 (the CCCH).
-
- * **SRB1** messages (over DCCH):
-
- - All the SRB1 messages modeled in the simulator (e.g.,
- **RrcConnectionCompleted**) are implemented as in real LTE systems,
- i.e., with a real RLC SDU sent over RLC AM using DL resources
- allocated via Buffer Status Reports. See the RLC model
- documentation for details.
-
- * **SRB2** messages (over DCCH):
-
- - According to [TS36331]_, "*SRB1 is for RRC messages (which may
- include a piggybacked NAS message) as well as for NAS messages
- prior to the establishment of SRB2, all using DCCH logical
- channel*", whereas "*SRB2 is for NAS messages, using DCCH
- logical channel*" and "*SRB2 has a lower-priority than SRB1 and is
- always configured by E-UTRAN after security
- activation*". Modeling security-related aspects is not a
- requirement of the LTE simulation model, hence we always use
- SRB1 and never activate SRB2.
-
-
-Radio Link Failure
-------------------
-
-Since at this stage the RRC supports the CONNECTED mode only, Radio Link
-Failure (RLF) is not handled. The reason is that one of the possible
-outcomes of RLF (when RRC re-establishment is unsuccessful) is to
-leave RRC CONNECTED notifying the NAS of the RRC connection
-failure. In order to model RLF properly, RRC IDLE mode should be
-supported.
-
-With the current model, an UE that experiences bad link quality will
-just stay associated with the same eNB, and the scheduler will stop
-allocating resources to it for communications. This is also consistent
-with the fact that, at this stage, only handovers explicitly triggered
-within the simulation program are supported (network-driven handovers
-based on UE measurements are planned only at a later stage).
-
-
-Non-Access Stratum (NAS) model
-++++++++++++++++++++++++++++++
-
-
-The focus of the LTE-EPC model is on the NAS Active state, which corresponds to EMM Registered, ECM connected, and RRC connected. Because of this, the following simplifications are made:
-
- - EMM and ECM are not modeled explicitly; instead, the NAS entity at the UE will interact directy with the EpcHelper to perfom actions that are equivalent (with gross simplifications) to taking the UE to the states EMM Connected and ECM Connected;
-
- - the NAS also takes care of multiplexing uplink data packets coming from the upper layers into the appropriate EPS bearer by using the Traffic Flow Template classifier (TftClassifier). (NB: this is currently in the RRC, but it is better to move it to the NAS).
-
-- the NAS does not support PLMN and CSG selection
-
-- the NAS does not support any location update/paging procedure in idle mode
-
-
-
-Figure :ref:`fig-nas-attach` shows how the simplified NAS model implements the attach procedure. Note that the default EPS bearer is also activated as part of this procedure.
-
-
-.. _fig-nas-attach:
-
-.. figure:: figures/nas-attach.*
- :align: center
-
- Sequence diagram of the attach procedure
-
-
-
-
-Figure :ref:`fig-nas-activate-dedicated-bearer` shows how the
-simplified NAS model implements the activation of a dedicated EPS
-bearer.
-
-
-.. _fig-nas-activate-dedicated-bearer:
-
-.. figure:: figures/nas-activate-dedicated-bearer.*
- :align: center
-
- Sequence diagram of the procedure for the activation of a dedicated EPS bearer
-
-
-
-
+ EPC control model
@@ -1316,17 +318,145 @@
-
-
-
-
-
+-----------------------
+Channel and Propagation
+-----------------------
+
+
+The LTE module works with the channel objects provided by the Spectrum module, i.e., either SingleModelSpectrumChannel or MultiModelSpectrumChannel. Because of these, all the propagation models supported by these objecs can be used within the LTE module.
+
+
+
+Use of the Buildings model with LTE
++++++++++++++++++++++++++++++++++++
+
+The recommended propagation model to be used with the LTE
+module is the one provided by the Buildings module, which was in fact
+designed specifically with LTE (though it can be used with other
+wireless technologies as well). Please refer to the documentation of
+the Buildings module for generic information on the propagation model
+it provides.
+
+In this section we will highlight some considerations that
+specifically apply when the Buildings module is used together with the
+LTE module.
+
+
+The naming convention used in the following will be:
+
+ * User equipment: UE
+ * Macro Base Station: MBS
+ * Small cell Base Station (e.g., pico/femtocell): SC
+
+
+The LTE module considers FDD only, and implements downlink and uplink propagation separately. As a consequence, the following pathloss computations are performed
+
+ * MBS <-> UE (indoor and outdoor)
+ * SC (indoor and outdoor) <-> UE (indoor and outdoor)
+
+The LTE model does not provide the following pathloss computations:
+
+ * UE <-> UE
+ * MBS <-> MBS
+ * MBS <-> SC
+ * SC <-> SC
+
+
+The Buildings model does not know the actual type of the node; i.e.,
+it is not aware of whether a transmitter node is a UE, a MBS, or a
+SC. Rather, the Buildings model only cares about the position of the
+node: whether it is indoor and outdoor, and what is its z-axis respect
+to the rooftop level. As a consequence, for an eNB node that is placed
+outdoor and at a z-coordinate above the rooftop level, the propagation
+models typical of MBS will be used by the Buildings
+module. Conversely, for an eNB that is placed outdoor but below the
+rooftop, or indoor, the propagation models typical of pico and
+femtocells will be used.
+
+For communications involving at least one indoor node, the
+corresponding wall penetration losses will be calculated by the
+Buildings model. This covers the following use cases:
+
+ * MBS <-> indoor UE
+ * outdoor SC <-> indoor UE
+ * indoor SC <-> indoor UE
+ * indoor SC <-> outdoor UE
+
+Please refer to the documentation of the Buildings module for details
+on the actual models used in each case.
+
+
+Fading Model
+++++++++++++
+
+The LTE module includes a trace-based fading model derived from the one developed during the GSoC 2010 [Piro2011]_. The main characteristic of this model is the fact that the fading evaluation during simulation run-time is based on per-calculated traces. This is done to limit the computational complexity of the simulator. On the other hand, it needs huge structures for storing the traces; therefore, a trade-off between the number of possible parameters and the memory occupancy has to be found. The most important ones are:
+
+ * users' speed: relative speed between users (affects the Doppler frequency, which in turns affects the time-variance property of the fading)
+ * number of taps (and relative power): number of multiple paths considered, which affects the frequency property of the fading.
+ * time granularity of the trace: sampling time of the trace.
+ * frequency granularity of the trace: number of values in frequency to be evaluated.
+ * length of trace: ideally large as the simulation time, might be reduced by windowing mechanism.
+ * number of users: number of independent traces to be used (ideally one trace per user).
+
+With respect to the mathematical channel propagation model, we suggest the one provided by the ``rayleighchan`` function of Matlab, since it provides a well accepted channel modelization both in time and frequency domain. For more information, the reader is referred to [mathworks]_.
+
+The simulator provides a matlab script (``/lte/model/JakesTraces/fading-trace-generator.m``) for generating traces based on the format used by the simulator.
+In detail, the channel object created with the rayleighchan function is used for filtering a discrete-time impulse signal in order to obtain the channel impulse response. The filtering is repeated for different TTI, thus yielding subsequent time-correlated channel responses (one per TTI). The channel response is then processed with the ``pwelch`` function for obtaining its power spectral density values, which are then saved in a file with the proper format compatible with the simulator model.
+
+Since the number of variable it is pretty high, generate traces considering all of them might produce a high number of traces of huge size. On this matter, we considered the following assumptions of the parameters based on the 3GPP fading propagation conditions (see Annex B.2 of [TS36104]_):
+
+ * users' speed: typically only a few discrete values are considered, i.e.:
+
+ * 0 and 3 kmph for pedestrian scenarios
+ * 30 and 60 kmph for vehicular scenarios
+ * 0, 3, 30 and 60 for urban scenarios
+
+ * channel taps: only a limited number of sets of channel taps are normally considered, for example three models are mentioned in Annex B.2 of [TS36104]_.
+ * time granularity: we need one fading value per TTI, i.e., every 1 ms (as this is the granularity in time of the ns-3 LTE PHY model).
+ * frequency granularity: we need one fading value per RB (which is the frequency granularity of the spectrum model used by the ns-3 LTE model).
+ * length of the trace: the simulator includes the windowing mechanism implemented during the GSoC 2011, which consists of picking up a window of the trace each window length in a random fashion.
+ * per-user fading process: users share the same fading trace, but for each user a different starting point in the trace is randomly picked up. This choice was made to avoid the need to provide one fading trace per user.
+
+According to the parameters we considered, the following formula express in detail the total size :math:`S_{traces}` of the fading traces:
+
+.. math::
+ S_{traces} = S_{sample} \times N_{RB} \times \frac{T_{trace}}{T_{sample}} \times N_{scenarios} \mbox{ [bytes]}
+
+where :math:`S_{sample}` is the size in bytes of the sample (e.g., 8 in case of double precision, 4 in case of float precision), :math:`N_{RB}` is the number of RB or set of RBs to be considered, :math:`T_{trace}` is the total length of the trace, :math:`T_{sample}` is the time resolution of the trace (1 ms), and :math:`N_{scenarios}` is the number of fading scenarios that are desired (i.e., combinations of different sets of channel taps and user speed values). We provide traces for 3 different scenarios one for each taps configuration defined in Annex B.2 of [TS36104]_:
+
+ * Pedestrian: with nodes' speed of 3 kmph.
+ * Vehicular: with nodes' speed of 60 kmph.
+ * Urban: with nodes' speed of 3 kmph.
+
+hence :math:`N_{scenarios} = 3`. All traces have :math:`T_{trace} = 10` s and :math:`RB_{NUM} = 100`. This results in a total 24 MB bytes of traces.
+
+
+Antennas
+++++++++
+
+Being based on the SpectrumPhy, the LTE PHY model supports antenna
+modeling via the ns-3 AntennaModel class. Hence, any model based on
+this class can be associated with any eNB or UE instance. For
+instance, the use of the CosineAntennaModel associated with an eNB
+device allows to model one sector of a macro base station. By default,
+the IsotropicAntennaModel is used for both eNBs and UEs.
+
+
+
+.. only:: latex
+
+ .. raw:: latex
+
+ \clearpage
+
+
+----
PHY
-+++
+----
Overview
---------
+++++++++
The physical layer model provided in this LTE simulator is based on
the one described in [Piro2011]_, with the following modifications. The model now includes the
@@ -1334,7 +464,7 @@
Subframe Structure
-^^^^^^^^^^^^^^^^^^
+------------------
The subframe is divided into control and data part as described in Figure :ref:`fig-lte-subframe-structure`.
@@ -1346,21 +476,21 @@
Lte subframe division.
-Considering the granularity of the simulator based on RB, the control and the reference signaling have to be consequently modeled considering this constraint. According to the standard [TS36.211]_, the downlink control frame starts at the beginning of each subframe and lasts up to three symbols across the whole system bandwidth, where the actual duration is provided by the Physical Control Format Indicator Channel (PCFICH). The information on the allocation are then mapped in the remaining resource up to the duration defined by the PCFICH, in the so called Physical Downlink Control Channel (PDCCH). A PDCCH transports a single message called Downlink Control Information (DCI) coming from the MAC layer, where the scheduler indicates the resource allocation for a specific user.
+Considering the granularity of the simulator based on RB, the control and the reference signaling have to be consequently modeled considering this constraint. According to the standard [TS36211]_, the downlink control frame starts at the beginning of each subframe and lasts up to three symbols across the whole system bandwidth, where the actual duration is provided by the Physical Control Format Indicator Channel (PCFICH). The information on the allocation are then mapped in the remaining resource up to the duration defined by the PCFICH, in the so called Physical Downlink Control Channel (PDCCH). A PDCCH transports a single message called Downlink Control Information (DCI) coming from the MAC layer, where the scheduler indicates the resource allocation for a specific user.
The PCFICH and PDCCH are modeled with the transmission of the control frame of a fixed duration of 3/14 of milliseconds spanning in the whole available bandwidth, since the scheduler does not estimate the size of the control region. This implies that a single transmission block models the entire control frame with a fixed power (i.e., the one used for the PDSCH) across all the available RBs. According to this feature, this transmission represents also a valuable support for the Reference Signal (RS). This allows of having every TTI an evaluation of the interference scenario since all the eNB are transmitting (simultaneously) the control frame over the respective available bandwidths. We note that, the model does not include the power boosting since it does not reflect any improvement in the implemented model of the channel estimation.
-The Sounding Reference Signal (SRS) is modeled similar to the downlink control frame. The SRS is periodically placed in the last symbol of the subframe in the whole system bandwidth. The RRC module already includes an algorithm for dynamically assigning the periodicity as function of the actual number of UEs attached to a eNB according to the UE-specific procedure (see Section 8.2 of [TS36.213]_).
+The Sounding Reference Signal (SRS) is modeled similar to the downlink control frame. The SRS is periodically placed in the last symbol of the subframe in the whole system bandwidth. The RRC module already includes an algorithm for dynamically assigning the periodicity as function of the actual number of UEs attached to a eNB according to the UE-specific procedure (see Section 8.2 of [TS36213]_).
MAC to Channel delay
-^^^^^^^^^^^^^^^^^^^^
+--------------------
To model the latency of real MAC and PHY implementations, the PHY model simulates a MAC-to-channel delay in multiples of TTIs (1ms). The transmission of both data and control packets are delayed by this amount.
CQI feedback
-^^^^^^^^^^^^
+------------
The generation of CQI feedback is done accordingly to what specified in [FFAPI]_. In detail, we considered the generation
of periodic wideband CQI (i.e., a single value of channel state that is deemed representative of all RBs
@@ -1369,7 +499,7 @@
The CQI feedbacks are currently evaluated according to the SINR perceived by data transmissions (i.e., PDSHC for downlink and PUSCH for uplink) instead of the one based on reference signals (i.e., RS for downlink and SRS for uplink) since that signals are not implemented in the current version of the PHY layer. This implies that a UE has to transmit some data in order to have CQI feedbacks. This assumption is based on the fact that the reference signals defined in LTE are usually multiplexed within the data transmissions resources.
Interference Model
-^^^^^^^^^^^^^^^^^^
+------------------
The PHY model is based on the well-known Gaussian interference models, according to which the powers of interfering signals (in linear units) are summed up together to determine the overall interference power.
@@ -1386,7 +516,7 @@
LTE Spectrum Model
-^^^^^^^^^^^^^^^^^^
+------------------
The usage of the radio spectrum by eNBs and UEs in LTE is described in
[TS36101]_. In the simulator, radio spectrum usage is modeled as follows.
@@ -1586,7 +716,7 @@
\clearpage
----------
-HARQ Model
+HARQ
----------
The HARQ scheme implemented is based on a incremental redundancy (IR) solutions combined with multiple stop-and-wait processes for enabling a continuous data flow. In detail, the solution adopted is the *soft combining hybrid IR Full incremental redundancy* (also called IR Type II), which implies that the retransmissions contain only new information respect to the previous ones. The resource allocation algorithm of the HARQ has been implemented within the respective scheduler classes (i.e., ``RrFfMacScheduler`` and ``PfFfMacScheduler``, refer to their correspondent sections for more info), while the decodification part of the HARQ has been implemented in the ``LteSpectrumPhy`` and ``LteHarqPhy`` classes which will be detailed in this section.
@@ -1637,202 +767,1480 @@
\clearpage
-
-
------------------------
-Channel and Propagation
------------------------
-
-
-The LTE module works with the channel objects provided by the Spectrum module, i.e., either SingleModelSpectrumChannel or MultiModelSpectrumChannel. Because of these, all the propagation models supported by these objecs can be used within the LTE module.
-
-
-
-Use of the Buildings model with LTE
-+++++++++++++++++++++++++++++++++++
-
-The recommended propagation model to be used with the LTE
-module is the one provided by the Buildings module, which was in fact
-designed specifically with LTE (though it can be used with other
-wireless technologies as well). Please refer to the documentation of
-the Buildings module for generic information on the propagation model
-it provides.
-
-In this section we will highlight some considerations that
-specifically apply when the Buildings module is used together with the
-LTE module.
-
-
-The naming convention used in the following will be:
-
- * User equipment: UE
- * Macro Base Station: MBS
- * Small cell Base Station (e.g., pico/femtocell): SC
-
-
-The LTE module considers FDD only, and implements downlink and uplink propagation separately. As a consequence, the following pathloss computations are performed
-
- * MBS <-> UE (indoor and outdoor)
- * SC (indoor and outdoor) <-> UE (indoor and outdoor)
-
-The LTE model does not provide the following pathloss computations:
-
- * UE <-> UE
- * MBS <-> MBS
- * MBS <-> SC
- * SC <-> SC
-
-
-The Buildings model does not know the actual type of the node; i.e.,
-it is not aware of whether a transmitter node is a UE, a MBS, or a
-SC. Rather, the Buildings model only cares about the position of the
-node: whether it is indoor and outdoor, and what is its z-axis respect
-to the rooftop level. As a consequence, for an eNB node that is placed
-outdoor and at a z-coordinate above the rooftop level, the propagation
-models typical of MBS will be used by the Buildings
-module. Conversely, for an eNB that is placed outdoor but below the
-rooftop, or indoor, the propagation models typical of pico and
-femtocells will be used.
-
-For communications involving at least one indoor node, the
-corresponding wall penetration losses will be calculated by the
-Buildings model. This covers the following use cases:
-
- * MBS <-> indoor UE
- * outdoor SC <-> indoor UE
- * indoor SC <-> indoor UE
- * indoor SC <-> outdoor UE
-
-Please refer to the documentation of the Buildings module for details
-on the actual models used in each case.
-
-
-Fading Model
-++++++++++++
-
-The LTE module includes a trace-based fading model derived from the one developed during the GSoC 2010 [Piro2011]_. The main characteristic of this model is the fact that the fading evaluation during simulation run-time is based on per-calculated traces. This is done to limit the computational complexity of the simulator. On the other hand, it needs huge structures for storing the traces; therefore, a trade-off between the number of possible parameters and the memory occupancy has to be found. The most important ones are:
-
- * users' speed: relative speed between users (affects the Doppler frequency, which in turns affects the time-variance property of the fading)
- * number of taps (and relative power): number of multiple paths considered, which affects the frequency property of the fading.
- * time granularity of the trace: sampling time of the trace.
- * frequency granularity of the trace: number of values in frequency to be evaluated.
- * length of trace: ideally large as the simulation time, might be reduced by windowing mechanism.
- * number of users: number of independent traces to be used (ideally one trace per user).
-
-With respect to the mathematical channel propagation model, we suggest the one provided by the ``rayleighchan`` function of Matlab, since it provides a well accepted channel modelization both in time and frequency domain. For more information, the reader is referred to [mathworks]_.
-
-The simulator provides a matlab script (``/lte/model/JakesTraces/fading-trace-generator.m``) for generating traces based on the format used by the simulator.
-In detail, the channel object created with the rayleighchan function is used for filtering a discrete-time impulse signal in order to obtain the channel impulse response. The filtering is repeated for different TTI, thus yielding subsequent time-correlated channel responses (one per TTI). The channel response is then processed with the ``pwelch`` function for obtaining its power spectral density values, which are then saved in a file with the proper format compatible with the simulator model.
-
-Since the number of variable it is pretty high, generate traces considering all of them might produce a high number of traces of huge size. On this matter, we considered the following assumptions of the parameters based on the 3GPP fading propagation conditions (see Annex B.2 of [TS36104]_):
-
- * users' speed: typically only a few discrete values are considered, i.e.:
-
- * 0 and 3 kmph for pedestrian scenarios
- * 30 and 60 kmph for vehicular scenarios
- * 0, 3, 30 and 60 for urban scenarios
-
- * channel taps: only a limited number of sets of channel taps are normally considered, for example three models are mentioned in Annex B.2 of [TS36104]_.
- * time granularity: we need one fading value per TTI, i.e., every 1 ms (as this is the granularity in time of the ns-3 LTE PHY model).
- * frequency granularity: we need one fading value per RB (which is the frequency granularity of the spectrum model used by the ns-3 LTE model).
- * length of the trace: the simulator includes the windowing mechanism implemented during the GSoC 2011, which consists of picking up a window of the trace each window length in a random fashion.
- * per-user fading process: users share the same fading trace, but for each user a different starting point in the trace is randomly picked up. This choice was made to avoid the need to provide one fading trace per user.
-
-According to the parameters we considered, the following formula express in detail the total size :math:`S_{traces}` of the fading traces:
+------
+MAC
+------
+
+
+Resource Allocation Model
++++++++++++++++++++++++++
+
+
+We now briefly describe how resource allocation is handled in LTE,
+clarifying how it is modeled in the simulator. The scheduler is in
+charge of generating specific structures calles Data Control Indication (DCI)
+which are then transmitted by the PHY of the eNB to the connected UEs, in order
+to inform them of the resource allocation on a per subframe basis. In doing this
+in the downlink direction, the scheduler has to fill some specific fields of the
+DCI structure with all the information, such as: the Modulation and Coding
+Scheme (MCS) to be used, the MAC Transport Block (TB) size, and the allocation
+bitmap which identifies which RBs will contain the data
+transmitted by the eNB to each user.
+
+For the mapping of resources to
+physical RBs, we adopt a *localized mapping* approach
+(see [Sesia2009]_, Section 9.2.2.1);
+hence in a given subframe each RB is always allocated to the same user in both
+slots.
+The allocation bitmap can be coded in
+different formats; in this implementation, we considered the *Allocation
+Type 0* defined in [TS36213]_, according to which the RBs are grouped in
+Resource Block Groups (RBG) of different size determined as a function of the
+Transmission Bandwidth Configuration in use.
+
+For certain bandwidth
+values not all the RBs are usable, since the
+group size is not a common divisor of the group. This is for instance the case
+when the bandwidth is equal to 25 RBs, which results in a RBG size of 2 RBs, and
+therefore 1 RB will result not addressable.
+In uplink the format of the DCIs is different, since only adjacent RBs
+can be used because of the SC-FDMA modulation. As a consequence, all
+RBs can be allocated by the eNB regardless of the bandwidth
+configuration.
+
+.. _sec-lte-amc:
+
+Adaptive Modulation and Coding
+++++++++++++++++++++++++++++++
+
+The simulator provides two Adaptive Modulation and Coding (AMC) models: one based on the GSoC model [Piro2011]_ and one based on the physical error model (described in the following sections).
+
+The former model is a modified version of the model described in [Piro2011]_,
+which in turn is inspired from [Seo2004]_. Our version is described in the
+following. Let :math:`i` denote the
+generic user, and let :math:`\gamma_i` be its SINR. We get the spectral efficiency
+:math:`\eta_i` of user :math:`i` using the following equations:
.. math::
- S_{traces} = S_{sample} \times N_{RB} \times \frac{T_{trace}}{T_{sample}} \times N_{scenarios} \mbox{ [bytes]}
-
-where :math:`S_{sample}` is the size in bytes of the sample (e.g., 8 in case of double precision, 4 in case of float precision), :math:`N_{RB}` is the number of RB or set of RBs to be considered, :math:`T_{trace}` is the total length of the trace, :math:`T_{sample}` is the time resolution of the trace (1 ms), and :math:`N_{scenarios}` is the number of fading scenarios that are desired (i.e., combinations of different sets of channel taps and user speed values). We provide traces for 3 different scenarios one for each taps configuration defined in Annex B.2 of [TS36104]_:
-
- * Pedestrian: with nodes' speed of 3 kmph.
- * Vehicular: with nodes' speed of 60 kmph.
- * Urban: with nodes' speed of 3 kmph.
-
-hence :math:`N_{scenarios} = 3`. All traces have :math:`T_{trace} = 10` s and :math:`RB_{NUM} = 100`. This results in a total 24 MB bytes of traces.
-
-
-Antennas
-++++++++
-
-Being based on the SpectrumPhy, the LTE PHY model supports antenna
-modeling via the ns-3 AntennaModel class. Hence, any model based on
-this class can be associated with any eNB or UE instance. For
-instance, the use of the CosineAntennaModel associated with an eNB
-device allows to model one sector of a macro base station. By default,
-the IsotropicAntennaModel is used for both eNBs and UEs.
-
-
--------
-Helpers
--------
-
-Two helper objects are use to setup simulations and configure the
-various components. These objects are:
-
-
- * LteHelper, which takes care of the configuration of the LTE radio
- access network, as well as of coordinating the setup and release of
- EPS bearers
- * EpcHelper, which takes care of the configuratio of the Evolved
- Packet Core
-
-It is possible to create a simple LTE-only simulations by
-using LteHelper alone, or to create complete LTE-EPC simulations by
-using both LteHelper and EpcHelper. When both helpers are used, they
-interact in a master-slave fashion, with LteHelper being the Master
-that interacts directly with the user program, and EpcHelper working
-"under the hood" to configure the EPC upon explicit methods called by
-LteHelper. The exact interactions are displayed in the Figure :ref:`fig-helpers`.
-
-.. _fig-helpers:
+
+ \mathrm{BER} = 0.00005
+
+ \Gamma = \frac{ -\ln{ (5 * \mathrm{BER}) } }{ 1.5}
+
+ \eta_i = \log_2 { \left( 1 + \frac{ {\gamma}_i }{ \Gamma } \right)}
+
+The procedure described in [R1-081483]_ is used to get
+the corresponding MCS scheme. The spectral efficiency is quantized based on the
+channel quality indicator (CQI), rounding to the lowest value, and is mapped to the corresponding MCS
+scheme.
+
+Finally, we note that there are some discrepancies between the MCS index
+in [R1-081483]_
+and that indicated by the standard: [TS36213]_ Table
+7.1.7.1-1 says that the MCS index goes from 0 to 31, and 0 appears to be a valid
+MCS scheme (TB size is not 0) but in [R1-081483]_ the first useful MCS
+index
+is 1. Hence to get the value as intended by the standard we need to subtract 1
+from the index reported in [R1-081483]_.
+
+The alternative model is based on the physical error model developed for this simulator and explained in the following subsections. This scheme is able to adapt the MCS selection to the actual PHY layer performance according to the specific CQI report. According to their definition, a CQI index is assigned when a single PDSCH TB with the modulation coding scheme and code rate correspondent to that CQI index in table 7.2.3-1 of [TS36213]_ can be received with an error probability less than 0.1. In case of wideband CQIs, the reference TB includes all the RBGs available in order to have a reference based on the whole available resources; while, for subband CQIs, the reference TB is sized as the RBGs.
+
+
+Transport Block model
++++++++++++++++++++++
+
+The model of the MAC Transport Blocks (TBs) provided by the simulator
+is simplified with respect to the 3GPP specifications. In particular,
+a simulator-specific class (PacketBurst) is used to aggregate
+MAC SDUs in order to achieve the simulator's equivalent of a TB,
+without the corresponding implementation complexity.
+The multiplexing of different logical channels to and from the RLC
+layer is performed using a dedicated packet tag (LteRadioBearerTag), which
+performs a functionality which is partially equivalent to that of the
+MAC headers specified by 3GPP.
+
+
+
+The FemtoForum MAC Scheduler Interface
+++++++++++++++++++++++++++++++++++++++
+
+This section describes the ns-3 specific version of the LTE MAC
+Scheduler Interface Specification published by the FemtoForum [FFAPI]_.
+
+We implemented the ns-3 specific version of the FemtoForum MAC Scheduler
+Interface [FFAPI]_ as a set of C++ abstract
+classes; in particular, each primitive is translated to a C++ method of a
+given class. The term *implemented* here is used with the same
+meaning adopted in [FFAPI]_, and hence refers to the process of translating
+the logical interface specification to a particular programming language.
+The primitives in [FFAPI]_ are grouped in two groups: the CSCHED
+primitives, which deal with scheduler configuration, and the SCHED primitives,
+which deal with the execution of the scheduler. Furthermore, [FFAPI]_
+defines primitives of two different kinds: those of type REQ go from the MAC to
+the Scheduler, and those of type IND/CNF go from the scheduler to the MAC. To
+translate these characteristics into C++, we define the following abstract
+classes that implement Service Access Points (SAPs) to be used to issue the
+primitives:
+
+ * the ``FfMacSchedSapProvider`` class defines all the C++ methods that
+ correspond to SCHED primitives of type REQ;
+ * the ``FfMacSchedSapUser`` class defines all the C++ methods that
+ correspond to SCHED primitives of type CNF/IND;
+ * the ``FfMacCschedSapProvider`` class defines all the C++ methods that
+ correspond to CSCHED primitives of type REQ;
+ * the ``FfMacCschedSapUser`` class defines all the C++ methods that
+ correspond to CSCHED primitives of type CNF/IND;
+
+
+There are 3 blocks involved in the MAC Scheduler interface: Control block,
+Subframe block and Scheduler block. Each of these blocks provide one part of the
+MAC Scheduler interface. The figure below shows the relationship
+between the blocks and the SAPs defined in our implementation of the MAC
+Scheduler Interface.
+
+.. figure:: figures/ff-mac-saps.*
+ :align: center
+
+In addition to the above principles, the following design choices have been
+taken:
+
+ * The definition of the MAC Scheduler interface classes follows the naming
+ conventions of the |ns3| Coding Style. In particular, we follow the
+ CamelCase convention for the primitive names. For example, the primitive
+ ``CSCHED_CELL_CONFIG_REQ`` is translated to ``CschedCellConfigReq``
+ in the |ns3| code.
+ * The same naming conventions are followed for the primitive parameters. As
+ the primitive parameters are member variables of classes, they are also prefixed
+ with a ``m_``.
+ * regarding the use of vectors and lists in data structures, we note
+ that [FFAPI]_ is a pretty much C-oriented API. However, considered that
+ C++ is used in ns-3, and that the use of C arrays is discouraged, we used STL
+ vectors (``std::vector``) for the implementation of the MAC Scheduler
+ Interface, instead of using C arrays as implicitly suggested by the
+ way [FFAPI]_ is written.
+ * In C++, members with constructors and destructors are not allow in
+ ``unions``. Hence all those data structures that are said to be
+ ``unions`` in [FFAPI]_ have been defined as ``structs`` in our code.
+
+The figure below shows how the MAC Scheduler Interface is
+used within the eNB.
+
+.. figure:: figures/ff-example.*
+ :align: center
+
+
+The User side of both the CSCHED SAP and the SCHED SAP are
+implemented within the eNB MAC, i.e., in the file ``lte-enb-mac.cc``.
+The eNB MAC can be used with different scheduler implementations without
+modifications. The same figure also shows, as an example, how the Round Robin
+Scheduler is implemented: to interact with the MAC of the eNB, the Round Robin
+scheduler implements the Provider side of the SCHED SAP and CSCHED
+SAP interfaces. A similar approach can be used to implement other schedulers as
+well. A description of each of the scheduler implementations that we provide as
+part of our LTE simulation module is provided in the following subsections.
+
+
+
+Round Robin (RR) Scheduler
+--------------------------
+
+The Round Robin (RR) scheduler is probably the simplest scheduler found in the literature. It works by dividing the
+available resources among the active flows, i.e., those logical channels which have a non-empty RLC queue. If the number of RBGs is greater than the number of active flows, all the flows can be allocated in the same subframe. Otherwise, if the number of active flows is greater than the number of RBGs, not all the flows can be scheduled in a given subframe; then, in the next subframe the allocation will start from the last flow that was not allocated. The MCS to be adopted for each user is done according to the received wideband CQIs.
+
+For what concern the HARQ, RR implements the non adaptive version, which implies that in allocating the retransmission attempts RR uses the same allocation configuration of the original block, which means maintaining the same RBGs and MCS. UEs that are allocated for HARQ retransmissions are not considered for the transmission of new data in case they have a transmission opportunity available in the same TTI. Finally, HARQ can be disabled with ns3 attribute system for maintaining backward compatibility with old test cases and code, in detail::
+
+ Config::SetDefault ("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue (false));
+
+
+
+Proportional Fair (PF) Scheduler
+--------------------------------
+
+The Proportional Fair (PF) scheduler [Sesia2009]_ works by scheduling a user
+when its
+instantaneous channel quality is high relative to its own average channel
+condition over time. Let :math:`i,j` denote generic users; let :math:`t` be the
+subframe index, and :math:`k` be the resource block index; let :math:`M_{i,k}(t)` be MCS
+usable by user :math:`i` on resource block :math:`k` according to what reported by the AMC
+model (see `Adaptive Modulation and Coding`_); finally, let :math:`S(M, B)` be the TB
+size in bits as defined in [TS36213]_ for the case where a number :math:`B` of
+resource blocks is used. The achievable rate :math:`R_{i}(k,t)` in bit/s for user :math:`i`
+on resource block group :math:`k` at subframe :math:`t` is defined as
+
+.. math::
+
+ R_{i}(k,t) = \frac{S\left( M_{i,k}(t), 1\right)}{\tau}
+
+where :math:`\tau` is the TTI duration.
+At the start of each subframe :math:`t`, each RBG is assigned to a certain user.
+In detail, the index :math:`\widehat{i}_{k}(t)` to which RBG :math:`k` is assigned at time
+:math:`t` is determined as
+
+.. math::
+
+ \widehat{i}_{k}(t) = \underset{j=1,...,N}{\operatorname{argmax}}
+ \left( \frac{ R_{j}(k,t) }{ T_\mathrm{j}(t) } \right)
+
+where :math:`T_{j}(t)` is the past througput performance perceived by the
+user :math:`j`.
+According to the above scheduling algorithm, a user can be allocated to
+different RBGs, which can be either adjacent or not, depending on the current
+condition of the channel and the past throughput performance :math:`T_{j}(t)`. The
+latter is determined at the end of the subframe :math:`t` using the following
+exponential moving average approach:
+
+.. math::
+
+ T_{j}(t) =
+ (1-\frac{1}{\alpha})T_{j}(t-1)
+ +\frac{1}{\alpha} \widehat{T}_{j}(t)
+
+where :math:`\alpha` is the time constant (in number of subframes) of
+the exponential moving average, and :math:`\widehat{T}_{j}(t)` is the actual
+throughput achieved by the user :math:`i` in the subframe :math:`t`. :math:`\widehat{T}_{j}(t)`
+is measured according to the following procedure. First we
+determine the MCS :math:`\widehat{M}_j(t)` actually used by user
+:math:`j`:
+
+.. math::
+
+ \widehat{M}_j(t) = \min_{k: \widehat{i}_{k}(t) = j}{M_{j,k}(t)}
+
+then we determine the total number :math:`\widehat{B}_j(t)` of RBGs allocated to user
+:math:`j`:
+
+.. math::
+
+ \widehat{B}_j(t) = \left| \{ k : \widehat{i}_{k}(t) = j \} \right|
+
+where :math:`|\cdot|` indicates the cardinality of the set; finally,
+
+.. math::
+
+ \widehat{T}_{j}(t) = \frac{S\left( \widehat{M}_j(t), \widehat{B}_j(t)
+ \right)}{\tau}
-.. figure:: figures/helpers.*
+
+For what concern the HARQ, PF implements the non adaptive version, which implies that in allocating the retransmission attempts the scheduler uses the same allocation configuration of the original block, which means maintaining the same RBGs and MCS. UEs that are allocated for HARQ retransmissions are not considered for the transmission of new data in case they have a transmission opportunity available in the same TTI. Finally, HARQ can be disabled with ns3 attribute system for maintaining backward compatibility with old test cases and code, in detail::
+
+ Config::SetDefault ("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue (false));
+
+
+Random Access
++++++++++++++
+
+The LTE model includes a model of the Random Access procedure based on
+some simplifying assumptions, which are detailed in the following for
+each of the messages and signals described in the specs [TS36321]_.
+
+ - **Random Access (RA) preamble**: in real LTE systems this
+ corresponds to a Zadoff-Chu (ZC)
+ sequence using one of several formats available and sent in the
+ PRACH slots which could in principle overlap with PUSCH.
+ The RA preamble is modeled using the LteControlMessage class,
+ i.e., as an ideal message that does not consume any radio
+ resources. The collision of preamble transmission by multiple UEs
+ in the same cell are modeled using a protocol interference model,
+ i.e., whenever two or more identical preambles are transmitted in
+ same cell at the same TTI, no one of these identical preambles
+ will be received by the eNB. Other than this collision model, no
+ error model is associated with the reception of a RA preamble.
+
+ - **Random Access Response (RAR)**: in real LTE systems, this is a
+ special MAC PDU sent on the DL-SCH. Since MAC control elements are not
+ accurately modeled in the simulator (only RLC and above PDUs
+ are), the RAR is modeled as an LteControlMessage that does not
+ consume any radio resources. Still, during the RA procedure, the
+ LteEnbMac will request to the scheduler the allocation of
+ resources for the RAR using the FF MAC Scheduler primitive
+ SCHED_DL_RACH_INFO_REQ. Hence, an enhanced scheduler
+ implementation (not available at the moment) could allocate radio
+ resources for the RAR, thus modeling the consumption of Radio
+ Resources for the transmission of the RAR.
+
+ - **Message 3**: in real LTE systems, this is an RLC TM
+ SDU sent over resources specified in the UL Grant in the RAR. In
+ the simulator, this is modeled as a real RLC TM RLC PDU
+ whose UL resources are allocated by the scheduler upon call to
+ SCHED_DL_RACH_INFO_REQ.
+
+ - **Contention Resolution (CR)**: in real LTE system, the CR phase
+ is needed to address the case where two or more UE sent the same
+ RA preamble in the same TTI, and the eNB was able to detect this
+ preamble in spite of the collision. Since this event does not
+ occur due to the protocol interference model used for the
+ reception of RA preambles, the CR phase is not modeled in the
+ simulator, i.e., the CR MAC CE is never sent by the eNB and the
+ UEs consider the RA to be successful upon reception of the
+ RAR. As a consequence, the radio resources consumed for the
+ transmission of the CR MAC CE are not modeled.
+
+
+
+Figure :ref:`fig-mac-random-access-contention` and
+:ref:`fig-mac-random-access-noncontention` shows the sequence diagrams
+of respectively the contention-based and non-contention-based MAC
+random access procedure, highlighting the interactions between the MAC
+and the other entities.
+
+
+.. _fig-mac-random-access-contention:
+
+.. figure:: figures/mac-random-access-contention.*
:align: center
- Sequence diagram of the interaction between LteHelper and EpcHelper
-
-
-A few notes on the above diagram:
-
- * the role of the MME is taken by the EpcHelper, since we don't have
- an MME at the moment (the current code supports data plane only);
-
- * in a real LTE/EPC system, the setup of the RadioBearer comes after
- the setup of the S1 bearer, but here due to the use of Helpers
- instead of S1-AP messages we do it the other way around
- (RadioBearers first, then S1 bearer) because of easier
- implementation. This is fine to do since the current code focuses
- on control plane only.
+ Sequence diagram of the Contention-based MAC Random Access procedure
+
+
+.. _fig-mac-random-access-noncontention:
+
+.. figure:: figures/mac-random-access-noncontention.*
+ :align: center
+
+ Sequence diagram of the Non-contention-based MAC Random Access procedure
+
.. only:: latex
.. raw:: latex
-
+
\clearpage
+
+----
+RLC
+----
+
+
+
+
+Overview
+++++++++
+
+The RLC entity is specified in the 3GPP technical specification
+[TS36322]_, and comprises three different types of RLC: Transparent
+Mode (TM), Unacknowledge Mode (UM) and Acknowledged Mode (AM). The
+simulator includes one model for each of these entitities
+
+The RLC entities provide the RLC service interface to the upper PDCP layer and the MAC service interface
+to the lower MAC layer. The RLC entities use the PDCP service interface from the upper PDCP layer and
+the MAC service interface from the lower MAC layer.
+
+Figure :ref:`fig-lte-rlc-implementation-model` shows the
+implementation model of the RLC entities and its relationship
+with all the other entities and services in the protocol stack.
+
+
+.. _fig-lte-rlc-implementation-model:
+
+.. figure:: figures/lte-rlc-implementation-model.*
+ :width: 800px
+
+ Implementation Model of PDCP, RLC and MAC entities and SAPs
+
+
+
+Service Interfaces
+++++++++++++++++++
+
+RLC Service Interface
+---------------------
+
+The RLC service interface is divided into two parts:
+
+ * the ``RlcSapProvider`` part is provided by the RLC layer and used by the upper PDCP layer and
+ * the ``RlcSapUser`` part is provided by the upper PDCP layer and used by the RLC layer.
+
+Both the UM and the AM RLC entities provide the same RLC service interface to the upper PDCP layer.
+
+RLC Service Primitives
+^^^^^^^^^^^^^^^^^^^^^^
+
+The following list specifies which service primitives are provided by the RLC service interfaces:
+
+ * ``RlcSapProvider::TransmitPdcpPdu``
+
+ * The PDCP entity uses this primitive to send a PDCP PDU to the lower RLC entity
+ in the transmitter peer
+
+ * ``RlcSapUser::ReceivePdcpPdu``
+
+ * The RLC entity uses this primitive to send a PDCP PDU to the upper PDCP entity
+ in the receiver peer
+
+MAC Service Interface
+---------------------
+
+The MAC service interface is divided into two parts:
+
+ * the ``MacSapProvider`` part is provided by the MAC layer and used by the upper RLC layer and
+ * the ``MacSapUser`` part is provided by the upper RLC layer and used by the MAC layer.
+
+MAC Service Primitives
+^^^^^^^^^^^^^^^^^^^^^^
+
+The following list specifies which service primitives are provided by the MAC service interfaces:
+
+ * ``MacSapProvider::TransmitPdu``
+
+ * The RLC entity uses this primitive to send a RLC PDU to the lower MAC entity
+ in the transmitter peer
+
+ * ``MacSapProvider::ReportBufferStatus``
+
+ * The RLC entity uses this primitive to report the MAC entity the size of pending buffers
+ in the transmitter peer
+
+ * ``MacSapUser::NotifyTxOpportunity``
+
+ * The MAC entity uses this primitive to nofify the RLC entity a transmission opportunity
+
+ * ``MacSapUser::ReceivePdu``
+
+ * The MAC entity uses this primitive to send an RLC PDU to the upper RLC entity
+ in the receiver peer
+
+
+.. _am_data_transfer:
+
+AM RLC
+++++++
+
+
+The processing of the data transfer in the Acknowledge Mode (AM) RLC entity is explained in section 5.1.3 of [TS36322]_.
+In this section we describe some details of the implementation of the
+RLC entity.
+
+
+Buffers for the transmit operations
+-----------------------------------
+
+Our implementation of the AM RLC entity maintains 3 buffers for the
+transmit operations:
+
+ * **Transmission Buffer**: it is the RLC SDU queue.
+ When the AM RLC entity receives a SDU in the TransmitPdcpPdu service primitive from the
+ upper PDCP entity, it enqueues it in the Transmission Buffer. We
+ put a limit on the RLC buffer size and just silently drop SDUs
+ when the buffer is full.
+
+ * **Transmitted PDUs Buffer**: it is the queue of transmitted RLC PDUs for which an ACK/NACK has not
+ been received yet. When the AM RLC entity sends a PDU to the MAC
+ entity, it also puts a copy of the transmitted PDU in the Transmitted PDUs Buffer.
+
+ * **Retransmission Buffer**: it is the queue of RLC PDUs which are considered for retransmission
+ (i.e., they have been NACKed). The AM RLC entity moves this PDU to the Retransmission Buffer,
+ when it retransmits a PDU from the Transmitted Buffer.
+
+
+.. _sec-rlc-am-tx-operations:
+
+Transmit operations in downlink
+-------------------------------
+
+The following sequence diagram shows the interactions between the
+different entities (RRC, PDCP, AM RLC, MAC and MAC scheduler) of the
+eNB in the downlink to perform data communications.
+
+Figure :ref:`fig-lte-rlc-data-txon-dl` shows how the upper layers send
+data PDUs and how the data flow is processed by the different
+entities/services of the LTE protocol stack.
+
+.. _fig-lte-rlc-data-txon-dl:
+
+.. figure:: figures/lte-rlc-data-txon-dl.*
+ :width: 800px
+
+ Sequence diagram of data PDU transmission in downlink
+
+
+The PDCP entity calls the ``Transmit_PDCP_PDU service primitive`` in
+order to send a data PDU. The AM RLC entity processes this service
+primitive according to the AM data transfer procedures defined in
+section 5.1.3 of [TS36322]_.
+
+When the ``Transmit_PDCP_PDU`` service primitive is called, the AM RLC
+entity performs the following operations:
+
+ * Put the data SDU in the Transmission Buffer.
+ * Compute the size of the buffers (how the size of buffers is
+ computed will be explained afterwards).
+ * Call the ``Report_Buffer_Status`` service primitive of the eNB
+ MAC entity in order to notify to the eNB MAC
+ entity the sizes of the buffers of the AM RLC entity. Then, the
+ eNB MAC entity updates the buffer status in the MAC scheduler
+ using the SchedDlRlcBufferReq service primitive of the FF MAC
+ Scheduler API.
+
+Afterwards, when the MAC scheduler decides that some data can be sent,
+the MAC entity notifies it to the RLC entity, i.e. it calls the
+``Notify_Tx_Opportunity`` service primitive, then the AM RLC entity
+does the following:
+
+ * Create a single data PDU by segmenting and/or concatenating the
+ SDUs in the Transmission Buffer.
+ * Move the data PDU from the Transmission Buffer to the
+ Transmitted PDUs Buffer.
+ * Update state variables according section 5.1.3.1.1 of
+ [TS36322]_.
+ * Call the ``Transmit_PDU`` primitive in order to send the data
+ PDU to the MAC entity.
+
+Retransmission in downlink
+--------------------------
+
+The sequence diagram of Figure :ref:`fig-lte-rlc-data-retx-dl` shows
+the interactions between the different entities (AM RLC, MAC and MAC
+scheduler) of the eNB in downlink when data PDUs must be retransmitted
+by the AM RLC entity.
+
+.. _fig-lte-rlc-data-retx-dl:
+
+.. figure:: figures/lte-rlc-data-retx-dl.*
+ :width: 500px
+
+ Sequence diagram of data PDU retransmission in downlink
+
+
+The transmitting AM RLC entity can receive STATUS PDUs from the peer AM RLC entity. STATUS PDUs are
+sent according section 5.3.2 of [TS36322]_ and the processing of reception is made according
+section 5.2.1 of [TS36322]_.
+
+When a data PDUs is retransmitted from the Transmitted PDUs Buffer, it is also moved to the
+Retransmission Buffer.
+
+Transmit operations in uplink
+-----------------------------
+
+The sequence diagram of Figure :ref:`fig-lte-rlc-data-txon-ul` shows
+the interactions between the different entities of the UE (RRC, PDCP,
+RLC and MAC) and the eNB (MAC and Scheduler) in uplink when data PDUs
+are sent by the upper layers.
+
+.. _fig-lte-rlc-data-txon-ul:
+
+.. figure:: figures/lte-rlc-data-txon-ul.*
+ :width: 800px
+
+ Sequence diagram of data PDU transmission in uplink
+
+
+It is similar to the sequence diagram in downlink; the main difference
+is that in this case the Report_Buffer_Status is sent from the UE MAC
+to the MAC Scheduler in the eNB over the air using the control
+channel.
+
+Retransmission in uplink
+------------------------
+
+The sequence diagram of Figure :ref:`fig-lte-rlc-data-retx-ul` shows
+the interactions between the different entities of the UE (AM RLC and
+MAC) and the eNB (MAC) in uplink when data PDUs must be retransmitted
+by the AM RLC entity.
+
+.. _fig-lte-rlc-data-retx-ul:
+
+.. figure:: figures/lte-rlc-data-retx-ul.*
+ :width: 500px
+
+ Sequence diagram of data PDU retransmission in uplink
+
+
+.. _sec-rlc-am-buffer-size:
+
+Calculation of the buffer size
+------------------------------
+
+The Transmission Buffer contains RLC SDUs. A RLC PDU is one or more SDU segments plus an RLC header.
+The size of the RLC header of one RLC PDU depends on the number of SDU segments the PDU contains.
+
+The 3GPP standard (section 6.1.3.1 of [TS36321]_) says clearly that,
+for the uplink, the RLC and MAC headers are not considered in the
+buffer size that is to be report as part of the Buffer Status Report.
+For the downlink, the behavior is not specified. Neither [FFAPI]_ specifies
+how to do it. Our RLC model works by assuming that the calculation of
+the buffer size in the downlink is done exactly as in the uplink,
+i.e., not considering the RLC and MAC header size.
+
+We note that this choice affects the interoperation with the
+MAC scheduler, since, in response to the
+``Notify_Tx_Opportunity`` service primitive, the RLC is expected to
+create a PDU of no more than the size requested by the MAC, including
+RLC overhead. Hence, unneeded fragmentation can occur if (for example)
+the MAC notifies a transmission exactly equal to the buffer size
+previously reported by the RLC. We assume that it is left to the Scheduler
+to implement smart strategies for the selection of the size of the
+transmission opportunity, in order to eventually avoid the inefficiency
+of unneeded fragmentation.
+
+
+
+Concatenation and Segmentation
+------------------------------
+
+The AM RLC entity generates and sends exactly one RLC PDU for each transmission opportunity even
+if it is smaller than the size reported by the transmission opportunity. So for instance, if a
+STATUS PDU is to be sent, then only this PDU will be sent in that transmission opportunity.
+
+The segmentation and concatenation for the SDU queue of the AM RLC entity follows the same philosophy
+as the same procedures of the UM RLC entity but there are new state
+variables (see [TS36322]_ section 7.1) only present in the AM RLC entity.
+
+It is noted that, according to the 3GPP specs, there is no concatenation for the Retransmission Buffer.
+
+Re-segmentation
+---------------
+
+The current model of the AM RLC entity does not support the
+re-segmentation of the retransmission buffer. Rather, the AM RLC
+entity just expects to receive a big enough transmission
+opportunity. An assertion fails if a too small transmission opportunity is
+received.
+
+
+Unsupported features
+--------------------
+
+We do not support the following procedures of [TS36322]_ :
+
+ * “Send an indication of successful delivery of RLC SDU” (See section 5.1.3.1.1)
+ * “Indicate to upper layers that max retransmission has been reached” (See section 5.2.1)
+ * “SDU discard procedures” (See section 5.3)
+ * “Re-establishment procedure” (See section 5.4)
+
+We do not support any of the additional primitives of RLC SAP for AM RLC entity. In particular:
+
+ * no SDU discard notified by PDCP
+ * no notification of successful / failed delivery by AM RLC entity to PDCP entity
+
+
+UM RLC
+++++++
+
+In this section we describe the implemnetation of the Unacknowledge Mode (UM) RLC entity.
+
+Transmit operations in downlink
+-------------------------------
+
+The transmit operations of the UM RLC are similar to those of the AM
+RLC previously described in Section :ref:`sec-rlc-am-tx-operations`,
+with the difference that, following the specifications of [TS36322]_,
+retransmission are not performed, and there are no STATUS PDUs.
+
+Transmit operations in uplink
+------------------------------
+
+The transmit operations in the uplink are similar to those of the
+downlink, with the main difference that the Report_Buffer_Status is
+sent from the UE MAC to the MAC Scheduler in the eNB over the air
+using the control channel.
+
+
+Calculation of the buffer size
+------------------------------
+
+The calculation of the buffer size for the UM RLC is done using the
+same approach of the AM RLC, please refer to section
+:ref:`sec-rlc-am-buffer-size` for the corresponding description.
+
+
+
+
+TM RLC
+++++++
+
+In this section we describe the implementation of the Transparent Mode (TM) RLC entity.
+
+
+Transmit operations in downlink
+-------------------------------
+
+In the simulator, the TM RLC still provides to the upper layers the
+same service interface provided by the AM and UM RLC
+entities to the PDCP layer; in practice, this interface is used by an RRC
+entity (not a PDCP entity) for the transmission of RLC SDUs. This
+choice is motivated by the fact that the services provided by the TM
+RLC to the upper layers, according to [TS36322]_, is a subset of those
+provided by the UM and AM RLC entities to the PDCP layer; hence,
+we reused the same interface for simplicity.
+
+The transmit operations in the downlink are performed as follows. When
+the ``Transmit_PDCP_PDU service primitive`` is called by the upper
+layers, the TM RLC does the following:
+
+ * put the SDU in the Transmission Buffer
+ * compute the size of the Transmission Buffer
+ * call the ``Report_Buffer_Status`` service primitive of the eNB
+ MAC entity
+
+Afterwards, when the MAC scheduler decides that some data can be sent
+by the logical channel to which the TM RLC entity belongs, the MAC
+entity notifies it to the TM RLC entity by calling the
+``Notify_Tx_Opportunity`` service primitive. Upon reception of this
+primitive, the TM RLC entity does the following:
+
+ * if the TX opportunity has a size that is greater than or equal to
+ the size of the head-of-line SDU in the Transmission Buffer
+
+ - dequeue the head-of-line SDU from the Transmission Buffer
+
+ - create one RLC PDU that contains entirely that SDU, without any
+ RLC header
+
+ - Call the ``Transmit_PDU`` primitive in order to send the RLC
+ PDU to the MAC entity.
+
+
+Transmit operations in uplink
+-----------------------------
+
+The transmit operations in the uplink are similar to those of the
+downlink, with the main difference that a transmission opportunity can
+also arise from the assignment of the UL GRANT as part of the Random
+Access procedure, without an explicit Buffer Status Report issued by
+the TM RLC entity.
+
+
+
+Calculation of the buffer size
+------------------------------
+
+As per the specifications [TS36322]_, the TM RLC does not add any RLC
+header to the PDUs being transmitted. Because of this, the buffer size
+reported to the MAC layer is calculated simply by summing the size of
+all packets in the transmission buffer, thus notifying to the MAC the
+exact buffer size.
+
+
+
+SM RLC
+++++++
+
+In addition to the AM, UM and TM implementations that are modeled
+after the 3GPP specifications, a simplified RLC model is provided,
+which is called Saturation Mode (SM) RLC. This RLC model does not accept
+PDUs from any above layer (such as PDCP); rather, the SM RLC takes care of the
+generation of RLC PDUs in response to
+the notification of transmission opportunities notified by the MAC.
+In other words, the SM RLC simulates saturation conditions, i.e., it
+assumes that the RLC buffer is always full and can generate a new PDU
+whenever notified by the scheduler.
+
+The SM RLC is used for simplified simulation scenarios in which only the
+LTE Radio model is used, without the EPC and hence without any IP
+networking support. We note that, although the SM RLC is an
+unrealistic traffic model, it still allows for the correct simulation
+of scenarios with multiple flows belonging to different (non real-time)
+QoS classes, in order to test the QoS performance obtained by different
+schedulers. This can be
+done since it is the task of the Scheduler to assign transmission
+resources based on the characteristics (e.g., Guaranteed Bit Rate) of
+each Radio Bearer, which are specified upon the definition of each
+Bearer within the simulation program.
+
+As for schedulers designed to work with real-time QoS
+traffic that has delay constraints, the SM RLC is probably not an appropriate choice.
+This is because the absence of actual RLC SDUs (replaced by the artificial
+generation of Buffer Status Reports) makes it not possible to provide
+the Scheduler with meaningful head-of-line-delay information, which is
+often the metric of choice for the implementation of scheduling
+policies for real-time traffic flows. For the simulation and testing
+of such schedulers, it is advisable to use either the UM or the AM RLC
+models instead.
+
+
+----
+PDCP
+----
+
+Overview
+++++++++
+
+The reference document for the specification of the PDCP entity is
+[TS36323]_. With respect to this specification, the PDCP model
+implemented in the simulator supports only the following features:
+
+ * transfer of data (user plane or control plane);
+ * maintenance of PDCP SNs;
+
+The following features are currently not supported:
+
+ * header compression and decompression of IP data flows using the ROHC protocol;
+ * in-sequence delivery of upper layer PDUs at re-establishment of lower layers;
+ * duplicate elimination of lower layer SDUs at re-establishment of lower layers for radio bearers mapped on RLC AM;
+ * ciphering and deciphering of user plane data and control plane data;
+ * integrity protection and integrity verification of control plane data;
+ * timer based discard;
+ * duplicate discarding.
+
+
+PDCP Service Interface
+++++++++++++++++++++++
+
+The PDCP service interface is divided into two parts:
+
+ * the ``PdcpSapProvider`` part is provided by the PDCP layer and used by the upper layer and
+ * the ``PdcpSapUser`` part is provided by the upper layer and used by the PDCP layer.
+
+PDCP Service Primitives
+-----------------------
+
+The following list specifies which service primitives are provided by the PDCP service interfaces:
+
+ * ``PdcpSapProvider::TransmitPdcpSdu``
+
+ * The RRC entity uses this primitive to send an RRC PDU to the lower PDCP entity
+ in the transmitter peer
+
+ * ``PdcpSapUser::ReceivePdcpSdu``
+
+ * The PDCP entity uses this primitive to send an RRC PDU to the upper RRC entity
+ in the receiver peer
+
+
+
+.. only:: latex
+
+ .. raw:: latex
+
+ \clearpage
+
+
+---
+RRC
+---
+
+Features
+++++++++
+
+The RRC model implemented in the simulator provides the following functionality:
+
+ - generation (at the eNB) and interpretation (at the UE) of System
+ Information (in particular the Master Information Block and, at the
+ time of this writing, only System Information Block Type 2)
+ - RRC connection establishment procedure
+ - RRC reconfiguration procedure, supporting the following use cases:
+ + reconfiguration of the SRS configuration index
+ + reconfiguration of the PHY TX mode (MIMO)
+ + data radio bearer setup
+ + handover
+ - RRC connection re-establishment, supporting the following use
+ cases:
+ + handover
+
+
+Architecture
+++++++++++++
+
+The RRC model is divided into the following components:
+
+ - the RRC entities `LteUeRrc` and `LteEnbRrc`, which implement the state
+ machines of the RRC entities respectively at the UE and the eNB;
+ - the RRC SAPs `LteUeRrcSapProvider`, `LteUeRrcSapUser`,
+ `LteEnbRrcSapProvider`, `LteEnbRrcSapUser`, which allow the RRC
+ entities to send and receive RRC messages and information
+ elmenents;
+ - the RRC protocol classes `LteUeRrcProtocolIdeal`,
+ `LteEnbRrcProtocolIdeal`, `LteUeRrcProtocolReal`,
+ `LteEnbRrcProtocolReal`, which implement two different models for
+ the transmission of RRC messages.
+
+Additionally, the RRC components use various other SAPs in order to
+interact with the rest of the protocol stack. A representation of all
+the SAPs that are used is provided in the figures :ref:`fig-lte-arch-ue-data`,
+:ref:`fig-lte-arch-ue-ctrl`, :ref:`fig-lte-arch-enb-data` and
+:ref:`fig-lte-arch-enb-ctrl`.
+
+
+UE RRC State Machine
+++++++++++++++++++++
+
+In Figure :ref:`fig-lte-ue-rrc-states` we represent the state machine
+as implemented in the RRC UE entity.
+
+.. _fig-lte-ue-rrc-states:
+
+.. figure:: figures/lte-ue-rrc-states.*
+ :align: center
+
+ UE RRC State Machine
+
+It is to be noted that most of the states are transient, i.e., once
+the UE goes into one of the CONNECTED states it will never switch back
+to any of the IDLE states. This choice is done for the following reasons:
+
+ - as discussed in the section :ref:`sec-design-criteria`, the focus
+ of the LTE-EPC simulation model is on CONNECTED mode
+ - radio link failure is not currently modeled, as discussed in the
+ section :ref:`sec-radio-link-failure`, so an UE cannot go IDLE
+ because of radio link failure
+ - RRC connection release is currently never triggered neither by the EPC
+ nor by the NAS
+
+Still, we chose to model explicitly the IDLE states, because:
+
+ - a realistic UE RRC configuration is needed for handover, which is a
+ required feature, and in order to have a cleaner implementation it makes sense to
+ use the same UE RRC configuration also for the initial connection
+ establishment
+ - it makes easier to implement idle mode cell selection in the
+ future, which is a highly desirable feature
+
+
+ENB RRC State Machine
++++++++++++++++++++++
+
+The eNB RRC maintains the state for each UE that is attached to the
+cell. From an implementation point of view, the state of each UE is
+contained in an instance of the UeManager class. The state machine is
+represented in Figure :ref:`fig-lte-enb-rrc-states`.
+
+.. _fig-lte-enb-rrc-states:
+
+.. figure:: figures/lte-enb-rrc-states.*
+ :align: center
+
+ ENB RRC State Machine for each UE
+
+
+
+
+Radio Bearer Configuration
+++++++++++++++++++++++++++
+
+Some implementation choices have been made in the RRC regarding the setup of radio bearers:
+
+ - three Logical Channel Groups (out of four available) are configured
+ for uplink buffer status report purposes, according to the following policy:
+ + LCG 0 is for signaling radio bearers
+ + LCG 1 is for GBR data radio bearers
+ + LCG 2 is for Non-GBR data radio bearers
+
+
+.. _sec-radio-link-failure:
+
+Radio Link Failure
+++++++++++++++++++
+
+Since at this stage the RRC supports the CONNECTED mode only, Radio Link
+Failure (RLF) is not handled. The reason is that one of the possible
+outcomes of RLF (when RRC re-establishment is unsuccessful) is to
+leave RRC CONNECTED notifying the NAS of the RRC connection
+failure. In order to model RLF properly, RRC IDLE mode should be
+supported, including in particular idle mode cell (re-)selection.
+
+With the current model, an UE that experiences bad link quality will
+just stay associated with the same eNB, and the scheduler will stop
+allocating resources to it for communications. This is also consistent
+with the fact that, at this stage, only handovers explicitly triggered
+within the simulation program are supported (network-driven handovers
+based on UE measurements are planned only at a later stage).
+
+
+
+
+RRC sequence diagrams
++++++++++++++++++++++
+
+In this section we provide some sequence diagrams that explain the
+most important RRC procedures being modeled.
+
+RRC connection establishment
+----------------------------
+
+Figure :ref:`fig-rrc-connection-establishment` shows how the RRC
+Connection Establishment procedure is modeled, highlighting the role
+of the RRC layer at both the UE and the eNB, as well as the
+interaction with the other layers.
+
+.. _fig-rrc-connection-establishment:
+
+.. figure:: figures/rrc-connection-establishment.*
+ :align: center
+
+ Sequence diagram of the RRC Connection Establishment procedure
+
+
+
+RRC connection reconfiguration
+------------------------------
+
+Figure :ref:`fig-rrc-connection-reconfiguration` shows how the RRC
+Connection Reconfiguration procedure is modeled for the case where
+MobilityControlInfo is not provided, i.e., handover is not
+performed.
+
+
+.. _fig-rrc-connection-reconfiguration:
+
+.. figure:: figures/rrc-connection-reconfiguration.*
+ :align: center
+
+ Sequence diagram of the RRC Connection Reconfiguration procedure
+
+
+
+Figure :ref:`fig-rrc-connection-reconf-handover` shows how the RRC
+Connection Reconfiguration procedure is modeled for the case where
+MobilityControlInfo is provided, i.e., handover is to be performed.
+As specified in [TS36331]_, *After receiving the handover message,
+the UE attempts to access the target cell at the first available RACH
+occasion according to Random Access resource selection defined in [TS36321]_,
+i.e. the handover is asynchronous. Consequently, when
+allocating a dedicated preamble for the random access in the target
+cell, E-UTRA shall ensure it is available from the first RACH occasion
+the UE may use. Upon successful completion of the handover, the UE
+sends a message used to confirm the handover.* Note that the random
+access procedure in this case is non-contention based, hence in a real
+LTE system it differs slightly from the one used in RRC connection
+established. Also note that the RA Preamble ID is signalled via the
+Handover Command included in the X2 Handover Request ACK message sent
+from the target eNB to the source eNB; in particular, the preamble is
+included in the RACH-ConfigDedicated IE which is part of
+MobilityControlInfo.
+
+
+.. _fig-rrc-connection-reconf-handover:
+
+.. figure:: figures/rrc-connection-reconfiguration-handover.*
+ :align: center
+
+ Sequence diagram of the RRC Connection Reconfiguration procedure
+ for the handover case
+
+
+RRC protocol models
++++++++++++++++++++
+
+As previously anticipated, we provide two different models for the
+transmission and reception of RRC messages: *Ideal*
+and *Real*. Each of them is described in one of the following
+subsections.
+
+
+Ideal RRC protocol model
+------------------------
+
+According to this model, implemented in the classes and `LteUeRrcProtocolIdeal` and
+`LteEnbRrcProtocolIdeal`, all RRC messages and information elements
+are transmitted between the eNB and the UE in an ideal fashion,
+without consuming radio resources and without errors. From an
+implementation point of view, this is achieved by passing the RRC data
+structure directly between the UE and eNB RRC entities, without
+involving the lower layers (PDCP, RLC, MAC, scheduler).
+
+
+Real RRC protocol model
+-----------------------
+
+This model is implemented in the classes `LteUeRrcProtocolReal` and
+`LteEnbRrcProtocolReal` and aims at modeling the transmission of RRC
+PDUs as commonly performed in real LTE systems. In particular:
+
+ - for every RRC message being sent, a real RRC PDUs is created
+ following the ASN.1 encoding of RRC PDUs and information elements (IEs)
+ specified in [TS36331]_. Some simplification are made with respect
+ to the IEs included in the PDU, i.e., only those IEs that are
+ useful for simulation purposes are included. For a detailed list,
+ please see the IEs defined in `lte-rrc-sap.h` and compare with
+ [TS36331]_.
+ - the encoded RRC PDUs are sent on Signaling Radio Bearers and are
+ subject to the same transmission modeling used for data
+ communications, thus including scheduling, radio resource
+ consumption, channel errors, delays, retransmissions, etc.
+
+
+Signaling Radio Bearer model
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We now describe the Signaling Radio Bearer model that is used for the
+*Real* RRC protocol model.
+
+ * **SRB0** messages (over CCCH):
+
+ - **RrcConnectionRequest**: in real LTE systems, this is an RLC TM
+ SDU sent over resources specified in the UL Grant in the RAR (not
+ in UL DCIs); the reason is that C-RNTI is not known yet at this
+ stage. In the simulator, this is modeled as a real RLC TM RLC PDU
+ whose UL resources are allocated by the sched upon call to
+ SCHED_DL_RACH_INFO_REQ.
+
+ - **RrcConnectionSetup**: in the simulator this is implemented as in
+ real LTE systems, i.e., with an RLC TM SDU sent over resources
+ indicated by a regular UL DCI, allocated with
+ SCHED_DL_RLC_BUFFER_REQ triggered by the RLC TM instance that is
+ mapped to LCID 0 (the CCCH).
+
+ * **SRB1** messages (over DCCH):
+
+ - All the SRB1 messages modeled in the simulator (e.g.,
+ **RrcConnectionCompleted**) are implemented as in real LTE systems,
+ i.e., with a real RLC SDU sent over RLC AM using DL resources
+ allocated via Buffer Status Reports. See the RLC model
+ documentation for details.
+
+ * **SRB2** messages (over DCCH):
+
+ - According to [TS36331]_, "*SRB1 is for RRC messages (which may
+ include a piggybacked NAS message) as well as for NAS messages
+ prior to the establishment of SRB2, all using DCCH logical
+ channel*", whereas "*SRB2 is for NAS messages, using DCCH
+ logical channel*" and "*SRB2 has a lower-priority than SRB1 and is
+ always configured by E-UTRAN after security
+ activation*". Modeling security-related aspects is not a
+ requirement of the LTE simulation model, hence we always use
+ SRB1 and never activate SRB2.
+
+
+
+
+ASN.1 encoding of RRC IE's
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+The messages defined in RRC SAP, common to all Ue/Enb SAP Users/Providers, are transported in a transparent container to/from a Ue/Enb. The encoding format for the different Information Elements are specified in [TS36331]_, using ASN.1 rules in the unaligned variant. The implementation in Ns3/Lte has been divided in the following classes:
+
+ * Asn1Header : Contains the encoding / decoding of basic ASN types
+
+ * RrcAsn1Header : Inherits Asn1Header and contains the encoding / decoding of common IE's defined in [TS36331]_
+
+ * Rrc specific messages/IEs classes : A class for each of the messages defined in RRC SAP header
+
+
+Asn1Header class - Implementation of base ASN.1 types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This class implements the methods to Serialize / Deserialize the ASN.1 types being used in [TS36331]_, according to the packed encoding rules in ITU-T X.691. The types considered are:
+
+ * Boolean : a boolean value uses a single bit (1=true, 0=false).
+
+ * Integer : a constrained integer (with min and max values defined) uses the minimum amount of bits to encode its range (max-min+1).
+
+ * Bitstring : a bistring will be copied bit by bit to the serialization buffer.
+
+ * Octetstring : not being currently used.
+
+ * Sequence : the sequence generates a preamble indicating the presence of optional and default fields. It also adds a bit indicating the presence of extension marker.
+
+ * Sequence...Of : the sequence...of type encodes the number of elements of the sequence as an integer (the subsequent elements will need to be encoded afterwards).
+
+ * Choice : indicates which element among the ones in the choice set is being encoded.
+
+ * Enumeration : is serialized as an integer indicating which value is used, among the ones in the enumeration, with the number of elements in the enumeration as upper bound.
+
+ * Null : the null value is not encoded, although its serialization function is defined to provide a clearer map between specification and implementation.
+
+The class inherits from ns-3 Header, but Deserialize() function is declared pure virtual, thus inherited classes having to implement it. The reason is that deserialization will retrieve the elements in RRC messages, each of them containing different information elements.
+
+Additionally, it has to be noted that the resulting byte length of a specific type/message can vary, according to the presence of optional fields, and due to the optimized encoding. Hence, the serialized bits will be processed using PreSerialize() function, saving the result in m_serializationResult Buffer. As the methods to read/write in a ns3 buffer are defined in a byte basis, the serialization bits are stored into m_serializationPendingBits attribute, until the 8 bits are set and can be written to buffer iterator. Finally, when invoking Serialize(), the contents of the m_serializationResult attribute will be copied to Buffer::Iterator parameter
+
+RrcAsn1Header : Common IEs
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As some Information Elements are being used for several RRC messages, this class implements the following common IE's:
+
+ * SrbToAddModList
+
+ * DrbToAddModList
+
+ * LogicalChannelConfig
+
+ * RadioResourceConfigDedicated
+
+ * PhysicalConfigDedicated
+
+ * SystemInformationBlockType1
+
+ * SystemInformationBlockType2
+
+ * RadioResourceConfigCommonSIB
+
+
+Rrc specific messages/IEs classes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following RRC SAP have been implemented:
+
+ * RrcConnectionRequest
+
+ * RrcConnectionSetup
+
+ * RrcConnectionSetupCompleted
+
+ * RrcConnectionReconfiguration
+
+ * RrcConnectionReconfigurationCompleted
+
+ * HandoverPreparationInfo
+
+ * RrcConnectionReestablishmentRequest
+
+ * RrcConnectionReestablishment
+
+ * RrcConnectionReestablishmentComplete
+
+ * RrcConnectionReestablishmentReject
+
+ * RrcConnectionRelease
+
+
+
+
+.. only:: latex
+
+ .. raw:: latex
+
+ \clearpage
+
+
+
+--------
+NAS
+--------
+
+
+The focus of the LTE-EPC model is on the NAS Active state, which corresponds to EMM Registered, ECM connected, and RRC connected. Because of this, the following simplifications are made:
+
+ - EMM and ECM are not modeled explicitly; instead, the NAS entity at the UE will interact directy with the MME to perfom actions that are equivalent (with gross simplifications) to taking the UE to the states EMM Connected and ECM Connected;
+
+ - the NAS also takes care of multiplexing uplink data packets coming from the upper layers into the appropriate EPS bearer by using the Traffic Flow Template classifier (TftClassifier).
+
+- the NAS does not support PLMN and CSG selection
+
+- the NAS does not support any location update/paging procedure in idle mode
+
+
+
+Figure :ref:`fig-nas-attach` shows how the simplified NAS model
+implements the attach procedure. Note that both the default and
+eventual dedicated EPS bearers are activated as part of this
+procedure.
+
+.. _fig-nas-attach:
+
+.. figure:: figures/nas-attach.*
+ :align: center
+
+ Sequence diagram of the attach procedure
+
+
+
+
+
+
+
+.. only:: latex
+
+ .. raw:: latex
+
+ \clearpage
+
+
+
-----------------
-X2-based handover
+S1
-----------------
-The X2 interface interconnects two eNBs [TS36420]_. From a logical point of view, the X2 interface is a point-to-point interface between the two eNBs. In a real E-UTRAN, the logical point-to-point interface should be feasible even in the absence of a physical direct connection between the two eNBs. In the X2 model implemented in the simulator, the X2 interface is a point-to-point link between the two eNBs. A point-to-point device is created in both eNBs and the two point-to-point devices are attached to the point-to-point link.
-
-The overall architecture of the LENA simulation model is depicted in the figure :ref:`fig-epc-topology-x2-enhanced`. It adds the X2 interface between eNBs to the original architecture described in :ref:`overall-architecture`.
-
-.. _fig-epc-topology-x2-enhanced:
+S1-U
++++++++++
+
+The S1-U interface is modeled in a realistic way by encapsulating
+data packets over GTP/UDP/IP, as done in real LTE-EPC systems. The
+corresponding protocol stack is shown in Figure
+:ref:`fig-lte-epc-e2e-data-protocol-stack`. As shown in the figure,
+there are two different layers of
+IP networking. The first one is the end-to-end layer, which provides end-to-end
+connectivity to the users; this layers involves the UEs, the PGW and
+the remote host (including eventual internet routers and hosts in
+between), but does not involve the eNB. By default, UEs are assigned a public IPv4 address in the 7.0.0.0/8
+network, and the PGW gets the address 7.0.0.1, which is used by all
+UEs as the gateway to reach the internet.
+
+The second layer of IP networking is the EPC local area network. This
+involves all eNB nodes and the SGW/PGW node. This network is
+implemented as a set of point-to-point links which connect each eNB
+with the SGW/PGW node; thus, the SGW/PGW has a set of point-to-point
+devices, each providing connectivity to a different eNB. By default, a
+10.x.y.z/30 subnet is assigned to each point-to-point link (a /30
+subnet is the smallest subnet that allows for two distinct host
+addresses).
+
+As specified by 3GPP, the end-to-end IP
+communications is tunneled over the local EPC IP network using
+GTP/UDP/IP. In the following, we explain how this tunneling is
+implemented in the EPC model. The explanation is done by discussing the
+end-to-end flow of data packets.
+
+.. _fig-epc-data-flow-dl:
+
+.. figure:: figures/epc-data-flow-dl.*
+ :align: center
+
+ Data flow in the downlink between the internet and the UE
+
+To begin with, we consider the case of the downlink, which is depicted
+in Figure :ref:`fig-epc-data-flow-dl`.
+Downlink Ipv4 packets are generated from a generic remote host, and
+addressed to one of the UE device. Internet routing will take care of
+forwarding the packet to the generic NetDevice of the SGW/PGW node
+which is connected to the internet (this is the Gi interface according
+to 3GPP terminology). The SGW/PGW has a VirtualNetDevice which is
+assigned the gateway IP address of the UE subnet; hence, static
+routing rules will cause the incoming packet from the internet to be
+routed through this VirtualNetDevice. Such device starts the
+GTP/UDP/IP tunneling procedure, by forwarding the packet to a
+dedicated application in the SGW/PGW node which is called
+EpcSgwPgwApplication. This application does the following operations:
+
+ #. it determines the eNB node to which the UE is attached, by looking
+ at the IP destination address (which is the address of the UE);
+ #. it classifies the packet using Traffic Flow Templates (TFTs) to
+ identify to which EPS Bearer it belongs. EPS bearers have a
+ one-to-one mapping to S1-U Bearers, so this operation returns the
+ GTP-U Tunnel Endpoint Identifier (TEID) to which the packet
+ belongs;
+ #. it adds the corresponding GTP-U protocol header to the packet;
+ #. finally, it sends the packet over an UDP socket to the S1-U
+ point-to-point NetDevice, addressed to the eNB to which the UE is
+ attached.
+
+As a consequence, the end-to-end IP packet with newly added IP, UDP
+and GTP headers is sent through one of the S1 links to the eNB, where
+it is received and delivered locally (as the destination address of
+the outmost IP header matches the eNB IP address). The local delivery
+process will forward the packet, via an UDP socket, to a dedicated
+application called EpcEnbApplication. This application then performs
+the following operations:
+
+ #. it removes the GTP header and retrieves the TEID which is
+ contained in it;
+ #. leveraging on the one-to-one mapping between S1-U bearers and
+ Radio Bearers (which is a 3GPP requirement), it determines the Radio
+ Bearer ID (RBID) to which the packet belongs;
+ #. it records the RBID in a dedicated tag called LteRadioBearerTag,
+ which is added to the packet;
+ #. it forwards the packet to the LteEnbNetDevice of the eNB node via
+ a raw packet socket
+
+Note that, at this point, the outmost header of the packet is the
+end-to-end IP header, since the IP/UDP/GTP headers of the S1 protocol
+stack have already been stripped. Upon reception of
+the packet from the EpcEnbApplication, the LteEnbNetDevice will
+retrieve the RBID from the LteRadioBearerTag, and based on the RBID
+will determine the Radio Bearer instance (and the corresponding PDCP
+and RLC protocol instances) which are then used to forward the packet
+to the UE over the LTE radio interface. Finally, the LteUeNetDevice of
+the UE will receive the packet, and delivery it locally to the IP
+protocol stack, which will in turn delivery it to the application of
+the UE, which is the end point of the downlink communication.
+
+
+
+.. _fig-epc-data-flow-ul:
-.. figure:: figures/epc-topology-x2-enhanced.*
+.. figure:: figures/epc-data-flow-ul.*
:align: center
- Overall architecture of the LTE-EPC simulation model enhanced with X2 interface
-
-
-X2 model
-++++++++
-
-The X2 model implemented in the simulator provides detailed implementation of the following elementary procedures of the Mobility Management functionality [TS36423]_:
+ Data flow in the uplink between the UE and the internet
+
+
+The case of the uplink is depicted in Figure :ref:`fig-epc-data-flow-ul`.
+Uplink IP packets are generated by a generic application inside the UE,
+and forwarded by the local TCP/IP stack to the LteUeNetDevice of the
+UE. The LteUeNetDevice then performs the following operations:
+
+ #. it classifies the packet using TFTs and determines the
+ Radio Bearer to which the packet belongs (and the corresponding
+ RBID);
+ #. it identifies the corresponding PDCP protocol instance, which is
+ the entry point of the LTE Radio Protocol stack for this packet;
+ #. it sends the packet to the eNB over the LTE Radio Protocol stack.
+
+The eNB receives the packet via its LteEnbNetDevice. Since there is a
+single PDCP and RLC protocol instance for each Radio Bearer, the
+LteEnbNetDevice is able to determine the RBID of the packet. This RBID
+is then recorded onto an LteRadioBearerTag, which is added to the
+packet. The LteEnbNetDevice then forwards the packet to the
+EpcEnbApplication via a raw packet socket.
+
+Upon receiving the packet, the EpcEnbApplication performs the
+following operations:
+
+ #. it retrieves the RBID from the LteRadioBearerTag in the packet;
+ #. it determines the corresponding EPS Bearer instance and GTP-U TEID by
+ leveraging on the one-to-one mapping between S1-U bearers and Radio
+ Bearers;
+ #. it adds a GTP-U header on the packet, including the TEID
+ determined previously;
+ #. it sends the packet to the SGW/PGW node via the UDP socket
+ connected to the S1-U point-to-point net device.
+
+At this point, the packet contains the S1-U IP, UDP and GTP headers in
+addition to the original end-to-end IP header. When the packet is
+received by the corresponding S1-U point-to-point NetDevice of the
+SGW/PGW node, it is delivered locally (as the destination address of
+the outmost IP header matches the address of the point-to-point net
+device). The local delivery process will forward the packet to the
+EpcSgwPgwApplication via the correponding UDP socket. The
+EpcSgwPgwApplication then removes the GTP header and forwards the
+packet to the VirtualNetDevice. At this point, the outmost header
+of the packet is the end-to-end IP header. Hence, if the destination
+address within this header is a remote host on the internet, the
+packet is sent to the internet via the corresponding NetDevice of the
+SGW/PGW. In the event that the packet is addressed to another UE, the
+IP stack of the SGW/PGW will redirect the packet again to the
+VirtualNetDevice, and the packet will go through the dowlink delivery
+process in order to reach its destination UE.
+
+S1AP
++++++
+
+The S1-AP interface provides control plane interaction between the eNB
+and the MME. In the simulator, this interface is modeled in an ideal
+fashion, with direct interaction between the eNB and the MME objects,
+without actually implementing the encoding of S1AP messages and
+information elements specified in [TS36413]_ and without actually
+transmitting any PDU on any link.
+
+The S1-AP primitives that are modeled are:
+
+ * INITIAL UE MESSAGE
+ * INITIAL CONTEXT SETUP REQUEST
+ * INITIAL CONTEXT SETUP RESPONSE
+ * PATH SWITCH REQUEST
+ * PATH SWITCH REQUEST ACKNOWLEDGE
+
+.. only:: latex
+
+ .. raw:: latex
+
+ \clearpage
+
+
+
+
+
+---
+X2
+---
+
+The X2 interface interconnects two eNBs [TS36420]_. From a logical
+point of view, the X2 interface is a point-to-point interface between
+the two eNBs. In a real E-UTRAN, the logical point-to-point interface
+should be feasible even in the absence of a physical direct connection
+between the two eNBs. In the X2 model implemented in the simulator,
+the X2 interface is a point-to-point link between the two eNBs. A
+point-to-point device is created in both eNBs and the two
+point-to-point devices are attached to the point-to-point link.
+
+For a representation of how the X2 interface fits in the overall
+architecture of the LENA simulation model, the reader is referred to
+the figure :ref:`overall-architecture`.
+
+
+The X2 interface implemented in the simulator provides detailed implementation of the following elementary procedures of the Mobility Management functionality [TS36423]_:
* Handover Request procedure
@@ -1915,120 +2323,83 @@
* the ``EpcX2SapUser`` part is provided by the RRC entity and used by the RRC enity.
-X2 Service Primitives
----------------------
-
-The following list specifies which service primitives are provided by the X2 service interface:
-
- * ``EpcX2SapProvider::SendHandoverRequest``
-
- * The RRC entity uses this primitive to indicate to the X2 entity that it must initiate a handover preparation procedure by sending a HANDOVER REQUEST message.
-
- * ``EpcX2SapUser::RecvHandoverRequest``
-
- * The X2 entity in the target eNB uses this primitive to indicate to the RRC entity that a HANDOVER REQUEST message has been received from the source eNB.
-
- * ``EpcX2Sapuser::SendHandoverRequestAck``
-
- * The RRC entity uses this primitive to indicate to the X2 entity that it must send a HANDOVER REQUEST ACKNOWLEDGE message back to the source eNB.
-
- * ``EpcX2SapProvider::RecvHandoverRequestAck``
-
- * The X2 entity in the source eNB uses this primitive to indicate to the RRC entity that a HANDOVER REQUEST ACKNOWLEDGE message has been received from the target eNB.
-
-S1 Service Interface
-++++++++++++++++++++
-
-The S1 service interface is used by the X2 entity to get some information neeeded to build the X2 messages. It is divided into two parts:
-
- * the ``S1SapProvider`` part is provided by the S1 entity and used by the X2 entity and
-
- * the ``S1SapUser`` part is provided by the X2 entity and used by the S1 entity.
-
---------------------------
-ASN.1 encoding of RRC IE's
---------------------------
-
-The messages defined in RRC SAP, common to all Ue/Enb SAP Users/Providers, are transported in a transparent container to/from a Ue/Enb. The encoding format for the different Information Elements are specified in 3GPP TS 36.331, using ASN.1 rules in the unaligned variant. The implementation in Ns3/Lte has been divided in the following classes:
-
- * Asn1Header : Contains the encoding / decoding of basic ASN types
-
- * RrcAsn1Header : Inherits Asn1Header and contains the encoding / decoding of common IE's defined in 3GPP TS 36.331
-
- * Rrc specific messages/IEs classes : A class for each of the messages defined in RRC SAP header
-
-Asn1Header class - Implementation of base ASN.1 types
-+++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-This class implements the methods to Serialize / Deserialize the ASN.1 types being used in 3GPP TS 36.331, according to the packed encoding rules in ITU-T X.691. The types considered are:
-
- * Boolean : a boolean value uses a single bit (1=true, 0=false).
-
- * Integer : a constrained integer (with min and max values defined) uses the minimum amount of bits to encode its range (max-min+1).
-
- * Bitstring : a bistring will be copied bit by bit to the serialization buffer.
-
- * Octetstring : not being currently used.
-
- * Sequence : the sequence generates a preamble indicating the presence of optional and default fields. It also adds a bit indicating the presence of extension marker.
-
- * Sequence...Of : the sequence...of type encodes the number of elements of the sequence as an integer (the subsequent elements will need to be encoded afterwards).
-
- * Choice : indicates which element among the ones in the choice set is being encoded.
-
- * Enumeration : is serialized as an integer indicating which value is used, among the ones in the enumeration, with the number of elements in the enumeration as upper bound.
-
- * Null : the null value is not encoded, although its serialization function is defined to provide a clearer map between specification and implementation.
-
-The class inherits from ns-3 Header, but Deserialize() function is declared pure virtual, thus inherited classes having to implement it. The reason is that deserialization will retrieve the elements in RRC messages, each of them containing different information elements.
-
-Additionally, it has to be noted that the resulting byte length of a specific type/message can vary, according to the presence of optional fields, and due to the optimized encoding. Hence, the serialized bits will be processed using PreSerialize() function, saving the result in m_serializationResult Buffer. As the methods to read/write in a ns3 buffer are defined in a byte basis, the serialization bits are stored into m_serializationPendingBits attribute, until the 8 bits are set and can be written to buffer iterator. Finally, when invoking Serialize(), the contents of the m_serializationResult attribute will be copied to Buffer::Iterator parameter
-
-RrcAsn1Header : Common 3GPP TS 36.331 IE's
-++++++++++++++++++++++++++++++++++++++++++
-
-As some Information Elements are being used for several RRC messages, this class implements the following common IE's:
-
- * SrbToAddModList
-
- * DrbToAddModList
-
- * LogicalChannelConfig
-
- * RadioResourceConfigDedicated
-
- * PhysicalConfigDedicated
-
- * SystemInformationBlockType1
-
- * SystemInformationBlockType2
-
- * RadioResourceConfigCommonSIB
-
-
-Rrc specific messages/IEs classes
-+++++++++++++++++++++++++++++++++
-
-The following RRC SAP have been implemented:
-
- * RrcConnectionRequest
-
- * RrcConnectionSetup
-
- * RrcConnectionSetupCompleted
-
- * RrcConnectionReconfiguration
-
- * RrcConnectionReconfigurationCompleted
-
- * HandoverPreparationInfo
-
- * RrcConnectionReestablishmentRequest
-
- * RrcConnectionReestablishment
-
- * RrcConnectionReestablishmentComplete
-
- * RrcConnectionReestablishmentReject
-
- * RrcConnectionRelease
+For a list of the X2 Service Primitives supported by the above
+classes, as well as for a description of the parameters passed to
+these primitives, the reader is advised to consult the file
+`epc-x2-sap.h` and/or the corresponding doxygen documentation.
+
+
+
+
+.. only:: latex
+
+ .. raw:: latex
+
+ \clearpage
+
+
+
+
+-----------------
+S11
+-----------------
+
+The S11 interface provides control plane interaction between the SGW
+and the MME using the GTPv2-C protocol specified in [TS29274]_. In the
+simulator, this interface is modeled in an ideal
+fashion, with direct interaction between the SGW and the MME objects,
+without actually implementing the encoding of the messages and without actually
+transmitting any PDU on any link.
+
+The S11 primitives that are modeled are:
+
+ * CREATE SESSION REQUEST
+ * CREATE SESSION RESPONSE
+ * MODIFY BEARER REQUEST
+ * MODIFY BEARER RESPONSE
+
+Of these primitives, the first two are used upon initial UE attachment
+for the establishment of the S1-U bearers; the other two are used
+during handover to switch the S1-U bearers from the source eNB to the
+target eNB as a consequence of the reception by the MME of a PATH
+SWITCH REQUEST S1-AP message.
+
+
+
+
+.. only:: latex
+
+ .. raw:: latex
+
+ \clearpage
+
+
+-------
+Helpers
+-------
+
+Two helper objects are use to setup simulations and configure the
+various components. These objects are:
+
+
+ * LteHelper, which takes care of the configuration of the LTE radio
+ access network, as well as of coordinating the setup and release of
+ EPS bearers
+ * EpcHelper, which takes care of the configuratio of the Evolved
+ Packet Core
+
+It is possible to create a simple LTE-only simulations by
+using LteHelper alone, or to create complete LTE-EPC simulations by
+using both LteHelper and EpcHelper. When both helpers are used, they
+interact in a master-slave fashion, with LteHelper being the Master
+that interacts directly with the user program, and EpcHelper working
+"under the hood" to configure the EPC upon explicit methods called by
+LteHelper. The exact interactions are displayed in the Figure :ref:`fig-helpers`.
+
+.. _fig-helpers:
+
+.. figure:: figures/helpers.*
+ :align: center
+
+ Sequence diagram of the interaction between LteHelper and EpcHelper
+
--- a/src/lte/doc/source/lte-references.rst Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/doc/source/lte-references.rst Thu Dec 13 12:22:43 2012 +0100
@@ -6,6 +6,8 @@
.. [TS25814] 3GPP TS 25.814 "Physical layer aspect for evolved Universal Terrestrial Radio Access"
+.. [TS29274] 3GPP TS 29.274 "Tunnelling Protocol for Control plane (GTPv2-C)"
+
.. [TS36101] 3GPP TS 36.101 "E-UTRA User Equipment (UE) radio transmission and reception"
.. [TS36104] 3GPP TS 36.104 "E-UTRA Base Station (BS) radio transmission and reception"
@@ -28,10 +30,13 @@
.. [TS36331] 3GPP TS 36.331 "E-UTRA Radio Resource Control (RRC) protocol specification"
+.. [TS36413] 3GPP TS 36.413 "E-UTRAN S1 application protocol (S1AP)"
+
.. [TS36420] 3GPP TS 36.420 "E-UTRAN X2 general aspects and principles"
.. [TS36423] 3GPP TS 36.423 "E-UTRAN X2 application protocol (X2AP)"
+
.. [R1-081483] 3GPP R1-081483 `Conveying MCS and TB size via PDCCH <http://www.3gpp.org/ftp/tsg_ran/WG1_RL1/TSGR1_52b/Docs/R1-081483.zip>`_
.. [R4-092042] 3GPP R4-092042 "Simulation assumptions and parameters for FDD HeNB RF requirements"
--- a/src/lte/examples/lena-simple.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/examples/lena-simple.cc Thu Dec 13 12:22:43 2012 +0100
@@ -81,7 +81,7 @@
EpsBearer bearer (q);
lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
- Simulator::Stop (Seconds (0.010));
+ Simulator::Stop (Seconds (0.100));
Simulator::Run ();
--- a/src/lte/helper/epc-helper.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/helper/epc-helper.cc Thu Dec 13 12:22:43 2012 +0100
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ * Copyright (c) 2011-2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,6 +17,7 @@
*
* Author: Jaume Nin <jnin@cttc.es>
* Nicola Baldo <nbaldo@cttc.es>
+ * Manuel Requena <manuel.requena@cttc.es>
*/
#include <ns3/epc-helper.h>
@@ -128,6 +129,21 @@
UintegerValue (2000),
MakeUintegerAccessor (&EpcHelper::m_s1uLinkMtu),
MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("X2LinkDataRate",
+ "The data rate to be used for the next X2 link to be created",
+ DataRateValue (DataRate ("10Gb/s")),
+ MakeDataRateAccessor (&EpcHelper::m_x2LinkDataRate),
+ MakeDataRateChecker ())
+ .AddAttribute ("X2LinkDelay",
+ "The delay to be used for the next X2 link to be created",
+ TimeValue (Seconds (0)),
+ MakeTimeAccessor (&EpcHelper::m_x2LinkDelay),
+ MakeTimeChecker ())
+ .AddAttribute ("X2LinkMtu",
+ "The MTU of the next X2 link to be created. Note that, because of some big X2 messages, you need a big MTU.",
+ UintegerValue (3000),
+ MakeUintegerAccessor (&EpcHelper::m_x2LinkMtu),
+ MakeUintegerChecker<uint16_t> ())
;
return tid;
}
@@ -230,11 +246,9 @@
enbNodes.Add (enb1);
enbNodes.Add (enb2);
PointToPointHelper p2ph;
-// TODO Add m_x2Link*** parameters in epc.helper.h
-// TODO Create Make***Accessor functions
-// p2ph.SetDeviceAttribute ("DataRate", DataRateValue (m_x2LinkDataRate));
-// p2ph.SetDeviceAttribute ("Mtu", UintegerValue (m_x2LinkMtu));
-// p2ph.SetChannelAttribute ("Delay", TimeValue (m_x2LinkDelay));
+ p2ph.SetDeviceAttribute ("DataRate", DataRateValue (m_x2LinkDataRate));
+ p2ph.SetDeviceAttribute ("Mtu", UintegerValue (m_x2LinkMtu));
+ p2ph.SetChannelAttribute ("Delay", TimeValue (m_x2LinkDelay));
NetDeviceContainer enbDevices = p2ph.Install (enb1, enb2);
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
@@ -259,7 +273,7 @@
retval = enb2X2cSocket->Bind (InetSocketAddress (enb2Address, m_x2cUdpPort));
NS_ASSERT (retval == 0);
-
+
// Add X2 interface to the eNB1's X2 entity
Ptr<EpcX2> enb1X2 = enb1->GetObject<EpcX2> ();
Ptr<LteEnbNetDevice> enb1LteDev = enb1->GetDevice (0)->GetObject<LteEnbNetDevice> ();
--- a/src/lte/helper/epc-helper.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/helper/epc-helper.h Thu Dec 13 12:22:43 2012 +0100
@@ -1,6 +1,6 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ * Copyright (c) 2011-2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,6 +17,7 @@
*
* Author: Jaume Nin <jnin@cttc.es>
* Nicola Baldo <nbaldo@cttc.es>
+ * Manuel Requena <manuel.requena@cttc.es>
*/
#ifndef EPC_HELPER_H
--- a/src/lte/helper/lte-helper.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/helper/lte-helper.cc Thu Dec 13 12:22:43 2012 +0100
@@ -650,17 +650,19 @@
public:
DrbActivator (Ptr<NetDevice> ueDevice, EpsBearer bearer);
static void ActivateCallback (Ptr<DrbActivator> a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti);
- void ActivateDrb ();
+ void ActivateDrb (uint64_t imsi, uint16_t cellId, uint16_t rnti);
private:
bool m_active;
Ptr<NetDevice> m_ueDevice;
EpsBearer m_bearer;
+ uint64_t m_imsi;
};
DrbActivator::DrbActivator (Ptr<NetDevice> ueDevice, EpsBearer bearer)
: m_active (false),
m_ueDevice (ueDevice),
- m_bearer (bearer)
+ m_bearer (bearer),
+ m_imsi (m_ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ())
{
}
@@ -668,14 +670,14 @@
DrbActivator::ActivateCallback (Ptr<DrbActivator> a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
{
NS_LOG_FUNCTION (a << context << imsi << cellId << rnti);
- a->ActivateDrb ();
+ a->ActivateDrb (imsi, cellId, rnti);
}
void
-DrbActivator::ActivateDrb ()
+DrbActivator::ActivateDrb (uint64_t imsi, uint16_t cellId, uint16_t rnti)
{
- NS_LOG_FUNCTION (this << m_active);
- if (!m_active)
+ NS_LOG_FUNCTION (this << imsi << cellId << rnti << m_active);
+ if ((!m_active) && (imsi == m_imsi))
{
Ptr<LteUeRrc> ueRrc = m_ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ();
NS_ASSERT (ueRrc->GetState () == LteUeRrc::CONNECTED_NORMALLY);
@@ -684,7 +686,8 @@
Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
NS_ASSERT (ueRrc->GetCellId () == enbLteDevice->GetCellId ());
Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
- NS_ASSERT (ueManager->GetState () == UeManager::CONNECTION_SETUP);
+ NS_ASSERT (ueManager->GetState () == UeManager::CONNECTED_NORMALLY ||
+ ueManager->GetState () == UeManager::CONNECTION_RECONFIGURATION);
EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
params.rnti = rnti;
params.bearer = m_bearer;
@@ -701,15 +704,19 @@
{
NS_LOG_FUNCTION (this << ueDevice);
NS_ASSERT_MSG (m_epcHelper == 0, "this method must not be used when EPC is being used");
-
+
// Normally it is the EPC that takes care of activating DRBs
- // after the UE gets connected. When the EPC is not used, we achieve
+ // when the UE gets connected. When the EPC is not used, we achieve
// the same behavior by hooking a dedicated DRB activation function
- // to the UE RRC Connection Established trace source
+ // to the Enb RRC Connection Established trace source
+
+
+ Ptr<LteEnbNetDevice> enbLteDevice = ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
+
std::ostringstream path;
- path << "/NodeList/" << ueDevice->GetNode ()->GetId ()
- << "/DeviceList/" << ueDevice->GetIfIndex ()
- << "/LteUeRrc/ConnectionEstablished";
+ path << "/NodeList/" << enbLteDevice->GetNode ()->GetId ()
+ << "/DeviceList/" << enbLteDevice->GetIfIndex ()
+ << "/LteEnbRrc/ConnectionEstablished";
Ptr<DrbActivator> arg = Create<DrbActivator> (ueDevice, bearer);
Config::Connect (path.str (), MakeBoundCallback (&DrbActivator::ActivateCallback, arg));
}
--- a/src/lte/model/epc-x2-header.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/epc-x2-header.cc Thu Dec 13 12:22:43 2012 +0100
@@ -527,7 +527,7 @@
erabItem.dlGtpTeid = i.ReadNtohU32 ();
m_erabsAdmittedList.push_back (erabItem);
- m_headerLength += 6;
+ m_headerLength += 10;
}
sz = i.ReadNtohU32 ();
@@ -783,6 +783,198 @@
/////////////////////////////////////////////////////////////////////
+NS_OBJECT_ENSURE_REGISTERED (EpcX2SnStatusTransferHeader);
+
+EpcX2SnStatusTransferHeader::EpcX2SnStatusTransferHeader ()
+ : m_numberOfIes (3),
+ m_headerLength (6),
+ m_oldEnbUeX2apId (0xfffa),
+ m_newEnbUeX2apId (0xfffa)
+{
+ m_erabsSubjectToStatusTransferList.clear ();
+}
+
+EpcX2SnStatusTransferHeader::~EpcX2SnStatusTransferHeader ()
+{
+ m_numberOfIes = 0;
+ m_headerLength = 0;
+ m_oldEnbUeX2apId = 0xfffb;
+ m_newEnbUeX2apId = 0xfffb;
+ m_erabsSubjectToStatusTransferList.clear ();
+}
+
+TypeId
+EpcX2SnStatusTransferHeader::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::EpcX2SnStatusTransferHeader")
+ .SetParent<Header> ()
+ .AddConstructor<EpcX2SnStatusTransferHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+EpcX2SnStatusTransferHeader::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::GetSerializedSize (void) const
+{
+ return m_headerLength;
+}
+
+void
+EpcX2SnStatusTransferHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteHtonU16 (m_oldEnbUeX2apId);
+ i.WriteHtonU16 (m_newEnbUeX2apId);
+
+ std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem>::size_type sz = m_erabsSubjectToStatusTransferList.size ();
+ i.WriteHtonU16 (sz); // number of ErabsSubjectToStatusTransferItems
+
+ for (int j = 0; j < (int) sz; j++)
+ {
+ EpcX2Sap::ErabsSubjectToStatusTransferItem item = m_erabsSubjectToStatusTransferList [j];
+
+ i.WriteHtonU16 (item.erabId);
+
+ uint16_t bitsetSize = EpcX2Sap::m_maxPdcpSn / 64;
+ for (int k = 0; k < bitsetSize; k++)
+ {
+ uint64_t statusValue = 0;
+ for (int m = 0; m < 64; m++)
+ {
+ statusValue |= item.receiveStatusOfUlPdcpSdus[64 * k + m] << m;
+ }
+ i.WriteHtonU64 (statusValue);
+ }
+
+ i.WriteHtonU16 (item.ulPdcpSn);
+ i.WriteHtonU32 (item.ulHfn);
+ i.WriteHtonU16 (item.dlPdcpSn);
+ i.WriteHtonU32 (item.dlHfn);
+ }
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ m_oldEnbUeX2apId = i.ReadNtohU16 ();
+ m_newEnbUeX2apId = i.ReadNtohU16 ();
+ int sz = i.ReadNtohU16 ();
+
+ m_numberOfIes = 3;
+ m_headerLength = 6 + sz * (14 + (EpcX2Sap::m_maxPdcpSn / 64));
+
+ for (int j = 0; j < sz; j++)
+ {
+ EpcX2Sap::ErabsSubjectToStatusTransferItem ErabItem;
+ ErabItem.erabId = i.ReadNtohU16 ();
+
+ uint16_t bitsetSize = EpcX2Sap::m_maxPdcpSn / 64;
+ for (int k = 0; k < bitsetSize; k++)
+ {
+ uint64_t statusValue = i.ReadNtohU64 ();
+ for (int m = 0; m < 64; m++)
+ {
+ ErabItem.receiveStatusOfUlPdcpSdus[64 * k + m] = (statusValue >> m) & 1;
+ }
+ }
+
+ ErabItem.ulPdcpSn = i.ReadNtohU16 ();
+ ErabItem.ulHfn = i.ReadNtohU32 ();
+ ErabItem.dlPdcpSn = i.ReadNtohU16 ();
+ ErabItem.dlHfn = i.ReadNtohU32 ();
+
+ m_erabsSubjectToStatusTransferList.push_back (ErabItem);
+ }
+
+ return GetSerializedSize ();
+}
+
+void
+EpcX2SnStatusTransferHeader::Print (std::ostream &os) const
+{
+ os << "OldEnbUeX2apId = " << m_oldEnbUeX2apId;
+ os << " NewEnbUeX2apId = " << m_newEnbUeX2apId;
+ os << " ErabsSubjectToStatusTransferList size = " << m_erabsSubjectToStatusTransferList.size ();
+
+ std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem>::size_type sz = m_erabsSubjectToStatusTransferList.size ();
+ if (sz > 0)
+ {
+ os << " [";
+ }
+ for (int j = 0; j < (int) sz; j++)
+ {
+ os << m_erabsSubjectToStatusTransferList[j].erabId;
+ if (j < (int) sz - 1)
+ {
+ os << ", ";
+ }
+ else
+ {
+ os << "]";
+ }
+ }
+}
+
+uint16_t
+EpcX2SnStatusTransferHeader::GetOldEnbUeX2apId () const
+{
+ return m_oldEnbUeX2apId;
+}
+
+void
+EpcX2SnStatusTransferHeader::SetOldEnbUeX2apId (uint16_t x2apId)
+{
+ m_oldEnbUeX2apId = x2apId;
+}
+
+uint16_t
+EpcX2SnStatusTransferHeader::GetNewEnbUeX2apId () const
+{
+ return m_newEnbUeX2apId;
+}
+
+void
+EpcX2SnStatusTransferHeader::SetNewEnbUeX2apId (uint16_t x2apId)
+{
+ m_newEnbUeX2apId = x2apId;
+}
+
+std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem>
+EpcX2SnStatusTransferHeader::GetErabsSubjectToStatusTransferList () const
+{
+ return m_erabsSubjectToStatusTransferList;
+}
+
+void
+EpcX2SnStatusTransferHeader::SetErabsSubjectToStatusTransferList (std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> erabs)
+{
+ m_headerLength += erabs.size () * (14 + (EpcX2Sap::m_maxPdcpSn / 8));
+ m_erabsSubjectToStatusTransferList = erabs;
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::GetLengthOfIes () const
+{
+ return m_headerLength;
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::GetNumberOfIes () const
+{
+ return m_numberOfIes;
+}
+
+/////////////////////////////////////////////////////////////////////
+
NS_OBJECT_ENSURE_REGISTERED (EpcX2UeContextReleaseHeader);
EpcX2UeContextReleaseHeader::EpcX2UeContextReleaseHeader ()
@@ -1119,8 +1311,8 @@
EpcX2ResourceStatusUpdateHeader::EpcX2ResourceStatusUpdateHeader ()
: m_numberOfIes (3),
m_headerLength (6),
- m_enb1MeasurementId (0),
- m_enb2MeasurementId (0)
+ m_enb1MeasurementId (0xfffa),
+ m_enb2MeasurementId (0xfffa)
{
m_cellMeasurementResultList.clear ();
}
@@ -1129,8 +1321,8 @@
{
m_numberOfIes = 0;
m_headerLength = 0;
- m_enb1MeasurementId = 0;
- m_enb2MeasurementId = 0;
+ m_enb1MeasurementId = 0xfffb;
+ m_enb2MeasurementId = 0xfffb;
m_cellMeasurementResultList.clear ();
}
--- a/src/lte/model/epc-x2-header.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/epc-x2-header.h Thu Dec 13 12:22:43 2012 +0100
@@ -57,6 +57,7 @@
enum ProcedureCode_t {
HandoverPreparation = 0,
LoadIndication = 2,
+ SnStatusTransfer = 4,
UeContextRelease = 5,
ResourceStatusReporting = 10
};
@@ -206,6 +207,42 @@
};
+class EpcX2SnStatusTransferHeader : public Header
+{
+public:
+ EpcX2SnStatusTransferHeader ();
+ virtual ~EpcX2SnStatusTransferHeader ();
+
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+
+
+ uint16_t GetOldEnbUeX2apId () const;
+ void SetOldEnbUeX2apId (uint16_t x2apId);
+
+ uint16_t GetNewEnbUeX2apId () const;
+ void SetNewEnbUeX2apId (uint16_t x2apId);
+
+ std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> GetErabsSubjectToStatusTransferList () const;
+ void SetErabsSubjectToStatusTransferList (std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> erabs);
+
+ uint32_t GetLengthOfIes () const;
+ uint32_t GetNumberOfIes () const;
+
+private:
+ uint32_t m_numberOfIes;
+ uint32_t m_headerLength;
+
+ uint16_t m_oldEnbUeX2apId;
+ uint16_t m_newEnbUeX2apId;
+ std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> m_erabsSubjectToStatusTransferList;
+};
+
+
class EpcX2UeContextReleaseHeader : public Header
{
public:
--- a/src/lte/model/epc-x2-sap.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/epc-x2-sap.h Thu Dec 13 12:22:43 2012 +0100
@@ -25,6 +25,8 @@
#include "ns3/eps-bearer.h"
#include "ns3/ipv4-address.h"
+#include <bitset>
+
namespace ns3 {
@@ -89,6 +91,22 @@
};
/**
+ * E-RABs subject to status transfer item as
+ * it is used in the SN STATUS TRANSFER message.
+ * See section 9.1.1.4 for further info about the parameters
+ */
+ static const uint16_t m_maxPdcpSn = 4096;
+ struct ErabsSubjectToStatusTransferItem
+ {
+ uint16_t erabId;
+ std::bitset<m_maxPdcpSn> receiveStatusOfUlPdcpSdus;
+ uint16_t ulPdcpSn;
+ uint32_t ulHfn;
+ uint16_t dlPdcpSn;
+ uint32_t dlHfn;
+ };
+
+ /**
* UL Interference OverloadIndication as
* it is used in the LOAD INFORMATION message.
* See section 9.2.17 for further info about the values
@@ -248,6 +266,20 @@
};
/**
+ * \brief Parameters of the SN STATUS TRANSFER message.
+ *
+ * See section 9.1.1.4 for further info about the parameters
+ */
+ struct SnStatusTransferParams
+ {
+ uint16_t oldEnbUeX2apId;
+ uint16_t newEnbUeX2apId;
+ uint16_t sourceCellId;
+ uint16_t targetCellId;
+ std::vector <ErabsSubjectToStatusTransferItem> erabsSubjectToStatusTransferList;
+ };
+
+ /**
* \brief Parameters of the UE CONTEXT RELEASE message.
*
* See section 9.1.1.5 for further info about the parameters
@@ -257,6 +289,7 @@
uint16_t oldEnbUeX2apId;
uint16_t newEnbUeX2apId;
uint16_t sourceCellId;
+ uint16_t targetCellId;
};
/**
@@ -305,6 +338,8 @@
virtual void SendHandoverPreparationFailure (HandoverPreparationFailureParams params) = 0;
+ virtual void SendSnStatusTransfer (SnStatusTransferParams params) = 0;
+
virtual void SendUeContextRelease (UeContextReleaseParams params) = 0;
virtual void SendLoadInformation (LoadInformationParams params) = 0;
@@ -332,6 +367,8 @@
virtual void RecvHandoverPreparationFailure (HandoverPreparationFailureParams params) = 0;
+ virtual void RecvSnStatusTransfer (SnStatusTransferParams params) = 0;
+
virtual void RecvUeContextRelease (UeContextReleaseParams params) = 0;
virtual void RecvLoadInformation (LoadInformationParams params) = 0;
@@ -357,6 +394,8 @@
virtual void SendHandoverPreparationFailure (HandoverPreparationFailureParams params);
+ virtual void SendSnStatusTransfer (SnStatusTransferParams params);
+
virtual void SendUeContextRelease (UeContextReleaseParams params);
virtual void SendLoadInformation (LoadInformationParams params);
@@ -402,6 +441,13 @@
template <class C>
void
+EpcX2SpecificEpcX2SapProvider<C>::SendSnStatusTransfer (SnStatusTransferParams params)
+{
+ m_x2->DoSendSnStatusTransfer (params);
+}
+
+template <class C>
+void
EpcX2SpecificEpcX2SapProvider<C>::SendUeContextRelease (UeContextReleaseParams params)
{
m_x2->DoSendUeContextRelease (params);
@@ -439,6 +485,8 @@
virtual void RecvHandoverPreparationFailure (HandoverPreparationFailureParams params);
+ virtual void RecvSnStatusTransfer (SnStatusTransferParams params);
+
virtual void RecvUeContextRelease (UeContextReleaseParams params);
virtual void RecvLoadInformation (LoadInformationParams params);
@@ -484,6 +532,13 @@
template <class C>
void
+EpcX2SpecificEpcX2SapUser<C>::RecvSnStatusTransfer (SnStatusTransferParams params)
+{
+ m_rrc->DoRecvSnStatusTransfer (params);
+}
+
+template <class C>
+void
EpcX2SpecificEpcX2SapUser<C>::RecvUeContextRelease (UeContextReleaseParams params)
{
m_rrc->DoRecvUeContextRelease (params);
--- a/src/lte/model/epc-x2.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/epc-x2.cc Thu Dec 13 12:22:43 2012 +0100
@@ -164,6 +164,10 @@
Ptr<Packet> packet = socket->Recv ();
NS_LOG_LOGIC ("packetLen = " << packet->GetSize ());
+ NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
+ "Missing infos of local and remote CellId");
+ Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
+
EpcX2Header x2Header;
packet->RemoveHeader (x2Header);
@@ -172,9 +176,6 @@
uint8_t messageType = x2Header.GetMessageType ();
uint8_t procedureCode = x2Header.GetProcedureCode ();
- NS_LOG_LOGIC ("messageType = " << (uint32_t)messageType);
- NS_LOG_LOGIC ("procedureCode = " << (uint32_t)procedureCode);
-
if (procedureCode == EpcX2Header::HandoverPreparation)
{
if (messageType == EpcX2Header::InitiatingMessage)
@@ -186,10 +187,6 @@
NS_LOG_INFO ("X2 HandoverRequest header: " << x2HoReqHeader);
- NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
- "Missing infos of local and remote CellId");
- Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
-
EpcX2SapUser::HandoverRequestParams params;
params.oldEnbUeX2apId = x2HoReqHeader.GetOldEnbUeX2apId ();
params.cause = x2HoReqHeader.GetCause ();
@@ -218,9 +215,7 @@
EpcX2HandoverRequestAckHeader x2HoReqAckHeader;
packet->RemoveHeader (x2HoReqAckHeader);
- NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
- "Missing infos of local and remote CellId");
- Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
+ NS_LOG_INFO ("X2 HandoverRequestAck header: " << x2HoReqAckHeader);
EpcX2SapUser::HandoverRequestAckParams params;
params.oldEnbUeX2apId = x2HoReqAckHeader.GetOldEnbUeX2apId ();
@@ -245,9 +240,7 @@
EpcX2HandoverPreparationFailureHeader x2HoPrepFailHeader;
packet->RemoveHeader (x2HoPrepFailHeader);
- NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
- "Missing infos of local and remote CellId");
- Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
+ NS_LOG_INFO ("X2 HandoverPreparationFailure header: " << x2HoPrepFailHeader);
EpcX2SapUser::HandoverPreparationFailureParams params;
params.oldEnbUeX2apId = x2HoPrepFailHeader.GetOldEnbUeX2apId ();
@@ -284,6 +277,33 @@
m_x2SapUser->RecvLoadInformation (params);
}
}
+ else if (procedureCode == EpcX2Header::SnStatusTransfer)
+ {
+ if (messageType == EpcX2Header::InitiatingMessage)
+ {
+ NS_LOG_LOGIC ("Recv X2 message: SN STATUS TRANSFER");
+
+ EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
+ packet->RemoveHeader (x2SnStatusXferHeader);
+
+ NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
+
+ EpcX2SapUser::SnStatusTransferParams params;
+ params.oldEnbUeX2apId = x2SnStatusXferHeader.GetOldEnbUeX2apId ();
+ params.newEnbUeX2apId = x2SnStatusXferHeader.GetNewEnbUeX2apId ();
+ params.sourceCellId = cellsInfo->m_remoteCellId;
+ params.targetCellId = cellsInfo->m_localCellId;
+ params.erabsSubjectToStatusTransferList = x2SnStatusXferHeader.GetErabsSubjectToStatusTransferList ();
+
+ NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+ NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
+ NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
+ NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
+ NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
+
+ m_x2SapUser->RecvSnStatusTransfer (params);
+ }
+ }
else if (procedureCode == EpcX2Header::UeContextRelease)
{
if (messageType == EpcX2Header::InitiatingMessage)
@@ -486,6 +506,54 @@
void
+EpcX2::DoSendSnStatusTransfer (EpcX2SapProvider::SnStatusTransferParams params)
+{
+ NS_LOG_FUNCTION (this);
+
+ NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+ NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
+ NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
+ NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
+ NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
+
+ NS_ASSERT_MSG (m_x2InterfaceSockets.find (params.targetCellId) != m_x2InterfaceSockets.end (),
+ "Socket infos not defined for targetCellId = " << params.targetCellId);
+
+ Ptr<Socket> localSocket = m_x2InterfaceSockets [params.targetCellId]->m_localSocket;
+ Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.targetCellId]->m_remoteIpAddr;
+
+ NS_LOG_LOGIC ("localSocket = " << localSocket);
+ NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
+
+ NS_LOG_INFO ("Send X2 message: SN STATUS TRANSFER");
+
+ // Build the X2 message
+ EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
+ x2SnStatusXferHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
+ x2SnStatusXferHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
+ x2SnStatusXferHeader.SetErabsSubjectToStatusTransferList (params.erabsSubjectToStatusTransferList);
+
+ EpcX2Header x2Header;
+ x2Header.SetMessageType (EpcX2Header::InitiatingMessage);
+ x2Header.SetProcedureCode (EpcX2Header::SnStatusTransfer);
+ x2Header.SetLengthOfIes (x2SnStatusXferHeader.GetLengthOfIes ());
+ x2Header.SetNumberOfIes (x2SnStatusXferHeader.GetNumberOfIes ());
+
+ NS_LOG_INFO ("X2 header: " << x2Header);
+ NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
+
+ // Build the X2 packet
+ Ptr<Packet> packet = Create <Packet> ();
+ packet->AddHeader (x2SnStatusXferHeader);
+ packet->AddHeader (x2Header);
+ NS_LOG_INFO ("packetLen = " << packet->GetSize ());
+
+ // Send the X2 message through the socket
+ localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
+}
+
+
+void
EpcX2::DoSendUeContextRelease (EpcX2SapProvider::UeContextReleaseParams params)
{
NS_LOG_FUNCTION (this);
--- a/src/lte/model/epc-x2.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/epc-x2.h Thu Dec 13 12:22:43 2012 +0100
@@ -116,6 +116,7 @@
virtual void DoSendHandoverRequest (EpcX2SapProvider::HandoverRequestParams params);
virtual void DoSendHandoverRequestAck (EpcX2SapProvider::HandoverRequestAckParams params);
virtual void DoSendHandoverPreparationFailure (EpcX2SapProvider::HandoverPreparationFailureParams params);
+ virtual void DoSendSnStatusTransfer (EpcX2SapProvider::SnStatusTransferParams params);
virtual void DoSendUeContextRelease (EpcX2SapProvider::UeContextReleaseParams params);
virtual void DoSendLoadInformation (EpcX2SapProvider::LoadInformationParams params);
virtual void DoSendResourceStatusUpdate (EpcX2SapProvider::ResourceStatusUpdateParams params);
--- a/src/lte/model/lte-enb-phy.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-enb-phy.cc Thu Dec 13 12:22:43 2012 +0100
@@ -891,8 +891,10 @@
m_srsUeOffset.clear ();
m_srsUeOffset.resize (p, 0);
m_srsPeriodicity = p;
- // inhibit SRS until RRC Connection Reconfiguration propagates to UEs
- m_srsStartTime = Simulator::Now () + MilliSeconds (2);
+ // inhibit SRS until RRC Connection Reconfiguration propagates
+ // to UEs, otherwise we might be wrong in determining the UE who
+ // actually sent the SRS (if the UE was using a stale SRS config)
+ m_srsStartTime = Simulator::Now () + MilliSeconds (m_macChTtiDelay) + MilliSeconds (3);
}
NS_LOG_DEBUG (this << " ENB SRS P " << m_srsPeriodicity << " RNTI " << rnti << " offset " << GetSrsSubframeOffset (srcCi) << " CI " << srcCi);
--- a/src/lte/model/lte-enb-rrc.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.cc Thu Dec 13 12:22:43 2012 +0100
@@ -141,16 +141,22 @@
m_sourceCellId (0)
{
NS_LOG_FUNCTION (this);
+}
+void
+UeManager::DoStart ()
+{
+ NS_LOG_FUNCTION (this);
m_drbPdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<UeManager> (this);
m_physicalConfigDedicated.haveAntennaInfoDedicated = true;
m_physicalConfigDedicated.antennaInfo.transmissionMode = m_rrc->m_defaultTransmissionMode;
m_physicalConfigDedicated.haveSoundingRsUlConfigDedicated = true;
m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex = m_rrc->GetNewSrsConfigurationIndex ();
+ m_physicalConfigDedicated.soundingRsUlConfigDedicated.type = LteRrcSap::SoundingRsUlConfigDedicated::SETUP;
- m_rrc->m_cmacSapProvider->AddUe (rnti);
- m_rrc->m_cphySapProvider->AddUe (rnti);
+ m_rrc->m_cmacSapProvider->AddUe (m_rnti);
+ m_rrc->m_cphySapProvider->AddUe (m_rnti);
// setup the eNB side of SRB0
{
@@ -163,7 +169,7 @@
m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
m_srb0->m_rlc = rlc;
- m_srb0->m_srbIdentity = 1;
+ m_srb0->m_srbIdentity = 0;
// no need to store logicalChannelConfig as SRB0 is pre-configured
LteEnbCmacSapProvider::LcInfo lcinfo;
@@ -219,13 +225,13 @@
// configure MAC (and scheduler)
LteEnbCmacSapProvider::UeConfig req;
- req.m_rnti = rnti;
+ req.m_rnti = m_rnti;
req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
m_rrc->m_cmacSapProvider->UeUpdateConfigurationReq (req);
// configure PHY
- m_rrc->m_cphySapProvider->SetTransmissionMode (rnti, m_physicalConfigDedicated.antennaInfo.transmissionMode);
- m_rrc->m_cphySapProvider->SetSrsConfigurationIndex (rnti, m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex);
+ m_rrc->m_cphySapProvider->SetTransmissionMode (m_rnti, m_physicalConfigDedicated.antennaInfo.transmissionMode);
+ m_rrc->m_cphySapProvider->SetSrsConfigurationIndex (m_rnti, m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex);
}
@@ -272,8 +278,8 @@
m_imsi = imsi;
}
-uint8_t
-UeManager::SetupDataRadioBearer (EpsBearer bearer, uint32_t gtpTeid, Ipv4Address transportLayerAddress)
+void
+UeManager::SetupDataRadioBearer (EpsBearer bearer, uint8_t bearerId, uint32_t gtpTeid, Ipv4Address transportLayerAddress)
{
NS_LOG_FUNCTION (this << (uint32_t) m_rnti);
@@ -281,6 +287,7 @@
uint8_t drbid = AddDataRadioBearerInfo (drbInfo);
uint8_t lcid = Drbid2Lcid (drbid);
uint8_t bid = Drbid2Bid (drbid);
+ NS_ASSERT_MSG ( bearerId == 0 || bid == bearerId, "bearer ID mismatch (" << (uint32_t) bid << " != " << (uint32_t) bearerId << ", the assumption that ID are allocated in the same way by MME and RRC is not valid any more");
drbInfo->m_epsBearerIdentity = bid;
drbInfo->m_drbIdentity = drbid;
drbInfo->m_logicalChannelIdentity = lcid;
@@ -346,7 +353,23 @@
}
drbInfo->m_logicalChannelConfig.bucketSizeDurationMs = 1000;
- return drbid;
+ ScheduleRrcConnectionReconfiguration ();
+}
+
+void
+UeManager::StartDataRadioBearers ()
+{
+ NS_LOG_FUNCTION (this << (uint32_t) m_rnti);
+ for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
+ it != m_drbMap.end ();
+ ++it)
+ {
+ it->second->m_rlc->Start ();
+ if (it->second->m_pdcp)
+ {
+ it->second->m_pdcp->Start ();
+ }
+ }
}
@@ -447,17 +470,50 @@
}
-
void
-UeManager::SendHandoverCommand (LteRrcSap::RrcConnectionReconfiguration rcr)
+UeManager::RecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params)
{
NS_LOG_FUNCTION (this);
- m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration (m_rnti, rcr);
+
+ NS_ASSERT_MSG (params.notAdmittedBearers.empty (), "not admission of some bearers upon handover is not supported");
+ NS_ASSERT_MSG (params.admittedBearers.size () == m_drbMap.size (), "not enough bearers in admittedBearers");
+
+ // note: the Handover command from the target eNB to the source eNB
+ // is expected to be sent transparently to the UE; however, here we
+ // decode the message and eventually reencode it. This way we can
+ // support both a real RRC protocol implementation and an ideal one
+ // without actual RRC protocol encoding.
+
+ Ptr<Packet> encodedHandoverCommand = params.rrcContext;
+ LteRrcSap::RrcConnectionReconfiguration handoverCommand = m_rrc->m_rrcSapUser->DecodeHandoverCommand (encodedHandoverCommand);
+ m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration (m_rnti, handoverCommand);
SwitchToState (HANDOVER_LEAVING);
- NS_ASSERT (rcr.haveMobilityControlInfo);
- m_rrc->m_handoverStartTrace (m_imsi, m_rrc->m_cellId, m_rnti, rcr.mobilityControlInfo.targetPhysCellId);
+ NS_ASSERT (handoverCommand.haveMobilityControlInfo);
+ m_rrc->m_handoverStartTrace (m_imsi, m_rrc->m_cellId, m_rnti, handoverCommand.mobilityControlInfo.targetPhysCellId);
+
+ EpcX2SapProvider::SnStatusTransferParams sst;
+ sst.oldEnbUeX2apId = params.oldEnbUeX2apId;
+ sst.newEnbUeX2apId = params.newEnbUeX2apId;
+ sst.sourceCellId = params.sourceCellId;
+ sst.targetCellId = params.targetCellId;
+ for ( std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbIt = m_drbMap.begin ();
+ drbIt != m_drbMap.end ();
+ ++drbIt)
+ {
+ // SN status transfer is only for AM RLC
+ if (0 != drbIt->second->m_rlc->GetObject<LteRlcAm> ())
+ {
+ LtePdcp::Status status = drbIt->second->m_pdcp->GetStatus ();
+ EpcX2Sap::ErabsSubjectToStatusTransferItem i;
+ i.dlPdcpSn = status.txSn;
+ i.ulPdcpSn = status.rxSn;
+ sst.erabsSubjectToStatusTransferList.push_back (i);
+ }
+ }
+ m_rrc->m_x2SapProvider->SendSnStatusTransfer (sst);
}
+
LteRrcSap::RadioResourceConfigDedicated
UeManager::GetRadioResourceConfigForHandoverPreparationInfo ()
{
@@ -546,6 +602,25 @@
}
}
+void
+UeManager::RecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params)
+{
+ NS_LOG_FUNCTION (this);
+ for (std::vector<EpcX2Sap::ErabsSubjectToStatusTransferItem>::iterator erabIt
+ = params.erabsSubjectToStatusTransferList.begin ();
+ erabIt != params.erabsSubjectToStatusTransferList.end ();
+ ++erabIt)
+ {
+ // LtePdcp::Status status;
+ // status.txSn = erabIt->dlPdcpSn;
+ // status.rxSn = erabIt->ulPdcpSn;
+ // uint8_t drbId = Bid2Drbid (erabIt->erabId);
+ // std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbIt = m_drbMap.find (drbId);
+ // NS_ASSERT_MSG (drbIt != m_drbMap.end (), "could not find DRBID " << (uint32_t) drbId);
+ // drbIt->second->m_pdcp->SetStatus (status);
+ }
+}
+
// methods forwarded from RRC SAP
void
@@ -589,7 +664,8 @@
NS_LOG_FUNCTION (this);
switch (m_state)
{
- case CONNECTION_SETUP:
+ case CONNECTION_SETUP:
+ StartDataRadioBearers ();
SwitchToState (CONNECTED_NORMALLY);
m_rrc->m_connectionEstablishedTrace (m_imsi, m_rrc->m_cellId, m_rnti);
break;
@@ -606,7 +682,8 @@
NS_LOG_FUNCTION (this);
switch (m_state)
{
- case CONNECTION_RECONFIGURATION:
+ case CONNECTION_RECONFIGURATION:
+ StartDataRadioBearers ();
SwitchToState (CONNECTED_NORMALLY);
m_rrc->m_connectionReconfigurationTrace (m_imsi, m_rrc->m_cellId, m_rnti);
break;
@@ -1214,11 +1291,8 @@
void
LteEnbRrc::DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters request)
{
-
Ptr<UeManager> ueManager = GetUeManager (request.rnti);
- uint8_t bid = ueManager->SetupDataRadioBearer (request.bearer, request.gtpTeid, request.transportLayerAddress);
- NS_ASSERT_MSG ( request.bearerId == 0 || bid == request.bearerId, "bearer ID mismatch (" << (uint32_t) bid << " != " << (uint32_t) request.bearerId << ", the assumption that ID are allocated in the same way by MME and RRC is not valid any more");
- ueManager->ScheduleRrcConnectionReconfiguration ();
+ ueManager->SetupDataRadioBearer (request.bearer, request.bearerId, request.gtpTeid, request.transportLayerAddress);
}
void
@@ -1269,11 +1343,20 @@
ueManager->SetSource (req.sourceCellId, req.oldEnbUeX2apId);
ueManager->SetImsi (req.mmeUeS1apId);
+ EpcX2SapProvider::HandoverRequestAckParams ackParams;
+ ackParams.oldEnbUeX2apId = req.oldEnbUeX2apId;
+ ackParams.newEnbUeX2apId = rnti;
+ ackParams.sourceCellId = req.sourceCellId;
+ ackParams.targetCellId = req.targetCellId;
+
for (std::vector <EpcX2Sap::ErabToBeSetupItem>::iterator it = req.bearers.begin ();
it != req.bearers.end ();
++it)
{
- ueManager->SetupDataRadioBearer (it->erabLevelQosParameters, it->gtpTeid, it->transportLayerAddress);
+ ueManager->SetupDataRadioBearer (it->erabLevelQosParameters, it->erabId, it->gtpTeid, it->transportLayerAddress);
+ EpcX2Sap::ErabAdmittedItem i;
+ i.erabId = it->erabId;
+ ackParams.admittedBearers.push_back (i);
}
LteRrcSap::RrcConnectionReconfiguration handoverCommand = ueManager->GetRrcConnectionReconfigurationForHandover ();
@@ -1291,14 +1374,9 @@
handoverCommand.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex = anrcrv.raPrachMaskIndex;
Ptr<Packet> encodedHandoverCommand = m_rrcSapUser->EncodeHandoverCommand (handoverCommand);
- NS_LOG_LOGIC ("Send X2 message: HANDOVER REQUEST ACK");
+ ackParams.rrcContext = encodedHandoverCommand;
- EpcX2SapProvider::HandoverRequestAckParams ackParams;
- ackParams.oldEnbUeX2apId = req.oldEnbUeX2apId;
- ackParams.newEnbUeX2apId = rnti;
- ackParams.sourceCellId = req.sourceCellId;
- ackParams.targetCellId = req.targetCellId;
- ackParams.rrcContext = encodedHandoverCommand;
+ NS_LOG_LOGIC ("Send X2 message: HANDOVER REQUEST ACK");
NS_LOG_LOGIC ("oldEnbUeX2apId = " << ackParams.oldEnbUeX2apId);
NS_LOG_LOGIC ("newEnbUeX2apId = " << ackParams.newEnbUeX2apId);
@@ -1322,17 +1400,7 @@
uint16_t rnti = params.oldEnbUeX2apId;
Ptr<UeManager> ueManager = GetUeManager (rnti);
-
- // note: the Handover command from the target eNB to the source eNB
- // is expected to be sent transparently to the UE; however, here we
- // decode the message and eventually reencode it. This way we can
- // support both a real RRC protocol implementation and an ideal one
- // without actual RRC protocol encoding.
-
- Ptr<Packet> encodedHandoverCommand = params.rrcContext;
- LteRrcSap::RrcConnectionReconfiguration handoverCommand = m_rrcSapUser->DecodeHandoverCommand (encodedHandoverCommand);
- ueManager->SendHandoverCommand (handoverCommand);
-
+ ueManager->RecvHandoverRequestAck (params);
}
void
@@ -1354,6 +1422,22 @@
}
void
+LteEnbRrc::DoRecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params)
+{
+ NS_LOG_FUNCTION (this);
+
+ NS_LOG_LOGIC ("Recv X2 message: SN STATUS TRANSFER");
+
+ NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+ NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
+ NS_LOG_LOGIC ("erabsSubjectToStatusTransferList size = " << params.erabsSubjectToStatusTransferList.size ());
+
+ uint16_t rnti = params.newEnbUeX2apId;
+ Ptr<UeManager> ueManager = GetUeManager (rnti);
+ ueManager->RecvSnStatusTransfer (params);
+}
+
+void
LteEnbRrc::DoRecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params)
{
NS_LOG_FUNCTION (this);
@@ -1436,6 +1520,7 @@
m_lastAllocatedRnti = rnti;
Ptr<UeManager> ueManager = CreateObject<UeManager> (this, rnti, state);
m_ueMap.insert (std::pair<uint16_t, Ptr<UeManager> > (rnti, ueManager));
+ ueManager->Start ();
NS_LOG_DEBUG (this << " New UE RNTI " << rnti << " cellId " << m_cellId << " srs CI " << ueManager->GetSrsConfigurationIndex ());
return rnti;
}
@@ -1545,7 +1630,7 @@
std::set<uint16_t>::reverse_iterator rit = m_ueSrsConfigurationIndexSet.rbegin ();
NS_ASSERT (rit != m_ueSrsConfigurationIndexSet.rend ());
NS_LOG_DEBUG (this << " lower bound " << (*rit) << " of " << g_srsCiHigh[m_srsCurrentPeriodicityId]);
- if ((*rit) <= g_srsCiHigh[m_srsCurrentPeriodicityId])
+ if ((*rit) < g_srsCiHigh[m_srsCurrentPeriodicityId])
{
// got it from the upper bound
m_lastAllocatedConfigurationIndex = (*rit) + 1;
--- a/src/lte/model/lte-enb-rrc.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.h Thu Dec 13 12:22:43 2012 +0100
@@ -95,6 +95,7 @@
// inherited from Object
protected:
+ virtual void DoStart ();
virtual void DoDispose ();
public:
static TypeId GetTypeId (void);
@@ -119,14 +120,21 @@
* Setup a new data radio bearer, including both the configuration
* within the eNB and the necessary RRC signaling with the UE
*
- * \param bearer
+ * \param bearer the QoS characteristics of the bearer
+ * \param bearerId the EPS bearer identifier
* \param gtpTeid S1-bearer GTP tunnel endpoint identifier, see 36.423 9.2.1
* \param transportLayerAddress IP Address of the SGW, see 36.423 9.2.1
*
- * \return the EPS Bearer Id
*/
- uint8_t SetupDataRadioBearer (EpsBearer bearer, uint32_t gtpTeid, Ipv4Address transportLayerAddress);
+ void SetupDataRadioBearer (EpsBearer bearer, uint8_t bearerId, uint32_t gtpTeid, Ipv4Address transportLayerAddress);
+ /**
+ * Start all configured data radio bearers. It is safe to call this
+ * method if any bearer had been already started previously.
+ *
+ */
+ void StartDataRadioBearers ();
+
/**
*
* Release a given radio bearer
@@ -149,15 +157,11 @@
void PrepareHandover (uint16_t cellId);
/**
- * In the X2-based handover procedure, at the source eNB, trigger
- * handover by sending to the UE a RRC Connection
- * Reconfiguration message including Mobility Control Info
+ * take the necessary actions in response to the reception of an X2 HANDOVER REQUEST ACK message
*
- * \param rcr the RrcConnectionReconfiguration message including the
- * Mobility Control Info. The content of this struct shall be
- * provided by the target eNB.
+ * \param params
*/
- void SendHandoverCommand (LteRrcSap::RrcConnectionReconfiguration rcr);
+ void RecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
/**
*
@@ -205,6 +209,13 @@
* \param cellId id of the target cell
*/
void RecvHandoverPreparationFailure (uint16_t cellId);
+
+ /**
+ * Take the necessary actions in response to the reception of an X2 SN STATUS TRANSFER message
+ *
+ * \param params the SN STATUS
+ */
+ void RecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params);
// methods forwarded from RRC SAP
@@ -575,6 +586,7 @@
void DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params);
void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
void DoRecvHandoverPreparationFailure (EpcX2SapUser::HandoverPreparationFailureParams params);
+ void DoRecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params);
void DoRecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params);
void DoRecvLoadInformation (EpcX2SapUser::LoadInformationParams params);
void DoRecvResourceStatusUpdate (EpcX2SapUser::ResourceStatusUpdateParams params);
--- a/src/lte/model/lte-pdcp.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-pdcp.cc Thu Dec 13 12:22:43 2012 +0100
@@ -142,6 +142,22 @@
return m_rlcSapUser;
}
+LtePdcp::Status
+LtePdcp::GetStatus ()
+{
+ Status s;
+ s.txSn = m_txSequenceNumber;
+ s.rxSn = m_rxSequenceNumber;
+ return s;
+}
+
+void
+LtePdcp::SetStatus (Status s)
+{
+ m_txSequenceNumber = s.txSn;
+ m_rxSequenceNumber = s.rxSn;
+}
+
////////////////////////////////////////
void
--- a/src/lte/model/lte-pdcp.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-pdcp.h Thu Dec 13 12:22:43 2012 +0100
@@ -87,6 +87,30 @@
*/
LteRlcSapUser* GetLteRlcSapUser ();
+ static const uint16_t MAX_PDCP_SN = 4096;
+
+ /**
+ * Status variables of the PDCP
+ *
+ */
+ struct Status
+ {
+ uint16_t txSn; ///< TX sequence number
+ uint16_t rxSn; ///< RX sequence number
+ };
+
+ /**
+ *
+ * \return the current status of the PDCP
+ */
+ Status GetStatus ();
+
+ /**
+ * Set the status of the PDCP
+ *
+ * \param s
+ */
+ void SetStatus (Status s);
protected:
// Interface provided to upper RRC entity
--- a/src/lte/model/lte-rlc-am.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc-am.cc Thu Dec 13 12:22:43 2012 +0100
@@ -72,8 +72,6 @@
// SDU reassembling process
m_reassemblingState = WAITING_S0_FULL;
m_expectedSeqNumber = 0;
-
- Simulator::ScheduleNow (&LteRlcAm::Start, this);
}
LteRlcAm::~LteRlcAm ()
@@ -127,42 +125,7 @@
NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
/** Report Buffer Status */
-
- // Transmission Queue HOL time
- RlcTag txonQueueHolTimeTag;
- m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
- Time txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp ();
-
- // Retransmission Queue HOL time
- RlcTag retxQueueHolTimeTag;
- Time retxQueueHolDelay (0);
- if ( m_retxBufferSize )
- {
-//MRE m_retxBuffer.front ().m_pdu->PeekPacketTag (retxQueueHolTimeTag);
- retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
- }
-
- LteMacSapProvider::ReportBufferStatusParameters r;
- r.rnti = m_rnti;
- r.lcid = m_lcid;
- r.txQueueSize = m_txonBufferSize;
- r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
- r.retxQueueSize = m_retxBufferSize;
- r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
-
- if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
- {
- r.statusPduSize = m_statusPduBufferSize;
- }
- else
- {
- r.statusPduSize = 0;
- }
-
- NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
- << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
- << r.statusPduSize);
- m_macSapProvider->ReportBufferStatus (r);
+ DoReportBufferStatus ();
}
@@ -174,7 +137,7 @@
LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId)
{
NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes);
-
+
if (bytes <= 2)
{
// Stingy MAC: Header fix part is 2 bytes, we need more bytes for the data
@@ -203,12 +166,15 @@
params.harqProcessId = harqId;
m_macSapProvider->TransmitPdu (params);
+
+ m_statusPduRequested = false;
+ m_statusPduBufferSize = 0;
return;
}
else if ( m_retxBufferSize > 0 )
{
NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
-
+
Ptr<Packet> packet = m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->Copy ();
if ( packet->GetSize () <= bytes )
@@ -518,7 +484,7 @@
{
NS_LOG_LOGIC ("Start PollRetransmit timer");
- m_pollRetransmitTimer = Simulator::Schedule (Time ("0.1s"),
+ m_pollRetransmitTimer = Simulator::Schedule (Time ("0.01s"),
&LteRlcAm::ExpirePollRetransmitTimer, this);
}
else
@@ -526,7 +492,7 @@
NS_LOG_LOGIC ("Restart PollRetransmit timer");
m_pollRetransmitTimer.Cancel ();
- m_pollRetransmitTimer = Simulator::Schedule (Time ("0.1s"),
+ m_pollRetransmitTimer = Simulator::Schedule (Time ("0.01s"),
&LteRlcAm::ExpirePollRetransmitTimer, this);
}
}
@@ -540,7 +506,7 @@
NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer");
m_txedBufferSize += packet->GetSize ();
m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ) = packet->Copy ();
-
+
// Sender timestamp
RlcTag rlcTag (Simulator::Now ());
packet->AddByteTag (rlcTag);
@@ -659,47 +625,7 @@
if (! m_statusProhibitTimer.IsRunning ())
{
- Time now = Simulator::Now ();
-
- // Transmission Queue HOL time
- RlcTag txonQueueHolTimeTag;
- Time txonQueueHolDelay (0);
- if ( ! m_txonBuffer.empty () )
- {
- m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
- txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp ();
- }
-
- // Retransmission Queue HOL time
- RlcTag retxQueueHolTimeTag;
- Time retxQueueHolDelay (0);
- if ( m_retxBufferSize )
- {
- m_retxBuffer.front ().m_pdu->PeekPacketTag (retxQueueHolTimeTag);
- retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
- }
-
- LteMacSapProvider::ReportBufferStatusParameters r;
- r.rnti = m_rnti;
- r.lcid = m_lcid;
- r.txQueueSize = m_txonBufferSize;
- r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
- r.retxQueueSize = m_retxBufferSize;
- r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
-
- if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
- {
- r.statusPduSize = m_statusPduBufferSize;
- }
- else
- {
- r.statusPduSize = 0;
- }
-
- NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
- << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
- << r.statusPduSize );
- m_macSapProvider->ReportBufferStatus (r);
+ DoReportBufferStatus ();
}
}
@@ -1017,24 +943,6 @@
}
-void
-LteRlcAm::Start ()
-{
- NS_LOG_FUNCTION (this);
-
- LteMacSapProvider::ReportBufferStatusParameters p;
- p.rnti = m_rnti;
- p.lcid = m_lcid;
- p.txQueueSize = 0;
- p.txQueueHolDelay = 0;
- p.retxQueueSize = 0;
- p.retxQueueHolDelay = 0;
- p.statusPduSize = 0;
-
- m_macSapProvider->ReportBufferStatus (p);
-}
-
-
bool
LteRlcAm::IsInsideReceivingWindow (SequenceNumber10 seqNumber)
{
@@ -1531,8 +1439,61 @@
void
+LteRlcAm::DoReportBufferStatus (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ Time now = Simulator::Now ();
+
+ // Transmission Queue HOL time
+ Time txonQueueHolDelay (0);
+ if ( m_txonBufferSize > 0 )
+ {
+ RlcTag txonQueueHolTimeTag;
+ m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
+ txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp ();
+ }
+
+ // Retransmission Queue HOL time
+ Time retxQueueHolDelay (0);
+ if ( m_retxBufferSize > 0 )
+ {
+ RlcTag retxQueueHolTimeTag;
+// m_retxBuffer.front ().m_pdu->PeekPacketTag (retxQueueHolTimeTag);
+ retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
+ }
+
+ LteMacSapProvider::ReportBufferStatusParameters r;
+ r.rnti = m_rnti;
+ r.lcid = m_lcid;
+ r.txQueueSize = m_txonBufferSize;
+ r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
+ r.retxQueueSize = m_retxBufferSize;
+ r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
+
+ if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
+ {
+ r.statusPduSize = m_statusPduBufferSize;
+ }
+ else
+ {
+ r.statusPduSize = 0;
+ }
+
+ NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
+ << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
+ << r.statusPduSize);
+ m_macSapProvider->ReportBufferStatus (r);
+
+// m_statusPduRequested = false;
+// m_statusPduBufferSize = 0;
+}
+
+
+void
LteRlcAm::ExpireReorderingTimer (void)
{
+ NS_LOG_FUNCTION (this);
NS_LOG_LOGIC ("Reordering Timer has expired");
// 5.1.3.2.4 Actions when t-Reordering expires
@@ -1569,8 +1530,17 @@
void
LteRlcAm::ExpirePollRetransmitTimer (void)
{
+ NS_LOG_FUNCTION (this);
NS_LOG_LOGIC ("PollRetransmit Timer has expired");
- NS_LOG_LOGIC ("TODO To Check");
+
+ NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
+ NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
+ NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
+
+ NS_LOG_LOGIC ("statusPduRequested = " << m_statusPduRequested);
+ NS_LOG_LOGIC ("VT(S) = " << m_vtS);
+
+ DoReportBufferStatus ();
}
--- a/src/lte/model/lte-rlc-am.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc-am.h Thu Dec 13 12:22:43 2012 +0100
@@ -53,8 +53,6 @@
virtual void DoNotifyHarqDeliveryFailure ();
virtual void DoReceivePdu (Ptr<Packet> p);
- void Start ();
-
private:
/**
* This method will schedule a timeout at WaitReplyTimeout interval
@@ -71,6 +69,8 @@
//
void ReassembleAndDeliver (Ptr<Packet> packet);
+ void DoReportBufferStatus ();
+
private:
std::vector < Ptr<Packet> > m_txonBuffer; // Transmission buffer
std::vector < Ptr<Packet> > m_txedBuffer; // Transmitted packets buffer
--- a/src/lte/model/lte-rlc-tm.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc-tm.cc Thu Dec 13 12:22:43 2012 +0100
@@ -36,8 +36,6 @@
m_txBufferSize (0)
{
NS_LOG_FUNCTION (this);
-
- Simulator::ScheduleNow (&LteRlcTm::Start, this);
}
LteRlcTm::~LteRlcTm ()
@@ -188,15 +186,6 @@
void
-LteRlcTm::Start ()
-{
- NS_LOG_FUNCTION (this);
-
- DoReportBufferStatus ();
-}
-
-
-void
LteRlcTm::DoReportBufferStatus (void)
{
Time holDelay (0);
--- a/src/lte/model/lte-rlc-tm.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc-tm.h Thu Dec 13 12:22:43 2012 +0100
@@ -52,8 +52,6 @@
virtual void DoNotifyHarqDeliveryFailure ();
virtual void DoReceivePdu (Ptr<Packet> p);
- void Start ();
-
private:
void ExpireRbsTimer (void);
void DoReportBufferStatus ();
--- a/src/lte/model/lte-rlc-um.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc-um.cc Thu Dec 13 12:22:43 2012 +0100
@@ -44,8 +44,6 @@
{
NS_LOG_FUNCTION (this);
m_reassemblingState = WAITING_S0_FULL;
-
- Simulator::ScheduleNow (&LteRlcUm::Start, this);
}
LteRlcUm::~LteRlcUm ()
@@ -559,15 +557,6 @@
}
-void
-LteRlcUm::Start ()
-{
- NS_LOG_FUNCTION (this);
-
- DoReportBufferStatus ();
-}
-
-
bool
LteRlcUm::IsInsideReorderingWindow (SequenceNumber10 seqNumber)
{
--- a/src/lte/model/lte-rlc-um.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc-um.h Thu Dec 13 12:22:43 2012 +0100
@@ -52,8 +52,6 @@
virtual void DoNotifyHarqDeliveryFailure ();
virtual void DoReceivePdu (Ptr<Packet> p);
- void Start ();
-
private:
void ExpireReorderingTimer (void);
void ExpireRbsTimer (void);
--- a/src/lte/model/lte-rlc.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc.cc Thu Dec 13 12:22:43 2012 +0100
@@ -109,12 +109,6 @@
}
void
-LteRlcSm::DoDispose ()
-{
- NS_LOG_FUNCTION (this);
-}
-
-void
LteRlc::SetRnti (uint16_t rnti)
{
NS_LOG_FUNCTION (this << (uint32_t) rnti);
@@ -171,9 +165,7 @@
LteRlcSm::LteRlcSm ()
{
-
NS_LOG_FUNCTION (this);
- Simulator::ScheduleNow (&LteRlcSm::Start, this);
}
LteRlcSm::~LteRlcSm ()
@@ -192,6 +184,19 @@
}
void
+LteRlcSm::DoStart ()
+{
+ NS_LOG_FUNCTION (this);
+ ReportBufferStatus ();
+}
+
+void
+LteRlcSm::DoDispose ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
LteRlcSm::DoTransmitPdcpPdu (Ptr<Packet> p)
{
NS_LOG_FUNCTION (this << p);
@@ -245,13 +250,6 @@
}
void
-LteRlcSm::Start ()
-{
- NS_LOG_FUNCTION (this);
- ReportBufferStatus ();
-}
-
-void
LteRlcSm::ReportBufferStatus ()
{
NS_LOG_FUNCTION (this);
--- a/src/lte/model/lte-rlc.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rlc.h Thu Dec 13 12:22:43 2012 +0100
@@ -148,6 +148,7 @@
LteRlcSm ();
virtual ~LteRlcSm ();
static TypeId GetTypeId (void);
+ virtual void DoStart ();
virtual void DoDispose ();
virtual void DoTransmitPdcpPdu (Ptr<Packet> p);
@@ -155,7 +156,7 @@
virtual void DoNotifyHarqDeliveryFailure ();
virtual void DoReceivePdu (Ptr<Packet> p);
- void Start ();
+
private:
void ReportBufferStatus ();
--- a/src/lte/model/lte-rrc-header.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rrc-header.cc Thu Dec 13 12:22:43 2012 +0100
@@ -40,6 +40,12 @@
{
}
+int
+RrcAsn1Header::GetMessageType ()
+{
+ return m_messageType;
+}
+
void
RrcAsn1Header::SerializeDrbToAddModList (std::list<LteRrcSap::DrbToAddMod> drbToAddModList) const
{
@@ -68,23 +74,6 @@
switch (it->rlcConfig.choice)
{
- case LteRrcSap::RlcConfig::AM:
- // Serialize rlc-Config choice
- SerializeChoice (4,0);
-
- // Serialize UL-AM-RLC
- SerializeSequence<0> (std::bitset<0> (),false);
- SerializeEnum (64,0); // t-PollRetransmit
- SerializeEnum (8,0); // pollPDU
- SerializeEnum (16,0); // pollByte
- SerializeEnum (8,0); // maxRetxThreshold
-
- // Serialize DL-AM-RLC
- SerializeSequence<0> (std::bitset<0> (),false);
- SerializeEnum (32,0); // t-Reordering
- SerializeEnum (64,0); // t-StatusProhibit
- break;
-
case LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL:
// Serialize rlc-Config choice
SerializeChoice (4,1);
@@ -117,6 +106,24 @@
SerializeEnum (2,0); // sn-FieldLength
SerializeEnum (32,0); // t-Reordering
break;
+
+ case LteRrcSap::RlcConfig::AM:
+ default:
+ // Serialize rlc-Config choice
+ SerializeChoice (4,0);
+
+ // Serialize UL-AM-RLC
+ SerializeSequence<0> (std::bitset<0> (),false);
+ SerializeEnum (64,0); // t-PollRetransmit
+ SerializeEnum (8,0); // pollPDU
+ SerializeEnum (16,0); // pollByte
+ SerializeEnum (8,0); // maxRetxThreshold
+
+ // Serialize DL-AM-RLC
+ SerializeSequence<0> (std::bitset<0> (),false);
+ SerializeEnum (32,0); // t-Reordering
+ SerializeEnum (64,0); // t-StatusProhibit
+ break;
}
// Serialize logicalChannelIdentity ::=INTEGER (3..10)
@@ -257,7 +264,9 @@
SerializeChoice (2,0);
SerializeNull ();
break;
+
case LteRrcSap::SoundingRsUlConfigDedicated::SETUP:
+ default:
// 2 options, selected: 1 (setup)
SerializeChoice (2,1);
@@ -314,29 +323,42 @@
void
RrcAsn1Header::SerializeRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const
{
+ bool isSrbToAddModListPresent = !radioResourceConfigDedicated.srbToAddModList.empty ();
+ bool isDrbToAddModListPresent = !radioResourceConfigDedicated.drbToAddModList.empty ();
+ bool isDrbToReleaseListPresent = !radioResourceConfigDedicated.drbToReleaseList.empty ();
+
// 6 optional fields. Extension marker is present.
std::bitset<6> optionalFieldsPresent = std::bitset<6> ();
- optionalFieldsPresent.set (5,1); // srb-ToAddModList present
- optionalFieldsPresent.set (4,1); // drb-ToAddModList present
- optionalFieldsPresent.set (3,1); // drb-ToReleaseList present
+ optionalFieldsPresent.set (5,isSrbToAddModListPresent); // srb-ToAddModList present
+ optionalFieldsPresent.set (4,isDrbToAddModListPresent); // drb-ToAddModList present
+ optionalFieldsPresent.set (3,isDrbToReleaseListPresent); // drb-ToReleaseList present
optionalFieldsPresent.set (2,0); // mac-MainConfig not present
optionalFieldsPresent.set (1,0); // sps-Config not present
optionalFieldsPresent.set (0,(radioResourceConfigDedicated.havePhysicalConfigDedicated) ? 1 : 0);
SerializeSequence<6> (optionalFieldsPresent,true);
// Serialize srbToAddModList
- SerializeSrbToAddModList (radioResourceConfigDedicated.srbToAddModList);
+ if (isSrbToAddModListPresent)
+ {
+ SerializeSrbToAddModList (radioResourceConfigDedicated.srbToAddModList);
+ }
// Serialize drbToAddModList
- SerializeDrbToAddModList (radioResourceConfigDedicated.drbToAddModList);
+ if (isDrbToAddModListPresent)
+ {
+ SerializeDrbToAddModList (radioResourceConfigDedicated.drbToAddModList);
+ }
// Serialize drbToReleaseList
- SerializeSequenceOf (radioResourceConfigDedicated.drbToReleaseList.size (),MAX_DRB,1);
- std::list<uint8_t>::iterator it = radioResourceConfigDedicated.drbToReleaseList.begin ();
- for (; it != radioResourceConfigDedicated.drbToReleaseList.end (); it++)
+ if (isDrbToReleaseListPresent)
{
- // DRB-Identity ::= INTEGER (1..32)
- SerializeInteger (*it,1,32);
+ SerializeSequenceOf (radioResourceConfigDedicated.drbToReleaseList.size (),MAX_DRB,1);
+ std::list<uint8_t>::iterator it = radioResourceConfigDedicated.drbToReleaseList.begin ();
+ for (; it != radioResourceConfigDedicated.drbToReleaseList.end (); it++)
+ {
+ // DRB-Identity ::= INTEGER (1..32)
+ SerializeInteger (*it,1,32);
+ }
}
if (radioResourceConfigDedicated.havePhysicalConfigDedicated)
@@ -1427,6 +1449,7 @@
return bIterator;
}
+
//////////////////// RrcConnectionRequest class ////////////////////////
// Constructor
@@ -1452,6 +1475,8 @@
{
m_serializationResult = Buffer ();
+ SerializeUlCcchMessage (1);
+
// Serialize RRCConnectionRequest sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence<0> (std::bitset<0> (),false);
@@ -1495,6 +1520,8 @@
std::bitset<0> optionalOrDefaultMask;
int selectedOption;
+ bIterator = DeserializeUlCcchMessage (bIterator);
+
// Deserialize RCConnectionRequest sequence
bIterator = DeserializeSequence (&optionalOrDefaultMask,false,bIterator);
@@ -1533,6 +1560,15 @@
m_isDataSerialized = false;
}
+LteRrcSap::RrcConnectionRequest
+RrcConnectionRequestHeader::GetMessage () const
+{
+ RrcConnectionRequest msg;
+ msg.ueIdentity = (((uint64_t) m_mmec.to_ulong ()) << 32) | (m_mTmsi.to_ulong ());
+
+ return msg;
+}
+
std::bitset<8>
RrcConnectionRequestHeader::getMmec () const
{
@@ -1564,6 +1600,10 @@
{
m_serializationResult = Buffer ();
+ SerializeDlCcchMessage (3);
+
+ SerializeInteger (15,0,15);
+
// Serialize RRCConnectionSetup sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence (std::bitset<0> (),false);
@@ -1598,14 +1638,20 @@
uint32_t
RrcConnectionSetupHeader::Deserialize (Buffer::Iterator bIterator)
{
- // Deserialize RRCConnectionSetup sequence
+ int n;
+
std::bitset<0> bitset0;
std::bitset<1> bitset1;
std::bitset<2> bitset2;
+
+ bIterator = DeserializeDlCcchMessage (bIterator);
+
+ bIterator = DeserializeInteger (&n,0,15,bIterator);
+
+ // Deserialize RRCConnectionSetup sequence
bIterator = DeserializeSequence (&bitset0,false,bIterator);
// Deserialize rrc-TransactionIdentifier ::=INTEGER (0..3)
- int n;
bIterator = DeserializeInteger (&n,0,3,bIterator);
rrcTransactionIdentifier = n;
@@ -1659,6 +1705,15 @@
m_isDataSerialized = false;
}
+LteRrcSap::RrcConnectionSetup
+RrcConnectionSetupHeader::GetMessage () const
+{
+ RrcConnectionSetup msg;
+ msg.rrcTransactionIdentifier = rrcTransactionIdentifier;
+ msg.radioResourceConfigDedicated = radioResourceConfigDedicated;
+ return msg;
+}
+
uint8_t
RrcConnectionSetupHeader::GetRrcTransactionIdentifier () const
{
@@ -1712,6 +1767,9 @@
{
m_serializationResult = Buffer ();
+ // Serialize DCCH message
+ SerializeUlDcchMessage (4);
+
// Serialize RRCConnectionSetupComplete sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence<0> (std::bitset<0> (),false);
@@ -1737,6 +1795,9 @@
RrcConnectionSetupCompleteHeader::Deserialize (Buffer::Iterator bIterator)
{
std::bitset<0> bitset0;
+
+ bIterator = DeserializeUlDcchMessage (bIterator);
+
bIterator = DeserializeSequence (&bitset0,false,bIterator);
int n;
@@ -1789,6 +1850,14 @@
return m_rrcTransactionIdentifier;
}
+LteRrcSap::RrcConnectionSetupCompleted
+RrcConnectionSetupCompleteHeader::GetMessage () const
+{
+ LteRrcSap::RrcConnectionSetupCompleted msg;
+ msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
+ return msg;
+}
+
//////////////////// RrcConnectionReconfigurationCompleteHeader class ////////////////////////
RrcConnectionReconfigurationCompleteHeader::RrcConnectionReconfigurationCompleteHeader ()
@@ -1800,6 +1869,9 @@
{
m_serializationResult = Buffer ();
+ // Serialize DCCH message
+ SerializeUlDcchMessage (2);
+
// Serialize RRCConnectionSetupComplete sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence<0> (std::bitset<0> (),false);
@@ -1825,6 +1897,9 @@
bIterator = DeserializeSequence (&bitset0,false,bIterator);
int n;
+
+ bIterator = DeserializeUlDcchMessage (bIterator);
+
bIterator = DeserializeInteger (&n,0,3,bIterator);
m_rrcTransactionIdentifier = n;
@@ -1857,6 +1932,14 @@
m_isDataSerialized = false;
}
+LteRrcSap::RrcConnectionReconfigurationCompleted
+RrcConnectionReconfigurationCompleteHeader::GetMessage () const
+{
+ RrcConnectionReconfigurationCompleted msg;
+ msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
+ return msg;
+}
+
uint8_t
RrcConnectionReconfigurationCompleteHeader::GetRrcTransactionIdentifier () const
{
@@ -1874,6 +1957,8 @@
{
m_serializationResult = Buffer ();
+ SerializeDlDcchMessage (4);
+
// Serialize RRCConnectionSetupComplete sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence<0> (std::bitset<0> (),false);
@@ -1996,9 +2081,10 @@
uint32_t
RrcConnectionReconfigurationHeader::Deserialize (Buffer::Iterator bIterator)
{
- // pag 106
std::bitset<0> bitset0;
+ bIterator = DeserializeDlDcchMessage (bIterator);
+
// RRCConnectionReconfiguration sequence
bIterator = DeserializeSequence (&bitset0,false,bIterator);
@@ -2237,6 +2323,22 @@
m_isDataSerialized = false;
}
+LteRrcSap::RrcConnectionReconfiguration
+RrcConnectionReconfigurationHeader::GetMessage () const
+{
+ RrcConnectionReconfiguration msg;
+
+ msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
+ msg.haveMeasConfig = m_haveMeasConfig;
+ msg.measConfig = m_measConfig;
+ msg.haveMobilityControlInfo = m_haveMobilityControlInfo;
+ msg.mobilityControlInfo = m_mobilityControlInfo;
+ msg.haveRadioResourceConfigDedicated = m_haveRadioResourceConfigDedicated;
+ msg.radioResourceConfigDedicated = m_radioResourceConfigDedicated;
+
+ return msg;
+}
+
uint8_t
RrcConnectionReconfigurationHeader::GetRrcTransactionIdentifier () const
{
@@ -2575,6 +2677,15 @@
m_isDataSerialized = false;
}
+LteRrcSap::HandoverPreparationInfo
+HandoverPreparationInfoHeader::GetMessage () const
+{
+ HandoverPreparationInfo msg;
+ msg.asConfig = m_asConfig;
+
+ return msg;
+}
+
LteRrcSap::AsConfig
HandoverPreparationInfoHeader::GetAsConfig () const
{
@@ -2592,6 +2703,8 @@
{
m_serializationResult = Buffer ();
+ SerializeUlCcchMessage (0);
+
// Serialize RrcConnectionReestablishmentReques sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence<0> (std::bitset<0> (),false);
@@ -2642,6 +2755,8 @@
std::bitset<0> bitset0;
int n;
+ bIterator = DeserializeUlCcchMessage (bIterator);
+
// Deserialize RrcConnectionReestablishmentRequest sequence
// 0 optional fields, no extension marker
bIterator = DeserializeSequence (&bitset0,false,bIterator);
@@ -2717,6 +2832,16 @@
m_isDataSerialized = false;
}
+LteRrcSap::RrcConnectionReestablishmentRequest
+RrcConnectionReestablishmentRequestHeader::GetMessage () const
+{
+ RrcConnectionReestablishmentRequest msg;
+ msg.ueIdentity = m_ueIdentity;
+ msg.reestablishmentCause = m_reestablishmentCause;
+
+ return msg;
+}
+
LteRrcSap::ReestabUeIdentity
RrcConnectionReestablishmentRequestHeader::GetUeIdentity () const
{
@@ -2729,7 +2854,7 @@
return m_reestablishmentCause;
}
-//////////////////// RrcConnectionReestablishmentRequestHeader class ////////////////////////
+//////////////////// RrcConnectionReestablishmentHeader class ////////////////////////
RrcConnectionReestablishmentHeader::RrcConnectionReestablishmentHeader ()
{
@@ -2740,6 +2865,8 @@
{
m_serializationResult = Buffer ();
+ SerializeDlCcchMessage (0);
+
// Serialize RrcConnectionReestablishment sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence (std::bitset<0> (),false);
@@ -2773,6 +2900,8 @@
std::bitset<0> bitset0;
int n;
+ bIterator = DeserializeDlCcchMessage (bIterator);
+
// Deserialize RrcConnectionReestablishment sequence
// 0 optional fields, no extension marker
bIterator = DeserializeSequence (&bitset0,false,bIterator);
@@ -2832,6 +2961,15 @@
m_isDataSerialized = false;
}
+LteRrcSap::RrcConnectionReestablishment
+RrcConnectionReestablishmentHeader::GetMessage () const
+{
+ RrcConnectionReestablishment msg;
+ msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
+ msg.radioResourceConfigDedicated = m_radioResourceConfigDedicated;
+ return msg;
+}
+
uint8_t
RrcConnectionReestablishmentHeader::GetRrcTransactionIdentifier () const
{
@@ -2855,6 +2993,9 @@
{
m_serializationResult = Buffer ();
+ // Serialize DCCH message
+ SerializeUlDcchMessage (3);
+
// Serialize RrcConnectionReestablishmentComplete sequence:
// no default or optional fields. Extension marker not present.
SerializeSequence (std::bitset<0> (),false);
@@ -2879,6 +3020,8 @@
std::bitset<0> bitset0;
int n;
+ bIterator = DeserializeUlDcchMessage (bIterator);
+
// Deserialize RrcConnectionReestablishmentComplete sequence
// 0 optional fields, no extension marker
bIterator = DeserializeSequence (&bitset0,false,bIterator);
@@ -2923,11 +3066,538 @@
m_isDataSerialized = false;
}
+LteRrcSap::RrcConnectionReestablishmentComplete
+RrcConnectionReestablishmentCompleteHeader::GetMessage () const
+{
+ RrcConnectionReestablishmentComplete msg;
+ msg.rrcTransactionIdentifier = m_rrcTransactionIdentifier;
+ return msg;
+}
+
uint8_t
RrcConnectionReestablishmentCompleteHeader::GetRrcTransactionIdentifier () const
{
return m_rrcTransactionIdentifier;
}
+//////////////////// RrcConnectionReestablishmentRejectHeader class ////////////////////////
+
+RrcConnectionReestablishmentRejectHeader::RrcConnectionReestablishmentRejectHeader ()
+{
+}
+
+void
+RrcConnectionReestablishmentRejectHeader::PreSerialize () const
+{
+ m_serializationResult = Buffer ();
+
+ // Serialize CCCH message
+ SerializeDlCcchMessage (1);
+
+ // Serialize RrcConnectionReestablishmentReject sequence:
+ // no default or optional fields. Extension marker not present.
+ SerializeSequence (std::bitset<0> (),false);
+
+ // Serialize criticalExtensions choice
+ SerializeChoice (2,0);
+
+ // Serialize RRCConnectionReestablishmentReject-r8-IEs sequence
+ // 1 optional field (not present), no extension marker.
+ SerializeSequence (std::bitset<1> (0),false);
+
+ // Finish serialization
+ FinalizeSerialization ();
+}
+
+uint32_t
+RrcConnectionReestablishmentRejectHeader::Deserialize (Buffer::Iterator bIterator)
+{
+ std::bitset<0> bitset0;
+
+ bIterator = DeserializeDlCcchMessage (bIterator);
+
+ // Deserialize RrcConnectionReestablishmentReject sequence
+ // 0 optional fields, no extension marker
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+ // Deserialize criticalExtensions choice
+ int criticalExtensionsChoice;
+ bIterator = DeserializeChoice (2,&criticalExtensionsChoice,bIterator);
+ if (criticalExtensionsChoice == 1)
+ {
+ // Deserialize criticalExtensionsFuture
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ }
+ else if (criticalExtensionsChoice == 0)
+ {
+ // Deserialize rrcConnectionReestablishmentReject-r8
+ std::bitset<1> opts;
+ bIterator = DeserializeSequence (&opts,false,bIterator);
+ if (opts[0])
+ {
+ // Deserialize RRCConnectionReestablishmentReject-v8a0-IEs
+ // ...
+ }
+ }
+
+ return GetSerializedSize ();
+}
+
+void
+RrcConnectionReestablishmentRejectHeader::Print (std::ostream &os) const
+{
+}
+
+void
+RrcConnectionReestablishmentRejectHeader::SetMessage (RrcConnectionReestablishmentReject msg)
+{
+ m_rrcConnectionReestablishmentReject = msg;
+ m_isDataSerialized = false;
+}
+
+LteRrcSap::RrcConnectionReestablishmentReject
+RrcConnectionReestablishmentRejectHeader::GetMessage () const
+{
+ return m_rrcConnectionReestablishmentReject;
+}
+
+//////////////////// RrcConnectionReleaseHeader class ////////////////////////
+
+RrcConnectionReleaseHeader::RrcConnectionReleaseHeader ()
+{
+}
+
+void
+RrcConnectionReleaseHeader::PreSerialize () const
+{
+ m_serializationResult = Buffer ();
+
+ // Serialize DCCH message
+ SerializeDlDcchMessage (5);
+
+ // Serialize RrcConnectionRelease sequence:
+ // no default or optional fields. Extension marker not present.
+ SerializeSequence (std::bitset<0> (),false);
+
+ // Serialize rrc-TransactionIdentifier
+ SerializeInteger (m_rrcConnectionRelease.rrcTransactionIdentifier,0,3);
+
+ // Serialize criticalExtensions choice
+ SerializeChoice (2,0);
+
+ // Serialize c1 choice
+ SerializeChoice (4,0);
+
+ // Serialize RRCConnectionRelease-r8-IEs sequence
+ // 3 optional field (not present), no extension marker.
+ SerializeSequence (std::bitset<3> (0),false);
+
+ // Serialize ReleaseCause
+ SerializeEnum (4,1);
+
+ // Finish serialization
+ FinalizeSerialization ();
+}
+
+uint32_t
+RrcConnectionReleaseHeader::Deserialize (Buffer::Iterator bIterator)
+{
+ std::bitset<0> bitset0;
+ int n;
+
+ bIterator = DeserializeDlDcchMessage (bIterator);
+
+ // Deserialize RrcConnectionRelease sequence
+ // 0 optional fields, no extension marker
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+ // Deserialize rrc-TransactionIdentifier
+ bIterator = DeserializeInteger (&n,0,3,bIterator);
+ m_rrcConnectionRelease.rrcTransactionIdentifier = n;
+
+ // Deserialize criticalExtensions choice
+ int criticalExtensionsChoice;
+ bIterator = DeserializeChoice (2,&criticalExtensionsChoice,bIterator);
+ if (criticalExtensionsChoice == 1)
+ {
+ // Deserialize criticalExtensionsFuture
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ }
+ else if (criticalExtensionsChoice == 0)
+ {
+ // Deserialize c1
+ int c1Choice;
+ bIterator = DeserializeChoice (4,&c1Choice,bIterator);
+
+ if (c1Choice == 0)
+ {
+ // Deserialize RRCConnectionRelease-r8-IEs
+ std::bitset<3> opts;
+ bIterator = DeserializeSequence (&opts,false,bIterator);
+
+ // Deserialize releaseCause
+ bIterator = DeserializeEnum (4,&n,bIterator);
+
+ if (opts[2])
+ {
+ // Deserialize redirectedCarrierInfo
+ // ...
+ }
+ if (opts[1])
+ {
+ // Deserialize idleModeMobilityControlInfo
+ // ...
+ }
+ if (opts[0])
+ {
+ // Deserialize nonCriticalExtension
+ // ...
+ }
+ }
+
+ else
+ {
+ bIterator = DeserializeNull (bIterator);
+ }
+ }
+
+ return GetSerializedSize ();
+}
+
+void
+RrcConnectionReleaseHeader::Print (std::ostream &os) const
+{
+}
+
+void
+RrcConnectionReleaseHeader::SetMessage (RrcConnectionRelease msg)
+{
+ m_rrcConnectionRelease = msg;
+ m_isDataSerialized = false;
+}
+
+LteRrcSap::RrcConnectionRelease
+RrcConnectionReleaseHeader::GetMessage () const
+{
+ return m_rrcConnectionRelease;
+}
+
+//////////////////// RrcConnectionRejectHeader class ////////////////////////
+
+RrcConnectionRejectHeader::RrcConnectionRejectHeader ()
+{
+}
+
+void
+RrcConnectionRejectHeader::PreSerialize () const
+{
+ m_serializationResult = Buffer ();
+
+ // Serialize CCCH message
+ SerializeDlCcchMessage (2);
+
+ // Serialize RrcConnectionReject sequence:
+ // no default or optional fields. Extension marker not present.
+ SerializeSequence (std::bitset<0> (),false);
+
+ // Serialize criticalExtensions choice
+ SerializeChoice (2,0);
+
+ // Serialize c1 choice
+ SerializeChoice (4,0);
+
+ // Serialize rrcConnectionReject-r8 sequence
+ // 1 optional field (not present), no extension marker.
+ SerializeSequence (std::bitset<1> (0),false);
+
+ // Serialize waitTime
+ SerializeInteger (m_rrcConnectionReject.waitTime, 1, 16);
+
+ // Finish serialization
+ FinalizeSerialization ();
+}
+
+uint32_t
+RrcConnectionRejectHeader::Deserialize (Buffer::Iterator bIterator)
+{
+ std::bitset<0> bitset0;
+ int n;
+
+ bIterator = DeserializeDlCcchMessage (bIterator);
+
+ // Deserialize RrcConnectionReject sequence
+ // 0 optional fields, no extension marker
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+
+ // Deserialize criticalExtensions choice
+ int criticalExtensionsChoice;
+ bIterator = DeserializeChoice (2,&criticalExtensionsChoice,bIterator);
+ if (criticalExtensionsChoice == 1)
+ {
+ // Deserialize criticalExtensionsFuture
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ }
+ else if (criticalExtensionsChoice == 0)
+ {
+ // Deserialize c1 choice
+ int c1Choice;
+ bIterator = DeserializeChoice (4,&c1Choice,bIterator);
+
+ if (c1Choice > 0)
+ {
+ bIterator = DeserializeNull(bIterator);
+ }
+ else if (c1Choice == 0)
+ {
+ // Deserialize rrcConnectionReject-r8
+ std::bitset<1> opts;
+ bIterator = DeserializeSequence (&opts,false,bIterator);
+
+ bIterator = DeserializeInteger (&n,1,16,bIterator);
+ m_rrcConnectionReject.waitTime = n;
+
+ if (opts[0])
+ {
+ // Deserialize RRCConnectionReject-v8a0-IEs
+ // ...
+ }
+ }
+ }
+
+ return GetSerializedSize ();
+}
+
+void
+RrcConnectionRejectHeader::Print (std::ostream &os) const
+{
+ os << "wait time: " << (int)m_rrcConnectionReject.waitTime << std::endl;
+}
+
+void
+RrcConnectionRejectHeader::SetMessage (RrcConnectionReject msg)
+{
+ m_rrcConnectionReject = msg;
+ m_isDataSerialized = false;
+}
+
+LteRrcSap::RrcConnectionReject
+RrcConnectionRejectHeader::GetMessage () const
+{
+ return m_rrcConnectionReject;
+}
+
+
+/////////////////// RrcUlDcchMessage //////////////////////////////////
+uint32_t
+RrcUlDcchMessage::Deserialize (Buffer::Iterator bIterator)
+{
+ DeserializeUlDcchMessage (bIterator);
+ return 1;
+}
+
+void
+RrcUlDcchMessage::Print (std::ostream &os) const
+{
+ std::cout << "UL DCCH MSG TYPE: " << m_messageType << std::endl;
+}
+
+void
+RrcUlDcchMessage::PreSerialize () const
+{
+ SerializeUlDcchMessage (m_messageType);
+}
+
+Buffer::Iterator
+RrcUlDcchMessage::DeserializeUlDcchMessage (Buffer::Iterator bIterator)
+{
+ std::bitset<0> bitset0;
+ int n;
+
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ bIterator = DeserializeChoice (2,&n,bIterator);
+ if (n == 1)
+ {
+ // Deserialize messageClassExtension
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ m_messageType = -1;
+ }
+ else if (n == 0)
+ {
+ // Deserialize c1
+ bIterator = DeserializeChoice (16,&m_messageType,bIterator);
+ }
+
+ return bIterator;
+}
+
+void
+RrcUlDcchMessage::SerializeUlDcchMessage (int messageType) const
+{
+ SerializeSequence (std::bitset<0> (),false);
+ // Choose c1
+ SerializeChoice (2,0);
+ // Choose message type
+ SerializeChoice (16,messageType);
+}
+
+/////////////////// RrcDlDcchMessage //////////////////////////////////
+uint32_t
+RrcDlDcchMessage::Deserialize (Buffer::Iterator bIterator)
+{
+ DeserializeDlDcchMessage (bIterator);
+ return 1;
+}
+
+void
+RrcDlDcchMessage::Print (std::ostream &os) const
+{
+ std::cout << "DL DCCH MSG TYPE: " << m_messageType << std::endl;
+}
+
+void
+RrcDlDcchMessage::PreSerialize () const
+{
+ SerializeDlDcchMessage (m_messageType);
+}
+
+Buffer::Iterator
+RrcDlDcchMessage::DeserializeDlDcchMessage (Buffer::Iterator bIterator)
+{
+ std::bitset<0> bitset0;
+ int n;
+
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ bIterator = DeserializeChoice (2,&n,bIterator);
+ if (n == 1)
+ {
+ // Deserialize messageClassExtension
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ m_messageType = -1;
+ }
+ else if (n == 0)
+ {
+ // Deserialize c1
+ bIterator = DeserializeChoice (16,&m_messageType,bIterator);
+ }
+
+ return bIterator;
+}
+
+void
+RrcDlDcchMessage::SerializeDlDcchMessage (int messageType) const
+{
+ SerializeSequence (std::bitset<0> (),false);
+ // Choose c1
+ SerializeChoice (2,0);
+ // Choose message type
+ SerializeChoice (16,messageType);
+}
+
+/////////////////// RrcUlCcchMessage //////////////////////////////////
+uint32_t
+RrcUlCcchMessage::Deserialize (Buffer::Iterator bIterator)
+{
+ DeserializeUlCcchMessage (bIterator);
+ return 1;
+}
+
+void
+RrcUlCcchMessage::Print (std::ostream &os) const
+{
+ std::cout << "UL CCCH MSG TYPE: " << m_messageType << std::endl;
+}
+
+void
+RrcUlCcchMessage::PreSerialize () const
+{
+ SerializeUlCcchMessage (m_messageType);
+}
+
+Buffer::Iterator
+RrcUlCcchMessage::DeserializeUlCcchMessage (Buffer::Iterator bIterator)
+{
+ std::bitset<0> bitset0;
+ int n;
+
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ bIterator = DeserializeChoice (2,&n,bIterator);
+ if (n == 1)
+ {
+ // Deserialize messageClassExtension
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ m_messageType = -1;
+ }
+ else if (n == 0)
+ {
+ // Deserialize c1
+ bIterator = DeserializeChoice (2,&m_messageType,bIterator);
+ }
+
+ return bIterator;
+}
+
+void
+RrcUlCcchMessage::SerializeUlCcchMessage (int messageType) const
+{
+ SerializeSequence (std::bitset<0> (),false);
+ // Choose c1
+ SerializeChoice (2,0);
+ // Choose message type
+ SerializeChoice (2,messageType);
+}
+
+/////////////////// RrcDlCcchMessage //////////////////////////////////
+uint32_t
+RrcDlCcchMessage::Deserialize (Buffer::Iterator bIterator)
+{
+ DeserializeDlCcchMessage (bIterator);
+ return 1;
+}
+
+void
+RrcDlCcchMessage::Print (std::ostream &os) const
+{
+ std::cout << "DL CCCH MSG TYPE: " << m_messageType << std::endl;
+}
+
+void
+RrcDlCcchMessage::PreSerialize () const
+{
+ SerializeDlCcchMessage (m_messageType);
+}
+
+Buffer::Iterator
+RrcDlCcchMessage::DeserializeDlCcchMessage (Buffer::Iterator bIterator)
+{
+ std::bitset<0> bitset0;
+ int n;
+
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ bIterator = DeserializeChoice (2,&n,bIterator);
+ if (n == 1)
+ {
+ // Deserialize messageClassExtension
+ bIterator = DeserializeSequence (&bitset0,false,bIterator);
+ m_messageType = -1;
+ }
+ else if (n == 0)
+ {
+ // Deserialize c1
+ bIterator = DeserializeChoice (4,&m_messageType,bIterator);
+ }
+
+ return bIterator;
+}
+
+void
+RrcDlCcchMessage::SerializeDlCcchMessage (int messageType) const
+{
+ SerializeSequence (std::bitset<0> (),false);
+ // Choose c1
+ SerializeChoice (2,0);
+ // Choose message type
+ SerializeChoice (4,messageType);
+}
+
} // namespace ns3
--- a/src/lte/model/lte-rrc-header.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rrc-header.h Thu Dec 13 12:22:43 2012 +0100
@@ -39,6 +39,7 @@
{
public:
RrcAsn1Header ();
+ int GetMessageType ();
protected:
// Serialization functions
@@ -63,12 +64,71 @@
Buffer::Iterator DeserializeRadioResourceConfigCommonSib (Buffer::Iterator bIterator);
void Print (std::ostream &os, LteRrcSap::RadioResourceConfigDedicated radioResourceConfigDedicated) const;
+
+ int m_messageType;
+};
+
+
+/**
+ * This class only serves to discriminate which message type has been received
+ * in uplink (ue to eNb) for channel DCCH
+ */
+class RrcUlDcchMessage : public RrcAsn1Header
+{
+public:
+ uint32_t Deserialize (Buffer::Iterator bIterator);
+ void Print (std::ostream &os) const;
+ void PreSerialize () const;
+ void SerializeUlDcchMessage (int msgType) const;
+ Buffer::Iterator DeserializeUlDcchMessage (Buffer::Iterator bIterator);
+};
+
+/**
+ * This class only serves to discriminate which message type has been received
+ * in downlink (eNb to ue) for channel DCCH
+ */
+class RrcDlDcchMessage : public RrcAsn1Header
+{
+public:
+ uint32_t Deserialize (Buffer::Iterator bIterator);
+ void Print (std::ostream &os) const;
+ void PreSerialize () const;
+ void SerializeDlDcchMessage (int msgType) const;
+ Buffer::Iterator DeserializeDlDcchMessage (Buffer::Iterator bIterator);
+};
+
+/**
+ * This class only serves to discriminate which message type has been received
+ * in uplink (ue to eNb) for channel CCCH
+ */
+class RrcUlCcchMessage : public RrcAsn1Header
+{
+public:
+ uint32_t Deserialize (Buffer::Iterator bIterator);
+ void Print (std::ostream &os) const;
+ void PreSerialize () const;
+ void SerializeUlCcchMessage (int msgType) const;
+ Buffer::Iterator DeserializeUlCcchMessage (Buffer::Iterator bIterator);
+};
+
+/**
+ * This class only serves to discriminate which message type has been received
+ * in downlink (eNb to ue) for channel CCCH
+ */
+class RrcDlCcchMessage : public RrcAsn1Header
+{
+public:
+ uint32_t Deserialize (Buffer::Iterator bIterator);
+ void Print (std::ostream &os) const;
+ void PreSerialize () const;
+ void SerializeDlCcchMessage (int msgType) const;
+ Buffer::Iterator DeserializeDlCcchMessage (Buffer::Iterator bIterator);
};
/**
* This class manages the serialization/deserialization of RrcConnectionRequest IE
*/
-class RrcConnectionRequestHeader : public RrcAsn1Header,
+class RrcConnectionRequestHeader : public RrcUlCcchMessage,
LteRrcSap
{
public:
@@ -77,7 +137,7 @@
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionRequest msg);
-
+ RrcConnectionRequest GetMessage () const;
std::bitset<8> getMmec () const;
std::bitset<32> getMtmsi () const;
@@ -95,7 +155,7 @@
/**
* This class manages the serialization/deserialization of RrcConnectionSetup IE
*/
-class RrcConnectionSetupHeader : public RrcAsn1Header,
+class RrcConnectionSetupHeader : public RrcDlCcchMessage,
LteRrcSap
{
public:
@@ -104,7 +164,7 @@
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionSetup msg);
-
+ RrcConnectionSetup GetMessage () const;
uint8_t GetRrcTransactionIdentifier () const;
bool HavePhysicalConfigDedicated () const;
std::list<LteRrcSap::SrbToAddMod> GetSrbToAddModList () const;
@@ -121,7 +181,7 @@
/**
* This class manages the serialization/deserialization of RrcConnectionSetupComplete IE
*/
-class RrcConnectionSetupCompleteHeader : public RrcAsn1Header,
+class RrcConnectionSetupCompleteHeader : public RrcUlDcchMessage,
LteRrcSap
{
public:
@@ -132,6 +192,7 @@
void SetMessage (RrcConnectionSetupCompleted msg);
uint8_t GetRrcTransactionIdentifier () const;
+ RrcConnectionSetupCompleted GetMessage () const;
private:
uint8_t m_rrcTransactionIdentifier;
@@ -141,7 +202,7 @@
/**
* This class manages the serialization/deserialization of RrcConnectionSetupComplete IE
*/
-class RrcConnectionReconfigurationCompleteHeader : public RrcAsn1Header,
+class RrcConnectionReconfigurationCompleteHeader : public RrcUlDcchMessage,
LteRrcSap
{
public:
@@ -150,7 +211,7 @@
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionReconfigurationCompleted msg);
-
+ RrcConnectionReconfigurationCompleted GetMessage () const;
uint8_t GetRrcTransactionIdentifier () const;
private:
@@ -161,7 +222,7 @@
/**
* This class manages the serialization/deserialization of RrcConnectionReconfiguration IE
*/
-class RrcConnectionReconfigurationHeader : public RrcAsn1Header,
+class RrcConnectionReconfigurationHeader : public RrcDlDcchMessage,
LteRrcSap
{
public:
@@ -171,6 +232,7 @@
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionReconfiguration msg);
+ RrcConnectionReconfiguration GetMessage () const;
uint8_t GetRrcTransactionIdentifier () const;
bool GetHaveMeasConfig ();
MeasConfig GetMeasConfig ();
@@ -209,6 +271,7 @@
void Print (std::ostream &os) const;
void SetMessage (HandoverPreparationInfo msg);
+ HandoverPreparationInfo GetMessage () const;
AsConfig GetAsConfig () const;
private:
@@ -218,7 +281,7 @@
/**
* This class manages the serialization/deserialization of RRCConnectionReestablishmentRequest IE
*/
-class RrcConnectionReestablishmentRequestHeader : public RrcAsn1Header,
+class RrcConnectionReestablishmentRequestHeader : public RrcUlCcchMessage,
LteRrcSap
{
public:
@@ -227,6 +290,7 @@
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionReestablishmentRequest msg);
+ RrcConnectionReestablishmentRequest GetMessage () const;
ReestabUeIdentity GetUeIdentity () const;
ReestablishmentCause GetReestablishmentCause () const;
@@ -239,7 +303,7 @@
/**
* This class manages the serialization/deserialization of RrcConnectionReestablishment IE
*/
-class RrcConnectionReestablishmentHeader : public RrcAsn1Header,
+class RrcConnectionReestablishmentHeader : public RrcDlCcchMessage,
LteRrcSap
{
public:
@@ -248,7 +312,7 @@
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionReestablishment msg);
-
+ RrcConnectionReestablishment GetMessage () const;
uint8_t GetRrcTransactionIdentifier () const;
RadioResourceConfigDedicated GetRadioResourceConfigDedicated () const;
@@ -260,7 +324,7 @@
/**
* This class manages the serialization/deserialization of RrcConnectionReestablishmentComplete IE
*/
-class RrcConnectionReestablishmentCompleteHeader : public RrcAsn1Header,
+class RrcConnectionReestablishmentCompleteHeader : public RrcUlDcchMessage,
LteRrcSap
{
public:
@@ -269,13 +333,67 @@
uint32_t Deserialize (Buffer::Iterator bIterator);
void Print (std::ostream &os) const;
void SetMessage (RrcConnectionReestablishmentComplete msg);
-
+ RrcConnectionReestablishmentComplete GetMessage () const;
uint8_t GetRrcTransactionIdentifier () const;
private:
uint8_t m_rrcTransactionIdentifier;
};
+/**
+* This class manages the serialization/deserialization of RrcConnectionReestablishmentReject IE
+*/
+class RrcConnectionReestablishmentRejectHeader : public RrcDlCcchMessage,
+ LteRrcSap
+{
+public:
+ RrcConnectionReestablishmentRejectHeader ();
+ void PreSerialize () const;
+ uint32_t Deserialize (Buffer::Iterator bIterator);
+ void Print (std::ostream &os) const;
+ void SetMessage (RrcConnectionReestablishmentReject msg);
+ RrcConnectionReestablishmentReject GetMessage () const;
+
+private:
+ RrcConnectionReestablishmentReject m_rrcConnectionReestablishmentReject;
+};
+
+/**
+* This class manages the serialization/deserialization of RrcConnectionRelease IE
+*/
+class RrcConnectionReleaseHeader : public RrcDlDcchMessage,
+ LteRrcSap
+{
+public:
+ RrcConnectionReleaseHeader ();
+ void PreSerialize () const;
+ uint32_t Deserialize (Buffer::Iterator bIterator);
+ void Print (std::ostream &os) const;
+ void SetMessage (RrcConnectionRelease msg);
+ RrcConnectionRelease GetMessage () const;
+ uint8_t GetRrcTransactionIdentifier () const;
+
+private:
+ RrcConnectionRelease m_rrcConnectionRelease;
+};
+
+/**
+* This class manages the serialization/deserialization of RrcConnectionReject IE
+*/
+class RrcConnectionRejectHeader : public RrcDlCcchMessage,
+ LteRrcSap
+{
+public:
+ RrcConnectionRejectHeader ();
+ void PreSerialize () const;
+ uint32_t Deserialize (Buffer::Iterator bIterator);
+ void Print (std::ostream &os) const;
+ void SetMessage (RrcConnectionReject msg);
+ RrcConnectionReject GetMessage () const;
+
+private:
+ RrcConnectionReject m_rrcConnectionReject;
+};
} // namespace ns3
--- a/src/lte/model/lte-rrc-protocol-ideal.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-ideal.cc Thu Dec 13 12:22:43 2012 +0100
@@ -457,6 +457,14 @@
msg);
}
+void
+LteEnbRrcProtocolIdeal::DoSendRrcConnectionReject (uint16_t rnti, LteRrcSap::RrcConnectionReject msg)
+{
+ Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
+ &LteUeRrcSapProvider::RecvRrcConnectionReject,
+ GetUeRrcSapProvider (rnti),
+ msg);
+}
/*
* The purpose of LteEnbRrcProtocolIdeal is to avoid encoding
--- a/src/lte/model/lte-rrc-protocol-ideal.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-ideal.h Thu Dec 13 12:22:43 2012 +0100
@@ -125,6 +125,7 @@
void DoSendRrcConnectionReestablishment (uint16_t rnti, LteRrcSap::RrcConnectionReestablishment msg);
void DoSendRrcConnectionReestablishmentReject (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentReject msg);
void DoSendRrcConnectionRelease (uint16_t rnti, LteRrcSap::RrcConnectionRelease msg);
+ void DoSendRrcConnectionReject (uint16_t rnti, LteRrcSap::RrcConnectionReject msg);
Ptr<Packet> DoEncodeHandoverPreparationInformation (LteRrcSap::HandoverPreparationInfo msg);
LteRrcSap::HandoverPreparationInfo DoDecodeHandoverPreparationInformation (Ptr<Packet> p);
Ptr<Packet> DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg);
--- a/src/lte/model/lte-rrc-protocol-real.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-real.cc Thu Dec 13 12:22:43 2012 +0100
@@ -15,7 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Nicola Baldo <nbaldo@cttc.es>
+ * Authors: Nicola Baldo <nbaldo@cttc.es>
+ * Lluis Parcerisa <lparcerisa@cttc.cat>
*/
#include <ns3/fatal-error.h>
@@ -43,7 +44,7 @@
LteUeRrcProtocolReal::LteUeRrcProtocolReal ()
: m_ueRrcSapProvider (0),
- m_enbRrcSapProvider (0)
+ m_enbRrcSapProvider (0)
{
m_ueRrcSapUser = new MemberLteUeRrcSapUser<LteUeRrcProtocolReal> (this);
}
@@ -57,6 +58,8 @@
{
NS_LOG_FUNCTION (this);
delete m_ueRrcSapUser;
+ delete m_completeSetupParameters.srb0SapUser;
+ delete m_completeSetupParameters.srb1SapUser;
m_rrc = 0;
}
@@ -66,7 +69,7 @@
static TypeId tid = TypeId ("ns3::LteUeRrcProtocolReal")
.SetParent<Object> ()
.AddConstructor<LteUeRrcProtocolReal> ()
- ;
+ ;
return tid;
}
@@ -97,6 +100,17 @@
// after handover). We don't care about SRB0/SRB1 since we use real
// RRC messages.
DoReestablish ();
+
+ m_setupParameters.srb0SapProvider = params.srb0SapProvider;
+ m_setupParameters.srb1SapProvider = params.srb1SapProvider;
+
+ LteRlcSapUser* srb0SapUser = new LteRlcSpecificLteRlcSapUser<LteUeRrcProtocolReal> (this);
+ LtePdcpSapUser* srb1SapUser = new LtePdcpSpecificLtePdcpSapUser<LteUeRrcProtocolReal> (this);
+
+ m_completeSetupParameters.srb0SapUser = srb0SapUser;
+ m_completeSetupParameters.srb1SapUser = srb1SapUser;
+
+ m_ueRrcSapProvider->CompleteSetup (m_completeSetupParameters);
}
void
@@ -107,10 +121,10 @@
// // eNB we are currently attached to
// m_rnti = m_rrc->GetRnti ();
// SetEnbRrcSapProvider ();
-
+
// if (m_havePendingRrcConnectionRequest == true)
- // {
+ // {
// Simulator::Schedule (RRC_REAL_MSG_DELAY,
// &LteEnbRrcSapProvider::RecvRrcConnectionRequest,
// m_enbRrcSapProvider,
@@ -126,22 +140,41 @@
// eNB we are currently attached to
m_rnti = m_rrc->GetRnti ();
SetEnbRrcSapProvider ();
-
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteEnbRrcSapProvider::RecvRrcConnectionRequest,
- m_enbRrcSapProvider,
- m_rnti,
- msg);
+
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionRequestHeader rrcConnectionRequestHeader;
+ rrcConnectionRequestHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionRequestHeader);
+
+ LteRlcSapProvider::TransmitPdcpPduParameters transmitPdcpPduParameters;
+ transmitPdcpPduParameters.pdcpPdu = packet;
+ transmitPdcpPduParameters.rnti = m_rnti;
+ transmitPdcpPduParameters.lcid = 0;
+
+ m_setupParameters.srb0SapProvider->TransmitPdcpPdu (transmitPdcpPduParameters);
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionSetupCompleted (LteRrcSap::RrcConnectionSetupCompleted msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteEnbRrcSapProvider::RecvRrcConnectionSetupCompleted,
- m_enbRrcSapProvider,
- m_rnti,
- msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionSetupCompleteHeader rrcConnectionSetupCompleteHeader;
+ rrcConnectionSetupCompleteHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionSetupCompleteHeader);
+
+ LtePdcpSapProvider::TransmitPdcpSduParameters transmitPdcpSduParameters;
+ transmitPdcpSduParameters.pdcpSdu = packet;
+ transmitPdcpSduParameters.rnti = m_rnti;
+ transmitPdcpSduParameters.lcid = 1;
+
+ if (m_setupParameters.srb1SapProvider)
+ {
+ m_setupParameters.srb1SapProvider->TransmitPdcpSdu (transmitPdcpSduParameters);
+ }
}
void
@@ -151,39 +184,63 @@
// eNB we are currently attached to
m_rnti = m_rrc->GetRnti ();
SetEnbRrcSapProvider ();
-
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteEnbRrcSapProvider::RecvRrcConnectionReconfigurationCompleted,
- m_enbRrcSapProvider,
- m_rnti,
- msg);
+
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionReconfigurationCompleteHeader rrcConnectionReconfigurationCompleteHeader;
+ rrcConnectionReconfigurationCompleteHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionReconfigurationCompleteHeader);
+
+ LtePdcpSapProvider::TransmitPdcpSduParameters transmitPdcpSduParameters;
+ transmitPdcpSduParameters.pdcpSdu = packet;
+ transmitPdcpSduParameters.rnti = m_rnti;
+ transmitPdcpSduParameters.lcid = 1;
+
+ m_setupParameters.srb1SapProvider->TransmitPdcpSdu (transmitPdcpSduParameters);
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteEnbRrcSapProvider::RecvRrcConnectionReestablishmentRequest,
- m_enbRrcSapProvider,
- m_rnti,
- msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionReestablishmentRequestHeader rrcConnectionReestablishmentRequestHeader;
+ rrcConnectionReestablishmentRequestHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionReestablishmentRequestHeader);
+
+ LteRlcSapProvider::TransmitPdcpPduParameters transmitPdcpPduParameters;
+ transmitPdcpPduParameters.pdcpPdu = packet;
+ transmitPdcpPduParameters.rnti = m_rnti;
+ transmitPdcpPduParameters.lcid = 0;
+
+ m_setupParameters.srb0SapProvider->TransmitPdcpPdu (transmitPdcpPduParameters);
}
void
LteUeRrcProtocolReal::DoSendRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteEnbRrcSapProvider::RecvRrcConnectionReestablishmentComplete,
- m_enbRrcSapProvider,
- m_rnti,
-msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionReestablishmentCompleteHeader rrcConnectionReestablishmentCompleteHeader;
+ rrcConnectionReestablishmentCompleteHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionReestablishmentCompleteHeader);
+
+ LtePdcpSapProvider::TransmitPdcpSduParameters transmitPdcpSduParameters;
+ transmitPdcpSduParameters.pdcpSdu = packet;
+ transmitPdcpSduParameters.rnti = m_rnti;
+ transmitPdcpSduParameters.lcid = 1;
+
+ m_setupParameters.srb1SapProvider->TransmitPdcpSdu (transmitPdcpSduParameters);
}
void
LteUeRrcProtocolReal::SetEnbRrcSapProvider ()
{
- uint16_t cellId = m_rrc->GetCellId ();
+ uint16_t cellId = m_rrc->GetCellId ();
// walk list of all nodes to get the peer eNB
Ptr<LteEnbNetDevice> enbDev;
@@ -208,18 +265,93 @@
{
if (enbDev->GetCellId () == cellId)
{
- found = true;
+ found = true;
break;
}
}
}
}
NS_ASSERT_MSG (found, " Unable to find eNB with CellId =" << cellId);
- m_enbRrcSapProvider = enbDev->GetRrc ()->GetLteEnbRrcSapProvider ();
+ m_enbRrcSapProvider = enbDev->GetRrc ()->GetLteEnbRrcSapProvider ();
Ptr<LteEnbRrcProtocolReal> enbRrcProtocolReal = enbDev->GetRrc ()->GetObject<LteEnbRrcProtocolReal> ();
enbRrcProtocolReal->SetUeRrcSapProvider (m_rnti, m_ueRrcSapProvider);
}
+void
+LteUeRrcProtocolReal::DoReceivePdcpPdu (Ptr<Packet> p)
+{
+ // Get type of message received
+ RrcDlCcchMessage rrcDlCcchMessage;
+ p->PeekHeader (rrcDlCcchMessage);
+
+ // Declare possible headers to receive
+ RrcConnectionReestablishmentHeader rrcConnectionReestablishmentHeader;
+ RrcConnectionReestablishmentRejectHeader rrcConnectionReestablishmentRejectHeader;
+ RrcConnectionSetupHeader rrcConnectionSetupHeader;
+
+ // Declare possible messages
+ LteRrcSap::RrcConnectionReestablishment rrcConnectionReestablishmentMsg;
+ LteRrcSap::RrcConnectionReestablishmentReject rrcConnectionReestablishmentRejectMsg;
+ LteRrcSap::RrcConnectionSetup rrcConnectionSetupMsg;
+
+ // Deserialize packet and call member recv function with appropiate structure
+ switch ( rrcDlCcchMessage.GetMessageType () )
+ {
+ case 0:
+ // RrcConnectionReestablishment
+ p->RemoveHeader (rrcConnectionReestablishmentHeader);
+ rrcConnectionReestablishmentMsg = rrcConnectionReestablishmentHeader.GetMessage ();
+ m_ueRrcSapProvider->RecvRrcConnectionReestablishment (rrcConnectionReestablishmentMsg);
+ break;
+ case 1:
+ // RrcConnectionReestablishmentReject
+ p->RemoveHeader (rrcConnectionReestablishmentRejectHeader);
+ rrcConnectionReestablishmentRejectMsg = rrcConnectionReestablishmentRejectHeader.GetMessage ();
+ // m_ueRrcSapProvider->RecvRrcConnectionReestablishmentReject (rrcConnectionReestablishmentRejectMsg);
+ break;
+ case 2:
+ // RrcConnectionReject
+ // ...
+ break;
+ case 3:
+ // RrcConnectionSetup
+ p->RemoveHeader (rrcConnectionSetupHeader);
+ rrcConnectionSetupMsg = rrcConnectionSetupHeader.GetMessage ();
+ m_ueRrcSapProvider->RecvRrcConnectionSetup (rrcConnectionSetupMsg);
+ break;
+ }
+}
+
+void
+LteUeRrcProtocolReal::DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params)
+{
+ // Get type of message received
+ RrcDlDcchMessage rrcDlDcchMessage;
+ params.pdcpSdu->PeekHeader (rrcDlDcchMessage);
+
+ // Declare possible headers to receive
+ RrcConnectionReconfigurationHeader rrcConnectionReconfigurationHeader;
+ RrcConnectionReleaseHeader rrcConnectionReleaseHeader;
+
+ // Declare possible messages to receive
+ LteRrcSap::RrcConnectionReconfiguration rrcConnectionReconfigurationMsg;
+ LteRrcSap::RrcConnectionRelease rrcConnectionReleaseMsg;
+
+ // Deserialize packet and call member recv function with appropiate structure
+ switch ( rrcDlDcchMessage.GetMessageType () )
+ {
+ case 4:
+ params.pdcpSdu->RemoveHeader (rrcConnectionReconfigurationHeader);
+ rrcConnectionReconfigurationMsg = rrcConnectionReconfigurationHeader.GetMessage ();
+ m_ueRrcSapProvider->RecvRrcConnectionReconfiguration (rrcConnectionReconfigurationMsg);
+ break;
+ case 5:
+ params.pdcpSdu->RemoveHeader (rrcConnectionReleaseHeader);
+ rrcConnectionReleaseMsg = rrcConnectionReleaseHeader.GetMessage ();
+ //m_ueRrcSapProvider->RecvRrcConnectionRelease (rrcConnectionReleaseMsg);
+ break;
+ }
+}
NS_OBJECT_ENSURE_REGISTERED (LteEnbRrcProtocolReal);
@@ -239,7 +371,7 @@
LteEnbRrcProtocolReal::DoDispose ()
{
NS_LOG_FUNCTION (this);
- delete m_enbRrcSapUser;
+ delete m_enbRrcSapUser;
}
TypeId
@@ -248,7 +380,7 @@
static TypeId tid = TypeId ("ns3::LteEnbRrcProtocolReal")
.SetParent<Object> ()
.AddConstructor<LteEnbRrcProtocolReal> ()
- ;
+ ;
return tid;
}
@@ -312,9 +444,9 @@
// {
// ueRrc = ueDev->GetRrc ();
// if ((ueRrc->GetRnti () == rnti) && (ueRrc->GetCellId () == m_cellId))
- // {
- // found = true;
- // break;
+ // {
+ // found = true;
+ // break;
// }
// }
// }
@@ -322,12 +454,25 @@
// NS_ASSERT_MSG (found , " Unable to find UE with RNTI=" << rnti << " cellId=" << m_cellId);
// m_enbRrcSapProviderMap[rnti] = ueRrc->GetLteUeRrcSapProvider ();
-
// just create empty entry, the UeRrcSapProvider will be set by the
// ue upon connection request or connection reconfiguration
// completed
m_enbRrcSapProviderMap[rnti] = 0;
+ // Store SetupUeParameters
+ m_setupUeParametersMap[rnti] = params;
+
+ // Create LteRlcSapUser, LtePdcpSapUser
+ LteRlcSapUser* srb0SapUser = new RealProtocolRlcSapUser (this,rnti);
+ LtePdcpSapUser* srb1SapUser = new LtePdcpSpecificLtePdcpSapUser<LteEnbRrcProtocolReal> (this);
+ LteEnbRrcSapProvider::CompleteSetupUeParameters completeSetupUeParameters;
+ completeSetupUeParameters.srb0SapUser = srb0SapUser;
+ completeSetupUeParameters.srb1SapUser = srb1SapUser;
+
+ // Store LteRlcSapUser, LtePdcpSapUser
+ m_completeSetupUeParametersMap[rnti] = completeSetupUeParameters;
+
+ m_enbRrcSapProvider->CompleteSetupUe (rnti,completeSetupUeParameters);
}
void
@@ -335,6 +480,7 @@
{
NS_LOG_FUNCTION (this << rnti);
m_enbRrcSapProviderMap.erase (rnti);
+ m_setupUeParametersMap.erase (rnti);
}
void
@@ -356,7 +502,7 @@
LteEnbRrcProtocolReal::DoSendSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
{
NS_LOG_FUNCTION (this << m_cellId);
- // walk list of all nodes to get UEs with this cellId
+ // walk list of all nodes to get UEs with this cellId
Ptr<LteUeRrc> ueRrc;
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
@@ -368,14 +514,14 @@
if (ueDev != 0)
{
NS_LOG_LOGIC ("considering UE " << ueDev->GetImsi ());
- Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
+ Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
if (ueRrc->GetCellId () == m_cellId)
- {
+ {
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvSystemInformationBlockType1,
ueRrc->GetLteUeRrcSapProvider (),
- msg);
- }
+ msg);
+ }
}
}
}
@@ -396,17 +542,17 @@
Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
if (ueDev != 0)
{
- Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
+ Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
NS_LOG_LOGIC ("considering UE IMSI " << ueDev->GetImsi () << " that has cellId " << ueRrc->GetCellId ());
if (ueRrc->GetCellId () == m_cellId)
- {
+ {
NS_LOG_LOGIC ("sending SI to IMSI " << ueDev->GetImsi ());
ueRrc->GetLteUeRrcSapProvider ()->RecvSystemInformation (msg);
Simulator::Schedule (RRC_REAL_MSG_DELAY,
&LteUeRrcSapProvider::RecvSystemInformation,
ueRrc->GetLteUeRrcSapProvider (),
- msg);
- }
+ msg);
+ }
}
}
}
@@ -415,146 +561,191 @@
void
LteEnbRrcProtocolReal::DoSendRrcConnectionSetup (uint16_t rnti, LteRrcSap::RrcConnectionSetup msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvRrcConnectionSetup,
- GetUeRrcSapProvider (rnti),
- msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionSetupHeader rrcConnectionSetupHeader;
+ rrcConnectionSetupHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionSetupHeader);
+
+ LteRlcSapProvider::TransmitPdcpPduParameters transmitPdcpPduParameters;
+ transmitPdcpPduParameters.pdcpPdu = packet;
+ transmitPdcpPduParameters.rnti = rnti;
+ transmitPdcpPduParameters.lcid = 0;
+
+ std::map<uint16_t, LteEnbRrcSapUser::SetupUeParameters>::iterator it;
+ if (m_setupUeParametersMap.find (rnti) == m_setupUeParametersMap.end () )
+ {
+ std::cout << "RNTI not found in Enb setup parameters Map!" << std::endl;
+ }
+ else
+ {
+ m_setupUeParametersMap[rnti].srb0SapProvider->TransmitPdcpPdu (transmitPdcpPduParameters);
+ }
+}
+
+void
+LteEnbRrcProtocolReal::DoSendRrcConnectionReject (uint16_t rnti, LteRrcSap::RrcConnectionReject msg)
+{
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionRejectHeader rrcConnectionRejectHeader;
+ rrcConnectionRejectHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionRejectHeader);
+
+ LteRlcSapProvider::TransmitPdcpPduParameters transmitPdcpPduParameters;
+ transmitPdcpPduParameters.pdcpPdu = packet;
+ transmitPdcpPduParameters.rnti = rnti;
+ transmitPdcpPduParameters.lcid = 0;
+
+ std::map<uint16_t, LteEnbRrcSapUser::SetupUeParameters>::iterator it;
+ m_setupUeParametersMap[rnti].srb0SapProvider->TransmitPdcpPdu (transmitPdcpPduParameters);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionReconfiguration (uint16_t rnti, LteRrcSap::RrcConnectionReconfiguration msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvRrcConnectionReconfiguration,
- GetUeRrcSapProvider (rnti),
- msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionReconfigurationHeader rrcConnectionReconfigurationHeader;
+ rrcConnectionReconfigurationHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionReconfigurationHeader);
+
+ LtePdcpSapProvider::TransmitPdcpSduParameters transmitPdcpSduParameters;
+ transmitPdcpSduParameters.pdcpSdu = packet;
+ transmitPdcpSduParameters.rnti = rnti;
+ transmitPdcpSduParameters.lcid = 1;
+
+ m_setupUeParametersMap[rnti].srb1SapProvider->TransmitPdcpSdu (transmitPdcpSduParameters);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionReestablishment (uint16_t rnti, LteRrcSap::RrcConnectionReestablishment msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvRrcConnectionReestablishment,
- GetUeRrcSapProvider (rnti),
- msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionReestablishmentHeader rrcConnectionReestablishmentHeader;
+ rrcConnectionReestablishmentHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionReestablishmentHeader);
+
+ LteRlcSapProvider::TransmitPdcpPduParameters transmitPdcpPduParameters;
+ transmitPdcpPduParameters.pdcpPdu = packet;
+ transmitPdcpPduParameters.rnti = rnti;
+ transmitPdcpPduParameters.lcid = 0;
+
+ m_setupUeParametersMap[rnti].srb0SapProvider->TransmitPdcpPdu (transmitPdcpPduParameters);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionReestablishmentReject (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentReject msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvRrcConnectionReestablishmentReject,
- GetUeRrcSapProvider (rnti),
- msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionReestablishmentRejectHeader rrcConnectionReestablishmentRejectHeader;
+ rrcConnectionReestablishmentRejectHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionReestablishmentRejectHeader);
+
+ LteRlcSapProvider::TransmitPdcpPduParameters transmitPdcpPduParameters;
+ transmitPdcpPduParameters.pdcpPdu = packet;
+ transmitPdcpPduParameters.rnti = rnti;
+ transmitPdcpPduParameters.lcid = 0;
+
+ m_setupUeParametersMap[rnti].srb0SapProvider->TransmitPdcpPdu (transmitPdcpPduParameters);
}
void
LteEnbRrcProtocolReal::DoSendRrcConnectionRelease (uint16_t rnti, LteRrcSap::RrcConnectionRelease msg)
{
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvRrcConnectionRelease,
- GetUeRrcSapProvider (rnti),
- msg);
+ Ptr<Packet> packet = Create<Packet> ();
+
+ RrcConnectionReleaseHeader rrcConnectionReleaseHeader;
+ rrcConnectionReleaseHeader.SetMessage (msg);
+
+ packet->AddHeader (rrcConnectionReleaseHeader);
+
+ LtePdcpSapProvider::TransmitPdcpSduParameters transmitPdcpSduParameters;
+ transmitPdcpSduParameters.pdcpSdu = packet;
+ transmitPdcpSduParameters.rnti = rnti;
+ transmitPdcpSduParameters.lcid = 1;
+
+ m_setupUeParametersMap[rnti].srb1SapProvider->TransmitPdcpSdu (transmitPdcpSduParameters);
}
-
-/*
- * The purpose of LteEnbRrcProtocolReal is to avoid encoding
- * messages. In order to do so, we need to have some form of encoding for
- * inter-node RRC messages like HandoverPreparationInfo and HandoverCommand. Doing so
- * directly is not practical (these messages includes a lot of
- * information elements, so encoding all of them would defeat the
- * purpose of LteEnbRrcProtocolReal. The workaround is to store the
- * actual message in a global map, so that then we can just encode the
- * key in a header and send that between eNBs over X2.
- *
- */
-
-std::map<uint32_t, LteRrcSap::HandoverPreparationInfo> g_handoverPreparationInfoMsgMap2;
-uint32_t g_handoverPreparationInfoMsgIdCounter2 = 0;
-
-/*
- * This header encodes the map key discussed above. We keep this
- * private since it should not be used outside this file.
- *
- */
-class RealHandoverPreparationInfoHeader : public Header
+void
+LteEnbRrcProtocolReal::DoReceivePdcpPdu (uint16_t rnti, Ptr<Packet> p)
{
-public:
- uint32_t GetMsgId ();
- void SetMsgId (uint32_t id);
- static TypeId GetTypeId (void);
- virtual TypeId GetInstanceTypeId (void) const;
- virtual void Print (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void Serialize (Buffer::Iterator start) const;
- virtual uint32_t Deserialize (Buffer::Iterator start);
+ // Get type of message received
+ RrcUlCcchMessage rrcUlCcchMessage;
+ p->PeekHeader (rrcUlCcchMessage);
-private:
- uint32_t m_msgId;
-};
+ // Declare possible headers to receive
+ RrcConnectionReestablishmentRequestHeader rrcConnectionReestablishmentRequestHeader;
+ RrcConnectionRequestHeader rrcConnectionRequestHeader;
-uint32_t
-RealHandoverPreparationInfoHeader::GetMsgId ()
-{
- return m_msgId;
-}
-
-void
-RealHandoverPreparationInfoHeader::SetMsgId (uint32_t id)
-{
- m_msgId = id;
-}
-
-
-TypeId
-RealHandoverPreparationInfoHeader::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::RealHandoverPreparationInfoHeader")
- .SetParent<Header> ()
- .AddConstructor<RealHandoverPreparationInfoHeader> ()
- ;
- return tid;
+ // Deserialize packet and call member recv function with appropiate structure
+ switch ( rrcUlCcchMessage.GetMessageType () )
+ {
+ case 0:
+ p->RemoveHeader (rrcConnectionReestablishmentRequestHeader);
+ LteRrcSap::RrcConnectionReestablishmentRequest rrcConnectionReestablishmentRequestMsg;
+ rrcConnectionReestablishmentRequestMsg = rrcConnectionReestablishmentRequestHeader.GetMessage ();
+ m_enbRrcSapProvider->RecvRrcConnectionReestablishmentRequest (rnti,rrcConnectionReestablishmentRequestMsg);
+ break;
+ case 1:
+ p->RemoveHeader (rrcConnectionRequestHeader);
+ LteRrcSap::RrcConnectionRequest rrcConnectionRequestMsg;
+ rrcConnectionRequestMsg = rrcConnectionRequestHeader.GetMessage ();
+ m_enbRrcSapProvider->RecvRrcConnectionRequest (rnti,rrcConnectionRequestMsg);
+ break;
+ }
}
-TypeId
-RealHandoverPreparationInfoHeader::GetInstanceTypeId (void) const
-{
- return GetTypeId ();
-}
-
-void RealHandoverPreparationInfoHeader::Print (std::ostream &os) const
-{
- os << " msgId=" << m_msgId;
-}
-
-uint32_t RealHandoverPreparationInfoHeader::GetSerializedSize (void) const
+void
+LteEnbRrcProtocolReal::DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params)
{
- return 4;
-}
+ // Get type of message received
+ RrcUlDcchMessage rrcUlDcchMessage;
+ params.pdcpSdu->PeekHeader (rrcUlDcchMessage);
-void RealHandoverPreparationInfoHeader::Serialize (Buffer::Iterator start) const
-{
- start.WriteU32 (m_msgId);
-}
+ // Declare possible headers to receive
+ RrcConnectionReconfigurationCompleteHeader rrcConnectionReconfigurationCompleteHeader;
+ RrcConnectionReestablishmentCompleteHeader rrcConnectionReestablishmentCompleteHeader;
+ RrcConnectionSetupCompleteHeader rrcConnectionSetupCompleteHeader;
-uint32_t RealHandoverPreparationInfoHeader::Deserialize (Buffer::Iterator start)
-{
- m_msgId = start.ReadU32 ();
- return GetSerializedSize ();
+ // Deserialize packet and call member recv function with appropiate structure
+ switch ( rrcUlDcchMessage.GetMessageType () )
+ {
+ case 2:
+ params.pdcpSdu->RemoveHeader (rrcConnectionReconfigurationCompleteHeader);
+ LteRrcSap::RrcConnectionReconfigurationCompleted rrcConnectionReconfigurationCompleteMsg;
+ rrcConnectionReconfigurationCompleteMsg = rrcConnectionReconfigurationCompleteHeader.GetMessage ();
+ m_enbRrcSapProvider->RecvRrcConnectionReconfigurationCompleted (params.rnti,rrcConnectionReconfigurationCompleteMsg);
+ break;
+ case 3:
+ params.pdcpSdu->RemoveHeader (rrcConnectionReestablishmentCompleteHeader);
+ LteRrcSap::RrcConnectionReestablishmentComplete rrcConnectionReestablishmentCompleteMsg;
+ rrcConnectionReestablishmentCompleteMsg = rrcConnectionReestablishmentCompleteHeader.GetMessage ();
+ m_enbRrcSapProvider->RecvRrcConnectionReestablishmentComplete (params.rnti,rrcConnectionReestablishmentCompleteMsg);
+ break;
+ case 4:
+ params.pdcpSdu->RemoveHeader (rrcConnectionSetupCompleteHeader);
+ LteRrcSap::RrcConnectionSetupCompleted rrcConnectionSetupCompletedMsg;
+ rrcConnectionSetupCompletedMsg = rrcConnectionSetupCompleteHeader.GetMessage ();
+ m_enbRrcSapProvider->RecvRrcConnectionSetupCompleted (params.rnti, rrcConnectionSetupCompletedMsg);
+ break;
+ }
}
-
-
Ptr<Packet>
LteEnbRrcProtocolReal::DoEncodeHandoverPreparationInformation (LteRrcSap::HandoverPreparationInfo msg)
{
- uint32_t msgId = ++g_handoverPreparationInfoMsgIdCounter2;
- NS_ASSERT_MSG (g_handoverPreparationInfoMsgMap2.find (msgId) == g_handoverPreparationInfoMsgMap2.end (), "msgId " << msgId << " already in use");
- NS_LOG_INFO (" encoding msgId = " << msgId);
- g_handoverPreparationInfoMsgMap2.insert (std::pair<uint32_t, LteRrcSap::HandoverPreparationInfo> (msgId, msg));
- RealHandoverPreparationInfoHeader h;
- h.SetMsgId (msgId);
+ HandoverPreparationInfoHeader h;
+ h.SetMessage (msg);
+
Ptr<Packet> p = Create<Packet> ();
p->AddHeader (h);
return p;
@@ -563,104 +754,17 @@
LteRrcSap::HandoverPreparationInfo
LteEnbRrcProtocolReal::DoDecodeHandoverPreparationInformation (Ptr<Packet> p)
{
- RealHandoverPreparationInfoHeader h;
+ HandoverPreparationInfoHeader h;
p->RemoveHeader (h);
- uint32_t msgId = h.GetMsgId ();
- NS_LOG_INFO (" decoding msgId = " << msgId);
- std::map<uint32_t, LteRrcSap::HandoverPreparationInfo>::iterator it = g_handoverPreparationInfoMsgMap2.find (msgId);
- NS_ASSERT_MSG (it != g_handoverPreparationInfoMsgMap2.end (), "msgId " << msgId << " not found");
- LteRrcSap::HandoverPreparationInfo msg = it->second;
- g_handoverPreparationInfoMsgMap2.erase (it);
+ LteRrcSap::HandoverPreparationInfo msg = h.GetMessage ();
return msg;
}
-
-
-std::map<uint32_t, LteRrcSap::RrcConnectionReconfiguration> g_handoverCommandMsgMap2;
-uint32_t g_handoverCommandMsgIdCounter2 = 0;
-
-/*
- * This header encodes the map key discussed above. We keep this
- * private since it should not be used outside this file.
- *
- */
-class RealHandoverCommandHeader : public Header
-{
-public:
- uint32_t GetMsgId ();
- void SetMsgId (uint32_t id);
- static TypeId GetTypeId (void);
- virtual TypeId GetInstanceTypeId (void) const;
- virtual void Print (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void Serialize (Buffer::Iterator start) const;
- virtual uint32_t Deserialize (Buffer::Iterator start);
-
-private:
- uint32_t m_msgId;
-};
-
-uint32_t
-RealHandoverCommandHeader::GetMsgId ()
-{
- return m_msgId;
-}
-
-void
-RealHandoverCommandHeader::SetMsgId (uint32_t id)
-{
- m_msgId = id;
-}
-
-
-TypeId
-RealHandoverCommandHeader::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::RealHandoverCommandHeader")
- .SetParent<Header> ()
- .AddConstructor<RealHandoverCommandHeader> ()
- ;
- return tid;
-}
-
-TypeId
-RealHandoverCommandHeader::GetInstanceTypeId (void) const
-{
- return GetTypeId ();
-}
-
-void RealHandoverCommandHeader::Print (std::ostream &os) const
-{
- os << " msgId=" << m_msgId;
-}
-
-uint32_t RealHandoverCommandHeader::GetSerializedSize (void) const
-{
- return 4;
-}
-
-void RealHandoverCommandHeader::Serialize (Buffer::Iterator start) const
-{
- start.WriteU32 (m_msgId);
-}
-
-uint32_t RealHandoverCommandHeader::Deserialize (Buffer::Iterator start)
-{
- m_msgId = start.ReadU32 ();
- return GetSerializedSize ();
-}
-
-
-
Ptr<Packet>
LteEnbRrcProtocolReal::DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg)
{
- uint32_t msgId = ++g_handoverCommandMsgIdCounter2;
- NS_ASSERT_MSG (g_handoverCommandMsgMap2.find (msgId) == g_handoverCommandMsgMap2.end (), "msgId " << msgId << " already in use");
- NS_LOG_INFO (" encoding msgId = " << msgId);
- g_handoverCommandMsgMap2.insert (std::pair<uint32_t, LteRrcSap::RrcConnectionReconfiguration> (msgId, msg));
- RealHandoverCommandHeader h;
- h.SetMsgId (msgId);
+ RrcConnectionReconfigurationHeader h;
+ h.SetMessage (msg);
Ptr<Packet> p = Create<Packet> ();
p->AddHeader (h);
return p;
@@ -669,19 +773,28 @@
LteRrcSap::RrcConnectionReconfiguration
LteEnbRrcProtocolReal::DoDecodeHandoverCommand (Ptr<Packet> p)
{
- RealHandoverCommandHeader h;
+ RrcConnectionReconfigurationHeader h;
p->RemoveHeader (h);
- uint32_t msgId = h.GetMsgId ();
- NS_LOG_INFO (" decoding msgId = " << msgId);
- std::map<uint32_t, LteRrcSap::RrcConnectionReconfiguration>::iterator it = g_handoverCommandMsgMap2.find (msgId);
- NS_ASSERT_MSG (it != g_handoverCommandMsgMap2.end (), "msgId " << msgId << " not found");
- LteRrcSap::RrcConnectionReconfiguration msg = it->second;
- g_handoverCommandMsgMap2.erase (it);
+ LteRrcSap::RrcConnectionReconfiguration msg = h.GetMessage ();
return msg;
}
+//////////////////////////////////////////////////////
+RealProtocolRlcSapUser::RealProtocolRlcSapUser (LteEnbRrcProtocolReal* pdcp, uint16_t rnti)
+ : m_pdcp (pdcp),
+ m_rnti (rnti)
+{
+}
+RealProtocolRlcSapUser::RealProtocolRlcSapUser ()
+{
+}
+void
+RealProtocolRlcSapUser::ReceivePdcpPdu (Ptr<Packet> p)
+{
+ m_pdcp->DoReceivePdcpPdu (m_rnti, p);
+}
} // namespace ns3
--- a/src/lte/model/lte-rrc-protocol-real.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rrc-protocol-real.h Thu Dec 13 12:22:43 2012 +0100
@@ -28,6 +28,9 @@
#include <ns3/ptr.h>
#include <ns3/object.h>
#include <ns3/lte-rrc-sap.h>
+#include <ns3/lte-pdcp-sap.h>
+#include <ns3/lte-rlc-sap.h>
+#include <ns3/lte-rrc-header.h>
namespace ns3 {
@@ -47,9 +50,10 @@
class LteUeRrcProtocolReal : public Object
{
friend class MemberLteUeRrcSapUser<LteUeRrcProtocolReal>;
+ friend class LteRlcSpecificLteRlcSapUser<LteUeRrcProtocolReal>;
+ friend class LtePdcpSpecificLtePdcpSapUser<LteUeRrcProtocolReal>;
public:
-
LteUeRrcProtocolReal ();
virtual ~LteUeRrcProtocolReal ();
@@ -59,12 +63,11 @@
void SetLteUeRrcSapProvider (LteUeRrcSapProvider* p);
LteUeRrcSapUser* GetLteUeRrcSapUser ();
-
+
void SetUeRrc (Ptr<LteUeRrc> rrc);
-
+
private:
-
// methods forwarded from LteUeRrcSapUser
void DoSetup (LteUeRrcSapUser::SetupParameters params);
void DoReestablish ();
@@ -75,13 +78,18 @@
void DoSendRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg);
void SetEnbRrcSapProvider ();
+ void DoReceivePdcpPdu (Ptr<Packet> p);
+ void DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params);
Ptr<LteUeRrc> m_rrc;
uint16_t m_rnti;
LteUeRrcSapProvider* m_ueRrcSapProvider;
LteUeRrcSapUser* m_ueRrcSapUser;
LteEnbRrcSapProvider* m_enbRrcSapProvider;
-
+
+ LteUeRrcSapUser::SetupParameters m_setupParameters;
+ LteUeRrcSapProvider::CompleteSetupParameters m_completeSetupParameters;
+
};
@@ -90,14 +98,16 @@
* a real fashion, by creating real RRC PDUs and transmitting them
* over Signaling Radio Bearers using radio resources allocated by the
* LTE MAC scheduler.
- *
+ *
*/
class LteEnbRrcProtocolReal : public Object
{
friend class MemberLteEnbRrcSapUser<LteEnbRrcProtocolReal>;
+ friend class LtePdcpSpecificLtePdcpSapUser<LteEnbRrcProtocolReal>;
+ friend class LteRlcSpecificLteRlcSapUser<LteEnbRrcProtocolReal>;
+ friend class RealProtocolRlcSapUser;
public:
-
LteEnbRrcProtocolReal ();
virtual ~LteEnbRrcProtocolReal ();
@@ -114,7 +124,6 @@
void SetUeRrcSapProvider (uint16_t rnti, LteUeRrcSapProvider* p);
private:
-
// methods forwarded from LteEnbRrcSapUser
void DoSetupUe (uint16_t rnti, LteEnbRrcSapUser::SetupUeParameters params);
void DoRemoveUe (uint16_t rnti);
@@ -127,20 +136,40 @@
void DoSendRrcConnectionReestablishment (uint16_t rnti, LteRrcSap::RrcConnectionReestablishment msg);
void DoSendRrcConnectionReestablishmentReject (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentReject msg);
void DoSendRrcConnectionRelease (uint16_t rnti, LteRrcSap::RrcConnectionRelease msg);
+ void DoSendRrcConnectionReject (uint16_t rnti, LteRrcSap::RrcConnectionReject msg);
Ptr<Packet> DoEncodeHandoverPreparationInformation (LteRrcSap::HandoverPreparationInfo msg);
LteRrcSap::HandoverPreparationInfo DoDecodeHandoverPreparationInformation (Ptr<Packet> p);
Ptr<Packet> DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg);
LteRrcSap::RrcConnectionReconfiguration DoDecodeHandoverCommand (Ptr<Packet> p);
+ void DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params);
+ void DoReceivePdcpPdu (uint16_t rnti, Ptr<Packet> p);
uint16_t m_rnti;
uint16_t m_cellId;
LteEnbRrcSapProvider* m_enbRrcSapProvider;
LteEnbRrcSapUser* m_enbRrcSapUser;
std::map<uint16_t, LteUeRrcSapProvider*> m_enbRrcSapProviderMap;
-
+ std::map<uint16_t, LteEnbRrcSapUser::SetupUeParameters> m_setupUeParametersMap;
+ std::map<uint16_t, LteEnbRrcSapProvider::CompleteSetupUeParameters> m_completeSetupUeParametersMap;
+
};
+///////////////////////////////////////
+
+class RealProtocolRlcSapUser : public LteRlcSapUser
+{
+public:
+ RealProtocolRlcSapUser (LteEnbRrcProtocolReal* pdcp, uint16_t rnti);
+
+ // Interface implemented from LteRlcSapUser
+ virtual void ReceivePdcpPdu (Ptr<Packet> p);
+
+private:
+ RealProtocolRlcSapUser ();
+ LteEnbRrcProtocolReal* m_pdcp;
+ uint16_t m_rnti;
+};
}
--- a/src/lte/model/lte-rrc-sap.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-rrc-sap.h Thu Dec 13 12:22:43 2012 +0100
@@ -315,6 +315,12 @@
struct RrcConnectionRelease
{
+ uint8_t rrcTransactionIdentifier;
+ };
+
+ struct RrcConnectionReject
+ {
+ uint8_t waitTime;
};
struct HandoverPreparationInfo
@@ -378,6 +384,7 @@
virtual void RecvRrcConnectionReestablishment (RrcConnectionReestablishment msg) = 0;
virtual void RecvRrcConnectionReestablishmentReject (RrcConnectionReestablishmentReject msg) = 0;
virtual void RecvRrcConnectionRelease (RrcConnectionRelease msg) = 0;
+ virtual void RecvRrcConnectionReject (RrcConnectionReject msg) = 0;
};
@@ -407,6 +414,7 @@
virtual void SendRrcConnectionReestablishment (uint16_t rnti, RrcConnectionReestablishment msg) = 0;
virtual void SendRrcConnectionReestablishmentReject (uint16_t rnti, RrcConnectionReestablishmentReject msg) = 0;
virtual void SendRrcConnectionRelease (uint16_t rnti, RrcConnectionRelease msg) = 0;
+ virtual void SendRrcConnectionReject (uint16_t rnti, RrcConnectionReject msg) = 0;
virtual Ptr<Packet> EncodeHandoverPreparationInformation (HandoverPreparationInfo msg) = 0;
virtual HandoverPreparationInfo DecodeHandoverPreparationInformation (Ptr<Packet> p) = 0;
virtual Ptr<Packet> EncodeHandoverCommand (RrcConnectionReconfiguration msg) = 0;
@@ -557,6 +565,7 @@
virtual void RecvRrcConnectionReestablishment (RrcConnectionReestablishment msg);
virtual void RecvRrcConnectionReestablishmentReject (RrcConnectionReestablishmentReject msg);
virtual void RecvRrcConnectionRelease (RrcConnectionRelease msg);
+ virtual void RecvRrcConnectionReject (RrcConnectionReject msg);
private:
MemberLteUeRrcSapProvider ();
@@ -637,6 +646,12 @@
m_owner->DoRecvRrcConnectionRelease (msg);
}
+template <class C>
+void
+MemberLteUeRrcSapProvider<C>::RecvRrcConnectionReject (RrcConnectionReject msg)
+{
+ m_owner->DoRecvRrcConnectionReject (msg);
+}
/**
@@ -662,6 +677,7 @@
virtual void SendRrcConnectionReestablishment (uint16_t rnti, RrcConnectionReestablishment msg);
virtual void SendRrcConnectionReestablishmentReject (uint16_t rnti, RrcConnectionReestablishmentReject msg);
virtual void SendRrcConnectionRelease (uint16_t rnti, RrcConnectionRelease msg);
+ virtual void SendRrcConnectionReject (uint16_t rnti, RrcConnectionReject msg);
virtual Ptr<Packet> EncodeHandoverPreparationInformation (HandoverPreparationInfo msg);
virtual HandoverPreparationInfo DecodeHandoverPreparationInformation (Ptr<Packet> p);
virtual Ptr<Packet> EncodeHandoverCommand (RrcConnectionReconfiguration msg);
@@ -754,6 +770,13 @@
}
template <class C>
+void
+MemberLteEnbRrcSapUser<C>::SendRrcConnectionReject (uint16_t rnti, RrcConnectionReject msg)
+{
+ m_owner->DoSendRrcConnectionReject (rnti, msg);
+}
+
+template <class C>
Ptr<Packet>
MemberLteEnbRrcSapUser<C>::EncodeHandoverPreparationInformation (HandoverPreparationInfo msg)
{
--- a/src/lte/model/lte-ue-cphy-sap.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-ue-cphy-sap.h Thu Dec 13 12:22:43 2012 +0100
@@ -48,6 +48,12 @@
virtual ~LteUeCphySapProvider ();
/**
+ * reset the PHY
+ *
+ */
+ virtual void Reset () = 0;
+
+ /**
* tell the PHY to synchronize with a given eNB for communication purposes
*
* \param cellId the ID of the eNB
@@ -125,6 +131,7 @@
MemberLteUeCphySapProvider (C* owner);
// inherited from LteUeCphySapProvider
+ virtual void Reset ();
virtual void SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
virtual void SetDlBandwidth (uint8_t ulBandwidth);
virtual void ConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth);
@@ -150,6 +157,13 @@
template <class C>
void
+MemberLteUeCphySapProvider<C>::Reset ()
+{
+ m_owner->DoReset ();
+}
+
+template <class C>
+void
MemberLteUeCphySapProvider<C>::SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn)
{
m_owner->DoSyncronizeWithEnb (cellId, dlEarfcn);
--- a/src/lte/model/lte-ue-mac.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-ue-mac.cc Thu Dec 13 12:22:43 2012 +0100
@@ -283,20 +283,20 @@
void
LteUeMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params)
{
- NS_LOG_FUNCTION (this);
+ NS_LOG_FUNCTION (this << (uint32_t) params.lcid);
- std::map <uint8_t, uint64_t>::iterator it;
+ std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
it = m_ulBsrReceived.find (params.lcid);
if (it!=m_ulBsrReceived.end ())
{
// update entry
- (*it).second = params.txQueueSize + params.retxQueueSize + params.statusPduSize;
+ (*it).second = params;
}
else
{
- m_ulBsrReceived.insert (std::pair<uint8_t, uint64_t> (params.lcid, params.txQueueSize + params.retxQueueSize + params.statusPduSize));
+ m_ulBsrReceived.insert (std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters> (params.lcid, params));
}
m_freshUlBsr = true;
}
@@ -323,7 +323,7 @@
bsr.m_macCeType = MacCeListElement_s::BSR;
// BSR is reported for each LCG
- std::map <uint8_t, uint64_t>::iterator it;
+ std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
std::vector<uint32_t> queue (4, 0); // one value per each of the 4 LCGs, initialized to 0
for (it = m_ulBsrReceived.begin (); it != m_ulBsrReceived.end (); it++)
{
@@ -332,7 +332,7 @@
lcInfoMapIt = m_lcInfoMap.find (lcid);
NS_ASSERT (lcInfoMapIt != m_lcInfoMap.end ());
uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
- queue.at (lcg) += (*it).second;
+ queue.at (lcg) += ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
}
// FF API says that all 4 LCGs are always present
@@ -501,6 +501,8 @@
}
}
m_rachConfigured = false;
+ m_freshUlBsr = false;
+ m_ulBsrReceived.clear ();
}
void
@@ -529,11 +531,11 @@
if (dci.m_ndi==1)
{
// New transmission -> retrieve data from RLC
- std::map <uint8_t, uint64_t>::iterator itBsr;
+ std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator itBsr;
uint16_t activeLcs = 0;
for (itBsr = m_ulBsrReceived.begin (); itBsr != m_ulBsrReceived.end (); itBsr++)
{
- if ((*itBsr).second > 0)
+ if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
{
activeLcs++;
}
@@ -549,18 +551,48 @@
for (it = m_lcInfoMap.begin (); it!=m_lcInfoMap.end (); it++)
{
itBsr = m_ulBsrReceived.find ((*it).first);
- if (((itBsr!=m_ulBsrReceived.end ()) && ((*itBsr).second > 0)))
+ if ( (itBsr!=m_ulBsrReceived.end ()) &&
+ ( ((*itBsr).second.statusPduSize > 0) ||
+ ((*itBsr).second.retxQueueSize > 0) ||
+ ((*itBsr).second.txQueueSize > 0)) )
{
- NS_LOG_LOGIC (this << "\t" << bytesPerActiveLc << " bytes to LC " << (uint32_t)(*it).first << " queue " << (*itBsr).second);
- (*it).second.macSapUser->NotifyTxOpportunity (bytesPerActiveLc, 0, 0); // layer and HARQ ID are not used in UL
- if ((*itBsr).second >= static_cast<uint64_t> (bytesPerActiveLc))
+ uint32_t bytesForThisLc = bytesPerActiveLc;
+ NS_LOG_LOGIC (this << "\t" << bytesPerActiveLc << " bytes to LC " << (uint32_t)(*it).first << " statusQueue " << (*itBsr).second.statusPduSize << " retxQueue" << (*itBsr).second.retxQueueSize << " txQueue" << (*itBsr).second.txQueueSize);
+ if (((*itBsr).second.statusPduSize > 0) && (bytesForThisLc > (*itBsr).second.statusPduSize))
+ {
+ (*it).second.macSapUser->NotifyTxOpportunity ((*itBsr).second.statusPduSize, 0, 0);
+ bytesForThisLc -= (*itBsr).second.statusPduSize;
+ (*itBsr).second.statusPduSize = 0;
+ }
+ if ((bytesForThisLc > 0) && (((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0)))
{
- (*itBsr).second -= bytesPerActiveLc;
+ if ((*itBsr).second.retxQueueSize > 0)
+ {
+ (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0);
+ if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
+ {
+ (*itBsr).second.retxQueueSize -= bytesForThisLc;
+ }
+ else
+ {
+ (*itBsr).second.retxQueueSize = 0;
+ }
+ }
+ else if ((*itBsr).second.txQueueSize > 0)
+ {
+ bytesForThisLc -= 2; // remove RLC header
+ (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0);
+ if ((*itBsr).second.txQueueSize >= bytesForThisLc)
+ {
+ (*itBsr).second.txQueueSize -= bytesForThisLc;
+ }
+ else
+ {
+ (*itBsr).second.txQueueSize = 0;
+ }
+ }
}
- else
- {
- (*itBsr).second = 0;
- }
+
}
}
}
--- a/src/lte/model/lte-ue-mac.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-ue-mac.h Thu Dec 13 12:22:43 2012 +0100
@@ -129,7 +129,8 @@
LteUePhySapProvider* m_uePhySapProvider;
LteUePhySapUser* m_uePhySapUser;
- std::map <uint8_t, uint64_t> m_ulBsrReceived; // BSR received from RLC (BSR up to now)
+ std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters> m_ulBsrReceived; // BSR received from RLC (the last one)
+
Time m_bsrPeriodicity;
Time m_bsrLast;
--- a/src/lte/model/lte-ue-phy.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-ue-phy.cc Thu Dec 13 12:22:43 2012 +0100
@@ -117,42 +117,21 @@
LteUePhy::LteUePhy (Ptr<LteSpectrumPhy> dlPhy, Ptr<LteSpectrumPhy> ulPhy)
: LtePhy (dlPhy, ulPhy),
- m_p10CqiPeriocity (MilliSeconds (1)),
- // ideal behavior
- m_p10CqiLast (MilliSeconds (0)),
- m_a30CqiPeriocity (MilliSeconds (1)),
- // ideal behavior
- m_a30CqiLast (MilliSeconds (0)),
+ m_p10CqiPeriocity (MilliSeconds (1)), // ideal behavior
+ m_a30CqiPeriocity (MilliSeconds (1)), // ideal behavior
m_uePhySapUser (0),
- m_ueCphySapUser (0),
- m_rnti (0),
- m_transmissionMode (0),
- m_srsPeriodicity (0),
- m_srsConfigured (false),
- m_dlConfigured (false),
- m_ulConfigured (false),
- m_addedToDlChannel (false),
- m_raPreambleId (255), // value out of range
- m_raRnti (11), // value out of range
- m_rsrpRsrqSampleCounter (0)
+ m_ueCphySapUser (0)
{
m_amc = CreateObject <LteAmc> ();
m_uePhySapProvider = new UeMemberLteUePhySapProvider (this);
m_ueCphySapProvider = new MemberLteUeCphySapProvider<LteUePhy> (this);
m_macChTtiDelay = UL_PUSCH_TTIS_DELAY;
- for (int i = 0; i < m_macChTtiDelay; i++)
- {
- Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
- m_packetBurstQueue.push_back (pb);
- std::list<Ptr<LteControlMessage> > l;
- m_controlMessagesQueue.push_back (l);
- }
- std::vector <int> ulRb;
- m_subChannelsForTransmissionQueue.resize (m_macChTtiDelay, ulRb);
-
+
NS_ASSERT_MSG (Simulator::Now ().GetNanoSeconds () == 0,
"Cannot create UE devices after simulation started");
Simulator::ScheduleNow (&LteUePhy::SubframeIndication, this, 1, 1);
+
+ DoReset ();
}
@@ -731,16 +710,16 @@
}
m_subChannelsForTransmissionQueue.at (m_macChTtiDelay-1).clear ();
- if (m_srsConfigured)
+ if (m_srsConfigured && (m_srsStartTime <= Simulator::Now ()))
{
NS_ASSERT_MSG (subframeNo > 0 && subframeNo <= 10, "the SRS index check code assumes that subframeNo starts at 1");
if ((((frameNo-1)*10 + (subframeNo-1)) % m_srsPeriodicity) == m_srsSubframeOffset)
{
NS_LOG_INFO ("frame " << frameNo << " subframe " << subframeNo << " sending SRS (offset=" << m_srsSubframeOffset << ", period=" << m_srsPeriodicity << ")");
- Simulator::Schedule (UL_SRS_DELAY_FROM_SUBFRAME_START,
- &LteUePhy::SendSrs,
- this);
+ m_sendSrsEvent = Simulator::Schedule (UL_SRS_DELAY_FROM_SUBFRAME_START,
+ &LteUePhy::SendSrs,
+ this);
}
}
@@ -786,9 +765,10 @@
}
void
- LteUePhy::SendSrs ()
+LteUePhy::SendSrs ()
{
- NS_LOG_FUNCTION (this << " UE " << m_rnti << " start tx SRS, cell Id " << m_cellId);
+ NS_LOG_FUNCTION (this << " UE " << m_rnti << " start tx SRS, cell Id " << (uint32_t) m_cellId);
+ NS_ASSERT (m_cellId > 0);
// set the current tx power spectral density (full bandwidth)
std::vector <int> dlRb;
for (uint8_t i = 0; i < m_ulBandwidth; i++)
@@ -800,12 +780,44 @@
}
+void
+LteUePhy::DoReset ()
+{
+ NS_LOG_FUNCTION (this);
+
+ m_rnti = 0;
+ m_transmissionMode = 0;
+ m_srsPeriodicity = 0;
+ m_srsConfigured = false;
+ m_dlConfigured = false;
+ m_ulConfigured = false;
+ m_raPreambleId = 255; // value out of range
+ m_raRnti = 11; // value out of range
+ m_rsrpRsrqSampleCounter = 0;
+ m_p10CqiLast = Simulator::Now ();
+ m_a30CqiLast = Simulator::Now ();
+
+ m_packetBurstQueue.clear ();
+ m_controlMessagesQueue.clear ();
+ m_subChannelsForTransmissionQueue.clear ();
+ for (int i = 0; i < m_macChTtiDelay; i++)
+ {
+ Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
+ m_packetBurstQueue.push_back (pb);
+ std::list<Ptr<LteControlMessage> > l;
+ m_controlMessagesQueue.push_back (l);
+ }
+ std::vector <int> ulRb;
+ m_subChannelsForTransmissionQueue.resize (m_macChTtiDelay, ulRb);
+
+ m_sendSrsEvent.Cancel ();
+}
void
LteUePhy::DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn)
{
NS_LOG_FUNCTION (this << cellId);
- m_enbCellId = cellId;
+ m_cellId = cellId;
m_dlEarfcn = dlEarfcn;
m_downlinkSpectrumPhy->SetCellId (cellId);
m_uplinkSpectrumPhy->SetCellId (cellId);
@@ -882,6 +894,12 @@
m_srsPeriodicity = GetSrsPeriodicity (srcCi);
m_srsSubframeOffset = GetSrsSubframeOffset (srcCi);
m_srsConfigured = true;
+
+ // Need a guard time for the case where the SRS periodicity is changed
+ // to make sure no UE sends SRSs before all UEs received the new SRS configuration.
+ // Note that the eNB will send the new SRS config to all UEs at the same time,
+ // but with the real RRC model the time it takes to reach each UE might vary.
+ m_srsStartTime = Simulator::Now () + MilliSeconds (3);
NS_LOG_DEBUG (this << " UE SRS P " << m_srsPeriodicity << " RNTI " << m_rnti << " offset " << m_srsSubframeOffset << " cellId " << m_cellId << " CI " << srcCi);
}
--- a/src/lte/model/lte-ue-phy.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-ue-phy.h Thu Dec 13 12:22:43 2012 +0100
@@ -216,6 +216,7 @@
void QueueSubChannelsForTransmission (std::vector <int> rbMap);
// UE CPHY SAP methods
+ void DoReset ();
void DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
void DoSetDlBandwidth (uint8_t ulBandwidth);
void DoConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth);
@@ -251,8 +252,6 @@
LteUeCphySapUser* m_ueCphySapUser;
uint16_t m_rnti;
-
- uint16_t m_enbCellId;
uint8_t m_transmissionMode;
std::vector <double> m_txModeGain;
@@ -260,10 +259,10 @@
uint16_t m_srsPeriodicity;
uint16_t m_srsSubframeOffset;
uint16_t m_srsConfigured;
+ Time m_srsStartTime;
bool m_dlConfigured;
bool m_ulConfigured;
- bool m_addedToDlChannel;
Ptr<LteHarqPhy> m_harqPhyModule;
@@ -278,6 +277,8 @@
uint16_t m_rsrpRsrqSamplePeriod;
uint16_t m_rsrpRsrqSampleCounter;
+ EventId m_sendSrsEvent;
+
/**
* Trace information regarding PHY stats from DL Tx perspective
* PhyTrasmissionStatParameters see lte-common.h
--- a/src/lte/model/lte-ue-rrc.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-ue-rrc.cc Thu Dec 13 12:22:43 2012 +0100
@@ -337,7 +337,11 @@
m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
m_srb0->m_rlc = rlc;
- m_srb0->m_srbIdentity = 1;
+ m_srb0->m_srbIdentity = 0;
+ LteUeRrcSapUser::SetupParameters ueParams;
+ ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
+ ueParams.srb1SapProvider = 0;
+ m_rrcSapUser->Setup (ueParams);
// CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
LteUeCmacSapProvider::LogicalChannelConfig lcConfig;
@@ -413,6 +417,7 @@
{
NS_LOG_FUNCTION (this << rnti);
m_rnti = rnti;
+ m_srb0->m_rlc->SetRnti (m_rnti);
m_rrcSapUser->Reestablish ();
m_cphySapProvider->SetRnti (m_rnti);
}
@@ -528,7 +533,10 @@
{
NS_LOG_FUNCTION (this);
m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
- m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
+ if (m_srb1)
+ {
+ m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
+ }
}
@@ -594,16 +602,14 @@
switch (m_state)
{
case CONNECTED_NORMALLY:
- if (msg.haveRadioResourceConfigDedicated)
- {
- ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
- }
if (msg.haveMobilityControlInfo)
{
NS_LOG_INFO ("haveMobilityControlInfo == true");
SwitchToState (CONNECTED_HANDOVER);
const LteRrcSap::MobilityControlInfo& mci = msg.mobilityControlInfo;
m_handoverStartTrace (m_imsi, m_cellId, m_rnti, mci.targetPhysCellId);
+ m_cmacSapProvider->Reset ();
+ m_cphySapProvider->Reset ();
m_cellId = mci.targetPhysCellId;
NS_ASSERT (mci.haveCarrierFreq);
NS_ASSERT (mci.haveCarrierBandwidth);
@@ -611,16 +617,25 @@
m_cphySapProvider->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
m_cphySapProvider->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
m_rnti = msg.mobilityControlInfo.newUeIdentity;
- NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
+ m_srb0->m_rlc->SetRnti (m_rnti);
+ NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
m_cmacSapProvider->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
m_cphySapProvider->SetRnti (m_rnti);
m_lastRrcTransactionIdentifier = msg.rrcTransactionIdentifier;
+ NS_ASSERT (msg.haveRadioResourceConfigDedicated);
+ m_srb1 = 0; // dispose SRB1
+ m_drbMap.clear (); // dispose all DRBs
+ ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
// RRC connection reconfiguration completed will be sent
- // after handover is completed
+ // after handover is complete
}
else
{
NS_LOG_INFO ("haveMobilityControlInfo == false");
+ if (msg.haveRadioResourceConfigDedicated)
+ {
+ ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
+ }
LteRrcSap::RrcConnectionReconfigurationCompleted msg2;
msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
m_rrcSapUser->SendRrcConnectionReconfigurationCompleted (msg2);
@@ -674,6 +689,11 @@
NS_LOG_FUNCTION (this);
}
+void
+LteUeRrc::DoRecvRrcConnectionReject (LteRrcSap::RrcConnectionReject msg)
+{
+ NS_LOG_FUNCTION (this);
+}
@@ -698,7 +718,8 @@
if (m_srb1 == 0)
{
// SRB1 not setup yet
- NS_ASSERT_MSG (m_state == IDLE_CONNECTING, "expected state IDLE_CONNECTING, actual state " << ToString (m_state));
+ NS_ASSERT_MSG ((m_state == IDLE_CONNECTING) || (m_state == CONNECTED_HANDOVER),
+ "unexpected state " << ToString (m_state));
NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
const uint8_t lcid = 1; // fixed LCID for SRB1
@@ -735,6 +756,11 @@
++stamIt;
NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
+
+ LteUeRrcSapUser::SetupParameters ueParams;
+ ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
+ ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
+ m_rrcSapUser->Setup (ueParams);
}
else
{
@@ -820,6 +846,7 @@
m_cmacSapProvider->AddLc (dtamIt->logicalChannelIdentity,
lcConfig,
rlc->GetLteMacSapUser ());
+ rlc->Start ();
}
else
{
--- a/src/lte/model/lte-ue-rrc.h Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/lte-ue-rrc.h Thu Dec 13 12:22:43 2012 +0100
@@ -247,6 +247,7 @@
void DoRecvRrcConnectionReestablishment (LteRrcSap::RrcConnectionReestablishment msg);
void DoRecvRrcConnectionReestablishmentReject (LteRrcSap::RrcConnectionReestablishmentReject msg);
void DoRecvRrcConnectionRelease (LteRrcSap::RrcConnectionRelease msg);
+ void DoRecvRrcConnectionReject (LteRrcSap::RrcConnectionReject msg);
// internal methods
--- a/src/lte/model/pf-ff-mac-scheduler.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/pf-ff-mac-scheduler.cc Thu Dec 13 12:22:43 2012 +0100
@@ -1707,8 +1707,9 @@
uint8_t bsrId = params.m_macCeList.at (i).m_macCeValue.m_bufferStatus.at (lcg);
buffer += BufferSizeLevelBsr::BsrId2BufferSize (bsrId);
}
-
+
uint16_t rnti = params.m_macCeList.at (i).m_rnti;
+ NS_LOG_LOGIC (this << "RNTI=" << rnti << " buffer=" << buffer);
it = m_ceBsrRxed.find (rnti);
if (it == m_ceBsrRxed.end ())
{
@@ -1960,7 +1961,6 @@
void
PfFfMacScheduler::UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size)
{
- size = size - 2; // remove the minimum RLC overhead
std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
LteFlowId_t flow (rnti, lcid);
it = m_rlcBufferReq.find (flow);
@@ -1969,37 +1969,26 @@
NS_LOG_INFO (this << " UE " << rnti << " LC " << (uint16_t)lcid << " txqueue " << (*it).second.m_rlcTransmissionQueueSize << " retxqueue " << (*it).second.m_rlcRetransmissionQueueSize << " status " << (*it).second.m_rlcStatusPduSize << " decrease " << size);
// Update queues: RLC tx order Status, ReTx, Tx
// Update status queue
- if ((*it).second.m_rlcStatusPduSize <= size)
- {
- size -= (*it).second.m_rlcStatusPduSize;
- (*it).second.m_rlcStatusPduSize = 0;
- }
- else
+ if (((*it).second.m_rlcStatusPduSize > 0) && (size >= (*it).second.m_rlcStatusPduSize))
{
- (*it).second.m_rlcStatusPduSize -= size;
- return;
+ (*it).second.m_rlcStatusPduSize = 0;
}
- // update retransmission queue
- if ((*it).second.m_rlcRetransmissionQueueSize <= size)
+ else if (((*it).second.m_rlcRetransmissionQueueSize > 0) && (size >= (*it).second.m_rlcRetransmissionQueueSize))
{
- size -= (*it).second.m_rlcRetransmissionQueueSize;
(*it).second.m_rlcRetransmissionQueueSize = 0;
}
- else
- {
- (*it).second.m_rlcRetransmissionQueueSize -= size;
- return;
- }
- // update transmission queue
- if ((*it).second.m_rlcTransmissionQueueSize <= size)
+ else if ((*it).second.m_rlcTransmissionQueueSize > 0)
{
- size -= (*it).second.m_rlcTransmissionQueueSize;
- (*it).second.m_rlcTransmissionQueueSize = 0;
- }
- else
- {
- (*it).second.m_rlcTransmissionQueueSize -= size;
- return;
+ // update transmission queue
+ if ((*it).second.m_rlcTransmissionQueueSize <= size)
+ {
+ (*it).second.m_rlcTransmissionQueueSize = 0;
+ }
+ else
+ {
+ size -= 2; // remove minimun RLC overhead due to header
+ (*it).second.m_rlcTransmissionQueueSize -= size;
+ }
}
}
else
--- a/src/lte/model/rr-ff-mac-scheduler.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/model/rr-ff-mac-scheduler.cc Thu Dec 13 12:22:43 2012 +0100
@@ -1752,7 +1752,6 @@
RrFfMacScheduler::UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size)
{
NS_LOG_FUNCTION (this);
- size = size - 2; // remove the minimum RLC overhead
std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
for (it = m_rlcBufferReq.begin (); it != m_rlcBufferReq.end (); it++)
{
@@ -1761,39 +1760,27 @@
NS_LOG_INFO (this << " UE " << rnti << " LC " << (uint16_t)lcid << " txqueue " << (*it).m_rlcTransmissionQueueSize << " retxqueue " << (*it).m_rlcRetransmissionQueueSize << " status " << (*it).m_rlcStatusPduSize << " decrease " << size);
// Update queues: RLC tx order Status, ReTx, Tx
// Update status queue
- if ((*it).m_rlcStatusPduSize <= size)
- {
- size -= (*it).m_rlcStatusPduSize;
- (*it).m_rlcStatusPduSize = 0;
- }
- else
- {
- (*it).m_rlcStatusPduSize -= size;
- return;
- }
- // update retransmission queue
- if ((*it).m_rlcRetransmissionQueueSize <= size)
- {
- size -= (*it).m_rlcRetransmissionQueueSize;
- (*it).m_rlcRetransmissionQueueSize = 0;
- }
- else
- {
- (*it).m_rlcRetransmissionQueueSize -= size;
- return;
- }
- // update transmission queue
- if ((*it).m_rlcTransmissionQueueSize <= size)
- {
- size -= (*it).m_rlcTransmissionQueueSize;
- (*it).m_rlcTransmissionQueueSize = 0;
- }
- else
- {
- (*it).m_rlcTransmissionQueueSize -= size;
- NS_LOG_DEBUG ("dequeue " << (*it).m_rlcTransmissionQueueSize);
- return;
- }
+ if (((*it).m_rlcStatusPduSize > 0) && (size >= (*it).m_rlcStatusPduSize))
+ {
+ (*it).m_rlcStatusPduSize = 0;
+ }
+ else if (((*it).m_rlcRetransmissionQueueSize > 0) && (size >= (*it).m_rlcRetransmissionQueueSize))
+ {
+ (*it).m_rlcRetransmissionQueueSize = 0;
+ }
+ else if ((*it).m_rlcTransmissionQueueSize > 0)
+ {
+ // update transmission queue
+ if ((*it).m_rlcTransmissionQueueSize <= size)
+ {
+ (*it).m_rlcTransmissionQueueSize = 0;
+ }
+ else
+ {
+ size -= 2; // remove minimun RLC overhead due to header
+ (*it).m_rlcTransmissionQueueSize -= size;
+ }
+ }
return;
}
}
--- a/src/lte/test/test-asn1-encoding.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/test/test-asn1-encoding.cc Thu Dec 13 12:22:43 2012 +0100
@@ -751,6 +751,55 @@
NS_TEST_ASSERT_MSG_EQ (source.GetRrcTransactionIdentifier (), destination.GetRrcTransactionIdentifier (), "rrcTransactionIdentifier");
}
+// --------------------------- CLASS RrcConnectionRejectTestCase -----------------------------
+class RrcConnectionRejectTestCase : public RrcHeaderTestCase
+{
+public:
+ RrcConnectionRejectTestCase ();
+ virtual void DoRun (void);
+};
+
+RrcConnectionRejectTestCase::RrcConnectionRejectTestCase () : RrcHeaderTestCase ("Testing RrcConnectionRejectTestCase")
+{
+}
+
+void
+RrcConnectionRejectTestCase::DoRun (void)
+{
+ std::cout << "============= RrcConnectionRejectTestCase ===========" << std::endl;
+ // add header
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->Print (std::cout);
+ std::cout << std::endl;
+
+ LteRrcSap::RrcConnectionReject msg;
+ msg.waitTime = 2;
+
+ RrcConnectionRejectHeader source;
+ source.SetMessage (msg);
+
+ std::cout << "--------- SOURCE INFO: -------" << std::endl;
+ source.Print (std::cout);
+ packet->AddHeader (source);
+ std::cout << std::endl;
+
+ // print serialized packet contents
+ std::cout << "---- SERIALIZED PACKET CONTENTS: -------" << std::endl;
+ std::cout << "Hex: ";
+ TestUtils::printPacketContentsHex (GetPointer (packet));
+ std::cout << "Bin: ";
+ TestUtils::printPacketContentsBin (GetPointer (packet));
+
+ // remove header
+ RrcConnectionRejectHeader destination;
+ packet->RemoveHeader (destination);
+ std::cout << "--------- DESTINATION INFO: -------" << std::endl;
+ destination.Print (std::cout);
+
+ // Check that the destination and source headers contain the same values
+ NS_TEST_ASSERT_MSG_EQ (source.GetMessage ().waitTime, destination.GetMessage ().waitTime, "Different waitTime!");
+}
+
// --------------------------- CLASS Asn1EncodingSuite -----------------------------
class Asn1EncodingSuite : public TestSuite
{
@@ -772,6 +821,7 @@
AddTestCase (new RrcConnectionReestablishmentRequestTestCase);
AddTestCase (new RrcConnectionReestablishmentTestCase);
AddTestCase (new RrcConnectionReestablishmentCompleteTestCase);
+ AddTestCase (new RrcConnectionRejectTestCase);
}
Asn1EncodingSuite asn1EncodingSuite;
--- a/src/lte/test/test-lte-rrc.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/test/test-lte-rrc.cc Thu Dec 13 12:22:43 2012 +0100
@@ -68,7 +68,7 @@
{
std::ostringstream oss;
oss << "nUes=" << nUes
- << "nBearers=" << nBearers
+ << ", nBearers=" << nBearers
<< ", tConnBase=" << tConnBase
<< ", tConnIncrPerUe=" << tConnIncrPerUe
<< ", delayDiscStart=" << delayDiscStart;
@@ -99,6 +99,7 @@
void
LteRrcConnectionEstablishmentTestCase::DoRun ()
{
+ NS_LOG_FUNCTION (this << GetName ());
// normal code
m_lteHelper = CreateObject<LteHelper> ();
--- a/src/lte/test/test-lte-x2-handover.cc Thu Dec 13 12:10:31 2012 +0100
+++ b/src/lte/test/test-lte-x2-handover.cc Thu Dec 13 12:22:43 2012 +0100
@@ -55,10 +55,10 @@
*
* \return
*/
- LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo);
+ LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc);
private:
- static std::string BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo);
+ static std::string BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc);
virtual void DoRun (void);
void CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
@@ -70,6 +70,7 @@
bool m_useUdp;
std::string m_schedulerType;
bool m_admitHo;
+ bool m_useIdealRrc;
Ptr<LteHelper> m_lteHelper;
Ptr<EpcHelper> m_epcHelper;
@@ -95,10 +96,11 @@
const Time m_maxHoDuration;
const Time m_statsDuration;
+
};
-std::string LteX2HandoverTestCase::BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo)
+std::string LteX2HandoverTestCase::BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
{
std::ostringstream oss;
oss << " nUes=" << nUes
@@ -107,11 +109,19 @@
<< " " << schedulerType
<< " admitHo=" << admitHo
<< " hoList: " << handoverEventListName;
+ if (useIdealRrc)
+ {
+ oss << ", ideal RRC";
+ }
+ else
+ {
+ oss << ", real RRC";
+ }
return oss.str ();
}
-LteX2HandoverTestCase::LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo)
- : TestCase (BuildNameString (nUes, nDedicatedBearers, handoverEventListName, useUdp, schedulerType, admitHo)),
+LteX2HandoverTestCase::LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
+ : TestCase (BuildNameString (nUes, nDedicatedBearers, handoverEventListName, useUdp, schedulerType, admitHo, useIdealRrc)),
m_nUes (nUes),
m_nDedicatedBearers (nDedicatedBearers),
m_handoverEventList (handoverEventList),
@@ -120,6 +130,7 @@
m_useUdp (useUdp),
m_schedulerType (schedulerType),
m_admitHo (admitHo),
+ m_useIdealRrc (useIdealRrc),
m_maxHoDuration (Seconds (0.1)),
m_statsDuration (Seconds (0.5))
{
@@ -128,15 +139,19 @@
void
LteX2HandoverTestCase::DoRun ()
{
- NS_LOG_FUNCTION (this << BuildNameString (m_nUes, m_nDedicatedBearers, m_handoverEventListName, m_useUdp, m_schedulerType, m_admitHo));
+ NS_LOG_FUNCTION (this << BuildNameString (m_nUes, m_nDedicatedBearers, m_handoverEventListName, m_useUdp, m_schedulerType, m_admitHo, m_useIdealRrc));
Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (MilliSeconds(100)));
Config::SetDefault ("ns3::UdpClient::MaxPackets", UintegerValue(1000000));
Config::SetDefault ("ns3::UdpClient::PacketSize", UintegerValue(100));
+
+ int64_t stream = 1;
m_lteHelper = CreateObject<LteHelper> ();
m_lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
- m_lteHelper->SetSchedulerType (m_schedulerType);
+ m_lteHelper->SetSchedulerType (m_schedulerType);
+ m_lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (m_useIdealRrc));
+
NodeContainer enbNodes;
enbNodes.Create (2);
@@ -164,6 +179,7 @@
NetDeviceContainer enbDevices;
enbDevices = m_lteHelper->InstallEnbDevice (enbNodes);
+ stream += m_lteHelper->AssignStreams (enbDevices, stream);
for (NetDeviceContainer::Iterator it = enbDevices.Begin ();
it != enbDevices.End ();
++it)
@@ -174,8 +190,7 @@
NetDeviceContainer ueDevices;
ueDevices = m_lteHelper->InstallUeDevice (ueNodes);
-
-
+ stream += m_lteHelper->AssignStreams (ueDevices, stream);
Ipv4Address remoteHostAddr;
Ipv4StaticRoutingHelper ipv4RoutingHelper;
@@ -233,6 +248,7 @@
Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable> ();
startTimeSeconds->SetAttribute ("Min", DoubleValue (0));
startTimeSeconds->SetAttribute ("Max", DoubleValue (0.010));
+ startTimeSeconds->SetStream (stream++);
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
@@ -371,6 +387,11 @@
hoEventIt != m_handoverEventList.end ();
++hoEventIt)
{
+ Simulator::Schedule (hoEventIt->startTime,
+ &LteX2HandoverTestCase::CheckConnected,
+ this,
+ ueDevices.Get (hoEventIt->ueDeviceIndex),
+ enbDevices.Get (hoEventIt->sourceEnbDeviceIndex));
m_lteHelper->HandoverRequest (hoEventIt->startTime,
ueDevices.Get (hoEventIt->ueDeviceIndex),
enbDevices.Get (hoEventIt->sourceEnbDeviceIndex),
@@ -410,6 +431,7 @@
void
LteX2HandoverTestCase::CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
{
+ NS_LOG_FUNCTION (this);
Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc ();
NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
@@ -433,8 +455,10 @@
uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn ();
uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn ();
uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn ();
+ uint64_t ueImsi = ueLteDevice->GetImsi ();
+ uint64_t enbImsi = ueManager->GetImsi ();
-
+ NS_TEST_ASSERT_MSG_EQ (ueImsi, enbImsi, "inconsistent IMSI");
NS_TEST_ASSERT_MSG_EQ (ueCellId, enbCellId, "inconsistent CellId");
NS_TEST_ASSERT_MSG_EQ (ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
NS_TEST_ASSERT_MSG_EQ (ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
@@ -473,6 +497,7 @@
void
LteX2HandoverTestCase::SaveStatsAfterHandover (uint32_t ueIndex)
{
+ NS_LOG_FUNCTION (this << ueIndex);
for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
++it)
@@ -484,7 +509,8 @@
void
LteX2HandoverTestCase::CheckStatsAWhileAfterHandover (uint32_t ueIndex)
-{
+{
+ NS_LOG_FUNCTION (this << ueIndex);
uint32_t b = 1;
for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
@@ -537,7 +563,7 @@
ue1fwdagain.targetEnbDeviceIndex = 1;
HandoverEvent ue2fwd;
- ue1fwd.startTime = MilliSeconds (110);
+ ue2fwd.startTime = MilliSeconds (110);
ue2fwd.ueDeviceIndex = 1;
ue2fwd.sourceEnbDeviceIndex = 0;
ue2fwd.targetEnbDeviceIndex = 1;
@@ -587,93 +613,57 @@
hel7.push_back (ue2fwd);
hel7.push_back (ue2bwd);
-
- // nUes, nDBearers, helist, name, useUdp, scheduler, admitHo
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, "ns3::RrFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, "ns3::RrFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, "ns3::RrFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, "ns3::RrFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, "ns3::RrFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, "ns3::RrFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel4, hel4name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel4, hel4name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel4, hel4name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel5, hel5name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel5, hel5name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel5, hel5name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel3, hel3name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel4, hel4name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel4, hel4name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel4, hel4name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel5, hel5name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel5, hel5name, true, "ns3::RrFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel5, hel5name, true, "ns3::RrFfMacScheduler", true));
-
+ std::vector<std::string> schedulers;
+ schedulers.push_back ("ns3::RrFfMacScheduler");
+ schedulers.push_back ("ns3::PfrFfMacScheduler");
+ for (std::vector<std::string>::iterator schedIt = schedulers.begin (); schedIt != schedulers.end (); ++schedIt)
+ {
+ for (int32_t useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc)
+ {
+ // nUes, nDBearers, helist, name, useUdp, sched, admitHo, idealRrc
+ AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, *schedIt, false, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, *schedIt, false, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, *schedIt, false, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, *schedIt, false, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, *schedIt, false, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, *schedIt, false, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel4, hel4name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel4, hel4name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel4, hel4name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel5, hel5name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel5, hel5name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel5, hel5name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel4, hel4name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel4, hel4name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel4, hel4name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel5, hel5name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel5, hel5name, true, *schedIt, true, useIdealRrc));
+ AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel5, hel5name, true, *schedIt, true, useIdealRrc));
-
- // nUes, nDBearers, helist, name, useUdp, scheduler, admitHo
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, "ns3::PfFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, "ns3::PfFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, "ns3::PfFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, "ns3::PfFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, "ns3::PfFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, "ns3::PfFfMacScheduler", false));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel4, hel4name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel4, hel4name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel4, hel4name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel5, hel5name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel5, hel5name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel5, hel5name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel3, hel3name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel4, hel4name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel4, hel4name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel4, hel4name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel5, hel5name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel5, hel5name, true, "ns3::PfFfMacScheduler", true));
- AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel5, hel5name, true, "ns3::PfFfMacScheduler", true));
-
+ }
+ }
}
static LteX2HandoverTestSuite g_lteX2HandoverTestSuiteInstance;