/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * 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: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 *         Ilya Moiseenko <iliamo@cs.ucla.edu>
 */

#include "ccnx-l3-protocol.h"

#include "ns3/packet.h"
#include "ns3/node.h"
#include "ns3/log.h"
#include "ns3/callback.h"
#include "ns3/uinteger.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/object-vector.h"
#include "ns3/pointer.h"
#include "ns3/simulator.h"
#include "ns3/random-variable.h"

#include "ns3/ccnx-header-helper.h"
#include "ns3/ccnx-pit.h"
#include "ns3/ccnx-interest-header.h"
#include "ns3/ccnx-content-object-header.h"

#include "ns3/ccnx-face.h"
#include "ns3/ccnx-forwarding-strategy.h"

// #include "fib/ccnx-fib-impl.h"

#include "ccnx-net-device-face.h"

#include <boost/foreach.hpp>

NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");

namespace ns3 {

const uint16_t CcnxL3Protocol::ETHERNET_FRAME_TYPE = 0x7777;


NS_OBJECT_ENSURE_REGISTERED (CcnxL3Protocol);

TypeId 
CcnxL3Protocol::GetTypeId (void)
{
  static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
    .SetParent<Ccnx> ()
    .SetGroupName ("Ccnx")
    .AddConstructor<CcnxL3Protocol> ()
    .AddAttribute ("FaceList", "List of faces associated with CCNx stack",
                   ObjectVectorValue (),
                   MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
                   MakeObjectVectorChecker<CcnxFace> ())
  ;
  return tid;
}

CcnxL3Protocol::CcnxL3Protocol()
: m_faceCounter (0)
{
  NS_LOG_FUNCTION (this);
}

CcnxL3Protocol::~CcnxL3Protocol ()
{
  NS_LOG_FUNCTION (this);
}

/*
 * This method is called by AddAgregate and completes the aggregation
 * by setting the node in the ccnx stack
 */
void
CcnxL3Protocol::NotifyNewAggregate ()
{
  // not really efficient, but this will work only once
  if (m_node == 0)
    {
      m_node = GetObject<Node> ();
      if (m_node != 0)
        {
          // NS_ASSERT_MSG (m_pit != 0 && m_fib != 0 && m_contentStore != 0 && m_forwardingStrategy != 0,
          //                "PIT, FIB, and ContentStore should be aggregated before CcnxL3Protocol");
          NS_ASSERT_MSG (m_forwardingStrategy != 0,
                         "Forwarding strategy should be aggregated before CcnxL3Protocol");
        }
    }
  // if (m_pit == 0)
  //   {
  //     m_pit = GetObject<CcnxPit> ();
  //   }
  // if (m_fib == 0)
  //   {
  //     m_fib = GetObject<CcnxFib> ();
  //   }
  if (m_forwardingStrategy == 0)
    {
      m_forwardingStrategy = GetObject<CcnxForwardingStrategy> ();
    }
  // if (m_contentStore == 0)
  //   {
  //     m_contentStore = GetObject<CcnxContentStore> ();
  //   }

  Ccnx::NotifyNewAggregate ();
}

void 
CcnxL3Protocol::DoDispose (void)
{
  NS_LOG_FUNCTION (this);

  for (CcnxFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
    {
      *i = 0;
    }
  m_faces.clear ();
  m_node = 0;

  // Force delete on objects
  m_forwardingStrategy = 0; // there is a reference to PIT stored in here

  Ccnx::DoDispose ();
}

uint32_t 
CcnxL3Protocol::AddFace (const Ptr<CcnxFace> &face)
{
  NS_LOG_FUNCTION (this << &face);

  face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes

  // ask face to register in lower-layer stack
  face->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::Receive, this));

  m_faces.push_back (face);
  m_faceCounter++;
  return face->GetId ();
}

