src/lte/model/lte-ue-mac.cc
changeset 7886 b65c16d4da83
child 7887 78911c978517
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-ue-mac.cc	Thu Mar 10 18:15:26 2011 +0100
@@ -0,0 +1,347 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 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
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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>
+ * Author: Marco Miozzo <mmiozzo@cttc.es>
+ */
+
+
+
+#include <ns3/log.h>
+#include <ns3/pointer.h>
+#include <ns3/packet.h>
+#include <ns3/packet-burst.h>
+
+#include "lte-ue-mac.h"
+#include "ue-net-device.h"
+#include "lte-mac-tag.h"
+#include <ns3/ff-mac-common.h>
+#include <ns3/ideal-control-messages.h>
+
+
+NS_LOG_COMPONENT_DEFINE ("LteUeMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (LteUeMac);
+
+
+
+int BufferSizeLevelBsr[64] = {
+
+  0, 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146,
+  171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132, 1326, 1552,
+  1817, 2127, 2490, 2915, 3413, 3995, 4677, 5476, 6411, 7505, 8787, 10287,
+  12043, 14099, 16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759, 58255,
+  68201, 79846, 93749, 109439, 128125, 150000, 150000
+
+};
+
+
+///////////////////////////////////////////////////////////
+// SAP forwarders
+///////////////////////////////////////////////////////////
+
+
+class UeMemberLteUeCmacSapProvider : public LteUeCmacSapProvider
+{
+public:
+  UeMemberLteUeCmacSapProvider (LteUeMac* mac);
+
+  // inherited from LteUeCmacSapProvider
+  virtual void ConfigureUe (uint16_t rnti);
+  virtual void AddLc (uint8_t lcId, LteMacSapUser* msu);
+  virtual void RemoveLc (uint8_t lcId);
+
+private:
+  LteUeMac* m_mac;
+};
+
+
+UeMemberLteUeCmacSapProvider::UeMemberLteUeCmacSapProvider (LteUeMac* mac)
+  : m_mac (mac)
+{
+}
+
+void
+UeMemberLteUeCmacSapProvider::ConfigureUe (uint16_t rnti)
+{
+  m_mac->DoConfigureUe (rnti);
+}
+
+void
+UeMemberLteUeCmacSapProvider::AddLc (uint8_t lcId, LteMacSapUser* msu)
+{
+  m_mac->DoAddLc (lcId, msu);
+}
+
+void
+UeMemberLteUeCmacSapProvider::RemoveLc (uint8_t lcid)
+{
+  m_mac->DoRemoveLc (lcid);
+}
+
+
+
+class UeMemberLteMacSapProvider : public LteMacSapProvider
+{
+public:
+  UeMemberLteMacSapProvider (LteUeMac* mac);
+
+  // inherited from LteMacSapProvider
+  virtual void TransmitPdu (TransmitPduParameters params);
+  virtual void ReportBufferStatus (ReportBufferStatusParameters params);
+
+private:
+  LteUeMac* m_mac;
+};
+
+
+UeMemberLteMacSapProvider::UeMemberLteMacSapProvider (LteUeMac* mac)
+  : m_mac (mac)
+{
+}
+
+void
+UeMemberLteMacSapProvider::TransmitPdu (TransmitPduParameters params)
+{
+  m_mac->DoTransmitPdu (params);
+}
+
+
+void
+UeMemberLteMacSapProvider::ReportBufferStatus (ReportBufferStatusParameters params)
+{
+  m_mac->DoReportBufferStatus (params);
+}
+
+
+
+
+class UeMemberUeLtePhySapUser : public LteUePhySapUser
+{
+public:
+  UeMemberUeLtePhySapUser (LteUeMac* mac);
+
+  // inherited from LtePhySapUser
+  virtual void ReceivePhyPdu (Ptr<Packet> p);
+  virtual void SubframeIndication (uint32_t frameNo, uint32_t subframeNo);
+  virtual void ReceiveIdealControlMessage (Ptr<IdealControlMessage> msg);
+
+private:
+  LteUeMac* m_mac;
+};
+
+UeMemberUeLtePhySapUser::UeMemberUeLtePhySapUser (LteUeMac* mac) : m_mac (mac)
+{
+
+}
+
+void
+UeMemberUeLtePhySapUser::ReceivePhyPdu (Ptr<Packet> p)
+{
+  m_mac->DoReceivePhyPdu (p);
+}
+
+
+void
+UeMemberUeLtePhySapUser::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
+{
+  NS_LOG_LOGIC (this << " UE-MAC does not yet support this primitive");
+}
+
+void
+UeMemberUeLtePhySapUser::ReceiveIdealControlMessage (Ptr<IdealControlMessage> msg)
+{
+  m_mac->DoReceiveIdealControlMessage (msg);
+}
+
+
+
+
+//////////////////////////////////////////////////////////
+// LteUeMac methods
+///////////////////////////////////////////////////////////
+
+
+TypeId
+LteUeMac::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::LteUeMac")
+    .SetParent<Object> ()
+    .AddConstructor<LteUeMac> ();
+  return tid;
+}
+
+
+LteUeMac::LteUeMac ()
+{
+  m_macSapProvider = new UeMemberLteMacSapProvider (this);
+  m_cmacSapProvider = new UeMemberLteUeCmacSapProvider (this);
+  m_uePhySapUser = new UeMemberUeLtePhySapUser (this);
+}
+
+
+LteUeMac::~LteUeMac ()
+{
+}
+
+void
+LteUeMac::DoDispose ()
+{
+  delete m_macSapProvider;
+  delete m_cmacSapProvider;
+  Object::DoDispose ();
+}
+
+
+LteUePhySapUser*
+LteUeMac::GetLteUePhySapUser (void)
+{
+  return m_uePhySapUser;
+}
+
+void
+LteUeMac::SetLteUePhySapProvider (LteUePhySapProvider* s)
+{
+  m_uePhySapProvider = s;
+}
+
+
+LteMacSapProvider*
+LteUeMac::GetLteMacSapProvider (void)
+{
+  return m_macSapProvider;
+}
+
+void
+LteUeMac::SetLteUeCmacSapUser (LteUeCmacSapUser* s)
+{
+  m_cmacSapUser = s;
+}
+
+LteUeCmacSapProvider*
+LteUeMac::GetLteUeCmacSapProvider (void)
+{
+  return m_cmacSapProvider;
+}
+
+
+void
+LteUeMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT_MSG (m_rnti == params.rnti, "RNTI mismatch between RLC and MAC");
+  LteMacTag tag (params.rnti, params.lcid);
+  params.pdu->AddPacketTag (tag);
+//   Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
+//   pb->AddPacket (params.pdu);
+  m_uePhySapProvider->SendMacPdu (params.pdu);
+  // Uplink not implemented yet, so we wait can wait for the PHY SAP
+  // to be defined before we implement the transmission method.
+}
+
+void
+LteUeMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params)
+{
+  NS_LOG_FUNCTION (this);
+  MacCeListElement_s bsr;
+  bsr.m_rnti = m_rnti;
+  bsr.m_macCeType = MacCeListElement_s::BSR;
+  // short BSR
+  int queue = params.txQueueSize;
+  int index = 0;
+  if (BufferSizeLevelBsr[63] < queue)
+    {
+      index = 63;
+    }
+  else
+    {
+      while (BufferSizeLevelBsr[index] < queue)
+        {
+          index++;
+        }
+    }
+  bsr.m_macCeValue.m_bufferStatus.push_back (index);
+
+  // create the feedback to eNB
+  Ptr<BsrIdealControlMessage> msg = Create<BsrIdealControlMessage> ();
+  msg->SetBsr (bsr);
+  m_uePhySapProvider->SendIdealControlMessage (msg);
+
+}
+
+void
+LteUeMac::DoConfigureUe (uint16_t rnti)
+{
+  NS_LOG_FUNCTION (this << " rnti" << rnti);
+  m_rnti = rnti;
+}
+
+void
+LteUeMac::DoAddLc (uint8_t lcId, LteMacSapUser* msu)
+{
+  NS_LOG_FUNCTION (this << " lcId" << lcId);
+  NS_ASSERT_MSG (m_macSapUserMap.find (lcId) == m_macSapUserMap.end (), "cannot add channel because LCID " << lcId << " is already present");
+  m_macSapUserMap[lcId] = msu;
+}
+
+void
+LteUeMac::DoRemoveLc (uint8_t lcId)
+{
+  NS_LOG_FUNCTION (this << " lcId" << lcId);
+  NS_ASSERT_MSG (m_macSapUserMap.find (lcId) == m_macSapUserMap.end (), "could not find LCID " << lcId);
+  m_macSapUserMap.erase (lcId);
+}
+
+
+void
+LteUeMac::DoReceivePhyPdu (Ptr<Packet> p)
+{
+  LteMacTag tag;
+  p->RemovePacketTag (tag);
+  if (tag.GetRnti () == m_rnti)
+    {
+      // packet is for the current user
+      std::map <uint8_t, LteMacSapUser*>::const_iterator it = m_macSapUserMap.find (tag.GetLcid ());
+      NS_ASSERT_MSG (it != m_macSapUserMap.end (), "received packet with unknown lcid");
+      it->second->ReceivePdu (p);
+    }
+}
+
+
+void
+LteUeMac::DoReceiveIdealControlMessage (Ptr<IdealControlMessage> msg)
+{
+  NS_LOG_FUNCTION (this);
+  if (msg->GetMessageType () == IdealControlMessage::UL_DCI)
+    {
+      Ptr<UlDciIdealControlMessage> msg2 = DynamicCast<UlDciIdealControlMessage> (msg);
+      UlDciListElement_s dci = msg2->GetDci ();
+      std::map <uint8_t, LteMacSapUser*>::iterator it; 
+      it = m_macSapUserMap.begin ();  // use only the first LC --> UE-SCHEDULER??
+      (*it).second->NotifyTxOpportunity (dci.m_tbSize);
+      
+    }
+  else
+    {
+      NS_LOG_FUNCTION (this << " IdealControlMessage not recognized");
+    }
+}
+
+
+} // namespace ns3