First steps in CCNx packet coding. ccnx_encode* routines rewritten in NS3 style (using NS3::Buffer)

diff --git a/in-progress/ccnx-pit.h b/in-progress/ccnx-pit.h
new file mode 100644
index 0000000..83fad09
--- /dev/null
+++ b/in-progress/ccnx-pit.h
@@ -0,0 +1,276 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+//
+// Copyright (c) 2010,2011 UCLA
+//
+// 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: 
+//
+
+#ifndef CCNX_PIT_H
+#define	CCNX_PIT_H
+
+#include "ns3/nstime.h"
+#include "hash-helper.h"
+#include <list>
+
+namespace ns3 {
+
+class Ccnx;
+class PitEntry;
+class PitIncomingInterest;
+typedef pair<PitEntry*,PitIncomingInterest*> PitExpirationEntry;
+typedef list<PitExpirationEntry>::iterator PitExpirationIterator;
+
+struct PitIncomingInterest
+{
+  int interfaceIndex;     // interface index of the incoming Interest
+  Time expireTime;        // life time of the incoming Interest
+  int nonce;				// nonce of the last received incoming Interest on this interface
+
+  PitExpirationIterator expirationPosition;
+
+public:
+PitIncomingInterest( int _interface, clocktype _expire, int _nonce )
+: interfaceIndex(_interface)
+, expireTime(_expire)
+	, nonce(_nonce)
+  { };
+
+  bool operator==( const PitIncomingInterest &dst ) { return interfaceIndex==dst.interfaceIndex; }
+  bool operator==( int interface ) { return interfaceIndex==interface; }
+};
+
+struct PitOutgoingInterest
+{
+  int interfaceIndex;
+  clocktype sendTime;     //time when the first outgoing interest is sent
+  int retxNum;            //number of retransmission
+  int nonce;              //nonce of the outgoing Interest
+  bool outstanding;		//flag to indicate that this interest is currently pending
+  bool waitingInVain;		//when flag is set, we do not expect data for this interest, only a small hope that it will happen
+	
+public:
+PitOutgoingInterest( int interface, clocktype time, int nonce )
+: interfaceIndex(interface)
+, sendTime( time )
+	, retxNum( 0 )
+	, nonce( nonce )
+	, outstanding( true )
+	, waitingInVain( false )
+  { };
+
+  bool operator==( const PitIncomingInterest &dst ) { return interfaceIndex==dst.interfaceIndex; }
+  bool operator==( int interface ) { return interfaceIndex==interface; }
+};
+
+
+//structure for PIT entry
+struct PitEntry
+{
+  string contentName;
+  list<PitIncomingInterest> incomingInterests;
+  list<PitOutgoingInterest> outgoingInterests;
+	
+  bool timerExpired;      
+  int  counterExpirations; //whether timer is expired (+ number of times timer expired)
+
+  /**
+   * This variable provides a list of interfaces that will be tried to propagate interest
+   *
+   * It should be initialized with all available interfaces upon reception of first or
+   * any retransmitted (i.e., after STO expired), but not duplicate interests
+   *  
+   * Reaction to duplicate interests depends on strategy. 
+   * 
+   * In case of flooding, this variable should always be empty (it is filled initially with
+   * all avaialble interfaces and then immediately emptied by interest flooding)
+   * 
+   * In case of routing strategies, this list will guide (and limit) the local recovery process
+   */
+  list<int> availableInterfaces;
+
+  Message *timerMsg;      //the timer message, used to cancel message if data is received
+
+  // Changing PIT removal policy. From now on it will be deleted only when all outgoing
+  // interests are satisfied
+  //
+  //	bool dontDeleteOnFirstData;	//don't delete when first data packet comes 
+  //								//(PIT will be deleted only upon timeout or reception data
+  //								//packets or prunes for all outgoing interests)
+
+public:
+PitEntry()
+: timerExpired( false )
+, counterExpirations( 0 )
+	, timerMsg( NULL )
+  { }
+	
+  inline void fillAvailableInterfacesFromFIB( const FibEntry &fe );
+
+  // Find best candidate, skipping `skip' first candidates (modulo availableInterfaces.size())
+  // !!! assert( availableInterfaces.size()>0 ) !!!
+  inline int findBestCandidate( int skip = 0 );
+	
+  // Get number of outgoing interests that we're expecting data from
+  inline size_t numberOfPromisingInterests( ) const; 
+};
+
+typedef string_key_hash_t<PitEntry>::point_iterator PitIterator;
+typedef string_key_hash_t<PitEntry>::iterator PitRangeIterator;
+
+typedef list<PitIncomingInterest>::iterator PitIncomingIterator;
+typedef list<PitOutgoingInterest>::iterator PitOutgoingIterator;
+typedef list<PitOutgoingInterest>::const_iterator PitOutgoingConstIterator;
+
+typedef map<int,int> PitCounter;
+typedef map<int,int>::iterator PitCounterIterator;
+
+typedef map<int,double> PitBucket;
+typedef map<int,double>::iterator PitBucketIterator;
+
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+// class implementing Pending Interests Table
+class CcnxPit
+{
+ public:
+  /**
+   * PIT constructor
+   */
+  CcnxPit( Ccnx &node );
+  virtual ~CcnxPit( );
+
+  //Find corresponding PIT entry for the given content name
+  PitIterator lookup( const string &prefix );
+  bool isValid( const PitIterator &it ) { return it!=_pit.end(); }
+
+  inline PitIncomingIterator findIncoming( PitEntry &pe, int interfaceIndex );
+  inline bool isValid( PitEntry &pe, PitIncomingIterator it );
+  inline PitOutgoingIterator findOutgoing( PitEntry &pe, int interfaceIndex );
+  inline bool isValid( PitEntry &pe, PitOutgoingIterator it );
+
+  // Add a new PIT entry and a correspondent new incoming interest
+  bool add( const string &contentName, const PitIncomingInterest &interest );
+
+  // Add a new outgoing interest
+  int  add( PitEntry &pe, const PitOutgoingInterest &interest );
+
+  // remove a PIT entry
+  void erase( const string &contentName );
+	
+  //	inline bool InterestAlreadyForwarded( PitEntry &pe, int interfaceIndex );
+
+  // Remove expired records from PIT
+  void cleanExpired( clocktype time );
+
+  // Dump content store entries
+  void dump( );
+
+  // Reset pending state in outgoing interests
+  void resetPendingState( PitEntry &pe );
+
+  //	// Check if there are any interfaces that we haven't sent data to yet
+  //	bool areFreeInterfaces( PitEntry &pe, int interface );
+
+  // Periodically generate pre-calculated number of tokens (leak buckets)
+  void leakBuckets( );
+	
+  // Selectively leak a bucket
+  void leakBucket( int interface, int amount );
+
+  // Delete incoming interest for the interface
+  bool deleteIncomingInterest( PitEntry &pe, int interfaceIndex );
+
+  // Remove all incoming interests
+  void deleteAllIncomingInterests( PitEntry &pe );
+	
+ public:
+  PitBucket				 maxBucketsPerInterface; // maximum number of buckets. Automatically computed based on link capacity
+  // averaging over 1 second (bandwidth * 1second)
+  PitBucket				 leakSize;				 // size of a periodic bucket leak
+	
+ private:
+  bool add( PitEntry &pe, const PitIncomingInterest &interest );
+  void deleteIncomingInterest( PitEntry &pe, PitIncomingIterator it );
+
+ private:
+  Ccnx &_node;
+
+  string_key_hash_t<PitEntry> _pit;
+
+  list<PitExpirationEntry> _pitExpirationList;  //list of incoming Interests sorted by expiration time
+
+  PitBucket				 _bucketsPerInterface;	// pending interface counter per interface
+	
+  QNThreadMutex			 _pitMutex; // just to make sure
+};
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+PitIncomingIterator CcnxPit::findIncoming( PitEntry &pe, int interfaceIndex )
+{
+  return find( pe.incomingInterests.begin( ),
+			   pe.incomingInterests.end( ),
+			   interfaceIndex );
+}
+
+PitOutgoingIterator CcnxPit::findOutgoing( PitEntry &pe, int interfaceIndex )
+{
+  return find( pe.outgoingInterests.begin( ),
+			   pe.outgoingInterests.end( ),
+			   interfaceIndex );
+}
+
+bool CcnxPit::isValid( PitEntry &pe, PitIncomingIterator it )
+{
+  return it!=pe.incomingInterests.end( );
+}
+
+bool CcnxPit::isValid( PitEntry &pe, PitOutgoingIterator it )
+{
+  return it!=pe.outgoingInterests.end( );
+}
+
+int PitEntry::findBestCandidate( int skip/* = 0*/ )
+{
+  assert( availableInterfaces.size()>0 );
+
+  skip = skip % availableInterfaces.size();
+  list<int>::iterator candidate = availableInterfaces.begin( );
+  while( skip>0 /* && candidate!=availableInterfaces.end() */ ) { skip--; candidate++; }
+
+  return *candidate;
+}
+
+size_t PitEntry::numberOfPromisingInterests( ) const
+{
+  size_t count = 0;
+	
+  for( PitOutgoingConstIterator i = outgoingInterests.begin();
+	   i!=outgoingInterests.end();
+	   i++ )
+	{
+	  if( !i->waitingInVain ) count++;
+	}
+
+  return count;
+}
+
+} // namespace ns3
+
+#endif	/* CCNX_PIT_H */