void
CcnxL3Protocol::RemoveFace (Ptr<CcnxFace> face)
{
  // ask face to register in lower-layer stack
  face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
  Ptr<CcnxPit> pit = GetObject<CcnxPit> ();

  // just to be on a safe side. Do the process in two steps
  std::list< Ptr<CcnxPitEntry> > entriesToRemoves;
  for (Ptr<CcnxPitEntry> pitEntry = pit->Begin (); pitEntry != 0; pitEntry = pit->Next (pitEntry))
    {
      pitEntry->RemoveAllReferencesToFace (face);
      
      // If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
      // Thus, we have to remove the whole PIT entry
      if (pitEntry->GetFibEntry ()->m_faces.size () == 1 &&
          pitEntry->GetFibEntry ()->m_faces.begin ()->m_face == face)
        {
          entriesToRemoves.push_back (pitEntry);
        }
    }
  BOOST_FOREACH (Ptr<CcnxPitEntry> removedEntry, entriesToRemoves)
    {
      pit->MarkErased (removedEntry);
    }

  CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
  NS_ASSERT_MSG (face_it != m_faces.end (), "Attempt to remove face that doesn't exist");
  m_faces.erase (face_it);
}

Ptr<CcnxFace>
CcnxL3Protocol::GetFace (uint32_t index) const
{
  BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
    {
      if (face->GetId () == index)
        return face;
    }
  return 0;
}

Ptr<CcnxFace>
CcnxL3Protocol::GetFaceByNetDevice (Ptr<NetDevice> netDevice) const
{
  BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
    {
      Ptr<CcnxNetDeviceFace> netDeviceFace = DynamicCast<CcnxNetDeviceFace> (face);
      if (netDeviceFace == 0) continue;

      if (netDeviceFace->GetNetDevice () == netDevice)
        return face;
    }
  return 0;
}

uint32_t 
CcnxL3Protocol::GetNFaces (void) const
{
  return m_faces.size ();
}

// Callback from lower layer
void 
CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
{
  if (!face->IsUp ())
    return;

  NS_LOG_DEBUG (*p);
  
  NS_LOG_LOGIC ("Packet from face " << *face << " received on node " <<  m_node->GetId ());

  Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
  try
    {
      CcnxHeaderHelper::Type type = CcnxHeaderHelper::GetCcnxHeaderType (p);
      switch (type)
        {
        case CcnxHeaderHelper::INTEREST:
          {
            Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();

            // Deserialization. Exception may be thrown
            packet->RemoveHeader (*header);
            NS_ASSERT_MSG (packet->GetSize () == 0, "Payload of Interests should be zero");

            m_forwardingStrategy->OnInterest (face, header, p/*original packet*/);
            // if (header->GetNack () > 0)
            //   OnNack (face, header, p/*original packet*/);
            // else
            //   OnInterest (face, header, p/*original packet*/);  
            break;
          }
        case CcnxHeaderHelper::CONTENT_OBJECT:
          {
            Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
            
            static CcnxContentObjectTail contentObjectTrailer; //there is no data in this object

            // Deserialization. Exception may be thrown
            packet->RemoveHeader (*header);
            packet->RemoveTrailer (contentObjectTrailer);

            m_forwardingStrategy->OnData (face, header, packet/*payload*/, p/*original packet*/);  
            break;
          }
        }
      
      // exception will be thrown if packet is not recognized
    }
  catch (CcnxUnknownHeaderException)
    {
      NS_ASSERT_MSG (false, "Unknown CCNx header. Should not happen");
      NS_LOG_ERROR ("Unknown CCNx header. Should not happen");
      return;
    }
}

// void
// CcnxL3Protocol::OnNack (const Ptr<CcnxFace> &incomingFace,
//                         Ptr<CcnxInterestHeader> &header,
//                         const Ptr<const Packet> &packet)
// {
//   NS_LOG_FUNCTION (incomingFace << header << packet);
//   m_inNacks (header, incomingFace);

//   Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
//   if (pitEntry == 0)
//     {
//       // somebody is doing something bad
//       m_dropNacks (header, NON_DUPLICATED, incomingFace);
//       return;
//     }
  
//   // CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry->GetIncoming ().find (incomingFace);
//   CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry->GetOutgoing ().find (incomingFace);

//   if (outFace == pitEntry->GetOutgoing ().end ())
//     {
// //      NS_ASSERT_MSG (false,
// //                     "Node " << GetObject<Node> ()->GetId () << ", outgoing entry should exist for face " << boost::cref(*incomingFace) << "\n" <<
// //                     "size: " << pitEntry.GetOutgoing ().size ());
      
//       // m_dropNacks (header, NON_DUPLICATE, incomingFace);
//       return;
//     }

//   // This was done in error. Never, never do anything, except normal leakage. This way we ensure that we will not have losses,
//   // at least when there is only one client
//   //
//   // incomingFace->LeakBucketByOnePacket ();

