--- a/src/lte/model/epc-ue-nas.cc Tue Aug 28 15:46:47 2012 +0200
+++ b/src/lte/model/epc-ue-nas.cc Tue Oct 30 16:02:07 2012 +0100
@@ -33,10 +33,30 @@
+
+
+const char* g_ueNasStateName[EpcUeNas::NUM_STATES] =
+ {
+ "OFF",
+ "ATTACHING",
+ "IDLE_REGISTERED",
+ "CONNECTING_TO_EPC",
+ "ACTIVE "
+ };
+
+std::string ToString (EpcUeNas::State s)
+{
+ return std::string (g_ueNasStateName[s]);
+}
+
+
+
+
NS_OBJECT_ENSURE_REGISTERED (EpcUeNas);
EpcUeNas::EpcUeNas ()
- : m_asSapProvider (0),
+ : m_state (OFF),
+ m_asSapProvider (0),
m_bidCounter (0)
{
NS_LOG_FUNCTION (this);
@@ -63,6 +83,9 @@
static TypeId tid = TypeId ("ns3::EpcUeNas")
.SetParent<Object> ()
.AddConstructor<EpcUeNas> ()
+ .AddTraceSource ("StateTransition",
+ "fired upon every UE NAS state transition",
+ MakeTraceSourceAccessor (&EpcUeNas::m_stateTransitionCallback))
;
return tid;
}
@@ -107,6 +130,9 @@
void
EpcUeNas::Connect (Ptr<NetDevice> enbDevice)
{
+ NS_LOG_FUNCTION (this);
+
+ m_enbDevice = enbDevice;
// since RRC Idle Mode cell selection is not supported yet, we
// force the UE RRC to be camped on a specific eNB
@@ -115,22 +141,35 @@
// tell RRC to go into connected mode
m_asSapProvider->Connect ();
+}
- if (m_epcHelper)
- {
- m_epcHelper->AttachUe (m_device, m_imsi, enbDevice);
- // also activate default EPS bearer
- ActivateEpsBearer (EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), EpcTft::Default ());
- }
+
+void
+EpcUeNas::Disconnect ()
+{
+ NS_LOG_FUNCTION (this);
+ m_asSapProvider->Disconnect ();
+ SwitchToState (OFF);
}
+
void
EpcUeNas::ActivateEpsBearer (EpsBearer bearer, Ptr<EpcTft> tft)
{
- NS_ASSERT_MSG (m_bidCounter < 11, "cannot have more than 11 EPS bearers");
- uint8_t bid = ++m_bidCounter;
- m_epcHelper->ActivateEpsBearer (m_device, m_imsi, tft, bearer);
- m_tftClassifier.Add (tft, bid);
+ NS_LOG_FUNCTION (this);
+ switch (m_state)
+ {
+ case ACTIVE:
+ DoActivateEpsBearer (bearer, tft);
+ break;
+
+ default:
+ BearerToBeActivated btba;
+ btba.bearer = bearer;
+ btba.tft = tft;
+ m_bearersToBeActivatedList.push_back (btba);
+ break;
+ }
}
bool
@@ -138,23 +177,43 @@
{
NS_LOG_FUNCTION (this << packet);
- uint32_t id = m_tftClassifier.Classify (packet, EpcTft::UPLINK);
- NS_ASSERT ((id & 0xFFFFFF00) == 0);
- uint8_t bid = (uint8_t) (id & 0x000000FF);
- if (bid == 0)
+ switch (m_state)
{
+ case ACTIVE:
+ {
+ uint32_t id = m_tftClassifier.Classify (packet, EpcTft::UPLINK);
+ NS_ASSERT ((id & 0xFFFFFF00) == 0);
+ uint8_t bid = (uint8_t) (id & 0x000000FF);
+ if (bid == 0)
+ {
+ return false;
+ }
+ else
+ {
+ m_asSapProvider->SendData (packet, bid);
+ return true;
+ }
+ }
+ break;
+
+ default:
+ NS_LOG_WARN (this << " NAS OFF, discarding packet");
return false;
- }
- else
- {
- m_asSapProvider->SendData (packet, bid);
- return true;
- }
+ break;
+ }
}
void
EpcUeNas::DoNotifyConnectionSuccessful ()
{
+ NS_LOG_FUNCTION (this);
+ if (m_epcHelper)
+ {
+ m_epcHelper->AttachUe (m_device, m_imsi, m_enbDevice);
+ // also activate default EPS bearer
+ DoActivateEpsBearer (EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), EpcTft::Default ());
+ SwitchToState (ACTIVE);
+ }
}
void
@@ -170,7 +229,48 @@
m_forwardUpCallback (packet);
}
+void
+EpcUeNas::DoNotifyConnectionReleased ()
+{
+ NS_FATAL_ERROR ("connection failed, it should not happen with the current model");
+}
+void
+EpcUeNas::DoActivateEpsBearer (EpsBearer bearer, Ptr<EpcTft> tft)
+{
+ NS_LOG_FUNCTION (this);
+ NS_ASSERT_MSG (m_bidCounter < 11, "cannot have more than 11 EPS bearers");
+ uint8_t bid = ++m_bidCounter;
+ m_epcHelper->ActivateEpsBearer (m_device, m_imsi, tft, bearer);
+ m_tftClassifier.Add (tft, bid);
+}
+
+void
+EpcUeNas::SwitchToState (State newState)
+{
+ NS_LOG_FUNCTION (this << newState);
+ State oldState = m_state;
+ m_state = newState;
+ NS_LOG_INFO ("IMSI " << m_imsi << " NAS " << ToString (oldState) << " --> " << ToString (newState));
+ m_stateTransitionCallback (oldState, newState);
+
+ // actions to be done when entering a new state:
+ switch (m_state)
+ {
+ case ACTIVE:
+ for (std::list<BearerToBeActivated>::iterator it = m_bearersToBeActivatedList.begin ();
+ it != m_bearersToBeActivatedList.end ();
+ m_bearersToBeActivatedList.erase (it++))
+ {
+ DoActivateEpsBearer (it->bearer, it->tft);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
} // namespace ns3