//   NS_LOG_ERROR ("Nack on " << boost::cref(*incomingFace));
  
//   pitEntry->SetWaitingInVain (outFace);

//   // If NACK is NACK_GIVEUP_PIT, then neighbor gave up trying to and removed it's PIT entry.
//   // So, if we had an incoming entry to this neighbor, then we can remove it now

//   if (header->GetNack () == CcnxInterestHeader::NACK_GIVEUP_PIT)
//     {
//       pitEntry->RemoveIncoming (incomingFace);
//     }

//   pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW);
//   // StaticCast<CcnxFibImpl> (m_fib)->modify (pitEntry->GetFibEntry (),
//   //                                           ll::bind (&CcnxFibEntry::UpdateStatus,
//   //                                                     ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));

//   if (pitEntry->GetIncoming ().size () == 0) // interest was actually satisfied
//     {
//       // no need to do anything
//       m_dropNacks (header, AFTER_SATISFIED, incomingFace);
//       return;
//     }

//   if (!pitEntry->AreAllOutgoingInVain ()) // not all ougtoing are in vain
//     {
//       NS_LOG_DEBUG ("Not all outgoing are in vain");
//       // suppress
//       // Don't do anything, we are still expecting data from some other face
//       m_dropNacks (header, SUPPRESSED, incomingFace);
//       return;
//     }
  
//   Ptr<Packet> nonNackInterest = Create<Packet> ();
//   header->SetNack (CcnxInterestHeader::NORMAL_INTEREST);
//   nonNackInterest->AddHeader (*header);
  
//   bool propagated = m_forwardingStrategy->
//     PropagateInterest (pitEntry, incomingFace, header, nonNackInterest);

//   // // ForwardingStrategy will try its best to forward packet to at least one interface.
//   // // If no interests was propagated, then there is not other option for forwarding or
//   // // ForwardingStrategy failed to find it. 
//   if (!propagated)
//     {
//       m_dropNacks (header, NO_FACES, incomingFace); // this headers doesn't have NACK flag set
//       GiveUpInterest (pitEntry, header);
//     }
// }

// Processing Interests
//
// // !!! Key point.
// // !!! All interests should be answerred!!! Either later with data, immediately with data, or immediately with NACK
// void CcnxL3Protocol::OnInterest (const Ptr<CcnxFace> &incomingFace,
//                                  Ptr<CcnxInterestHeader> &header,
//                                  const Ptr<const Packet> &packet)
// {
//   m_inInterests (header, incomingFace);

//   Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
//   if (pitEntry == 0)
//     {
//       pitEntry = m_pit->Create (header);
//     }

//   if (pitEntry == 0)
//     {
//       // if it is still not created, then give up processing
//       m_dropInterests (header, PIT_LIMIT, incomingFace);
//       return;
//     }
  
//   bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
//   bool isDuplicated = true;
//   if (!pitEntry->IsNonceSeen (header->GetNonce ()))
//     {
//       pitEntry->AddSeenNonce (header->GetNonce ());
//       isDuplicated = false;
//     }

//   NS_LOG_FUNCTION (header->GetName () << header->GetNonce () << boost::cref (*incomingFace) << isDuplicated);

//   /////////////////////////////////////////////////////////////////////////////////////////
//   /////////////////////////////////////////////////////////////////////////////////////////
//   /////////////////////////////////////////////////////////////////////////////////////////
//   //                                                                                     //
//   // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
//   //                                                                                     //
//   /////////////////////////////////////////////////////////////////////////////////////////
//   /////////////////////////////////////////////////////////////////////////////////////////
//   /////////////////////////////////////////////////////////////////////////////////////////
  
//   // Data is not in cache
//   CcnxPitEntry::in_iterator inFace   = pitEntry->GetIncoming ().find (incomingFace);
//   CcnxPitEntry::out_iterator outFace = pitEntry->GetOutgoing ().find (incomingFace);

//   bool isRetransmitted = false;
  
//   if (inFace != pitEntry->GetIncoming ().end ())
//     {
//       // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?

//       isRetransmitted = true;
//       // this is almost definitely a retransmission. But should we trust the user on that?
//     }
//   else
//     {
//       inFace = pitEntry->AddIncoming (incomingFace);
//     }
//   //////////////////////////////////////////////////////////////////////////////////
//   //////////////////////////////////////////////////////////////////////////////////
//   //////////////////////////////////////////////////////////////////////////////////
  
//   if (isDuplicated) 
//     {
//       NS_LOG_DEBUG ("Received duplicatie interest on " << *incomingFace);
//       m_dropInterests (header, DUPLICATED, incomingFace);

//       /**
//        * This condition will handle "routing" loops and also recently satisfied interests.
//        * Every time interest is satisfied, PIT entry (with empty incoming and outgoing faces)
//        * is kept for another small chunk of time.
//        */

//       if (m_nacksEnabled)
//         {
//           NS_LOG_DEBUG ("Sending NACK_LOOP");
//           header->SetNack (CcnxInterestHeader::NACK_LOOP);
//           Ptr<Packet> nack = Create<Packet> ();
//           nack->AddHeader (*header);

//           incomingFace->Send (nack);
//           m_outNacks (header, incomingFace);
//         }
      
//       return;
//     }

//   Ptr<Packet> contentObject;
//   Ptr<const CcnxContentObjectHeader> contentObjectHeader; // used for tracing
//   Ptr<const Packet> payload; // used for tracing
//   tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
//   if (contentObject != 0)
//     {
//       NS_ASSERT (contentObjectHeader != 0);      
//       NS_LOG_LOGIC("Found in cache");

//       OnDataDelayed (contentObjectHeader, payload, contentObject);
//       return;
//     }

//   // update PIT entry lifetime
//   pitEntry->UpdateLifetime (header->GetInterestLifetime ());
  
//   if (outFace != pitEntry->GetOutgoing ().end ())
//     {
//       NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
//       // got a non-duplicate interest from the face we have sent interest to
//       // Probably, there is no point in waiting data from that face... Not sure yet

//       // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
//       // Mark interface YELLOW, but keep a small hope that data will come eventually.

//       // ?? not sure if we need to do that ?? ...
      
//       pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW);
//       // StaticCast<CcnxFibImpl> (m_fib)->modify(pitEntry->GetFibEntry (),
//       //                                          ll::bind (&CcnxFibEntry::UpdateStatus,
//       //                                                    ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
//     }
//   else
//     if (!isNew && !isRetransmitted)
//       {
//         // Suppress this interest if we're still expecting data from some other face
//         NS_LOG_DEBUG ("Suppress interests");
//         m_dropInterests (header, SUPPRESSED, incomingFace);
//         return;
//       }
  
//   /////////////////////////////////////////////////////////////////////
//   // Propagate
//   /////////////////////////////////////////////////////////////////////
  
//   bool propagated = m_forwardingStrategy->
//     PropagateInterest (pitEntry, incomingFace, header, packet);

//   if (!propagated && isRetransmitted) //give another chance if retransmitted
//     {
//       // increase max number of allowed retransmissions
//       pitEntry->IncreaseAllowedRetxCount ();

//       // try again
//       propagated = m_forwardingStrategy->
//         PropagateInterest (pitEntry, incomingFace, header, packet);
//     }
  
//   // ForwardingStrategy will try its best to forward packet to at least one interface.
//   // If no interests was propagated, then there is not other option for forwarding or
//   // ForwardingStrategy failed to find it. 
//   if (!propagated)
//     {
//       NS_LOG_DEBUG ("Not propagated");
//       m_dropInterests (header, NO_FACES, incomingFace);
//       GiveUpInterest (pitEntry, header);
//     }
// }

// void
// CcnxL3Protocol::OnDataDelayed (Ptr<const CcnxContentObjectHeader> header,
//                                Ptr<const Packet> payload,
//                                const Ptr<const Packet> &packet)
// {
//   // 1. Lookup PIT entry
//   Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
//   if (pitEntry != 0)
//     {
//       //satisfy all pending incoming Interests
//       BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->GetIncoming ())
//         {
//           incoming.m_face->Send (packet->Copy ());
//           m_outData (header, payload, false, incoming.m_face);
//           NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
          
//           // successfull forwarded data trace
//         }

//       if (pitEntry->GetIncoming ().size () > 0)
//         {
//           // All incoming interests are satisfied. Remove them
//           pitEntry->ClearIncoming ();

//           // Remove all outgoing faces
//           pitEntry->ClearOutgoing ();
          
//           // Set pruning timout on PIT entry (instead of deleting the record)
//           m_pit->MarkErased (pitEntry);
//         }
//     }
//   else
//     {
//       NS_LOG_DEBUG ("Pit entry not found (was satisfied and removed before)");
//       return; // do not process unsoliced data packets
//     }
// }

// // Processing ContentObjects
// void
// CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
//                         Ptr<CcnxContentObjectHeader> &header,
//                         Ptr<Packet> &payload,
//                         const Ptr<const Packet> &packet)
// {
    
//   NS_LOG_FUNCTION (incomingFace << header->GetName () << payload << packet);
//   m_inData (header, payload, incomingFace);
  
//   // 1. Lookup PIT entry
//   Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
//   if (pitEntry != 0)
//     {
//       // Note that with MultiIndex we need to modify entries indirectly

//       CcnxPitEntry::out_iterator out = pitEntry->GetOutgoing ().find (incomingFace);
  
//       // If we have sent interest for this data via this face, then update stats.
//       if (out != pitEntry->GetOutgoing ().end ())
//         {
//           pitEntry->GetFibEntry ()->UpdateFaceRtt (incomingFace, Simulator::Now () - out->m_sendTime);
//           // StaticCast<CcnxFibImpl> (m_fib)->modify (pitEntry->GetFibEntry (),
//           //                                          ll::bind (&CcnxFibEntry::UpdateFaceRtt,
//           //                                                    ll::_1,
//           //                                                    incomingFace,
//           //                                                    Simulator::Now () - out->m_sendTime));
//         }
//       else
//         {
//           // Unsolicited data, but we're interested in it... should we get it?
//           // Potential hole for attacks

//           if (m_cacheUnsolicitedData)
//             {
//               // Optimistically add or update entry in the content store
//               m_contentStore->Add (header, payload);
//             }
//           else
//             {
//               NS_LOG_ERROR ("Node "<< m_node->GetId() <<
//                             ". PIT entry for "<< header->GetName ()<<" is valid, "
//                             "but outgoing entry for interface "<< boost::cref(*incomingFace) <<" doesn't exist\n");
//             }
//           // ignore unsolicited data
//           return;
//         }

//       // Update metric status for the incoming interface in the corresponding FIB entry
//       pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN);
//       // StaticCast<CcnxFibImpl>(m_fib)->modify (pitEntry->GetFibEntry (),
//       //                                          ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
//       //                                                    incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
  
//       // Add or update entry in the content store
//       m_contentStore->Add (header, payload);

//       pitEntry->RemoveIncoming (incomingFace);

//       if (pitEntry->GetIncoming ().size () == 0)
//         {
//           // Set pruning timout on PIT entry (instead of deleting the record)
//           m_pit->MarkErased (pitEntry);
//         }
//       else
//         {
//           OnDataDelayed (header, payload, packet);
//         }
//     }
//   else
//     {
//       NS_LOG_DEBUG ("Pit entry not found");
//       if (m_cacheUnsolicitedData)
//         {
//           // Optimistically add or update entry in the content store
//           m_contentStore->Add (header, payload);
//         }
//       else
//         {
//           // Drop data packet if PIT entry is not found
//           // (unsolicited data packets should not "poison" content store)
      
//           //drop dulicated or not requested data packet
//           m_dropData (header, payload, UNSOLICITED, incomingFace);
//         }
//       return; // do not process unsoliced data packets
//     }
// }

// void
// CcnxL3Protocol::GiveUpInterest (Ptr<CcnxPitEntry> pitEntry,
//                                 Ptr<CcnxInterestHeader> header)
// {
//   NS_LOG_FUNCTION (this);

//   if (m_nacksEnabled)
//     {
//       Ptr<Packet> packet = Create<Packet> ();
//       header->SetNack (CcnxInterestHeader::NACK_GIVEUP_PIT);
//       packet->AddHeader (*header);

//       BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->GetIncoming ())
//         {
//           NS_LOG_DEBUG ("Send NACK for " << boost::cref (header->GetName ()) << " to " << boost::cref (*incoming.m_face));
//           incoming.m_face->Send (packet->Copy ());

//           m_outNacks (header, incoming.m_face);
//         }
  
//       // All incoming interests cannot be satisfied. Remove them
//       pitEntry->ClearIncoming ();

//       // Remove also outgoing
//       pitEntry->ClearOutgoing ();
  
//       // Set pruning timout on PIT entry (instead of deleting the record)
//       m_pit->MarkErased (pitEntry);
//     }
// }

} //namespace ns3
