landmark.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:111k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * landmark.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: landmark.cc,v 1.8 2005/08/25 18:58:12 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. // $Header: /cvsroot/nsnam/ns-2/sensor-nets/landmark.cc,v 1.8 2005/08/25 18:58:12 johnh Exp $
  46. // Author: Satish Kumar, kkumar@isi.edu
  47. #include <stdarg.h>
  48. #include <float.h>
  49. #include "landmark.h"
  50. #include <random.h>
  51. #include <cmu-trace.h>
  52. #include <address.h>
  53. static int lm_index = 0;
  54. void
  55. LMNode::copy_tag_list(compr_taglist *taglist)
  56. {
  57.   compr_taglist *tags = NULL;
  58.   compr_taglist *tag_ptr1, *tag_ptr2;
  59.   // Delete the old tag list if it exists
  60.   if(tag_list_) {
  61.     tag_ptr1 = tag_list_;
  62.     while(tag_ptr1) {
  63.       tag_ptr2 = tag_ptr1;
  64.       tag_ptr1 = tag_ptr1->next_;
  65.       delete tag_ptr2;
  66.     }
  67.     tag_list_ = NULL;
  68.   }
  69.   // Copy the specified taglist
  70.   tag_ptr1 = taglist;
  71.   while(tag_ptr1) {
  72.     if(!tag_list_) {
  73.       tag_list_ = new compr_taglist;
  74.       tag_ptr2 = tag_list_;
  75.     }
  76.     else {
  77.       tag_ptr2->next_ = new compr_taglist;
  78.       tag_ptr2 = tag_ptr2->next_;
  79.     }
  80.     tag_ptr2->obj_name_ = tag_ptr1->obj_name_;
  81.     tag_ptr1 = tag_ptr1->next_;
  82.   }
  83. }
  84. // Returns a random number between 0 and max
  85. inline double 
  86. LandmarkAgent::jitter(double max, int be_random_)
  87. {
  88.   return (be_random_ ? Random::uniform(max) : 0);
  89. }
  90. // Returns a random number between 0 and max
  91. inline double 
  92. LandmarkAgent::random_timer(double max, int be_random_)
  93. {
  94.   return (be_random_ ? rn_->uniform(max) : 0);
  95. }
  96. void
  97. LandmarkAgent::stop()
  98. {
  99.   ParentChildrenList *pcl = parent_children_list_, *tmp_pcl;
  100.   trace("Node %d: LM Agent going down at time %f",myaddr_,NOW);
  101.   // Cancel any running timers and reset relevant variables
  102.   if(promo_timer_running_) {
  103.     promo_timer_running_ = 0;
  104.     promo_timer_->cancel();
  105.   }
  106.   num_resched_ = 0;
  107.   wait_state_ = 0;
  108.   total_wait_time_ = 0;
  109.   // Reset highest level of node
  110.   highest_level_ = 0;
  111.   // Delete ParentChildrenList objects for all levels
  112.   while(pcl) {
  113.     tmp_pcl = pcl;
  114.     pcl = pcl->next_;
  115.     delete tmp_pcl;
  116.   }
  117.   parent_children_list_ = NULL;
  118.   // Indicate that node is dead so that packets will not be processed
  119.   node_dead_ = 1;
  120.   global_lm_id_ = NO_GLOBAL_LM;
  121.   global_lm_level_ = -1;
  122.   // Event id > 0 for scheduled event
  123.   if(tag_advt_event_->uid_ > 0) {
  124.     Scheduler &s = Scheduler::instance();
  125.     s.cancel(tag_advt_event_);
  126.   }
  127. }
  128. void LandmarkAgent::
  129. trace (char *fmt,...)
  130. {
  131.   va_list ap; // Define a variable ap that will refer to each argument in turn
  132.   if (!tracetarget_)
  133.     return;
  134.   // Initializes ap to first argument
  135.   va_start (ap, fmt); 
  136.   // Prints the elements in turn
  137.   vsprintf (tracetarget_->buffer (), fmt, ap); 
  138.   tracetarget_->dump ();
  139.   // Does the necessary clean-up before returning
  140.   va_end (ap); 
  141. }
  142. static class LandmarkClass:public TclClass
  143. {
  144.   public:
  145.   LandmarkClass ():TclClass ("Agent/landmark")
  146.   {
  147.   }
  148.   TclObject *create (int, const char *const *)
  149.   {
  150.     return (new LandmarkAgent ());
  151.   }
  152. } class_landmark;
  153. LandmarkAgent::LandmarkAgent (): Agent(PT_MESSAGE), promo_start_time_(0), promo_timeout_(50), promo_timeout_decr_(1), promo_timer_running_(0), seqno_(0), highest_level_(0), parent_children_list_(NULL), ll_queue(0), be_random_(1), wait_state_(0), total_wait_time_(0), debug_(1) ,qry_debug_(0)
  154.  {
  155.   promo_timer_ = new PromotionTimer(this);
  156.   //  bind_time ("promo_timeout_", "&promo_timeout_");
  157.   num_resched_ = 0;
  158.   tag_dbase_ = NULL;
  159.   node_ = NULL;
  160.   cache_ = 0; // default is to disable caching
  161.   tag_cache_ = new TagCache[MAX_CACHE_ITEMS];
  162.   num_cached_items_ = 0;
  163.   recent_demotion_msgs_ = new RecentMsgRecord[MAX_DEMOTION_RECORDS];
  164.   num_demotion_msgs_ = 0;
  165.   // default value for the update period
  166.   update_period_ = 400;
  167.   update_timeout_ = update_period_ + 4 * LM_STARTUP_JITTER;
  168.   adverts_type_ = FLOOD;  // default is to flood adverts
  169.   global_lm_ = 0; // No global LMs by default
  170.   global_lm_id_ = NO_GLOBAL_LM;
  171.   global_lm_level_ = -1;
  172.   // myaddr_ not defined at this point ... So use lm_index for init
  173.   rn_ = new RNG(RNG::RAW_SEED_SOURCE,lm_index++);;
  174.   // Throw away a bunch of initial values
  175.   for(int i = 0; i < 128; ++i) {
  176.     rn_->uniform(200);
  177.   }
  178.   node_dead_ = 0;
  179.   bind ("be_random_", &be_random_);
  180.   //  bind ("myaddr_", &myaddr_);
  181.   bind ("debug_", &debug_);
  182.   num_nbrs_ = 0;
  183.   nbrs_ = NULL;
  184.   tag_mobility_ = new TagMobilityHandler(this);
  185.   tag_mobility_event_ = new Event;
  186.   // myaddr_ not defined at this point ... So use lm_index for init
  187.   tag_rng_ = new RNG(RNG::RAW_SEED_SOURCE,lm_index++);;
  188.   // Throw away a bunch of initial values
  189.   for(int i = 0; i < 128; ++i) {
  190.     tag_rng_->uniform(200);
  191.   }
  192.   mobility_period_ = 60;
  193.   mobile_tags_ = NULL;
  194.   tag_advt_handler_ = new TagAdvtHandler(this);
  195.   tag_advt_event_ = new Event;
  196. }
  197. int
  198. LandmarkAgent::CheckDemotionMsg(nsaddr_t id, int level, int origin_time)
  199. {
  200.   int i = 0;
  201.   // If object already exists in cache, update info if necessary
  202.   for(i = 0; i < num_demotion_msgs_; ++i) {
  203.     if(recent_demotion_msgs_[i].id_ == id && recent_demotion_msgs_[i].level_ == level) {
  204.       if(recent_demotion_msgs_[i].origin_time_ >= origin_time) {
  205.         return(OLD_MESSAGE);
  206.       }
  207.       else {
  208.         recent_demotion_msgs_[i].origin_time_ = origin_time;
  209.         return(NEW_ENTRY);
  210.       }
  211.     }
  212.   }
  213.   if(num_demotion_msgs_ < MAX_DEMOTION_RECORDS) {
  214.     i = num_demotion_msgs_;
  215.     ++num_demotion_msgs_;
  216.     recent_demotion_msgs_[i].id_ = id;
  217.     recent_demotion_msgs_[i].level_ = level;
  218.     recent_demotion_msgs_[i].origin_time_ = origin_time;
  219.   }
  220.   else {
  221.     // Use LRU cache replacement
  222.     int replace_index = 0;
  223.     int least_time = recent_demotion_msgs_[replace_index].origin_time_;
  224.     for(i = 0; i < MAX_DEMOTION_RECORDS; ++i) {
  225.       if(recent_demotion_msgs_[i].origin_time_ < least_time)
  226.         replace_index = i;
  227.     }
  228.     recent_demotion_msgs_[replace_index].id_ = id;
  229.     recent_demotion_msgs_[replace_index].level_ = level;
  230.     recent_demotion_msgs_[replace_index].origin_time_ = origin_time;
  231.   }
  232.   return(NEW_ENTRY);
  233. }
  234. void
  235. ParentChildrenList::UpdateChildLMAddr(nsaddr_t id, int num_lm_addrs, int64_t *lm_addrs)
  236. {
  237.   LMNode *potl_ch = NULL;
  238.   potl_ch = pchildren_;
  239.   while(potl_ch) {
  240.     if(potl_ch->id_ == id)
  241.       break;
  242.     potl_ch = potl_ch->next_;
  243.   }
  244.   assert(potl_ch);
  245.   (potl_ch->lmaddr_)->delete_lm_addrs();
  246.   for(int i = 0; i < num_lm_addrs; ++i)
  247.     (potl_ch->lmaddr_)->add_lm_addr(lm_addrs[i]);
  248. }
  249. int
  250. ParentChildrenList::UpdatePotlParent(nsaddr_t id, nsaddr_t next_hop, int num_hops, int level, int num_children, int energy, int origin_time, int delete_flag)
  251. {
  252.   LMNode *potl_parent, *list_ptr;
  253.   double now = Scheduler::instance().clock();
  254.   // Extract seqnum and origin time
  255.   int seqnum = origin_time & 0xFFFF;
  256.   origin_time = origin_time >> 16;
  257.   
  258.   assert(num_pparent_ >= 0);
  259.   // cannot delete from an empty list!
  260.   if(delete_flag && !pparent_)
  261.     return(ENTRY_NOT_FOUND);
  262.   //  if((a_->debug_) && (a_->myaddr_ == 24)) {
  263.   //    a_->trace("Node %d: Updating Potl Parent level %d, id %d, delete_flag %d, time %f",a_->myaddr_,level_,id,delete_flag,now);
  264.   //  }
  265.   if(pparent_ == NULL) {
  266.     pparent_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
  267.     pparent_->last_upd_seqnum_ = seqnum;
  268.     parent_ = pparent_;
  269.     ++num_pparent_;
  270.     return(NEW_ENTRY);
  271.   }
  272.   
  273.   list_ptr = pparent_;
  274.   potl_parent = list_ptr;
  275.   while(list_ptr != NULL) {
  276.     if(list_ptr->id_ == id) {
  277.       // Check if this is a old message floating around in the network
  278.       if(list_ptr->last_upd_origin_time_ > origin_time || (list_ptr->last_upd_origin_time_ == origin_time && list_ptr->last_upd_seqnum_ >= seqnum)) {
  279. // Check if we got the old update on a shorter path
  280. if(list_ptr->num_hops_ > num_hops) {
  281.   list_ptr->next_hop_ = next_hop;
  282.   list_ptr->num_hops_ = num_hops;
  283.   return(OLD_ENTRY);
  284. }
  285. return(OLD_MESSAGE); 
  286.       }
  287.       if(!delete_flag) {
  288. // Make this node as parent if it's closer than current parent
  289. if(parent_->num_hops_ > num_hops + 10 || num_hops == 0) {
  290.   parent_ = list_ptr;
  291. }
  292. list_ptr->next_hop_ = next_hop;
  293. list_ptr->num_hops_ = num_hops;
  294. list_ptr->level_ = level;
  295. list_ptr->num_children_ = num_children;
  296. list_ptr->energy_ = energy;
  297. list_ptr->last_upd_origin_time_ = origin_time;
  298. list_ptr->last_upd_seqnum_ = seqnum;
  299. list_ptr->last_update_rcvd_ = Scheduler::instance().clock();
  300.       }
  301.       else { // delete the entry
  302. if(num_pparent_)
  303.   --(num_pparent_);
  304. if(pparent_ == list_ptr)
  305.   pparent_ = list_ptr->next_;
  306. else
  307.   potl_parent->next_ = list_ptr->next_;
  308. if(parent_->id_ == list_ptr->id_)
  309.   assert(parent_ == list_ptr);
  310. // No parent if potl parent list is empty
  311. if(pparent_ == NULL) {
  312.   parent_ = NULL;
  313. }
  314. else if(parent_ == list_ptr) {
  315. // Select new parent if current parent is deleted and
  316. // potl parent is not empty; closest potl parent is new parent
  317.   LMNode *tmp = pparent_;
  318.   int best_num_hops = pparent_->num_hops_;
  319.   LMNode *best_parent = pparent_;
  320.   while(tmp != NULL) {
  321.     if(tmp->num_hops_ < best_num_hops) {
  322.       best_num_hops = tmp->num_hops_;
  323.       best_parent = tmp;
  324.     }
  325.     tmp = tmp->next_;
  326.   }
  327.   parent_ = best_parent;
  328. }
  329. delete list_ptr;
  330.       }
  331.       return(OLD_ENTRY);
  332.     }
  333.     potl_parent = list_ptr;
  334.     list_ptr = list_ptr->next_;
  335.   }
  336.   if(delete_flag)
  337.     return(ENTRY_NOT_FOUND);
  338.   potl_parent->next_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
  339.   (potl_parent->next_)->last_upd_seqnum_ = seqnum;
  340.   ++num_pparent_;
  341.   // Make this node as parent if it's closer than current parent
  342.   if(parent_->num_hops_ > num_hops) {
  343.     parent_ = potl_parent->next_;
  344.   }
  345.   return(NEW_ENTRY);
  346. }
  347. int
  348. ParentChildrenList::UpdatePotlChild(nsaddr_t id, nsaddr_t next_hop, int num_hops, int level, int num_children, int energy, int origin_time, int child_flag, int delete_flag, compr_taglist *taglist)
  349. {
  350.   LMNode *potl_child, *list_ptr;
  351.   double now = Scheduler::instance().clock();
  352.   int new_child = 0;
  353.   int tags_changed = 0;
  354.   int seqnum = origin_time & 0xFFFF;
  355.   origin_time = origin_time >> 16;
  356.   //  if(a_->debug_) printf("Node %d: Number of potl children %d",a_->myaddr_,num_potl_children_);
  357.   // cannot delete from an empty list!
  358.   if(delete_flag && !pchildren_) {
  359.     return(ENTRY_NOT_FOUND);
  360.   }
  361.   assert(num_potl_children_ >= 0);
  362.   assert(num_children_ >= 0);
  363.   if(pchildren_ == NULL) {
  364.     pchildren_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
  365.     pchildren_->child_flag_ = child_flag;
  366.     pchildren_->last_upd_seqnum_ = seqnum;
  367.     if(child_flag == IS_CHILD) ++(num_children_);
  368.     if(child_flag != NOT_POTL_CHILD) ++(num_potl_children_);
  369.     ++(num_heard_);
  370.     pchildren_->copy_tag_list(taglist);
  371.     if(child_flag == IS_CHILD)
  372.       return(NEW_CHILD);
  373.     else
  374.       return(NEW_ENTRY);
  375.   }
  376.   
  377.   list_ptr = pchildren_;
  378.   potl_child = list_ptr;
  379.   while(list_ptr != NULL) {
  380.     if(list_ptr->id_ == id) {
  381.       // Check if this is a old message floating around in the network
  382.       if(list_ptr->last_upd_origin_time_ > origin_time || (list_ptr->last_upd_origin_time_ == origin_time && list_ptr->last_upd_seqnum_ >= seqnum)) {
  383. // Check if we got this update on a shorter path; If the update rcvd
  384. // on a shorter path, we need to forward this message to ensure that
  385. // this message reaches all nodes in the advertising node's vicinity
  386. if(list_ptr->num_hops_ > num_hops) {
  387.   list_ptr->next_hop_ = next_hop;
  388.   list_ptr->num_hops_ = num_hops;
  389.   return(OLD_ENTRY);
  390. }
  391. return(OLD_MESSAGE);
  392.       }
  393.       if(!delete_flag) {
  394. // Old entry but the status has changed to child or vice-versa
  395. if((list_ptr->child_flag_ == NOT_CHILD || list_ptr->child_flag_ == NOT_POTL_CHILD) && (child_flag == IS_CHILD)) {
  396.   list_ptr->child_flag_ = child_flag;
  397.   ++(num_children_);
  398.   new_child = 1;
  399. }
  400. else if((list_ptr->child_flag_ == IS_CHILD) && (child_flag == NOT_CHILD || child_flag == NOT_POTL_CHILD)) {
  401.   list_ptr->child_flag_ = child_flag;
  402.   --(num_children_);
  403. }
  404. list_ptr->next_hop_ = next_hop;
  405. list_ptr->num_hops_ = num_hops;
  406. list_ptr->level_ = level;
  407. list_ptr->num_children_ = num_children;
  408. list_ptr->energy_ = energy;
  409. list_ptr->last_upd_origin_time_ = origin_time;
  410. list_ptr->last_upd_seqnum_ = seqnum;
  411. list_ptr->last_update_rcvd_ = Scheduler::instance().clock();
  412. if(!a_->compare_tag_lists(list_ptr->tag_list_,-1,taglist,-1)) {
  413.   tags_changed = 1;
  414.   // Delete the old tag list and copy the specified taglist
  415.   list_ptr->copy_tag_list(taglist);
  416. }
  417.       }
  418.       else {
  419. if(pchildren_ == list_ptr)
  420.   pchildren_ = list_ptr->next_;
  421. else
  422.   potl_child->next_ = list_ptr->next_;
  423. if(list_ptr->child_flag_ == IS_CHILD) --num_children_;
  424. if(list_ptr->child_flag_ != NOT_POTL_CHILD) --num_potl_children_;
  425. --num_heard_;
  426. delete list_ptr;
  427.       }
  428.       if(new_child)
  429. return(NEW_CHILD);
  430.       else if(tags_changed && child_flag == IS_CHILD)
  431. return(OLD_CHILD_TAGS_CHANGED);
  432.       else
  433. return(OLD_ENTRY);
  434.     }
  435.     potl_child = list_ptr;
  436.     list_ptr = list_ptr->next_;
  437.   }
  438.   // delete flag must be FALSE if we are here
  439.   // assert(!delete_flag);
  440.   if(delete_flag) {
  441.     return(ENTRY_NOT_FOUND);
  442.   }
  443.   
  444.   potl_child->next_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
  445.   (potl_child->next_)->copy_tag_list(taglist);
  446.   (potl_child->next_)->child_flag_ = child_flag;
  447.   (potl_child->next_)->last_upd_seqnum_ = seqnum;
  448.   if(child_flag == IS_CHILD) ++(num_children_);
  449.   if(child_flag != NOT_POTL_CHILD) ++(num_potl_children_);
  450.   ++(num_heard_);
  451.   if(child_flag == IS_CHILD)
  452.     return(NEW_CHILD);
  453.   else
  454.     return(NEW_ENTRY);
  455. }
  456. void
  457. LandmarkAgent::ProcessHierUpdate(Packet *p)
  458. {
  459.   hdr_ip *iph = HDR_IP(p);
  460.   hdr_cmn *hdrc = HDR_CMN(p);
  461.   Scheduler &s = Scheduler::instance();
  462.   double now = s.clock();
  463.   int origin_time = 0;
  464.   unsigned char *walk;
  465.   nsaddr_t origin_id, parent, next_hop;
  466.   int i, level, vicinity_radius, num_hops, potl_parent_flag = FALSE;
  467.   int action, energy = 0;
  468.   nsaddr_t *potl_children;
  469.   int num_children = 0;
  470.   int num_potl_children = 0;
  471.   int num_lm_addrs = 0;
  472.   int num_advert_lm_addrs = 0;
  473.   int64_t *advert_lm_addrs = NULL;
  474.   int64_t *lm_addrs = NULL;
  475.   // Packet will have seqnum, level, vicinity radii, parent info
  476.   // and possibly potential children (if the node is at level > 0)
  477.   int num_tags = 0;
  478.   compr_taglist *adv_tags = NULL, *tag_ptr;
  479.   compr_taglist *tag_ptr1, *tag_ptr2;
  480.   Packet *newp;
  481.   //  if(now > 412.5) {
  482.   //    purify_printf("ProcessHierUpdate1, %f, %dn",now,myaddr_);
  483.   //    purify_new_leaks();
  484.   //  }
  485.   //  if(debug_)
  486.   //    trace("Node %d: Received packet from %d with ttl %d", myaddr_,iph->saddr(),iph->ttl_);
  487.   walk = p->accessdata();
  488.   // Originator of the LM advertisement and the next hop to reach originator
  489.   origin_id = iph->saddr();    
  490.   // Free and return if we are seeing our own packet again
  491.   if(origin_id == myaddr_) {
  492.     Packet::free(p);
  493.     return;
  494.   }
  495.   
  496.   // type of advertisement
  497.   action = *walk++;
  498.   num_advert_lm_addrs = *walk++;
  499.   if(num_advert_lm_addrs)
  500.     advert_lm_addrs = new int64_t[num_advert_lm_addrs];
  501.   for(int j = 0; j < num_advert_lm_addrs; ++j) {
  502.     advert_lm_addrs[j] = *walk++;
  503.     advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
  504.     advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
  505.     advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
  506.     advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
  507.     advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
  508.     advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
  509.     advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
  510.   }
  511.   
  512.   // level of the originator
  513.   level = *walk++;
  514.     //    if(num_advert_lm_addrs)
  515.     //      trace("Node 10: Rcved msg from 0, level %d, num_lm_addrs %d, advert_lm_addrs %x, time %f",level,num_advert_lm_addrs,advert_lm_addrs[0],now);
  516.   //  trace("Node %d: Processing Hierarchy Update Packet", myaddr_);
  517.   //  if((myaddr_ == 153) && (origin_id == 29)) {
  518.   //    trace("Node 153: Receiving level %d update from node 29 at time %f,action = %d",level,s.clock(),action);
  519.   //  }
  520.   // energy level of advertising node
  521.   energy = *walk++;
  522.   energy = (energy << 8) | *walk++;
  523.   energy = (energy << 8) | *walk++;
  524.   energy = (energy << 8) | *walk++;
  525.   // next hop info
  526.   next_hop = *walk++;
  527.   next_hop = (next_hop << 8) | *walk;
  528.   // Change next hop to ourselves for the outgoing packet
  529.   --walk;
  530.   (*walk++) = (myaddr_ >> 8) & 0xFF;
  531.   (*walk++) = (myaddr_) & 0xFF;
  532.   
  533.   // vicinity radius
  534.   vicinity_radius = *walk++;
  535.   vicinity_radius = (vicinity_radius << 8) | *walk++;
  536.   // number of hops away from advertising LM
  537.   num_hops = vicinity_radius - (iph->ttl_ - 1);
  538.   //  if(myaddr_ == 155)
  539.   //    trace("Node 155: Receiving level %d update from node %d at time %f,action = %d, num_hops = %d",level,origin_id,s.clock(),action,num_hops);
  540.   // origin time of advertisement
  541.   origin_time = *walk++;
  542.   origin_time = (origin_time << 8) | *walk++;
  543.   origin_time = (origin_time << 8) | *walk++;
  544.   origin_time = (origin_time << 8) | *walk++;
  545.   
  546.   //  if(debug_ && myaddr_ == 33)
  547.   //    trace("Node %d: Processing level %d pkt from %d at t=%f, origin %d, num hops %d", myaddr_,level,iph->saddr_,now,origin_time,num_hops);
  548.   // Parent of the originator
  549.   parent = *walk++;
  550.   parent = parent << 8 | *walk++;
  551.   // Number of hops has to be less than vicinity radius to ensure that atleast
  552.   // 2 level K LMs see each other if they exist
  553.   if(level > 0 && (action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT || action == UNICAST_ADVERT_CHILD || action == UNICAST_ADVERT_PARENT)) {
  554.     // Number of children
  555.     num_children = *walk++;
  556.     num_children = num_children << 8 | *walk++;
  557.     // Number of potential children
  558.     num_potl_children = *walk++;
  559.     num_potl_children = num_potl_children << 8 | *walk++;
  560.   // If level of advertising LM > 1, check if we are in potl children list.
  561.   // If so, add as potl parent to level - 1
  562.     if(num_potl_children) {
  563.       potl_children = new nsaddr_t[num_potl_children];
  564.       for(i = 0; i < num_potl_children; ++i) {
  565. potl_children[i] = *walk++;
  566. potl_children[i] = potl_children[i] << 8 | *walk++;
  567. int tmp_num_addrs = *walk++;
  568. if(potl_children[i] == myaddr_) {
  569.   potl_parent_flag = TRUE;
  570.   num_lm_addrs = tmp_num_addrs;
  571.   if(num_lm_addrs) {
  572.     lm_addrs = new int64_t[num_lm_addrs];
  573.     for(int j = 0; j < num_lm_addrs; ++j) {
  574.       lm_addrs[j] = *walk++;
  575.       lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
  576.       lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
  577.       lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
  578.       lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
  579.       lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
  580.       lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
  581.       lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
  582.     }
  583.   }
  584. }
  585. else 
  586.   walk = walk + tmp_num_addrs*8;
  587.       }
  588.     }
  589.   }
  590.   
  591.   num_tags = 0;
  592.   if(action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT || action == UNICAST_ADVERT_CHILD || action == UNICAST_ADVERT_PARENT) {
  593.     num_tags = *walk++;
  594.     num_tags = (num_tags << 8) | *walk++;
  595.   }
  596.   adv_tags = NULL;
  597.   // Store tag info only if the level of advertising LM is less than 
  598.   // our highest level; otherwise we dont need this information
  599.   if(num_tags && level < highest_level_) {
  600.     adv_tags = new compr_taglist;
  601.     tag_ptr = adv_tags;
  602.     i = 0;
  603.     while(i < num_tags) {
  604.       if(i) {
  605. tag_ptr->next_ = new compr_taglist;
  606. tag_ptr = tag_ptr->next_;
  607.       }
  608.       tag_ptr->obj_name_ = *walk++;
  609.       tag_ptr->obj_name_ = (tag_ptr->obj_name_ << 8) | *walk++;
  610.       tag_ptr->obj_name_ = (tag_ptr->obj_name_ << 8) | *walk++;
  611.       tag_ptr->obj_name_ = (tag_ptr->obj_name_ << 8) | *walk++;
  612.       ++i;
  613.       // trace("tag name: %d.%d.%d",(tag_ptr->obj_name_ >> 24) & 0xFF,(tag_ptr->obj_name_ >> 16) & 0xFF,(tag_ptr->obj_name_) & 0xFFFF);
  614.     }
  615.   }
  616.   //  if(level == 253)
  617.   //    trace("Level is 253 at time %fn",now);
  618.   ParentChildrenList **pcl1 = NULL;
  619.   ParentChildrenList **pcl2 = NULL;
  620.   int found1 = FALSE;
  621.   int found2 = FALSE;
  622.   ParentChildrenList **pcl = &parent_children_list_;
  623.   // Insert parent-child objects for levels: level-1 (if level > 0) & level + 1
  624.   while((*pcl) != NULL) {
  625.     if((*pcl)->level_ == (level-1)) {
  626.       found1 = TRUE;
  627.       pcl1 = pcl;
  628.     }
  629.     if((*pcl)->level_ == (level+1)) {
  630.       found2 = TRUE;
  631.       pcl2 = pcl;
  632.     }
  633.     pcl = &((*pcl)->next_);
  634.   }
  635.   // check if level > 0
  636.   if(!found1 && level) {
  637.     *pcl = new ParentChildrenList(level-1, this);
  638.     pcl1 = pcl;
  639.     pcl = &((*pcl)->next_);
  640.   }
  641.   if(!found2) {
  642.     *pcl = new ParentChildrenList(level+1, this);
  643.     pcl2 = pcl;
  644.     pcl = &((*pcl)->next_);
  645.   }
  646.   // If level is same as our level, we can decrease the promotion timer 
  647.   // if it's running provided we havent already heard advertisements from
  648.   // this node
  649.   int delete_flag = FALSE; // Add the child/potl parent entry
  650.   if(action == DEMOTION) delete_flag = TRUE;
  651.   int child_flag = NOT_CHILD; // Indicates whether this node is our child
  652.   if(parent == myaddr_) 
  653.     child_flag = IS_CHILD;
  654.   else if(action == GLOBAL_ADVERT && num_hops > vicinity_radius) 
  655.   // The global LM may not be a potential child for us at any level if
  656.   // it is farther away than the vicinity radius
  657.     child_flag = NOT_POTL_CHILD;
  658.   int ret_value = (*pcl2)->UpdatePotlChild(origin_id, next_hop, num_hops, level, num_children, energy, origin_time, child_flag, delete_flag,adv_tags);
  659.   // Free packet and return if we have seen this packet before
  660.   if(ret_value == OLD_MESSAGE && action != UNICAST_ADVERT_CHILD && action != UNICAST_ADVERT_PARENT) {
  661.     if(num_potl_children) delete[] potl_children;
  662.     if(num_lm_addrs) delete[] lm_addrs;
  663.     if(num_advert_lm_addrs) delete[] advert_lm_addrs;
  664.     // Free the tag list
  665.     tag_ptr1 = adv_tags;
  666.     while(tag_ptr1) {
  667.       tag_ptr2 = tag_ptr1;
  668.       tag_ptr1 = tag_ptr1->next_;
  669.       delete tag_ptr2;
  670.     }
  671.     Packet::free(p);
  672.     return;
  673.   }
  674.   
  675.   // Send hierarchy advts if tag list has changed due to new child 
  676.   // or change in the taglist of an old child
  677.   if(ret_value == NEW_CHILD || ret_value == OLD_CHILD_TAGS_CHANGED)
  678.     SendChangedTagListUpdate(0,level);
  679.   
  680.   
  681.   //  if(level == highest_level_)
  682.   //     num_resched_ = (*pcl2)->num_potl_children_ - 1;
  683.   // If promotion timer is running, decrement by constant amount
  684.   if((ret_value == NEW_ENTRY) && (level == highest_level_) && (action == PERIODIC_ADVERTS || action == UNICAST_ADVERT_CHILD || action == UNICAST_ADVERT_PARENT) && (num_hops < radius(level))) {
  685.     // Promotion timer is running but is not in wait state
  686.     if(promo_timer_running_ && !wait_state_) {
  687.       double resched_time = promo_timeout_ - (now - promo_start_time_) - promo_timeout_decr_;
  688.       if(resched_time < 0) resched_time = 0;
  689.       //      trace("Node %d: Rescheduling timer in ProcessHierUpdate, now %f, st %f, decr %f, resch %fn", myaddr_, now, promo_start_time_, promo_timeout_decr_, resched_time);
  690.       promo_timer_->resched(resched_time);
  691.     }
  692.   }
  693.   // If our parent has demoted itself, we might have to start 
  694.   // the election process again
  695.   if(action == DEMOTION) {
  696.     (*pcl1)->UpdatePotlParent(origin_id, next_hop, num_hops, level, num_children, energy, origin_time, TRUE);
  697.     if(((*pcl1)->parent_ == NULL) && (!promo_timer_running_ || (promo_timer_running_ && wait_state_)) && (highest_level_ == level-1)) {
  698.       //      if (debug_) printf("Node %d: sched timer in ProcessHierUpdaten",myaddr_);
  699.       ParentChildrenList *tmp_pcl = parent_children_list_;
  700.       while(tmp_pcl) {
  701. if(tmp_pcl->level_ == level) break;
  702. tmp_pcl = tmp_pcl->next_;
  703.       }
  704.       assert(tmp_pcl);
  705.       
  706.       num_resched_ = tmp_pcl->num_heard_ - 1;
  707.       if(num_resched_) {
  708. // Cancel any timer running in wait state
  709. if(promo_timer_running_)
  710.   promo_timer_->cancel();
  711. promo_timer_running_ = 1;
  712. wait_state_ = 0;
  713. total_wait_time_ = 0;
  714. promo_timeout_ = random_timer(double(CONST_TIMEOUT + PROMO_TIMEOUT_MULTIPLES * radius(level) + MAX_TIMEOUT/((num_resched_+1) * pow(2,highest_level_+1))), be_random_);
  715. trace("Node %d: Promotion timeout after wait period in ProcessHierUpdate: %f", myaddr_,promo_timeout_);
  716. num_resched_ = 0;
  717. promo_start_time_ = s.clock();
  718. promo_timer_->resched(promo_timeout_);
  719.       }
  720.       else if(!promo_timer_running_) {
  721. double wait_time = PERIODIC_WAIT_TIME;
  722. promo_timer_running_ = 1;
  723. wait_state_ = 1;
  724. total_wait_time_ += wait_time;
  725. trace("Node %d: Entering wait state in ProcessHierUpdate because of no parent: %f", myaddr_,now);
  726. promo_timer_->resched(wait_time);
  727.       }
  728.     }
  729.   }
  730.   // If the advertising LM is a potl parent, add to level-1 
  731.   // ParentChildrenList object
  732.   else if(potl_parent_flag) {
  733.     LMNode *old_parent = (*pcl1)->parent_;
  734.     (*pcl1)->UpdatePotlParent(origin_id, next_hop, num_hops, level, num_children, energy, origin_time, FALSE);
  735.     // If we receive this message from a parent at some level, update
  736.     // the assigned addresses
  737.     if((((*pcl1)->parent_)->id_ == origin_id) && (level-1 == highest_level_)) {
  738.       //      if(num_lm_addrs) 
  739.       // trace("Node %d: Rcvd higher level lm addr from %d at time %f",myaddr_,origin_id,now);
  740.       //      else
  741.       // trace("Node %d: Rcvd higher level lm addr msg with no addrs from %d at time %f",myaddr_,origin_id,now);
  742.       ((*pcl1)->mylmaddrs_)->delete_lm_addrs();
  743.       assign_lmaddress(lm_addrs, num_lm_addrs, (*pcl1)->level_);
  744.     }
  745.     // Check if parent has changed
  746.     int new_advert = 0;
  747.     // The first condition may arise if the old parent obj is deleted ... (?)
  748.     if((*pcl1)->parent_ == old_parent && old_parent) {
  749.       if(((*pcl1)->parent_)->id_ != old_parent->id_)
  750. new_advert = 1;
  751.     }
  752.     else if((*pcl1)->parent_ != old_parent && (*pcl1)->parent_ && old_parent) {
  753.       if(((*pcl1)->parent_)->id_ != old_parent->id_)
  754. new_advert = 1;
  755.     }
  756.     else if((*pcl1)->parent_ != old_parent)
  757.       new_advert = 1;
  758.     
  759.     // Trigger advertisement if parent has changed
  760.     if(new_advert && (level-1 <= highest_level_)) {
  761.       newp = makeUpdate((*pcl1), HIER_ADVS, PERIODIC_ADVERTS);
  762.       s.schedule(target_,newp,0);
  763.       (*pcl1)->last_update_sent_ = now;
  764.     }
  765.   // If a parent has been selected for highest_level_, cancel promotion timer
  766.   // (for promotion to highest_level_+1) if it's running
  767.     if((level == (highest_level_ + 1)) && ((*pcl1)->parent_ != NULL)) {
  768.       if(promo_timer_running_ && !wait_state_) {
  769. trace("Node %d: Promotion timer cancelled at time %f in ProcessHierUpdaten",myaddr_,s.clock());
  770. promo_timer_->cancel();
  771. total_wait_time_ = 0;
  772. wait_state_ = 1;
  773. double wait_time = PERIODIC_WAIT_TIME;
  774. total_wait_time_ += wait_time;
  775. promo_timer_->sched(wait_time);
  776.       }
  777.     }
  778.     else if(level > 0 && level == highest_level_) {
  779.       // Check if the potl parent for highest_level_-1 that we see covers our
  780.       // potential children. If so, we can demote ourselves and cancel our 
  781.       // current promotion timer
  782.       pcl = &parent_children_list_;
  783.       while((*pcl) != NULL) {
  784. if((*pcl)->level_ == level) {
  785.   break;
  786. }
  787. pcl = &((*pcl)->next_);
  788.       }
  789.       assert(*pcl);
  790.       LMNode *lm = (*pcl)->pchildren_;
  791.       int is_subset = TRUE;
  792.       if((*pcl)->num_potl_children_ > num_potl_children) {
  793. is_subset = FALSE;
  794. lm = NULL;
  795.       }
  796.       int is_element = FALSE;
  797.       while(lm) {
  798. is_element = FALSE;
  799. for(i = 0; i < num_potl_children; ++i) 
  800.   if(lm->id_ == potl_children[i] && lm->child_flag_ != NOT_POTL_CHILD) {
  801.     is_element = TRUE;
  802.     break;
  803.   }
  804. if(is_element == FALSE && lm->child_flag_ != NOT_POTL_CHILD) {
  805.   is_subset = FALSE;
  806.   break;
  807. }
  808. lm = lm->next_;
  809.       }
  810.       // Demotion process
  811.       if(is_subset == TRUE) {
  812.      --(highest_level_);
  813.      delete_flag = TRUE;
  814. if((*pcl1)->parent_)
  815.   trace("Node %d: Num potl ch %d, Node %d: Num potl ch %d, time %d",myaddr_, (*pcl)->num_potl_children_,origin_id,num_potl_children,(int)now);
  816. trace("Node %d: Parent before demotion: %d, msg from %d at time %f",myaddr_, ((*pcl1)->parent_)->id_,origin_id,now);
  817. int upd_time = (int)now;
  818. upd_time = (upd_time << 16) | ((*pcl1)->seqnum_ & 0xFFFF);
  819. ++((*pcl1)->seqnum_);
  820. (*pcl1)->UpdatePotlParent(myaddr_, 0, 0, 0, 0, 0, upd_time, delete_flag);
  821. if((*pcl1)->parent_)
  822.   trace("Node %d: Parent after demotion: %d",myaddr_, ((*pcl1)->parent_)->id_);
  823. upd_time = (int) now;
  824. upd_time = (upd_time << 16) | ((*pcl2)->seqnum_ & 0xFFFF);
  825. ++((*pcl2)->seqnum_);
  826.      (*pcl2)->UpdatePotlChild(myaddr_, 0, 0, 0, 0, 0, upd_time, IS_CHILD, delete_flag,NULL);
  827. // Send out demotion messages
  828. newp = makeUpdate(*pcl, HIER_ADVS, DEMOTION);
  829. s.schedule(target_, newp, 0);
  830.      if(promo_timer_running_ && !wait_state_) {
  831.        trace("Node %d: Promotion timer cancelled due to demotion at time %dn",myaddr_,(int)now);
  832.        promo_timer_->cancel();
  833.   total_wait_time_ = 0;
  834.   wait_state_ = 1;
  835.   double wait_time = PERIODIC_WAIT_TIME;
  836.   total_wait_time_ += wait_time;
  837.   promo_timer_->sched(wait_time);
  838.      }
  839.       }
  840.     }      
  841.   }
  842.   // If new entry, flood advertisements for level > adv LM's level
  843.   if(ret_value == NEW_ENTRY) {
  844.     ParentChildrenList *tmp_pcl = parent_children_list_;
  845.     while(tmp_pcl) {
  846.       // New nodes should have an initial wait time of atleast 0.1 seconds
  847.       if(tmp_pcl->level_ <= highest_level_ && tmp_pcl->level_ >= level && (now - tmp_pcl->last_update_sent_) > 0.1) {
  848. newp = makeUpdate(tmp_pcl, HIER_ADVS, PERIODIC_ADVERTS);
  849. s.schedule(target_,newp,0);
  850. tmp_pcl->last_update_sent_ = now;
  851.       }
  852.       tmp_pcl = tmp_pcl->next_;
  853.     }
  854.   }
  855.   if(num_potl_children) delete[] potl_children;
  856.   if(num_lm_addrs) delete[] lm_addrs;
  857.   if(num_advert_lm_addrs) delete[] advert_lm_addrs;
  858.   // Delete tag list
  859.   tag_ptr1 = adv_tags;
  860.   while(tag_ptr1) {
  861.     tag_ptr2 = tag_ptr1;
  862.     tag_ptr1 = tag_ptr1->next_;
  863.     delete tag_ptr2;
  864.   }
  865.   
  866.   // Do not forward demotion message if we have seen this message before
  867.   if(action == DEMOTION) {
  868.     //    if(myaddr_ == 30)
  869.     //      printf("Am heren");
  870.     if(CheckDemotionMsg(origin_id, level, (int)origin_time) == OLD_MESSAGE) {
  871.       Packet::free(p);
  872.       return;
  873.     }
  874.   }
  875.   // Do not forward packet if ttl is lower unless the packet is from the global
  876.   // LM in which case the packet needs to be flooded throughout the network
  877.   if(--iph->ttl_ == 0 && action != GLOBAL_ADVERT) {
  878.     //    drop(p, DROP_RTR_TTL);
  879.     Packet::free(p);
  880.     return;
  881.   }
  882.   // Do not forward if the advertisement is for this node
  883.   if((iph->daddr() >> 8) == myaddr_) {
  884.     //    trace("Node %d: Received unicast advert from %d at level %d for us at time %f",myaddr_,iph->saddr(),level,now);
  885.     Packet::free(p);
  886.     return;
  887.   }
  888.   if(action == UNICAST_ADVERT_CHILD) {
  889.     hdrc->next_hop() = get_next_hop(iph->daddr(),level);
  890.     //    if(myaddr_ == 153)
  891.     //      trace("Node %d: Received child unicast advert from %d to %d at level %d at time %f, next hop %d",myaddr_,iph->saddr(),iph->daddr(),level,now,hdrc->next_hop());
  892.   }
  893.   else if(action == UNICAST_ADVERT_PARENT) {
  894.     //    trace("Node %d: Received parent unicast advert from %d to %d at level %d at time %f",myaddr_,iph->saddr(),iph->daddr(),level,now);
  895.     hdrc->next_hop() = get_next_hop(iph->daddr(),level+2);
  896.   }
  897.   
  898.   assert(hdrc->next_hop() != NO_NEXT_HOP);
  899.   //  if(now > 412.5) {
  900.   //    purify_printf("ProcessHierUpdate2n");
  901.   //    purify_new_leaks();
  902.   //  }
  903.   // Need to send the packet down the stack
  904.   hdrc->direction() = hdr_cmn::DOWN;
  905.   
  906.   //  if(debug_) printf("Node %d: Forwarding Hierarchy Update Packet", myaddr_);
  907.   s.schedule(target_, p, 0);
  908. }
  909.   
  910. void
  911. LandmarkAgent::assign_lmaddress(int64_t *lmaddr, int num_lm_addrs, int root_level)
  912. {
  913.   ParentChildrenList *tmp_pcl, *cur_pcl = NULL, *child_pcl = NULL;
  914.   ParentChildrenList *parent_pcl = NULL;
  915.   LMNode *pchild;
  916.   int i;  
  917.   int level = root_level;
  918.   //  assert(root_level != 0);
  919.   
  920.   while(level >= 0) {
  921.     tmp_pcl = parent_children_list_;
  922.     while(tmp_pcl) {
  923.       if(tmp_pcl->level_ == level)
  924. cur_pcl = tmp_pcl;
  925.       if(tmp_pcl->level_ == (level-1))
  926. child_pcl = tmp_pcl;
  927.       if(tmp_pcl->level_ == (level+1))
  928. parent_pcl = tmp_pcl;
  929.       tmp_pcl = tmp_pcl->next_;
  930.     }
  931.     
  932.     assert(cur_pcl);
  933.     if(level) assert(child_pcl);
  934.     assert(parent_pcl);
  935.     // Update LM address at the appropriate level
  936.     if(level == root_level) {
  937.       (cur_pcl->mylmaddrs_)->delete_lm_addrs();
  938.       if(num_lm_addrs) {
  939. for(i = 0; i < num_lm_addrs; ++i) {
  940.   (cur_pcl->mylmaddrs_)->add_lm_addr(lmaddr[i]);
  941. }
  942. parent_pcl->UpdateChildLMAddr(myaddr_,num_lm_addrs,lmaddr);
  943.       }
  944.     }
  945.     
  946.     int num_addrs = 0;
  947.     int64_t *assigned_addrs = NULL;
  948.     (cur_pcl->mylmaddrs_)->get_lm_addrs(&num_addrs,&assigned_addrs);
  949.     if(num_addrs == 0) {
  950.       pchild = cur_pcl->pchildren_;
  951.       while(pchild) {
  952. if(pchild->child_flag_ == IS_CHILD) {
  953.   (pchild->lmaddr_)->delete_lm_addrs();
  954.   if(pchild->id_ == myaddr_ && level)
  955.       (child_pcl->mylmaddrs_)->delete_lm_addrs();
  956. }
  957. pchild = pchild->next_;
  958.       }
  959.     }
  960.     else if(cur_pcl->num_children_) {
  961.       // ID at a particular level starts from 1
  962.       for(i = 0; i < num_addrs; ++i) {
  963. int64_t j = 1;
  964. int64_t addr = assigned_addrs[i] + (j << ((cur_pcl->level_-1)*8));
  965. // Assign addresses to child nodes
  966. // while( j <= MAX_CHILDREN) {
  967. pchild = cur_pcl->pchildren_;
  968. assert(cur_pcl->num_children_ <= MAX_CHILDREN);
  969. while(pchild) {
  970.   if(pchild->child_flag_ == IS_CHILD) {
  971.     (pchild->lmaddr_)->delete_lm_addrs();
  972.     (pchild->lmaddr_)->add_lm_addr(addr);
  973.     if(pchild->id_ == myaddr_ && level) {
  974.       (child_pcl->mylmaddrs_)->delete_lm_addrs();
  975.       (child_pcl->mylmaddrs_)->add_lm_addr(addr);
  976.     }
  977.     ++j;
  978.     addr = assigned_addrs[i] + (j << ((cur_pcl->level_-1)*8));
  979.     //     if(j > MAX_CHILDREN) break;
  980.     assert(j <= MAX_CHILDREN);
  981.   } /* if */
  982.   pchild = pchild->next_;
  983.   //   }/* while */
  984. }
  985.       }
  986.     }
  987.     if(num_addrs) delete[] assigned_addrs;
  988.     --level;
  989.   }
  990. }
  991. void
  992. LandmarkAgent::periodic_callback(Event *e, int level)
  993. {
  994.   //  if(debug_) printf("Periodic Callback for level %d", level);
  995.   Scheduler &s = Scheduler::instance();
  996.   double now = Scheduler::instance().clock(), next_update_delay;
  997.   int energy = (int)(node_->energy());
  998.   int unicast_flag = FALSE, suppress_flag = FALSE;
  999.   Packet *newp;
  1000.   hdr_ip *iph, *new_iph;
  1001.   hdr_cmn *cmh, *new_cmh;
  1002.   int action = PERIODIC_ADVERTS, parent_changed = 0, child_changed = 0;
  1003.   int upd_time = (int) now;
  1004.   //  if(now > 412.5) {
  1005.   //    purify_printf("periodic_callback1: %f,%dn",now,myaddr_);
  1006.   //    purify_new_leaks();
  1007.   //  }
  1008.   //  if(myaddr_ == 12 && now > 402)
  1009.   //    purify_new_leaks();
  1010.   // Should always have atleast the level 0 object
  1011.   assert(parent_children_list_ != NULL); 
  1012.   ParentChildrenList *pcl = parent_children_list_;
  1013.   ParentChildrenList *cur_pcl = NULL;
  1014.   ParentChildrenList *new_pcl = NULL;
  1015.   ParentChildrenList *pcl1 = NULL;
  1016.   ParentChildrenList *pcl2 = NULL;
  1017.   // return if we have been demoted from this level
  1018.   if(highest_level_ < level) 
  1019.     return; 
  1020.   
  1021.   while(pcl != NULL) {
  1022.     new_pcl = pcl;
  1023.     if(pcl->level_ == level){
  1024.       cur_pcl = pcl;
  1025.     }
  1026.     if(pcl->level_ == (level - 1)){
  1027.       pcl1 = pcl;
  1028.     }
  1029.     if(pcl->level_ == (level + 1)){
  1030.       pcl2 = pcl;
  1031.     }
  1032.     pcl = pcl->next_;
  1033.   }
  1034.   
  1035.   assert(cur_pcl);
  1036.   if(level)
  1037.     assert(pcl1);
  1038.   // Create level+1 object if it doesnt exist
  1039.   if(!pcl2) {
  1040.     new_pcl->next_ = new ParentChildrenList(level+1, this);
  1041.     pcl2 = new_pcl->next_;
  1042.   }
  1043.   assert(pcl2);
  1044.   // Delete stale potential parent entries
  1045.   LMNode *lmnode = cur_pcl->pparent_;
  1046.   LMNode *tmp_lmnode;
  1047.   int delete_flag = TRUE;
  1048.   LMNode *old_parent = cur_pcl->parent_;
  1049.   while(lmnode) {
  1050.     // Record next entry in linked list incase the current element is deleted
  1051.     tmp_lmnode = lmnode->next_;
  1052.     if(((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_)) {
  1053.       //      if(debug_) trace("Node %d: Deleting stale entry for %d at time %d",myaddr_,lmnode->id_,(int)now);
  1054.       upd_time = (int) now;
  1055.       upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_ + 1) & 0xFFFF);
  1056.       cur_pcl->UpdatePotlParent(lmnode->id_, 0, 0, 0, 0, 0, upd_time, delete_flag);
  1057.     }
  1058.     lmnode = tmp_lmnode;
  1059.   }
  1060.   
  1061.   // The first condition may arise if the old parent obj is deleted ... (?)
  1062.   if(cur_pcl->parent_ == old_parent && old_parent) {
  1063.     if((cur_pcl->parent_)->id_ != old_parent->id_)
  1064.       parent_changed = 1;
  1065.   }
  1066.   else if(cur_pcl->parent_ != old_parent && cur_pcl->parent_ && old_parent) {
  1067.     if((cur_pcl->parent_)->id_ != old_parent->id_)
  1068.       parent_changed = 1;
  1069.   }
  1070.   else if(cur_pcl->parent_ != old_parent)
  1071.     parent_changed = 1;
  1072.   
  1073.   // Delete stale potential children entries
  1074.   lmnode = cur_pcl->pchildren_;
  1075.   delete_flag = TRUE;
  1076.   int demotion = FALSE;
  1077.   while(lmnode) {
  1078.     // Record next entry in linked list incase the current element is deleted
  1079.     tmp_lmnode = lmnode->next_;
  1080.     if((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_) {
  1081.       if(lmnode->child_flag_ == IS_CHILD)
  1082. child_changed = 1;
  1083.       assert(level && lmnode->id_ != myaddr_);
  1084.       upd_time = (int) now;
  1085.       upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_ + 1) & 0xFFFF);
  1086.       cur_pcl->UpdatePotlChild(lmnode->id_, 0, 0, 0, 0, 0, upd_time, lmnode->child_flag_, delete_flag,NULL);
  1087.     }
  1088.     lmnode = tmp_lmnode;
  1089.   }
  1090.   
  1091.   // Send updates if tag list has changed i.e., when a child has changed
  1092.   if(child_changed)
  1093.     SendChangedTagListUpdate(0,level-1);
  1094.   
  1095.   // Demote ourself if any child's energy > 30 % of our energy
  1096.   if(demotion) {
  1097.     trace("Node %d: Demotion due to lesser energy than child",myaddr_);
  1098.     highest_level_ = level - 1;
  1099.     Packet *p = makeUpdate(cur_pcl, HIER_ADVS, DEMOTION);
  1100.     s.schedule(target_, p, 0);
  1101.   }
  1102.   // Check if a parent exists after updating potl parents. If not, start
  1103.   // promotion timer.
  1104.   // A LM at level 3 is also at levels 0, 1 and 2. For each of these levels,
  1105.   // the LM designates itself as parent. At any given instant, only the 
  1106.   // level 3 (i.e., highest_level_) LM may not have a parent and may need to 
  1107.   // promote itself. But if the promotion timer is running, then the election
  1108.   // process for the next level has already begun.
  1109.   if(parent_changed && (cur_pcl->parent_ == NULL) && !demotion) {
  1110.     // Cancel any promotion timer that is running for promotion from a higher 
  1111.     // level and send out demotion messages
  1112.     if(promo_timer_running_ && level <= highest_level_) {
  1113.       wait_state_ = 0;
  1114.       total_wait_time_ = 0;
  1115.       promo_timer_running_ = 0;
  1116.       promo_timer_->cancel();
  1117.     }
  1118.     num_resched_ = pcl2->num_heard_ - 1;
  1119.     if(num_resched_) {
  1120.       promo_timer_running_ = 1;
  1121.       wait_state_ = 0;
  1122.       total_wait_time_ = 0;
  1123.       promo_timeout_ = random_timer(double(CONST_TIMEOUT + PROMO_TIMEOUT_MULTIPLES * radius(level+1) + MAX_TIMEOUT/((num_resched_+1) * pow(2,highest_level_+1))), be_random_);
  1124.       trace("Node %d: Promotion timeout after wait period in periodic_callback: %f", myaddr_,promo_timeout_);
  1125.       num_resched_ = 0;
  1126.       promo_start_time_ = s.clock();
  1127.       promo_timer_->resched(promo_timeout_);
  1128.     }
  1129.     else {
  1130.       double wait_time = PERIODIC_WAIT_TIME;
  1131.       promo_timer_running_ = 1;
  1132.       wait_state_ = 1;
  1133.       total_wait_time_ += wait_time;
  1134.       // trace("Node %d: Entering wait period in periodic_callback at time %f", myaddr_,now);
  1135.       promo_timer_->resched(wait_time);
  1136.     }
  1137.   }
  1138.   // Update ourself as potential child and parent for appropriate levels
  1139.   // in our hierarchy tables
  1140.   if(!demotion) {
  1141.     if(level) {
  1142.       upd_time = (int) now;
  1143.       upd_time = (upd_time << 16) | (pcl1->seqnum_ & 0xFFFF);
  1144.       ++(pcl1->seqnum_);
  1145.       pcl1->UpdatePotlParent(myaddr_, myaddr_, 0, level, cur_pcl->num_children_, energy, upd_time, FALSE);
  1146.     }
  1147.     upd_time = (int) now;
  1148.     upd_time = (upd_time << 16) | (pcl2->seqnum_ & 0xFFFF);
  1149.     ++(pcl2->seqnum_);
  1150.     pcl2->UpdatePotlChild(myaddr_, myaddr_, 0, level, cur_pcl->num_children_, energy, upd_time, IS_CHILD, FALSE,cur_pcl->tag_list_);
  1151.   }
  1152.   
  1153.   // Check if this is the root node. If so, set the unicast flag or suppress
  1154.   // flag when no changes occur for 3 times the update period
  1155.   // If this is a lower level node that has a parent, either suppress 
  1156.   // (for hard-state case) or unicast maintenance messages
  1157.   if(!(cur_pcl->parent_) && (total_wait_time_ >= (2*PERIODIC_WAIT_TIME)) && wait_state_) {
  1158.     if(adverts_type_ == UNICAST) {
  1159.       unicast_flag = TRUE;
  1160.     }
  1161.     else if(adverts_type_ == SUPPRESS) {
  1162.       suppress_flag = TRUE;
  1163.     }
  1164.     
  1165.     // Start assigning landmark addresses to child nodes; 
  1166.     // Shift 1, number of levels * 8 times to left for address of root node
  1167.     int64_t *lmaddr = new int64_t[1];
  1168.     lmaddr[0] = 1;
  1169.     lmaddr[0] = (lmaddr[0] << (cur_pcl->level_ * 8));
  1170.     int num_lm_addrs = 1;
  1171.     assign_lmaddress(lmaddr, num_lm_addrs, cur_pcl->level_);
  1172.     // The advertisements from the root LM need to be broadcast in the hash
  1173.     // scheme
  1174.     delete[] lmaddr;
  1175.     if(global_lm_)
  1176.       action = GLOBAL_ADVERT;
  1177.   }
  1178.   else if(cur_pcl->parent_) {
  1179.     if(adverts_type_ == UNICAST) {
  1180.       unicast_flag = TRUE;
  1181.     }
  1182.     else if(adverts_type_ == SUPPRESS) {
  1183.       suppress_flag = TRUE;
  1184.     }
  1185.   } 
  1186.   
  1187.   //  if(!demotion && (now - cur_pcl->last_update_sent_ >= cur_pcl->update_period_) && !suppress_flag) 
  1188.   if(!demotion && !suppress_flag) {
  1189.     //    trace("Node %d: Sending update at time %f",myaddr_,now);
  1190.     Packet *p = makeUpdate(cur_pcl, HIER_ADVS, action);
  1191.     unsigned char *walk;
  1192.     if(unicast_flag) {
  1193.       if(level) {
  1194. // Unicast updates to parent and children for level > 0
  1195. lmnode = cur_pcl->pchildren_;
  1196. while(lmnode) {
  1197.   if(lmnode->id_ != myaddr_) {
  1198.     newp = p->copy();
  1199.     new_iph = HDR_IP(newp);
  1200.     new_cmh = HDR_CMN(newp);
  1201.     walk = newp->accessdata();
  1202.     //    trace("Node %d: Generating unicast advert to child %d at time %f with next hop %d",myaddr_,lmnode->id_,now,lmnode->next_hop_);
  1203.     
  1204.     new_iph->daddr() = lmnode->id_ << 8;
  1205.     new_iph->dport() = ROUTER_PORT;
  1206.     new_cmh->next_hop() = lmnode->next_hop_;
  1207.     new_cmh->addr_type() = NS_AF_INET;
  1208.     if(cur_pcl->level_)
  1209.       new_cmh->size() = new_cmh->size() - 4 * (cur_pcl->num_potl_children_ - 1);
  1210.     (*walk) = (UNICAST_ADVERT_CHILD) & 0xFF;
  1211.     walk++;
  1212.     int num_addrs = (*walk);
  1213.     walk += (10 + 8*num_addrs);
  1214.     
  1215.     // Update seqnum field for each packet; Otherwise subsequent 
  1216.             // (to first) messages would be dropped by intermediate nodes
  1217.     (*walk++) = (cur_pcl->seqnum_ >> 24) & 0xFF;
  1218.     (*walk++) = (cur_pcl->seqnum_ >> 16) & 0xFF;
  1219.     (*walk++) = (cur_pcl->seqnum_ >> 8) & 0xFF;
  1220.     (*walk++) = (cur_pcl->seqnum_) & 0xFF;
  1221.     ++(cur_pcl->seqnum_);
  1222.     
  1223.     s.schedule(target_,newp,0);
  1224.   }
  1225.   lmnode = lmnode->next_;
  1226. }
  1227.       }
  1228.       if(cur_pcl->parent_) {
  1229. if((cur_pcl->parent_)->id_ != myaddr_) {
  1230.   iph = HDR_IP(p);
  1231.   cmh = HDR_CMN(p);
  1232.   walk = p->accessdata();
  1233.   
  1234.   //   trace("Node %d: Generating unicast advert to parent %d at time %f with next hop %d",myaddr_,cur_pcl->parent_->id_,now,(cur_pcl->parent_)->next_hop_);
  1235.   iph->daddr() = (cur_pcl->parent_)->id_;
  1236.   iph->dport() = ROUTER_PORT;
  1237.   cmh->next_hop() = (cur_pcl->parent_)->next_hop_;
  1238.   cmh->addr_type() = NS_AF_INET;
  1239.   cmh->size() = cmh->size() - 4 * (cur_pcl->num_potl_children_);
  1240.   
  1241.   (*walk) = (UNICAST_ADVERT_PARENT) & 0xFF;
  1242.   walk++;
  1243.   int num_addrs = (*walk);
  1244.   walk += (10 + 8*num_addrs);
  1245.   // Update seqnum field for each packet; Otherwise subsequent 
  1246.   // (to first) messages would be dropped by intermediate nodes
  1247.   (*walk++) = (cur_pcl->seqnum_ >> 24) & 0xFF;
  1248.   (*walk++) = (cur_pcl->seqnum_ >> 16) & 0xFF;
  1249.   (*walk++) = (cur_pcl->seqnum_ >> 8) & 0xFF;
  1250.   (*walk++) = (cur_pcl->seqnum_) & 0xFF;
  1251.   ++(cur_pcl->seqnum_);
  1252.   
  1253.   s.schedule(target_,p,0);
  1254. }
  1255. else 
  1256.   Packet::free(p);
  1257.       }
  1258.       else
  1259. Packet::free(p);
  1260.     }
  1261.     else {
  1262.       //      trace("Node %d: Generating update msg at time %f",myaddr_,now);
  1263.       s.schedule(target_, p, 0);
  1264.     }
  1265.     cur_pcl->last_update_sent_ = now;
  1266.   }
  1267.   // Schedule next update 
  1268.   if(cur_pcl->last_update_sent_ == now || suppress_flag)
  1269.     next_update_delay = cur_pcl->update_period_ + jitter(LM_STARTUP_JITTER, be_random_);
  1270.   else
  1271.     next_update_delay = cur_pcl->update_period_ - (now - cur_pcl->last_update_sent_) + jitter(LM_STARTUP_JITTER, be_random_);
  1272.   
  1273.   if(!demotion)
  1274.     s.schedule(cur_pcl->periodic_handler_, cur_pcl->periodic_update_event_, next_update_delay);
  1275.   //  if(now > 412.5) {
  1276.   //    purify_printf("periodic_callback2: %f,%dn",now,myaddr_);
  1277.   //    purify_new_leaks();
  1278.   //  }
  1279.   //  if(myaddr_ == 12 && now > 402)
  1280.   //    purify_new_leaks();
  1281.   // Update entries for levels greater than our highest level in our
  1282.   // highest_level_ periodic_callback event
  1283.   if(level == highest_level_) {
  1284.     cur_pcl = parent_children_list_;
  1285.     while(cur_pcl) {
  1286.       if(cur_pcl->level_ > highest_level_) {
  1287. lmnode = cur_pcl->pparent_;
  1288. delete_flag = TRUE;
  1289. while(lmnode) {
  1290.   
  1291.   // Update potential parent list
  1292.   // Record next entry in list incase current element is deleted
  1293.   tmp_lmnode = lmnode->next_;
  1294.   if(((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_)) {
  1295.     //      if(debug_) trace("Node %d: Deleting stale entry for %d at time %d",myaddr_,lmnode->id_,(int)now);
  1296.     upd_time = (int) now;
  1297.     upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_+1) & 0xFFFF);
  1298.     cur_pcl->UpdatePotlParent(lmnode->id_, 0, 0, 0, 0, 0, upd_time, delete_flag);
  1299.   }
  1300.   lmnode = tmp_lmnode;
  1301. }
  1302. // Update children list
  1303. lmnode = cur_pcl->pchildren_;
  1304. while(lmnode) {
  1305.   // Record next entry in list incase current element is deleted
  1306.   tmp_lmnode = lmnode->next_;
  1307.   if((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_) {
  1308.     upd_time = (int) now;
  1309.     upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_+1) & 0xFFFF);
  1310.     // Check if global LM entry is being deleted; Global LM at level i
  1311.     // will have entry in level i+1 pcl object
  1312.     if(cur_pcl->level_ == global_lm_level_+1 && lmnode->id_ == global_lm_id_) {
  1313.       global_lm_level_ = -1;
  1314.       global_lm_id_ = NO_GLOBAL_LM;
  1315.     }
  1316.     cur_pcl->UpdatePotlChild(lmnode->id_, 0, 0, 0, 0, 0, upd_time, lmnode->child_flag_, delete_flag,NULL);
  1317.   }
  1318.   lmnode = tmp_lmnode;
  1319. }
  1320.       }
  1321.       cur_pcl = cur_pcl->next_;
  1322.     }
  1323.   }
  1324. }
  1325. Packet *
  1326. LandmarkAgent::makeUpdate(ParentChildrenList *pcl, int pkt_type, int action)
  1327. {
  1328.   Packet *p = allocpkt();
  1329.   hdr_ip *iph = HDR_IP(p);
  1330.   hdr_cmn *hdrc = HDR_CMN(p);
  1331.   unsigned char *walk;
  1332.   compr_taglist *adv_tags = NULL;
  1333.   double now = Scheduler::instance().clock();
  1334.   int64_t *lmaddrs;
  1335.   int num_lm_addrs = 0;
  1336.   hdrc->next_hop_ = IP_BROADCAST; // need to broadcast packet
  1337.   hdrc->addr_type_ = NS_AF_INET;
  1338.   iph->daddr() = IP_BROADCAST;  // packet needs to be broadcast
  1339.   iph->dport() = ROUTER_PORT;
  1340.   iph->ttl_ = radius(pcl->level_);
  1341.   iph->saddr() = myaddr_;
  1342.   iph->sport() = ROUTER_PORT;
  1343.   if(action == GLOBAL_ADVERT)
  1344.     trace("Node %d: Generating global LM message at time %f",myaddr_,now);
  1345.   assert(pcl->num_tags_ >= 0);
  1346.   if(pkt_type == HIER_ADVS) {
  1347.     
  1348.     if(pcl->level_ == 0) {
  1349.       // A level 0 node cannot be demoted!
  1350.       assert(action != DEMOTION);
  1351.       // No children for level 0 LM
  1352.       // totally 12 bytes in packet for now; need to add our energy level later
  1353.       // each tag name is 4 bytes; 2 bytes for num_tags info
  1354.       // Landmark address; 1 byte to indicate #addrs and 8 bytes for each addr
  1355.       lmaddrs = NULL;
  1356.       num_lm_addrs = 0;
  1357.       (pcl->mylmaddrs_)->get_lm_addrs(&num_lm_addrs, &lmaddrs);
  1358.       p->allocdata(12 + (4 * pcl->num_tags_) + 2 + 4 + 1 + (8*num_lm_addrs)); 
  1359.       walk = p->accessdata();
  1360.       // Packet type; 1 byte
  1361.       (*walk++) = (action) & 0xFF;
  1362.       // Landmark address; 1 byte to indicate #addrs and 8 bytes for each addr
  1363.       (*walk++) = (num_lm_addrs) & 0xFF;
  1364.       //      if(num_lm_addrs)
  1365.       // trace("Num_lm_addrs = %d",num_lm_addrs);
  1366.       for(int i = 0; i < num_lm_addrs; ++i) {
  1367. // Landmark address of node
  1368. (*walk++) = (lmaddrs[i] >> 56) & 0xFF;
  1369. (*walk++) = (lmaddrs[i] >> 48) & 0xFF;
  1370. (*walk++) = (lmaddrs[i] >> 40) & 0xFF;
  1371. (*walk++) = (lmaddrs[i] >> 32) & 0xFF;
  1372. (*walk++) = (lmaddrs[i] >> 24) & 0xFF;
  1373. (*walk++) = (lmaddrs[i] >> 16) & 0xFF;
  1374. (*walk++) = (lmaddrs[i] >> 8) & 0xFF;
  1375. (*walk++) = (lmaddrs[i]) & 0xFF;
  1376.       }
  1377.       if(num_lm_addrs) 
  1378. delete[] lmaddrs;
  1379.       // level of LM advertisement; 1 byte
  1380.       (*walk++) = (pcl->level_) & 0xFF;
  1381.       // Our energy level; 4 bytes (just integer portion)
  1382.       int energy = (int)(node_->energy());
  1383.       (*walk++) = (energy >> 24) & 0xFF;
  1384.       (*walk++) = (energy >> 16) & 0xFF;
  1385.       (*walk++) = (energy >> 8) & 0xFF;
  1386.       (*walk++) = (energy) & 0xFF;
  1387.       // make ourselves as next hop; 2 bytes
  1388.       (*walk++) = (myaddr_ >> 8) & 0xFF;
  1389.       (*walk++) = (myaddr_) & 0xFF;
  1390.       // Vicinity size in number of hops; Carrying this information allows
  1391.       // different LMs at same level to have different vicinity radii; 2 bytes
  1392.       (*walk++) = (radius(pcl->level_) >> 8) & 0xFF;
  1393.       (*walk++) = (radius(pcl->level_)) & 0xFF;
  1394.       // Time at which packet was originated;
  1395.       // 3 bytes for integer portion of time and 1 byte for fraction
  1396.       // Note that we probably need both an origin_time and sequence number
  1397.       // field to distinguish between msgs generated at same time.
  1398.       // (origin_time required to discard old state when net dynamics present)
  1399.       int origin_time = (int)now;
  1400.       (*walk++) = (origin_time >> 8) & 0xFF;
  1401.       (*walk++) = (origin_time) & 0xFF;
  1402.       (*walk++) = (pcl->seqnum_ >> 8) & 0xFF;
  1403.       (*walk++) = (pcl->seqnum_) & 0xFF;
  1404.       ++(pcl->seqnum_);
  1405.       // Parent ID; 2 bytes
  1406.       if(pcl->parent_ == NULL) {
  1407. (*walk++) = (NO_PARENT >> 8) & 0xFF;
  1408. (*walk++) = (NO_PARENT) & 0xFF;
  1409.       }
  1410.       else {
  1411. (*walk++) = ((pcl->parent_)->id_ >> 8) & 0xFF;
  1412. (*walk++) = ((pcl->parent_)->id_) & 0xFF;
  1413.       }
  1414.       (*walk++) = (pcl->num_tags_ >> 8) & 0xFF;
  1415.       (*walk++) = (pcl->num_tags_) & 0xFF;
  1416.       if(pcl->num_tags_) {
  1417. adv_tags = pcl->tag_list_;
  1418. while(adv_tags) {
  1419.   (*walk++) = (adv_tags->obj_name_ >> 24) & 0xFF;
  1420.   (*walk++) = (adv_tags->obj_name_ >> 16) & 0xFF;
  1421.          (*walk++) = (adv_tags->obj_name_ >> 8) & 0xFF;
  1422.   (*walk++) = (adv_tags->obj_name_) & 0xFF;
  1423.   adv_tags = adv_tags->next_;
  1424. }
  1425.       }
  1426.       // In real life each of the above fields would be 
  1427.       // 4 byte integers; 20 bytes for IP addr + 2 bytes for num_children
  1428.       // 4 byte for number of tags; 4 byte for each tag name; 4 byte for energy
  1429.       hdrc->size_ = 20 + 20 + 4 + (4 * pcl->num_tags_) + 4 + 1 + (8*num_lm_addrs); 
  1430.     }
  1431.     else {
  1432.       // Need to list all the potential children LMs
  1433.       // Pkt size: 12 bytes (as before); 2 each for number of children 
  1434.       // and potl_children; 
  1435.       // 2 byte for each child's id + 8 bytes for landmark address
  1436.       // 4 bytes for each tag name; 2 bytes for num_tags info
  1437.       int pkt_size = 0;
  1438.       lmaddrs = NULL;
  1439.       num_lm_addrs = 0;
  1440.       if(action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT) {
  1441. LMNode *pch = pcl->pchildren_;
  1442. // Compute number of landmark addrs of children for pkt size calc
  1443. int size = 0;
  1444. while(pch) {
  1445.   int64_t *addrs;
  1446.   int num_addrs = 0;
  1447.   (pch->lmaddr_)->get_lm_addrs(&num_addrs,&addrs);
  1448.   if(num_addrs) delete[] addrs;
  1449.   size += (1 + num_addrs*8);
  1450.   pch = pch->next_;
  1451. }
  1452. // Compute number of landmark addrs of this node for pkt size calc
  1453. // Landmark address; 1 byte to indicate #addrs and 8 bytes for each 
  1454. // addr
  1455. (pcl->mylmaddrs_)->get_lm_addrs(&num_lm_addrs, &lmaddrs);
  1456. pkt_size = 12 + 4 + (2 * pcl->num_potl_children_) + size + (4 * pcl->num_tags_) + 2 + 4 + 1 + (8*num_lm_addrs);
  1457.       }
  1458.       else
  1459. pkt_size = 17; // Demotion message
  1460.       p->allocdata(pkt_size);
  1461.       walk = p->accessdata();
  1462.       // Packet type; 1 byte
  1463.       (*walk++) = (action) & 0xFF;
  1464.       //      if(myaddr_ == 0)
  1465.       // trace("Node 0: Generating update message for level %d at time %f, num_lm_addrs %d",pcl->level_,now,num_lm_addrs);
  1466.       // Landmark address; 1 byte to indicate #addrs and 8 bytes for each addr
  1467.       (*walk++) = (num_lm_addrs) & 0xFF;
  1468.       for(int i = 0; i < num_lm_addrs; ++i) {
  1469. // Landmark address of node
  1470. (*walk++) = (lmaddrs[i] >> 56) & 0xFF;
  1471. (*walk++) = (lmaddrs[i] >> 48) & 0xFF;
  1472. (*walk++) = (lmaddrs[i] >> 40) & 0xFF;
  1473. (*walk++) = (lmaddrs[i] >> 32) & 0xFF;
  1474. (*walk++) = (lmaddrs[i] >> 24) & 0xFF;
  1475. (*walk++) = (lmaddrs[i] >> 16) & 0xFF;
  1476. (*walk++) = (lmaddrs[i] >> 8) & 0xFF;
  1477. (*walk++) = (lmaddrs[i]) & 0xFF;
  1478.       }
  1479.       if(num_lm_addrs) 
  1480. delete[] lmaddrs;
  1481.       
  1482.       // level of LM advertisement; 1 byte
  1483.       (*walk++) = (pcl->level_) & 0xFF;
  1484.       // Our energy level; 4 bytes (just integer portion)
  1485.       int energy = (int)(node_->energy());
  1486.       (*walk++) = (energy >> 24) & 0xFF;
  1487.       (*walk++) = (energy >> 16) & 0xFF;
  1488.       (*walk++) = (energy >> 8) & 0xFF;
  1489.       (*walk++) = (energy) & 0xFF;
  1490.       // make ourselves as next hop; 2 bytes
  1491.       (*walk++) = (myaddr_ >> 8) & 0xFF;
  1492.       (*walk++) = (myaddr_) & 0xFF;
  1493.       // Vicinity size in number of hops; 2 bytes
  1494.       (*walk++) = (radius(pcl->level_) >> 8) & 0xFF;
  1495.       (*walk++) = (radius(pcl->level_)) & 0xFF;
  1496.       // Time at which packet was originated;
  1497.       // 3 bytes for integer portion of time and 1 byte for fraction
  1498.       int origin_time = (int)now;
  1499.       (*walk++) = (origin_time >> 8) & 0xFF;
  1500.       (*walk++) = (origin_time) & 0xFF;
  1501.       (*walk++) = (pcl->seqnum_ >> 8) & 0xFF;
  1502.       (*walk++) = (pcl->seqnum_) & 0xFF;
  1503.       ++(pcl->seqnum_);
  1504.       if(origin_time > now) {
  1505. printf("Node %d: id %d, level %d, vicinity_radius %d",myaddr_,myaddr_,pcl->level_,radius(pcl->level_));
  1506. assert(origin_time < now);
  1507.       }
  1508.       // Parent's id; 2 bytes
  1509.       if(pcl->parent_ == NULL) {
  1510. (*walk++) = (NO_PARENT >> 8) & 0xFF;
  1511. (*walk++) = (NO_PARENT) & 0xFF;
  1512.       }
  1513.       else {
  1514. (*walk++) = ((pcl->parent_)->id_ >> 8) & 0xFF;
  1515. (*walk++) = ((pcl->parent_)->id_) & 0xFF;
  1516.       }
  1517.       
  1518.       if(action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT) {
  1519. // Number of children; 2 bytes
  1520. (*walk++) = (pcl->num_children_ >> 8) & 0xFF;
  1521. (*walk++) = (pcl->num_children_) & 0xFF;
  1522. // Number of potential children; 2 bytes
  1523. (*walk++) = (pcl->num_potl_children_ >> 8) & 0xFF;
  1524. (*walk++) = (pcl->num_potl_children_) & 0xFF;
  1525. LMNode *potl_ch = pcl->pchildren_;
  1526. while(potl_ch) {
  1527.   if(potl_ch->child_flag_ != NOT_POTL_CHILD) {
  1528.     (*walk++) = (potl_ch->id_ >> 8) & 0xFF;
  1529.     (*walk++) = (potl_ch->id_) & 0xFF;
  1530.     int64_t *addrs = NULL;
  1531.     int num_addrs = 0;
  1532.     ((potl_ch)->lmaddr_)->get_lm_addrs(&num_addrs, &addrs);
  1533.     //     if(myaddr_ == 0 && now > 1000)
  1534.     //       trace("Node 0: Child %d, num_addrs: %d at time %f",potl_ch->id_,num_addrs,now);
  1535.     // Number of landmark addrs
  1536.     (*walk++) = (num_addrs) & 0xFF;
  1537.     for(int i = 0; i < num_addrs; ++i) {
  1538.       // Landmark address of node
  1539.       (*walk++) = (addrs[i] >> 56) & 0xFF;
  1540.       (*walk++) = (addrs[i] >> 48) & 0xFF;
  1541.       (*walk++) = (addrs[i] >> 40) & 0xFF;
  1542.       (*walk++) = (addrs[i] >> 32) & 0xFF;
  1543.       (*walk++) = (addrs[i] >> 24) & 0xFF;
  1544.       (*walk++) = (addrs[i] >> 16) & 0xFF;
  1545.       (*walk++) = (addrs[i] >> 8) & 0xFF;
  1546.       (*walk++) = (addrs[i]) & 0xFF;
  1547.     }
  1548.     if(num_addrs) 
  1549.       delete[] addrs;
  1550.   }
  1551.   potl_ch = potl_ch->next_;
  1552. }
  1553. (*walk++) = (pcl->num_tags_ >> 8) & 0xFF;
  1554. (*walk++) = (pcl->num_tags_) & 0xFF;
  1555. if(pcl->num_tags_) {
  1556.   adv_tags = pcl->tag_list_;
  1557.   while(adv_tags) {
  1558.     (*walk++) = (adv_tags->obj_name_ >> 24) & 0xFF;
  1559.     (*walk++) = (adv_tags->obj_name_ >> 16) & 0xFF;
  1560.     (*walk++) = (adv_tags->obj_name_ >> 8) & 0xFF;
  1561.     (*walk++) = (adv_tags->obj_name_) & 0xFF;
  1562.     adv_tags = adv_tags->next_;
  1563.   }
  1564. }
  1565. // 8 addl bytes for num_children and num_potl_children info; Assuming 
  1566. // worst case of 8 levels in computing packet size
  1567. // SHOULD DISABLE SENDING TAG INFO IN THE HASH SCHEME
  1568. // Landmark address; 1 byte to indicate #addrs and 8 bytes 
  1569. // for each addr
  1570. hdrc->size_ = 20 + 8 + ((4+8) * pcl->num_potl_children_) + 20 + 4 + (4 * pcl->num_tags_) + 4 + 1 + (8 * num_lm_addrs); 
  1571. // In real life each of the above fields would be
  1572. // 4 byte integers; 20 bytes for IP addr
  1573. // if(myaddr_ == 11) 
  1574. //   trace("Node 11: Packet size: %d",hdrc->size_);
  1575.       }
  1576.       else if(action == DEMOTION) {
  1577. hdrc->size_ = 20 + 20;
  1578.       }      
  1579.     }
  1580.   }
  1581.   // Optimization for reducing energy consumption; Just advertise
  1582.   // sequence number in steady state
  1583.   //  if(pcl->parent_ == NULL && action != DEMOTION) 
  1584.   //    hdrc->size_ = 20 + 4;
  1585.   // Cancel periodic_callback event if node is being demoted
  1586.   if(action == DEMOTION && pcl->periodic_update_event_->uid_)
  1587.       Scheduler::instance().cancel(pcl->periodic_update_event_);
  1588.   hdrc->direction() = hdr_cmn::DOWN;
  1589.   return p;
  1590. }
  1591. int
  1592. LandmarkAgent::radius(int level)
  1593. {
  1594.   // level i's radius >= (2 *level i-1's radius) + 1
  1595.   return((int(pow(2,level+1) + pow(2,level) - 1)));
  1596.   //  return((level + 1)*2 + 1);
  1597.   //  return(int(pow(2,level+1)) + 1);
  1598. }
  1599. ParentChildrenList::ParentChildrenList(int level, LandmarkAgent *a) : parent_(NULL), num_heard_(0), num_children_(0), num_potl_children_(0), num_pparent_(0), pchildren_(NULL), pparent_(NULL) , seqnum_(0) ,last_update_sent_(-(a->update_period_)), update_period_(a->update_period_), update_timeout_(a->update_timeout_), next_(NULL)
  1600. {
  1601.   level_ = level;
  1602.   periodic_update_event_ = new Event;
  1603.   periodic_handler_ = new LMPeriodicAdvtHandler(this);
  1604.   a_ = a;
  1605.   tag_list_ = NULL;
  1606.   num_tags_ = 0;
  1607.   adverts_type_ = FLOOD; // default is to flood adverts
  1608.   mylmaddrs_ = new LMAddrs;
  1609. }
  1610. void
  1611. PromotionTimer::expire(Event *e) {
  1612.   ParentChildrenList *pcl = a_->parent_children_list_;
  1613.   ParentChildrenList *new_pcl, *higher_level_pcl = NULL, *lower_level_pcl;
  1614.   ParentChildrenList *pcl1 = NULL; // Pointer to new highest_level_-1 object
  1615.   ParentChildrenList *pcl2 = NULL; // Pointer to new highest_level_+1 object
  1616.   ParentChildrenList *cur_pcl = NULL;
  1617.   int found = FALSE, has_parent = FALSE;
  1618.   int64_t *my_lm_addrs = NULL;
  1619.   int num_my_lm_addrs = 0;
  1620.   int num_potl_ch = 0;
  1621.   int addr_changed = 0;
  1622.   Scheduler &s = Scheduler::instance();
  1623.   double now = s.clock();
  1624.   Packet *p, *newp;
  1625.   //  if(now > 412.5) {
  1626.   //    purify_printf("expire1: %f,%dn",now,a_->myaddr_);
  1627.   //    purify_new_leaks();
  1628.   //  }
  1629.   while(pcl != NULL) {
  1630.     if(pcl->level_ == (a_->highest_level_ + 1)) {
  1631.       // Exclude ourself from the count of the lower level nodes heard
  1632.       higher_level_pcl = pcl;
  1633.       a_->num_resched_ = pcl->num_heard_ - 1;
  1634.       num_potl_ch = pcl->num_potl_children_;
  1635.     }
  1636.     else if(pcl->level_ == a_->highest_level_) {
  1637.       cur_pcl = pcl;
  1638.       if(pcl->parent_) {
  1639. has_parent = TRUE;
  1640.       }
  1641.     }
  1642.     else if(pcl->level_ == (a_->highest_level_-1)) {
  1643.       lower_level_pcl = pcl;
  1644.     }
  1645.     pcl = pcl->next_;
  1646.   }
  1647.   assert(higher_level_pcl);
  1648.   if(a_->highest_level_)
  1649.     assert(lower_level_pcl);
  1650.   assert(cur_pcl);
  1651.   if(a_->wait_state_) {
  1652.     if(a_->num_resched_ && !has_parent) {
  1653.       a_->wait_state_ = 0;
  1654.       a_->total_wait_time_ = 0;
  1655.       
  1656.       // Promotion timeout is num_resched_ times the estimated time for 
  1657.       // a message to reach other nodes in its vicinity
  1658.       // PROM0_TIMEOUT_MULTIPLE is an estimate of time for adv to reach 
  1659.       // all nodes in vicinity
  1660.       a_->promo_timeout_ = a_->random_timer(double(CONST_TIMEOUT + PROMO_TIMEOUT_MULTIPLES * a_->radius(a_->highest_level_) + MAX_TIMEOUT/((a_->num_resched_+1) * pow(2,a_->highest_level_))), a_->be_random_);
  1661.       //      a_->promo_timeout_ = a_->random_timer(double(CONST_TIMEOUT + PROMO_TIMEOUT_MULTIPLES * a_->radius(a_->highest_level_) + MAX_TIMEOUT/((a_->num_resched_+1) * pow(2,a_->highest_level_))), a_->be_random_) + (MAX_ENERGY - (a_->node_)->energy())*200/MAX_ENERGY;
  1662.       a_->trace("Node %d: Promotion timeout after wait period in expire1: %f at time %f", a_->myaddr_,a_->promo_timeout_,s.clock());
  1663.       a_->num_resched_ = 0;
  1664.       a_->promo_start_time_ = s.clock();
  1665.       a_->promo_timer_->resched(a_->promo_timeout_);
  1666.     }
  1667.     else {
  1668.       double wait_time = PERIODIC_WAIT_TIME;
  1669.       a_->total_wait_time_ += wait_time;
  1670.       //      a_->trace("Node %d: Entering wait period in expire1 at time %f, highest level %d", a_->myaddr_,now,a_->highest_level_);
  1671.       a_->promo_timer_->resched(wait_time);
  1672.       // Demote ourself we do not have any children (excluding ourself) after
  1673.       // waiting for 1.5 times the update period
  1674.       if(a_->highest_level_ && (a_->total_wait_time_ > (a_->update_period_*1.5))) {
  1675. // a_->trace("Node %d: cur_pcl's number of children %d",a_->myaddr_,cur_pcl->num_children_);
  1676. // Demote ourself from this level if we have only one children
  1677. // and we have more than one potential parent at lower level
  1678. // If we dont have more than one potl parent at lower level,
  1679. // this node will oscillate between the two levels
  1680.  if(cur_pcl->num_children_ == 1 && lower_level_pcl->num_pparent_ > 1) {
  1681.    a_->trace("Node %d: Demoting from level %d because of no children at time %f",a_->myaddr_,a_->highest_level_,s.clock());
  1682.    // Update appropriate lists
  1683.    int delete_flag = TRUE;
  1684.    int upd_time = (int) now;
  1685.    upd_time = (upd_time << 16) | (lower_level_pcl->seqnum_ & 0xFFFF);
  1686.    ++(lower_level_pcl->seqnum_);
  1687.    lower_level_pcl->UpdatePotlParent(a_->myaddr_, 0, 0, 0, 0, 0, upd_time, delete_flag);
  1688.    upd_time = (int) now;
  1689.    upd_time = (upd_time << 16) | (higher_level_pcl->seqnum_ & 0xFFFF);
  1690.    ++(higher_level_pcl->seqnum_);
  1691.    higher_level_pcl->UpdatePotlChild(a_->myaddr_, 0, 0, 0, 0, 0, upd_time, IS_CHILD, delete_flag,NULL);
  1692.    --(a_->highest_level_);
  1693.    Packet *p = a_->makeUpdate(cur_pcl, HIER_ADVS, DEMOTION);
  1694.    s.schedule(a_->target_,p,0);
  1695.  }
  1696.       }
  1697.       else if(!(cur_pcl->parent_) && (a_->total_wait_time_ >= (2*PERIODIC_WAIT_TIME))) {
  1698. // We must be the global LM
  1699. a_->global_lm_id_ = a_->myaddr_;
  1700. a_->global_lm_level_ = a_->highest_level_;
  1701. // Get LM addresses if any
  1702. (cur_pcl->mylmaddrs_)->get_lm_addrs(&num_my_lm_addrs,&my_lm_addrs);
  1703. // Start assigning landmark addresses to child nodes; 
  1704. // Shift 1, number of levels * 8 times to left for address of root node
  1705. int64_t *lmaddr = new int64_t[1];
  1706. lmaddr[0] = 1;
  1707. lmaddr[0] = (lmaddr[0] << (cur_pcl->level_ * 8));
  1708. int num_lm_addrs = 1;
  1709. assert(num_my_lm_addrs <= 1);
  1710. if(num_my_lm_addrs == 0) {
  1711.   addr_changed = 1;
  1712. }
  1713. else {
  1714.   if(my_lm_addrs[0] != lmaddr[0])
  1715.     addr_changed = 1;
  1716. }
  1717. if(num_my_lm_addrs) delete[] my_lm_addrs;
  1718. if(addr_changed) {
  1719.   a_->trace("Node %d: LM addrs being assigned by global LM at time %f, level %d",a_->myaddr_,now,a_->highest_level_);
  1720.   a_->assign_lmaddress(lmaddr, num_lm_addrs, cur_pcl->level_);
  1721.   if(a_->global_lm_)
  1722.     p = a_->makeUpdate(cur_pcl, HIER_ADVS, GLOBAL_ADVERT);
  1723.   else
  1724.     p = a_->makeUpdate(cur_pcl, HIER_ADVS, PERIODIC_ADVERTS);
  1725.   a_->trace("Node %d: Generating ReHash msg at time %f",a_->myaddr_,NOW);
  1726.   a_->GenerateReHashMsg(lmaddr[0],NOW);
  1727.   // Generate updates for LM at lower levels as well since their LM
  1728.   // addresses have also changed
  1729.   ParentChildrenList *tmp_pcl = a_->parent_children_list_;
  1730.   while(tmp_pcl) {
  1731.     if(tmp_pcl->level_ < cur_pcl->level_) {
  1732.       a_->trace("Node %d: Generating level %d update at time %f",a_->myaddr_,tmp_pcl->level_,now);
  1733.       newp = a_->makeUpdate(tmp_pcl, HIER_ADVS, PERIODIC_ADVERTS);
  1734.       s.schedule(a_->target_,newp,0);
  1735.       tmp_pcl->last_update_sent_ = now;
  1736.     }
  1737.     tmp_pcl = tmp_pcl->next_;
  1738.   }
  1739.   s.schedule(a_->target_, p, 0);
  1740.   cur_pcl->last_update_sent_ = now;
  1741. }
  1742. // The advertisements from the root LM need to be broadcast in the hash
  1743. // scheme
  1744. if(num_lm_addrs) delete[] lmaddr;
  1745.       }
  1746.     }      
  1747.     return;
  1748.   }    
  1749.   
  1750.   // Promotion timer is off
  1751.   a_->promo_timer_running_ = 0;
  1752.   // Only one promotion timer can be running at a node at a given instant. 
  1753.   // On expiry, the node will be promoted one level higher to highest_level_+1
  1754.   // Add a parentchildrenlist object for the higher level if one doesnt already
  1755.   // exist
  1756.   higher_level_pcl = NULL;
  1757.   pcl = a_->parent_children_list_;
  1758.   while(pcl != NULL) {
  1759.     new_pcl = pcl;
  1760.     if(pcl->level_ == a_->highest_level_+1){
  1761.       found = TRUE;
  1762.       higher_level_pcl = pcl;
  1763.     }
  1764.     if(pcl->level_ == (a_->highest_level_)){
  1765.       pcl1 = pcl;
  1766.     }
  1767.     if(pcl->level_ == (a_->highest_level_+2)){
  1768.       pcl2 = pcl;
  1769.     }
  1770.     pcl = pcl->next_;
  1771.   }
  1772.   
  1773.   // highest_level_-1 object should exist
  1774.   assert(pcl1);
  1775.   if(pcl1->parent_ != NULL) {
  1776.     a_->trace("Node %d: Not promoted to higher level %dn", a_->myaddr_, a_->highest_level_+1);
  1777.     return;
  1778.   }
  1779.   ++(a_->highest_level_);
  1780.   assert(a_->highest_level_ < MAX_LEVELS);
  1781.   if(!found) {
  1782.     new_pcl->next_ = new ParentChildrenList(a_->highest_level_, a_);
  1783.     higher_level_pcl = new_pcl->next_;
  1784.     new_pcl = new_pcl->next_;
  1785.   }
  1786.   // Create highest_level_+1 object if it doesnt exist
  1787.   if(!pcl2) {
  1788.     new_pcl->next_ = new ParentChildrenList((a_->highest_level_)+1, a_);
  1789.     pcl2 = new_pcl->next_;
  1790.   }
  1791.   assert(pcl2);
  1792.   if(a_->debug_) {
  1793.     a_->trace("Node %d: Promoted to level %d, num_potl_children %d at time %f", a_->myaddr_, a_->highest_level_, num_potl_ch, now);
  1794.     //    LMNode *lm = higher_level_pcl->pchildren_;
  1795.     //    a_->trace("Potential Children:");
  1796.     //    while(lm) {
  1797.     //      a_->trace("%d (level %d) Number of hops: %d", lm->id_,lm->level_,lm->num_hops_);
  1798.     //      lm = lm->next_;
  1799.     //    }
  1800.     
  1801.     //    lm = higher_level_pcl->pparent_;
  1802.     //    a_->trace("Potential Parent:");
  1803.     //    while(lm) {
  1804.     //      a_->trace("%d (level %d)", lm->id_,lm->level_);
  1805.     //      lm = lm->next_;
  1806.     //    }
  1807.   }
  1808.   // Update tag lists and send out corresponding advertisements
  1809.   a_->SendChangedTagListUpdate(0,a_->highest_level_-1);
  1810.   // start off periodic advertisements for this higher level
  1811.   s.schedule(higher_level_pcl->periodic_handler_, higher_level_pcl->periodic_update_event_, 0);
  1812.   
  1813.   // add myself as potential parent for highest_level-1 and child for 
  1814.   // highest_level+1 
  1815.   int num_hops = 0;
  1816.   int energy = (int)((a_->node_)->energy());
  1817.   int child_flag = IS_CHILD;
  1818.   int delete_flag = FALSE;
  1819.   int upd_time = (int) now;
  1820.   upd_time = (upd_time << 16) | (pcl1->seqnum_ & 0xFFFF);
  1821.   ++(pcl1->seqnum_);
  1822.   pcl1->UpdatePotlParent(a_->myaddr_, a_->myaddr_, num_hops, a_->highest_level_, higher_level_pcl->num_children_, energy, upd_time, delete_flag);
  1823.   // tag_list == NULL doesnt matter because we're at a smaller level than
  1824.   // pcl2->level_ at this point. periodic_callback_ will update this field
  1825.   // correctly
  1826.   upd_time = (int) now;
  1827.   upd_time = (upd_time << 16) | (pcl2->seqnum_ & 0xFFFF);
  1828.   ++(pcl2->seqnum_);
  1829.   pcl2->UpdatePotlChild(a_->myaddr_, a_->myaddr_, num_hops, a_->highest_level_,higher_level_pcl->num_children_, energy, upd_time, child_flag, delete_flag, higher_level_pcl->tag_list_);
  1830.   
  1831.   // If we havent seen a LM that can be our parent at this higher level, start
  1832.   // promotion timer for promotion to next level
  1833.   a_->num_resched_ = pcl2->num_heard_ - 1;
  1834.   if(higher_level_pcl->parent_ == NULL && a_->num_resched_) {
  1835.     //    if (a_->debug_) printf("PromotionTimer's expire method: Scheduling timer for promo to level %dn",a_->highest_level_);
  1836.     // Timer's status is TIMER_HANDLING in handle; so we just reschedule to
  1837.     // avoid "cant start timer" abort if sched is called
  1838.     a_->promo_timer_running_ = 1;
  1839.     a_->wait_state_ = 0;
  1840.     a_->total_wait_time_ = 0;
  1841.     a_->promo_timeout_ = a_->random_timer(double(CONST_TIMEOUT + PROMO_TIMEOUT_MULTIPLES * a_->radius(a_->highest_level_+1) + MAX_TIMEOUT/((a_->num_resched_+1) * pow(2,a_->highest_level_+1))), a_->be_random_);
  1842.     a_->trace("Node %d: Promotion timeout after wait period in expire2: %f at time %f, num_resched_ %d, energy %f", a_->myaddr_,a_->promo_timeout_,s.clock(),a_->num_resched_,(a_->node_)->energy());
  1843.     a_->num_resched_ = 0;
  1844.     a_->promo_start_time_ = s.clock();
  1845.     a_->promo_timer_->resched(a_->promo_timeout_);
  1846.   }
  1847.   else {
  1848.     double wait_time = PERIODIC_WAIT_TIME;
  1849.     a_->promo_timer_running_ = 1;
  1850.     a_->total_wait_time_ = 0;
  1851.     a_->wait_state_ = 1;
  1852.     a_->total_wait_time_ += wait_time;
  1853.     //    a_->trace("Node %d: Entering wait period in expire1 at time %f", a_->myaddr_,now);
  1854.     a_->promo_timer_->resched(wait_time);
  1855.   }
  1856.   
  1857.   //  if(now > 412.5) {
  1858.   //    purify_printf("expire2: %f,%dn",now,a_->myaddr_);
  1859.   //    purify_new_leaks();
  1860.   //  }
  1861. }
  1862.   
  1863. int 
  1864. LandmarkAgent::command (int argc, const char *const *argv)
  1865. {
  1866.   if (argc == 2)
  1867.     {
  1868.       if (strcmp (argv[1], "start") == 0)
  1869. {
  1870.   startUp();
  1871.   return (TCL_OK);
  1872. }
  1873.       if (strcmp (argv[1], "stop") == 0)
  1874. {
  1875.   stop();
  1876.   return (TCL_OK);
  1877. }
  1878.       if (strcmp (argv[1], "print-nbrs") == 0)
  1879. {
  1880.   get_nbrinfo();
  1881.   return (TCL_OK);
  1882. }
  1883.       if (strcmp (argv[1], "enable-caching") == 0)
  1884. {
  1885.   cache_ = 1;
  1886.   return (TCL_OK);
  1887. }
  1888.       if (strcmp (argv[1], "unicast-adverts") == 0)
  1889. {
  1890.   adverts_type_ = UNICAST;
  1891.   return (TCL_OK);
  1892. }
  1893.       if (strcmp (argv[1], "hard-state-adverts") == 0)
  1894. {
  1895.   adverts_type_ = SUPPRESS;
  1896.   // Entries should never timeout in a hard-state scheme
  1897.   update_timeout_ = 1000000;
  1898.   return (TCL_OK);
  1899. }
  1900.       if (strcmp (argv[1], "enable-global-landmark") == 0)
  1901. {
  1902.   global_lm_ = 1;
  1903.   return (TCL_OK);
  1904. }
  1905.       else if (strcmp (argv[1], "dumprtab") == 0)
  1906. {
  1907.   Packet *p2 = allocpkt ();
  1908.   hdr_ip *iph2 = HDR_IP(p2);
  1909.   //   rtable_ent *prte;
  1910.           trace ("Table Dump %d[%d]n----------------------------------n",
  1911.     myaddr_, iph2->sport());
  1912.   trace ("VTD %.5f %d:%dn", Scheduler::instance ().clock (),
  1913.  myaddr_, iph2->sport());
  1914.   trace ("Remaining energy: %f", node_->energy());
  1915.   //   trace ("Energy consumed by queries: %f", node_->qry_energy());
  1916.   /*
  1917.    * Freeing a routing layer packet --> don't need to
  1918.    * call drop here.
  1919.    */
  1920.   trace("Highest Level: %d", highest_level_);
  1921.   Packet::free (p2);
  1922.   ParentChildrenList *pcl = parent_children_list_;
  1923.   LMNode *pch;
  1924.   while(pcl) {
  1925.     trace("Level %d:", pcl->level_);
  1926.     if(pcl->parent_)
  1927.       trace("Parent: %d", (pcl->parent_)->id_);
  1928.     else
  1929.       trace("Parent: NULL");
  1930.     int num_lm_addrs = 0;
  1931.     int64_t *lmaddrs = NULL;
  1932.     (pcl->mylmaddrs_)->get_lm_addrs(&num_lm_addrs,&lmaddrs);
  1933.     for( int i = 0; i < num_lm_addrs; ++i) {
  1934.       int i1,i2,i3,i4,i5,i6,i7,i8;
  1935.       i1 = (lmaddrs[i] >> 56) & 0xFF;
  1936.       i2 = (lmaddrs[i] >> 48) & 0xFF;
  1937.       i3 = (lmaddrs[i] >> 40) & 0xFF;
  1938.       i4 = (lmaddrs[i] >> 32) & 0xFF;
  1939.       i5 = (lmaddrs[i] >> 24) & 0xFF;
  1940.       i6 = (lmaddrs[i] >> 16) & 0xFF;
  1941.       i7 = (lmaddrs[i] >> 8) & 0xFF;
  1942.       i8 = (lmaddrs[i]) & 0xFF;
  1943.       trace("Landmark Address: %d.%d.%d.%d.%d.%d.%d.%d",i1,i2,i3,i4,i5,i6,i7,i8);
  1944.     }
  1945.     if(num_lm_addrs) delete[] lmaddrs;
  1946.     if(myaddr_ == 134) {
  1947.       pch = pcl->pchildren_;
  1948.       while(pch) {
  1949. int num_addrs = 0;
  1950. int64_t *addrs = NULL;
  1951. (pch->lmaddr_)->get_lm_addrs(&num_addrs,&addrs);
  1952. int j1=0,j2=0,j3=0,j4=0,j5=0,j6=0,j7=0,j8=0;
  1953. if(num_addrs) {
  1954.   j1 = (addrs[0] >> 56) & 0xFF;
  1955.   j2 = (addrs[0] >> 48) & 0xFF;
  1956.   j3 = (addrs[0] >> 40) & 0xFF;
  1957.   j4 = (addrs[0] >> 32) & 0xFF;
  1958.   j5 = (addrs[0] >> 24) & 0xFF;
  1959.   j6 = (addrs[0] >> 16) & 0xFF;
  1960.   j7 = (addrs[0] >> 8) & 0xFF;
  1961.   j8 = (addrs[0]) & 0xFF;
  1962. }
  1963. trace("Node %d: Potl Child id %d, LM addr %d.%d.%d.%d.%d.%d.%d.%d, next_hop %d, num_children %d",myaddr_,pch->id_,j1,j2,j3,j4,j5,j6,j7,j8,pch->next_hop_,pch->num_children_);
  1964. if(num_addrs) delete[] addrs;
  1965. pch = pch->next_;
  1966.       }
  1967.     }
  1968.     trace("Number of potl children: %dn", pcl->num_potl_children_);
  1969.     if(myaddr_ == 166) {
  1970.       trace("Number of children: %dn", pcl->num_children_);
  1971.       trace("Number of level %d nodes heard: %dn", (pcl->level_)-1, pcl->num_heard_);
  1972.       
  1973.       trace("Number of potl parent: %dn", pcl->num_pparent_);
  1974.       if(pcl->level_ >= 1 && highest_level_ >= 1) {
  1975. pch = pcl->pchildren_;
  1976. trace("Potential Children (radius %d):",radius(pcl->level_));
  1977. while(pch) {
  1978.   if(pch->child_flag_ != NOT_POTL_CHILD)
  1979.     trace("Node %d (%d hops away)",pch->id_,pch->num_hops_);
  1980.   pch = pch->next_;
  1981. }
  1982. pch = pcl->pparent_;
  1983. trace("Potential parent:");
  1984. while(pch) {
  1985.   trace("Node %d (%d hops away)",pch->id_,pch->num_hops_);
  1986.   pch = pch->next_;
  1987.       }
  1988.     }
  1989.     pcl = pcl->next_;
  1990.   }
  1991.   Packet::free(p2);
  1992.   return (TCL_OK);
  1993. }
  1994.     }
  1995.   else if (argc == 3)
  1996.     {
  1997.       if (strcasecmp (argv[1], "tracetarget") == 0)
  1998. {
  1999.   TclObject *obj;
  2000. if ((obj = TclObject::lookup (argv[2])) == 0)
  2001.     {
  2002.       fprintf (stderr, "%s: %s lookup of %s failedn", __FILE__, argv[1],
  2003.        argv[2]);
  2004.       return TCL_ERROR;
  2005.     }
  2006.   tracetarget_ = (Trace *) obj;
  2007.   return TCL_OK;
  2008. }
  2009.       else if (strcasecmp (argv[1], "addr") == 0) {
  2010. int temp;
  2011. temp = Address::instance().str2addr(argv[2]);
  2012. myaddr_ = temp;
  2013. return TCL_OK;
  2014.       }
  2015.       else if (strcasecmp (argv[1], "set-update-period") == 0) {
  2016. update_period_ = atof(argv[2]);
  2017. if(adverts_type_ != SUPPRESS)
  2018.   update_timeout_ = update_period_ + 4 * LM_STARTUP_JITTER;
  2019. return TCL_OK;
  2020.       }
  2021.       else if (strcasecmp (argv[1], "set-update-timeout") == 0) {
  2022. update_timeout_ = atof(argv[2]);
  2023. return TCL_OK;
  2024.       }
  2025.       else if (strcasecmp (argv[1], "start-tag-motion") == 0) {
  2026. mobility_period_ = atof(argv[2]);
  2027. Scheduler::instance().schedule(tag_mobility_,tag_mobility_event_,Random::uniform(mobility_period_));
  2028. return (TCL_OK);
  2029.       }
  2030.       else if (strcasecmp (argv[1], "attach-tag-dbase") == 0)
  2031. {
  2032.   TclObject *obj;
  2033. if ((obj = TclObject::lookup (argv[2])) == 0)
  2034.     {
  2035.       fprintf (stderr, "%s: %s lookup of %s failedn", __FILE__, argv[1],
  2036.        argv[2]);
  2037.       return TCL_ERROR;
  2038.     }
  2039.   tag_dbase_ = (tags_database *) obj;
  2040.   return TCL_OK;
  2041. }
  2042.       else if (strcasecmp (argv[1], "node") == 0)
  2043. {
  2044.   assert(node_ == NULL);
  2045.   TclObject *obj;
  2046. if ((obj = TclObject::lookup (argv[2])) == 0)
  2047.     {
  2048.       fprintf (stderr, "%s: %s lookup of %s failedn", __FILE__, argv[1],
  2049.        argv[2]);
  2050.       return TCL_ERROR;
  2051.     }
  2052.   node_ = (MobileNode *) obj;
  2053.   return TCL_OK;
  2054. }
  2055.       else if (strcmp (argv[1], "query-debug") == 0)
  2056. {
  2057.   qry_debug_ = atoi(argv[2]);
  2058.   return (TCL_OK);
  2059. }
  2060.       else if (strcasecmp (argv[1], "ll-queue") == 0)
  2061. {
  2062. if (!(ll_queue = (PriQueue *) TclObject::lookup (argv[2])))
  2063.     {
  2064.       fprintf (stderr, "Landmark_Agent: ll-queue lookup of %s failedn", argv[2]);
  2065.       return TCL_ERROR;
  2066.     }
  2067.   return TCL_OK;
  2068. }
  2069.     }
  2070. return (Agent::command (argc, argv));
  2071. }
  2072. void
  2073. LandmarkAgent::startUp()
  2074. {
  2075.   int i,ntags, j = 0, read_new_mobile_tags = 0;
  2076.   Scheduler &s = Scheduler::instance();
  2077.   compr_taglist *local_tags0, *local_tags1, *local_tags2, *t_ptr;
  2078.   compr_taglist *tag_ptr1, *tag_ptr2;
  2079.   God *gd = God::instance();
  2080.   //  AgentList *alist = AgentList::instance();
  2081.   int *nbrs;
  2082.   int num_nbrs = 0, num_nodes = 0;
  2083.   
  2084.   // Adding ourself to global tag agent database
  2085.   //  alist->AddAgent(myaddr_,this);
  2086.   //  num_nodes = gd->numNodes()-1;
  2087.   //  nbrs = new int[num_nodes];
  2088.   
  2089.   //  for(i = 1; i <= num_nodes; ++i) {
  2090.       // God sees node id as id+1 ...
  2091.   //    if(gd->hops(myaddr_+1,i) == 1) {
  2092.   //      nbrs[num_nbrs++] = i-1;
  2093.   //    }
  2094.   //  }
  2095.   //  trace("Node %d: Number of nbrs %d, Neighbours:",myaddr_,num_nbrs);
  2096.   //  num_nbrs_ = num_nbrs;
  2097.   //  nbrs_ = new int[num_nbrs_];
  2098.   //  for(i = 0; i < num_nbrs_; ++i) {
  2099.   //    nbrs_[i] = nbrs[i];
  2100.     //    trace("%d",nbrs_[i]);
  2101.   //  }
  2102.   //  if(nbrs) delete[] nbrs;
  2103.   
  2104.   trace("Node %d: LM Agent starting up at time %f",myaddr_,NOW);
  2105.   // Set node to be alive (this method might be called after a call to reset
  2106.   node_dead_ = 0;
  2107.   
  2108.   double x,y,z;
  2109.   node_->getLoc(&x,&y,&z);
  2110.   //  printf("Node %d position: (%f,%f,%f)n",myaddr_,x,y,z);
  2111.   // Detection range smaller than transmission range. This is because, if 
  2112.   // the tags are passive, they may not have sufficient energy to re-radiate
  2113.   // information to the sensor
  2114.   double r = 60;
  2115.   local_tags0 = tag_dbase_->Gettags(x,y,r);
  2116.   //  trace("Node %d's at (%f,%f,%f) senses tags:",myaddr_,x,y,z);
  2117.   t_ptr = local_tags0;
  2118.   ntags = 0;
  2119.   while(t_ptr) {
  2120.     //    trace("tag name: %d.%d.%d",(t_ptr->obj_name_ >> 24) & 0xFF,(t_ptr->obj_name_ >> 16) & 0xFF,(t_ptr->obj_name_) & 0xFFFF);
  2121.     ++ntags;
  2122.     if(!(t_ptr->next_) && mobile_tags_ && !read_new_mobile_tags) {
  2123.       // Update our tag list with any new tags that have come into our range
  2124.       // while we were dead
  2125.       read_new_mobile_tags = 1;
  2126.       t_ptr->next_ = mobile_tags_;
  2127.       mobile_tags_ = NULL;
  2128.     }
  2129.     t_ptr = t_ptr->next_;
  2130.   }
  2131.   //  trace("Number of tags: %d",ntags);
  2132.   /*
  2133.   int agg_level = 1;
  2134.   int num_tags = 0;
  2135.   local_tags1 = aggregate_tags(local_tags0,agg_level,&num_tags);
  2136.   trace("Level 1 aggregates, num = %d",num_tags);
  2137.   t_ptr = local_tags1;
  2138.   while(t_ptr) {
  2139.     trace("tag name: %d.%d.%d",(t_ptr->obj_name_ >> 24) & 0xFF,(t_ptr->obj_name_ >> 16) & 0xFF,(t_ptr->obj_name_) & 0xFFFF);
  2140.     t_ptr = t_ptr->next_;
  2141.   }
  2142.   agg_level = 2;
  2143.   num_tags = 0;
  2144.   local_tags2 = aggregate_tags(local_tags1,agg_level,&num_tags);
  2145.   trace("Level 2 aggregates, num = %d",num_tags);
  2146.   t_ptr = local_tags2;
  2147.   while(t_ptr) {
  2148.     trace("tag name: %d.%d.%d",(t_ptr->obj_name_ >> 24) & 0xFF,(t_ptr->obj_name_ >> 16) & 0xFF,(t_ptr->obj_name_) & 0xFFFF);
  2149.     t_ptr = t_ptr->next_;
  2150.   }
  2151.   // Delete local_tags1
  2152.   tag_ptr1 = local_tags1;
  2153.   while(tag_ptr1) {
  2154.     tag_ptr2 = tag_ptr1;
  2155.     tag_ptr1 = tag_ptr1->next_;
  2156.     delete tag_ptr2;
  2157.   }
  2158.   // Delete local_tags2
  2159.   tag_ptr1 = local_tags2;
  2160.   while(tag_ptr1) {
  2161.     tag_ptr2 = tag_ptr1;
  2162.     tag_ptr1 = tag_ptr1->next_;
  2163.     delete tag_ptr2;
  2164.   }
  2165.   */
  2166.   assert(highest_level_ == 0);
  2167.   assert(parent_children_list_ == NULL);
  2168.   parent_children_list_ = new ParentChildrenList(highest_level_, this);
  2169.   ParentChildrenList **pcl = &parent_children_list_;
  2170.   // Start off periodic LM advertisements
  2171.   assert(highest_level_ == 0);
  2172.   s.schedule((*pcl)->periodic_handler_, (*pcl)->periodic_update_event_, INITIAL_WAIT_TIME + jitter(LM_STARTUP_JITTER, be_random_));
  2173.   (*pcl)->tag_list_ = local_tags0;
  2174.   (*pcl)->num_tags_ = ntags;
  2175.   // Start off promotion timer
  2176.   //  if (debug_) printf("startUp: Scheduling timern");
  2177.   promo_timer_running_ = 1;
  2178.   num_resched_ = 0;
  2179.   // Node enters "wait" state where it waits to receive other node's 
  2180.   // advertisements; Wait for 5 * radius(level) seconds; Should be
  2181.   // atleast the same as the period of LM advts (10s)
  2182.   total_wait_time_ = 0;
  2183.   wait_state_ = 1;
  2184.   double wait_time = WAIT_TIME * radius(highest_level_) + INITIAL_WAIT_TIME + LM_STARTUP_JITTER;
  2185.   total_wait_time_ += wait_time;
  2186.   //  trace("Node %d: Wait time at startUp: %f",myaddr_,wait_time);
  2187.   promo_timer_->sched(wait_time);
  2188.   //  promo_timer_->sched(promo_timeout_);
  2189. }
  2190. compr_taglist *
  2191. LandmarkAgent::aggregate_taginfo(compr_taglist *unagg_tags, int agg_level, int *num_tags)
  2192. {
  2193.   compr_taglist *agg_tags, *agg_ptr1, *agg_ptr2,  *last_agg_ptr;
  2194.   int found;
  2195.   
  2196.   *num_tags = 0;
  2197.   // agg_level is 1 implies ignore the last field
  2198.   // agg_level >= 2 implies ignore the last two fields
  2199.   agg_ptr1 = unagg_tags;
  2200.   agg_tags = NULL;
  2201.   
  2202.   while(agg_ptr1) {
  2203.     if(agg_level == 1) {
  2204.       found = FALSE;
  2205.       if(agg_tags) {
  2206. agg_ptr2 = agg_tags;
  2207. while(agg_ptr2) {
  2208.   if((((agg_ptr2->obj_name_ >> 24) & 0xFF) == ((agg_ptr1->obj_name_ >> 24) & 0xFF)) && (((agg_ptr2->obj_name_ >> 16) & 0xFF) == ((agg_ptr1->obj_name_ >> 16) & 0xFF))) {
  2209.     found = TRUE;
  2210.     break;
  2211.   }
  2212.   last_agg_ptr = agg_ptr2;
  2213.   agg_ptr2 = agg_ptr2->next_;
  2214. }
  2215.       }
  2216.       if(!found) {
  2217. ++(*num_tags);
  2218. if(!agg_tags) {
  2219.   agg_tags = new compr_taglist;
  2220.   last_agg_ptr = agg_tags;
  2221. }
  2222. else {
  2223.   last_agg_ptr->next_ = new compr_taglist;
  2224.   last_agg_ptr = last_agg_ptr->next_;
  2225. }
  2226. last_agg_ptr->obj_name_ = (agg_ptr1->obj_name_ & 0xFFFF0000);
  2227.       }
  2228.     }
  2229.     else if(agg_level >= 2) {
  2230.       found = FALSE;
  2231.       if(agg_tags) {
  2232. agg_ptr2 = agg_tags;
  2233. while(agg_ptr2) {
  2234.   if(((agg_ptr2->obj_name_ >> 24) & 0xFF) == ((agg_ptr1->obj_name_ >> 24) & 0xFF)) {
  2235.     found = TRUE;
  2236.     break;
  2237.   }
  2238.   last_agg_ptr = agg_ptr2;
  2239.   agg_ptr2 = agg_ptr2->next_;
  2240. }
  2241.       }
  2242.       if(!found) {
  2243. ++(*num_tags);
  2244. if(!agg_tags) {
  2245.   agg_tags = new compr_taglist;
  2246.   last_agg_ptr = agg_tags;
  2247. }
  2248. else {
  2249.   last_agg_ptr->next_ = new compr_taglist;
  2250.   last_agg_ptr = last_agg_ptr->next_;
  2251. }
  2252. last_agg_ptr->obj_name_ = (agg_ptr1->obj_name_ & 0xFF000000);
  2253.       }
  2254.     }
  2255.     agg_ptr1 = agg_ptr1->next_;
  2256.   }
  2257.   return(agg_tags);
  2258. }
  2259. compr_taglist *
  2260. LandmarkAgent::aggregate_tags(compr_taglist *unagg_tags, int agg_level, int *num_tags)
  2261. {
  2262.   compr_taglist *agg_tags = NULL, *tag_ptr;
  2263.   aggreg_taglist *t1, *t2, *t3, *tmp_ptr;
  2264.   aggreg_taglist *list1 = NULL, *list2 = NULL, *list3 = NULL, *list = NULL;
  2265.   aggreg_taglist *prev_tag, *next_tag, *old_list;
  2266.   int found;
  2267.   int p1,p2,p3,q1,q2,q3,object_name;
  2268.   
  2269.   // Tag names have 3 fields
  2270.   // List 1 is list of tags with first field > 0, last 2 fields = 0
  2271.   // List 2 is list of tags with first two fields > 0 and last field = 0
  2272.   // List 3 is list of tags with all three fields > 0 
  2273.   tag_ptr = unagg_tags;
  2274.   while(tag_ptr) {
  2275.     p1 = (tag_ptr->obj_name_ >> 24) & 0xFF;
  2276.     p2 = (tag_ptr->obj_name_ >> 16) & 0xFF;
  2277.     p3 = tag_ptr->obj_name_ & 0xFFFF;
  2278.     found = 0;
  2279.     if(p1 && p2 && p3) {
  2280.       // Check if p1.p2.0 is already in list2; If so, goto next object
  2281.       object_name = (int)((p1 * pow(2,24)) + (p2 * pow(2,16))) ;
  2282.       old_list = list2;
  2283.       while(old_list) {
  2284. if(old_list->obj_name_ == object_name) {
  2285.   found = TRUE;
  2286.   break;
  2287. }
  2288. old_list = old_list->next_;
  2289.       }
  2290.       // Check if p1.0.0 is already in list1; If so, goto next object
  2291.       old_list = list1;
  2292.       while(old_list) {
  2293. q1 = (old_list->obj_name_ >> 24) & 0xFF;
  2294. if(p1 == q1) {
  2295.   found = TRUE;
  2296.   break;
  2297. }
  2298. old_list = old_list->next_;
  2299.       }
  2300.       
  2301.       tmp_ptr = list3;
  2302.       while(tmp_ptr && !found) {
  2303. q1 = (tmp_ptr->obj_name_ >> 24) & 0xFF;
  2304. q2 = (tmp_ptr->obj_name_ >> 16) & 0xFF;
  2305. q3 = tmp_ptr->obj_name_ & 0xFFFF;
  2306. // If 2 objects have same value for first two fields, store the
  2307. // aggregate p1.p2.0 in list2; We have already checked if p1.p2.0
  2308. // is already in list2 or not
  2309. if(p1 == q1 && p2 == q2 && p3 != q3) {
  2310.   if(!list2) {
  2311.     list2 = new aggreg_taglist;
  2312.     t2 = list2;
  2313.   }
  2314.   else {
  2315.     t2->next_ = new aggreg_taglist;
  2316.     t2 = t2->next_;
  2317.   }
  2318.   t2->obj_name_ = object_name;
  2319.   // Indicate that this is a new aggregate
  2320.   t2->marked_ = 1;
  2321.   // Remove this object from list3; We simply set the obj_name_ to 1
  2322.   // to indicate that this tag object is not valid
  2323.   tmp_ptr->obj_name_ = -1;
  2324.   found = TRUE;
  2325.   break;
  2326. }
  2327. else if(p1 == q1 && p2 == q2 && p3 == q3) {
  2328.   found = TRUE;
  2329.   break;
  2330. }
  2331. tmp_ptr = tmp_ptr->next_;
  2332.       }
  2333.       if(found) {
  2334. tag_ptr = tag_ptr->next_;
  2335. continue;
  2336.       }
  2337.       
  2338.       if(!list3) {
  2339. list3 = new aggreg_taglist;
  2340. t3 = list3;
  2341.       }
  2342.       else {
  2343. t3->next_ = new aggreg_taglist;
  2344. t3 = t3->next_;
  2345.       }
  2346.       t3->obj_name_ = tag_ptr->obj_name_;
  2347.     }
  2348.     else if(p1 && p2 && !p3) {
  2349.       // Check if p1.0.0 is already in list1; If so, goto next object
  2350.       object_name = (int)(p1 * pow(2,24)) ;
  2351.       if(list1) {
  2352. old_list = list1;
  2353. while(old_list) {
  2354.   if(old_list->obj_name_ == object_name) {
  2355.     found = TRUE;
  2356.     break;
  2357.   }
  2358.   old_list = old_list->next_;
  2359. }
  2360.       }
  2361.       tmp_ptr = list2;
  2362.       while(tmp_ptr && !found) {
  2363. q1 = (tmp_ptr->obj_name_ >> 24) & 0xFF;
  2364. q2 = (tmp_ptr->obj_name_ >> 16) & 0xFF;
  2365. // If 2 objects have same value for the first field, store the
  2366. // aggregate in list1 provided the other object is not a new aggregate
  2367. if(p1 == q1 && p2 != q2 && !tmp_ptr->marked_) {
  2368.   if(!list1) {
  2369.     list1 = new aggreg_taglist;
  2370.     t1 = list1;
  2371.   }
  2372.   else {
  2373.     t1->next_ = new aggreg_taglist;
  2374.     t1 = t1->next_;
  2375.   }
  2376.   t1->obj_name_ = object_name;
  2377.   
  2378.   // Indicate that this is a new aggregate
  2379.   t1->marked_ = 1;
  2380.   // Remove this object from list3; We simply set the obj_name_ to 1
  2381.   // to indicate that this tag object is not valid
  2382.   tmp_ptr->obj_name_ = -1;
  2383.   // Remove any elements p1.*.* from list3 i.e., set obj_name_ to -1
  2384.   old_list = list3;
  2385.   while(old_list) {
  2386.     q1 = (old_list->obj_name_ >> 24) & 0xFF;
  2387.     if(p1 == q1)
  2388.       old_list->obj_name_ = -1;
  2389.     old_list = old_list->next_;
  2390.   }
  2391.   found = TRUE;
  2392.   break;
  2393. }
  2394. else if(p1 == q1 && p2 == q2) {
  2395.   found = TRUE;
  2396.   break;
  2397. }
  2398. tmp_ptr = tmp_ptr->next_;
  2399.       }
  2400.       
  2401.       if(found) {
  2402. tag_ptr = tag_ptr->next_;
  2403. continue;
  2404.       }
  2405.       if(!list2) {
  2406. list2 = new aggreg_taglist;
  2407. t2 = list2;
  2408.       }
  2409.       else {
  2410. t2->next_ = new aggreg_taglist;
  2411. t2 = t2->next_;
  2412.       }
  2413.       t2->obj_name_ = tag_ptr->obj_name_;
  2414.       // Remove any elements p1.p2.* from list3 i.e., set obj_name_ to -1
  2415.       old_list = list3;
  2416.       while(old_list) {
  2417. q1 = (old_list->obj_name_ >> 24) & 0xFF;
  2418. q2 = (old_list->obj_name_ >> 16) & 0xFF;       
  2419. if(p1 == q1 && p2 == q2)
  2420.   old_list->obj_name_ = -1;
  2421. old_list = old_list->next_;
  2422.       }
  2423.     }
  2424.     else if(p1 && !p2 && !p3) {
  2425.       // Check if object p1.0.0 already in list; If so, goto next object
  2426.       tmp_ptr = list1;
  2427.       while(tmp_ptr) {
  2428. if(tmp_ptr->obj_name_ == tag_ptr->obj_name_) {
  2429.   found = TRUE;
  2430.   break;
  2431. }
  2432. tmp_ptr = tmp_ptr->next_;
  2433.       }
  2434.       
  2435.       // Add object to list1
  2436.       if(!found) {
  2437. if(!list1) {
  2438.   list1 = new aggreg_taglist;
  2439.   t1 = list1;
  2440. }
  2441. else {
  2442.   t1->next_ = new aggreg_taglist;
  2443.   t1 = t1->next_;
  2444. }
  2445. t1->obj_name_ = tag_ptr->obj_name_;
  2446.       }
  2447.       // Remove any elements p1.*.* from list2 i.e., set obj_name_ to -1
  2448.       old_list = list2;
  2449.       while(old_list) {
  2450. q1 = (old_list->obj_name_ >> 24) & 0xFF;
  2451. if(p1 == q1)
  2452.   old_list->obj_name_ = -1;
  2453. old_list = old_list->next_;
  2454.       }
  2455.       // Remove any elements p1.*.* from list3 i.e., set obj_name_ to -1
  2456.       old_list = list3;
  2457.       while(old_list) {
  2458. q1 = (old_list->obj_name_ >> 24) & 0xFF;
  2459. if(p1 == q1)
  2460.   old_list->obj_name_ = -1;
  2461. old_list = old_list->next_;
  2462.       }
  2463.     }
  2464.     else
  2465.       assert(0);
  2466.     tag_ptr = tag_ptr->next_;
  2467.   }
  2468.   // Make list1, list2, list3 into one list
  2469.   list = NULL;
  2470.   if(list3) {
  2471.     list = list3;
  2472.     if(list2) {
  2473.       t3->next_ = list2;
  2474.       if(list1) {
  2475. t2->next_ = list1;
  2476.       }
  2477.     }
  2478.     else if(list1)
  2479.       t3->next_ = list1;
  2480.   }
  2481.   else if(list2) {
  2482.     list = list2;
  2483.     if(list1)
  2484.       t2->next_ = list1;
  2485.   }
  2486.   else if(list1)
  2487.     list = list1;
  2488.   
  2489.   
  2490.   // Return the list of aggregated tags
  2491.   *num_tags = 0;
  2492.   agg_tags = NULL;
  2493.   tmp_ptr = list;
  2494.   while(tmp_ptr) {
  2495.     if(tmp_ptr->obj_name_ != -1) {
  2496.       if(!agg_tags) {
  2497. agg_tags = new compr_taglist;
  2498. tag_ptr = agg_tags;
  2499.       }
  2500.       else {
  2501. tag_ptr->next_ = new compr_taglist;
  2502. tag_ptr = tag_ptr->next_;
  2503.       }
  2504.       ++(*num_tags);
  2505.       tag_ptr->obj_name_ = tmp_ptr->obj_name_;
  2506.     }
  2507.     tmp_ptr = tmp_ptr->next_;
  2508.   }
  2509.   // Delete list
  2510.   list1 = NULL;
  2511.   list2 = NULL;
  2512.   list1 = list;
  2513.   while(list1) {
  2514.     list2 = list1;
  2515.     list1 = list1->next_;
  2516.     delete list2;
  2517.   }
  2518.   return(agg_tags);
  2519. }
  2520. void
  2521. LandmarkAgent::recv(Packet *p, Handler *)
  2522. {
  2523.   hdr_ip *iph = HDR_IP(p);
  2524.   hdr_cmn *cmh = HDR_CMN(p);
  2525.   /*
  2526.    *  Must be a packet being originated by the query agent at my node?
  2527.    */
  2528.   if(node_dead_) {
  2529.     Packet::free(p);
  2530.     return;
  2531.   }
  2532.   if(iph->saddr() == myaddr_ && iph->sport() == 0) {
  2533.     /*
  2534.      * Add the IP Header
  2535.      */
  2536.     cmh->size() += IP_HDR_LEN;    
  2537.   }
  2538.   /*
  2539.    *  I received a packet that I sent.  Probably
  2540.    *  a routing loop.
  2541.    */
  2542.   else if(iph->saddr() == myaddr_) {
  2543.     Packet::free(p);
  2544.     //   drop(p, DROP_RTR_ROUTE_LOOP);
  2545.     return;
  2546.   }
  2547.   /*
  2548.    *  Packet I'm forwarding...
  2549.    */
  2550.   // Move the ttl check to the following methods?
  2551.   //    if(--iph->ttl_ == 0) {
  2552.   //      drop(p, DROP_RTR_TTL);
  2553.   //      return;
  2554.   //    }
  2555.   
  2556.   // Packet will be forwarded down (if it's not dropped)
  2557.   cmh->direction_ = hdr_cmn::DOWN;
  2558.   
  2559.   unsigned char *walk = p->accessdata();
  2560.   int action = *walk++;
  2561.   int data_pkt = 0;
  2562.   if(action == QUERY_PKT || action == HASH_PKT || action == HASH_ACK_PKT || action == REHASH_PKT || action == DIR_QUERY_PKT || action == DIR_RESPONSE_PKT || action == OBJECT_QUERY_PKT || action == OBJECT_RESPONSE_PKT) 
  2563.     data_pkt = 1;
  2564.   if ((iph->saddr() != myaddr_) && (iph->dport() == ROUTER_PORT) && !data_pkt)
  2565.     {
  2566.       ProcessHierUpdate(p);
  2567.     }
  2568.   else
  2569.     {
  2570.       ForwardPacket(p);
  2571.     }
  2572. }
  2573. void
  2574. LandmarkAgent::ForwardPacket(Packet *p)
  2575. {
  2576.   hdr_ip *iph = HDR_IP(p);
  2577.   hdr_cmn *cmh = HDR_CMN(p);
  2578.   Packet *newp;
  2579.   hdr_ip *new_iph;
  2580.   hdr_cmn *new_cmh;
  2581.   unsigned char *walk, *X_ptr, *Y_ptr, *level_ptr, *num_src_hops_ptr;
  2582.   unsigned char *last_hop_ptr, *pkt_end_ptr;
  2583.   int X, Y, next_hop_level, prev_hop_level, obj_name, num_src_hops;
  2584.   double local_x, local_y, local_z;
  2585.   int num_dst = 0, action, origin_time;
  2586.   NodeIDList *dst_nodes = NULL, *dst_ptr = NULL;
  2587.   int query_for_us = FALSE;
  2588.   Scheduler &s = Scheduler::instance();
  2589.   double now = s.clock();
  2590.   nsaddr_t last_hop_id;
  2591.   int cache_index = -1; // index into cache if object is found
  2592.   int found = FALSE; // whether object has been found in cache
  2593.   walk = p->accessdata();
  2594.   // Type of advertisement
  2595.   action = *walk++;
  2596.   X = 0;
  2597.   X_ptr = walk;
  2598.   X = *walk++;
  2599.   X = (X << 8) | *walk++;
  2600.   Y_ptr = walk;
  2601.   Y = *walk++;
  2602.   Y = (Y << 8) | *walk++;
  2603.   // level of our parent/child node that forwarded the query to us
  2604.   level_ptr = walk;
  2605.   next_hop_level = *walk++;
  2606.   obj_name = *walk++;
  2607.   obj_name = (obj_name << 8) | *walk++;
  2608.   obj_name = (obj_name << 8) | *walk++;
  2609.   obj_name = (obj_name << 8) | *walk++;
  2610.     // origin time of advertisement
  2611.   origin_time = *walk++;
  2612.   origin_time = (origin_time << 8) | *walk++;
  2613.   origin_time = (origin_time << 8) | *walk++;
  2614.   origin_time = (origin_time << 8) | *walk++;
  2615.   
  2616.   num_src_hops_ptr = walk;
  2617.   num_src_hops = *walk++;
  2618.   num_src_hops = (num_src_hops << 8) | *walk++;
  2619.   assert(num_src_hops <= 30);
  2620.   last_hop_ptr = NULL;
  2621.   for(int i = 0; i < num_src_hops; ++i) {
  2622.     last_hop_ptr = walk;
  2623.     walk += 3;
  2624.   }
  2625.   if(last_hop_ptr) {
  2626.     prev_hop_level = *(last_hop_ptr+2);
  2627.     last_hop_id = *last_hop_ptr;
  2628.     last_hop_id = (last_hop_id << 8) | *(last_hop_ptr+1);
  2629.   }
  2630.   else {
  2631.     prev_hop_level = 0;
  2632.     last_hop_id = NO_NEXT_HOP;
  2633.   }
  2634.   // Used to add source route to packet
  2635.   pkt_end_ptr = walk;
  2636.   
  2637.   // If this is a response pkt, cache this information
  2638.   if(cache_) {
  2639.     if(X != 65000 && Y != 65000) {
  2640.       if(num_cached_items_ < MAX_CACHE_ITEMS) {
  2641. int replace_index = num_cached_items_;
  2642. // If object already exists in cache, update info if necessary
  2643. for(int i = 0; i < num_cached_items_; ++i) {
  2644.   if(tag_cache_[i].obj_name_ == obj_name && tag_cache_[i].origin_time_ < origin_time) {
  2645.   replace_index = i;
  2646.   break;
  2647.   }
  2648. }
  2649. tag_cache_[replace_index].obj_name_ = obj_name;
  2650. tag_cache_[replace_index].origin_time_ = origin_time;
  2651. tag_cache_[replace_index].X_ = X;
  2652. tag_cache_[replace_index].Y_ = Y;
  2653. ++num_cached_items_;
  2654.       }
  2655.       else {
  2656. // Use LRU cache replacement
  2657. int replace_index = 0;
  2658. int least_time = tag_cache_[replace_index].origin_time_;
  2659. for(int i = 0; i < MAX_CACHE_ITEMS; ++i) {
  2660.   if(tag_cache_[i].origin_time_ < least_time)
  2661.     replace_index = i;
  2662.       }
  2663. tag_cache_[replace_index].obj_name_ = obj_name;
  2664. tag_cache_[replace_index].origin_time_ = origin_time;
  2665. tag_cache_[replace_index].X_ = X;
  2666. tag_cache_[replace_index].Y_ = Y;
  2667.       }
  2668.     }
  2669.     else {
  2670.       // If this is a query pkt; check if we have the relevant information 
  2671.       // cached. TTL = 600 seconds for the cache entries
  2672.       found = FALSE;
  2673.       for(int i = 0; i < num_cached_items_; ++i) {
  2674. if(tag_cache_[i].obj_name_ == obj_name && tag_cache_[i].origin_time_ > origin_time - 600) {
  2675.   found = TRUE;
  2676.   cache_index = i;
  2677.   break;
  2678. }
  2679.       }
  2680.     }
  2681.   }
  2682.   // Loop check i.e., if response to our query agent has looped back
  2683.   // Following not the correct condition to detect a loop!
  2684.   //  assert(!(iph->daddr() == myaddr_ && iph->dport() == 0));
  2685.   // Reduce the source route to just parent-children (O(#levels))
  2686.   // This is possible since parent and child in each others vicinity
  2687.   cmh->direction() = hdr_cmn::DOWN;
  2688.   if(iph->daddr() == myaddr_)
  2689.     query_for_us = TRUE;
  2690.   // Query pkt if X and Y are 65000
  2691.   if(X == 65000 && Y == 65000) {
  2692.     if(query_for_us || found) {
  2693.       if(qry_debug_)
  2694. trace("Node %d: Rcved qry for us from node %d at time %f",myaddr_,last_hop_id,s.clock());
  2695.       if(!found)
  2696. dst_nodes = search_tag(obj_name,prev_hop_level,next_hop_level,last_hop_id,&num_dst);
  2697.       if((num_dst == 0 && dst_nodes) || found) {
  2698. delete dst_nodes;
  2699. // if num_dst = 0 but dst_nodes is not NULL, we sense the
  2700. // requested tag; add X,Y info and send response
  2701. // if found is true, we have the cached information
  2702. if(found) {
  2703.   (*X_ptr++) = ((int)tag_cache_[cache_index].X_ >> 8) & 0xFF;
  2704.   (*X_ptr) = ((int)tag_cache_[cache_index].X_) & 0xFF;
  2705.   (*Y_ptr++) = ((int)tag_cache_[cache_index].Y_ >> 8) & 0xFF;
  2706.   (*Y_ptr) = ((int)tag_cache_[cache_index].Y_) & 0xFF;
  2707. }
  2708. else {
  2709.   node_->getLoc(&local_x, &local_y, &local_z);
  2710.   (*X_ptr++) = ((int)local_x >> 8) & 0xFF;
  2711.   (*X_ptr) = ((int)local_x) & 0xFF;
  2712.   (*Y_ptr++) = ((int)local_y >> 8) & 0xFF;
  2713.   (*Y_ptr) = ((int)local_y) & 0xFF;
  2714. }
  2715. // Send response
  2716. iph->ttl_ = 1000;
  2717. // Add 50 bytes to response 
  2718. cmh->size() += 50;
  2719. // Query from an agent at our node
  2720. if(!num_src_hops) {
  2721.   iph->daddr() = myaddr_;
  2722.   iph->dport() = 0;
  2723.   cmh->next_hop_ = myaddr_;
  2724. }
  2725. else {
  2726.   --num_src_hops;
  2727.   *num_src_hops_ptr = (num_src_hops >> 8) & 0xFF;
  2728.   *(num_src_hops_ptr + 1) = num_src_hops & 0xFF;
  2729.   // Decr pkt size
  2730.   cmh->size() -= 4;
  2731.   iph->daddr() = *last_hop_ptr++;
  2732.   iph->daddr() = (iph->daddr() << 8) | *last_hop_ptr++;
  2733.   if(!num_src_hops)
  2734.     iph->dport() = 0;
  2735.   else
  2736.     iph->dport() = ROUTER_PORT;
  2737.   
  2738.   int relevant_level = *last_hop_ptr;
  2739.   cmh->next_hop_ = get_next_hop(iph->daddr(),relevant_level);
  2740.   //   assert(cmh->next_hop_ != NO_NEXT_HOP);   
  2741.   if(cmh->next_hop_ == NO_NEXT_HOP) {
  2742.     Packet::free(p);
  2743.     trace("Node %d: Packet dropped because of no next hop info",myaddr_);
  2744.     return;
  2745.   }
  2746.   *level_ptr = *last_hop_ptr;   
  2747. }
  2748. // if(found) 
  2749.   //   trace("Node %d: Gen response from cache at time %f to node %d",myaddr_,s.clock(),iph->daddr());
  2750. // else
  2751.   //   trace("Node %d: Gen response at time %f to node %d",myaddr_,s.clock(),iph->daddr() >> 8);
  2752. if(!num_src_hops && iph->daddr() == myaddr_) {
  2753.   // TEMPORARY HACK! Cant forward from routing agent to some other
  2754.   // agent on our node!
  2755.   Packet::free(p);
  2756.   trace("Node %d: Found object %d.%d.%d at (%d,%d) at time %f",myaddr_, (obj_name >> 24) & 0xFF, (obj_name >> 16) & 0xFF, obj_name & 0xFFFF,X,Y,s.clock());
  2757.   return;
  2758. }
  2759. else if(iph->daddr() == myaddr_) {
  2760.   ForwardPacket(p);
  2761. }
  2762. else {
  2763.   s.schedule(target_,p,0);
  2764. }
  2765.       }
  2766.       else if(num_dst >= 1) {
  2767. if(--iph->ttl_ == 0) {
  2768.   drop(p, DROP_RTR_TTL);
  2769.   return;
  2770. }
  2771. // Add ourself to source route and increase the number of src hops
  2772. // if(last_hop_id != myaddr_) {
  2773. ++num_src_hops;
  2774. *num_src_hops_ptr = (num_src_hops >> 8) & 0xFF;
  2775. *(num_src_hops_ptr+1) = num_src_hops & 0xFF;
  2776. *pkt_end_ptr++ = (myaddr_ >> 8) & 0xFF;
  2777. *pkt_end_ptr++ = myaddr_ & 0xFF;
  2778. // Indicate the level of the pcl object that a node should look-up
  2779. // to find the relevant routing table entry
  2780. *pkt_end_ptr = (next_hop_level+1) & 0xFF;
  2781. // Incr pkt size
  2782. cmh->size() += 4;
  2783. dst_ptr = dst_nodes;
  2784. // Replicate pkt to each destination
  2785. iph->daddr() = dst_ptr->dst_node_;
  2786. iph->dport() = ROUTER_PORT;
  2787. cmh->next_hop_ = dst_ptr->dst_next_hop_;
  2788. cmh->addr_type_ = NS_AF_INET;
  2789. // Copy next hop variable to this variable temporarily
  2790. // Copy it back into packet before sending the packet
  2791. int tmp_next_hop_level = dst_ptr->next_hop_level_;
  2792. if(qry_debug_)
  2793.   trace("Node %d: Forwarding qry to node %d at time %f",myaddr_,dst_ptr->dst_node_,s.clock());
  2794. dst_ptr = dst_ptr->next_;
  2795. delete dst_nodes;
  2796. dst_nodes = dst_ptr;
  2797. for(int i = 1; i < num_dst; ++i) {
  2798.   if(qry_debug_)
  2799.     trace("Node %d: Forwarding qry to node %d at time %f",myaddr_,dst_ptr->dst_node_,s.clock());
  2800.   // Change level and copy the packet
  2801.   *level_ptr = dst_ptr->next_hop_level_;
  2802.   newp = p->copy();
  2803.   new_iph = HDR_IP(newp);
  2804.   new_cmh = HDR_CMN(newp);
  2805.   new_iph->daddr() = dst_ptr->dst_node_;
  2806.   new_iph->dport() = ROUTER_PORT;
  2807.   new_cmh->next_hop_ = dst_ptr->dst_next_hop_;
  2808.   new_cmh->addr_type_ = NS_AF_INET;
  2809.   if(new_iph->daddr() == myaddr_)
  2810.     ForwardPacket(newp);
  2811.   else
  2812.     s.schedule(target_,newp,0);
  2813.   dst_ptr = dst_ptr->next_;
  2814.   delete dst_nodes;
  2815.   dst_nodes = dst_ptr;
  2816. }
  2817. *level_ptr = tmp_next_hop_level;
  2818. if(iph->daddr() == myaddr_) {
  2819.   ForwardPacket(p);
  2820. }
  2821. else
  2822.   s.schedule(target_,p,0);
  2823.       }
  2824.       else if(num_dst == 0) {
  2825. // Free packet if we dont have any dst to forward packet
  2826. if(qry_debug_)
  2827.   trace("Node %d: Dropping query from %d at time %f,num_src_hops %d",myaddr_,iph->saddr(),s.clock(),num_src_hops);
  2828. Packet::free(p);
  2829. return;
  2830.       }
  2831.     }
  2832.     else {
  2833.       // simply forward to next hop
  2834.       if(qry_debug_)
  2835. trace("Node %d: Forwarding query to node %d at time %f,num_src_hops %d",myaddr_,iph->daddr(),s.clock(),num_src_hops);
  2836.       if(--iph->ttl_ == 0) {
  2837. drop(p, DROP_RTR_TTL);
  2838.         return;
  2839.       }
  2840.       cmh->next_hop_ = get_next_hop(iph->daddr(),next_hop_level+1);
  2841.       //      assert(cmh->next_hop_ != NO_NEXT_HOP);   
  2842.       if(cmh->next_hop_ == NO_NEXT_HOP) {
  2843. Packet::free(p);
  2844. trace("Node %d: Packet dropped because of no next hop info",myaddr_);
  2845. return;
  2846.       }
  2847.       s.schedule(target_,p,0);
  2848.     }
  2849.   }
  2850.   else {
  2851.     // Forward the response packet
  2852.     if(qry_debug_)
  2853.       trace("Node %d: Forwarding response to node %d at time %f,num_src_hops %d",myaddr_,iph->daddr(),s.clock(),num_src_hops);
  2854.     if(--iph->ttl_ == 0) {
  2855.       drop(p, DROP_RTR_TTL);
  2856.       return;
  2857.     }
  2858.     // Check if query from an agent at our node
  2859.     if(query_for_us) {
  2860.       if(!num_src_hops) {
  2861. iph->daddr() = myaddr_;
  2862. iph->dport() = 0;
  2863. cmh->next_hop_ = myaddr_;
  2864.       }
  2865.       else {
  2866. --num_src_hops;
  2867. *num_src_hops_ptr = (num_src_hops >> 8) & 0xFF;
  2868. *(num_src_hops_ptr + 1) = num_src_hops & 0xFF;
  2869. // Decr pkt size
  2870. cmh->size() -= 4;
  2871. iph->daddr() = *last_hop_ptr++;
  2872. iph->daddr() = (iph->daddr() << 8) | *last_hop_ptr++;
  2873. if(!num_src_hops)
  2874.   iph->dport() = 0;
  2875. else
  2876.   iph->dport() = ROUTER_PORT;
  2877. int relevant_level = *last_hop_ptr;
  2878. cmh->next_hop_ = get_next_hop(iph->daddr(),relevant_level);
  2879. // assert(cmh->next_hop_ != NO_NEXT_HOP);   
  2880. if(cmh->next_hop_ == NO_NEXT_HOP) {
  2881.   Packet::free(p);
  2882.   trace("Node %d: Packet dropped because of no next hop info",myaddr_);
  2883.   return;
  2884. }
  2885. *level_ptr = *last_hop_ptr;   
  2886.       }
  2887.       if(!num_src_hops && iph->daddr() == myaddr_) {
  2888. // TEMPORARY HACK! Cant forward from routing agent to some other
  2889. // agent on our node!
  2890. Packet::free(p);
  2891. trace("Node %d: Found object %d.%d.%d at (%d,%d) at time %f",myaddr_, (obj_name >> 24) & 0xFF, (obj_name >> 16) & 0xFF, obj_name & 0xFFFF,X,Y,s.clock());
  2892. return;
  2893.       }
  2894.       else if(iph->daddr() == myaddr_)
  2895. ForwardPacket(p);
  2896.       else
  2897. s.schedule(target_,p,0);      
  2898.     }
  2899.     else {
  2900.       cmh->next_hop_ = get_next_hop(iph->daddr(),next_hop_level);
  2901.       //      assert(cmh->next_hop_ != NO_NEXT_HOP);   
  2902.       if(cmh->next_hop_ == NO_NEXT_HOP) {
  2903. Packet::free(p);
  2904. trace("Node %d: Packet dropped because of no next hop info",myaddr_);
  2905. return;
  2906.       }
  2907.       s.schedule(target_,p,0);
  2908.     }
  2909.   }
  2910. }
  2911. NodeIDList *
  2912. LandmarkAgent::search_tag(int obj_name, int prev_hop_level, int next_hop_level,nsaddr_t last_hop_id, int *num_dst)
  2913. {
  2914.   ParentChildrenList *pcl = parent_children_list_;
  2915.   LMNode *child;
  2916.   compr_taglist *tag_ptr;
  2917.   int forward = FALSE;
  2918.   NodeIDList *nlist = NULL, *nlist_ptr = NULL;
  2919.   int p1, p2, p3, q1, q2, q3;
  2920.   int match = 0, exact_match = 0;
  2921.   *num_dst = 0;
  2922.   // Check if our node senses the requested tag
  2923.   while(pcl) {
  2924.     if(pcl->level_ == 0)
  2925.       break;
  2926.     pcl = pcl->next_;
  2927.   }
  2928.   if(!pcl)
  2929.     return(NULL);
  2930.   // if our node senses the tag, add the node to nlist but do not increase
  2931.   // num_dst
  2932.   tag_ptr = pcl->tag_list_;
  2933.   while(tag_ptr) {
  2934.     if(tag_ptr->obj_name_ == obj_name) {
  2935.       nlist = new NodeIDList;
  2936.       nlist->dst_node_ = myaddr_;
  2937.       nlist->dst_next_hop_ = myaddr_;
  2938.       return(nlist);
  2939.     }
  2940.     tag_ptr = tag_ptr->next_;
  2941.   }
  2942.   // If next_hop_level = 2, lookup would be done in the level 2 object
  2943.   // that would have level 1 tag aggregates
  2944.   //  if(next_hop_level == 2)
  2945.   //    obj_name = obj_name & 0xFFFF0000;
  2946.   //  else if(next_hop_level >= 3)
  2947.   //    obj_name = obj_name & 0xFF000000;
  2948.   p1 = (obj_name >> 24) & 0xFF;
  2949.   p2 = (obj_name >> 16) & 0xFF;
  2950.   p3 = obj_name & 0xFFFF;
  2951.   pcl = parent_children_list_;
  2952.   while(pcl) {
  2953.     if(pcl->level_ == next_hop_level)
  2954.       break;
  2955.     pcl = pcl->next_;
  2956.   }
  2957.   if(!pcl)
  2958.     return(NULL);
  2959.   //  assert(pcl);
  2960.   child = pcl->pchildren_;
  2961.   while(child) {
  2962.     // Dont forward back to child if child forwarded this query to us
  2963.     // We should forward to all children though if the message is going
  2964.     // down the hierarchy
  2965.     forward = FALSE;
  2966.     if(next_hop_level < prev_hop_level || (child->id_ != last_hop_id && next_hop_level >= prev_hop_level))
  2967.       forward = TRUE;
  2968.     if(child->child_flag_ == IS_CHILD && forward) {
  2969.       tag_ptr = child->tag_list_;
  2970.       match = 0;
  2971.       exact_match = 0;
  2972.       while(tag_ptr) {
  2973. q1 = (tag_ptr->obj_name_ >> 24) & 0xFF;
  2974. q2 = (tag_ptr->obj_name_ >> 16) & 0xFF;
  2975. q3 = tag_ptr->obj_name_ & 0xFFFF;
  2976. if(p1 == q1 && p2 == q2 && p3 == q3)
  2977.   exact_match = 1;
  2978. else if((p1 == q1 && p2 == q2 && !q3) || (p1 == q1 && !q2 && !q3))
  2979.   match = 1;
  2980. if(match) {
  2981.   if(!nlist) {
  2982.     nlist = new NodeIDList;
  2983.     nlist_ptr = nlist;
  2984.   }
  2985.   else {
  2986.     nlist_ptr->next_ = new NodeIDList;
  2987.     nlist_ptr = nlist_ptr->next_;
  2988.   }
  2989.   nlist_ptr->dst_node_ = child->id_;
  2990.   nlist_ptr->dst_next_hop_ = child->next_hop_;
  2991.   nlist_ptr->next_hop_level_= next_hop_level - 1;
  2992.   ++(*num_dst);
  2993.   break;
  2994. }
  2995. else if(exact_match) {
  2996.   // Delete all old elements
  2997.   NodeIDList *n1, *n2;
  2998.   n1 = nlist;
  2999.   while(n1) {
  3000.     n2 = n1;
  3001.     n1 = n1->next_;
  3002.     delete n2;
  3003.   }
  3004.   // Return just single element i.e., the ID of the child with an
  3005.   // exact match for the object name
  3006.   nlist = new NodeIDList;
  3007.   nlist->dst_node_ = child->id_;
  3008.   nlist->dst_next_hop_ = child->next_hop_;
  3009.   nlist->next_hop_level_= next_hop_level - 1;
  3010.   (*num_dst) = 1;
  3011.   return(nlist);
  3012. }
  3013. tag_ptr = tag_ptr->next_;
  3014.       }
  3015.     }
  3016.     child = child->next_;
  3017.   }
  3018.   // Add parent if query is travelling up the hierarchy
  3019.   if(next_hop_level >= prev_hop_level && pcl->parent_) {
  3020.     if(!nlist) {
  3021.       nlist = new NodeIDList;
  3022.       nlist_ptr = nlist;
  3023.     }
  3024.     else {
  3025.       nlist_ptr->next_ = new NodeIDList;
  3026.       nlist_ptr = nlist_ptr->next_;
  3027.     }
  3028.     nlist_ptr->dst_node_ = (pcl->parent_)->id_;
  3029.     nlist_ptr->dst_next_hop_ = (pcl->parent_)->next_hop_;
  3030.     nlist_ptr->next_hop_level_= next_hop_level + 1;
  3031.     ++(*num_dst);
  3032.   }
  3033.   return(nlist);
  3034. }
  3035. nsaddr_t
  3036. LandmarkAgent::get_next_hop(nsaddr_t dst, int next_hop_level)
  3037. {
  3038.   ParentChildrenList *pcl = parent_children_list_;
  3039.   LMNode *pchild;
  3040.   while(pcl->level_ != next_hop_level) {
  3041.     pcl = pcl->next_;
  3042.   }
  3043.   
  3044.   assert(pcl);
  3045.   pchild = pcl->pchildren_;
  3046.   while(pchild) {
  3047.     if(pchild->id_ == dst)
  3048.       return(pchild->next_hop_);
  3049.     pchild = pchild->next_;
  3050.   }
  3051.   return(NO_NEXT_HOP);
  3052. }
  3053. void
  3054. LandmarkAgent::get_nbrinfo()
  3055. {
  3056.   ParentChildrenList *pcl;
  3057.   LMNode *pchild;
  3058.   int num_nbrs = 0;
  3059.   pcl = parent_children_list_;
  3060.   
  3061.   if(!pcl) {
  3062.     trace("Node %d: Neighbour info not available; perhaps the node is down");
  3063.     return;
  3064.   }
  3065.   while(pcl) {
  3066.     if(pcl->level_ == 1)
  3067.       break;
  3068.     pcl = pcl->next_;
  3069.   }
  3070.   //  assert(pcl);
  3071.   if(!pcl) {
  3072.     trace("Node %d: Neighbour info not available; perhaps the node is down");
  3073.     return;
  3074.   }
  3075.   pchild = pcl->pchildren_;
  3076.   //  assert(pchild);
  3077.   while(pchild) {
  3078.     if(pchild->num_hops_ == 1)
  3079.       ++num_nbrs;
  3080.     pchild = pchild->next_;
  3081.   }
  3082.   
  3083.   trace("Node %d: Number of neighbours: %d",myaddr_,num_nbrs);
  3084. }
  3085. void
  3086. LandmarkAgent::MoveTags() {
  3087.   ParentChildrenList *pcl = parent_children_list_;
  3088.   compr_taglist *tag = NULL, *prev_tag, *next_tag;
  3089.   int removed_tag = 0, our_tags_changed = 0;
  3090.   trace("Node %d: Moving tags at time %f", myaddr_,NOW);
  3091.   
  3092.   if(!pcl && !mobile_tags_) {
  3093.     Scheduler::instance().schedule(tag_mobility_,tag_mobility_event_,tag_rng_->uniform(mobility_period_));
  3094.     return;
  3095.   }
  3096.   
  3097.   if(pcl) {
  3098.     // Get level 0 pcl object
  3099.     while(pcl) {
  3100.       if(pcl->level_ == 0)
  3101. break;
  3102.       pcl = pcl->next_;
  3103.     }
  3104.     assert(pcl);
  3105.   }    
  3106.   
  3107.   // Pick tag(s) at random and move them to one of the neighbours
  3108.   // Only tags with the last field > 5 are mobile.
  3109.   if(pcl)
  3110.     tag = pcl->tag_list_;
  3111.   else
  3112.     tag = mobile_tags_;
  3113.   
  3114.   prev_tag = tag;
  3115.   while(tag) {
  3116.     removed_tag = 0;
  3117.     // Tags with last field < 30 are not mobile
  3118.     if((tag->obj_name_ & 0xFFFF) > 30) {
  3119.       // Move tag to neighbouring node with probability of 0.3
  3120.       int n = tag_rng_->uniform(10);
  3121.       if(n <= 2) {
  3122. assert(nbrs_);
  3123. int nbr_index = tag_rng_->uniform(num_nbrs_);
  3124. LandmarkAgent *nbr_agent = (LandmarkAgent *)AgentList::instance()->GetAgent(nbrs_[nbr_index]);
  3125. assert(nbr_agent);
  3126. trace("Node %d: Moving tag %d.%d.%d at time %f to nbr %d",myaddr_,(tag->obj_name_ >> 24) & 0xFF,(tag->obj_name_ >> 16) & 0xFF,tag->obj_name_ & 0xFFFF,NOW,nbrs_[nbr_index]);
  3127. // Remove tag from our list
  3128. removed_tag = 1;
  3129. our_tags_changed = 1;
  3130. if(prev_tag == tag) {
  3131.   if(pcl)
  3132.     pcl->tag_list_ = tag->next_;
  3133.   else if(mobile_tags_)
  3134.     mobile_tags_ = tag->next_;
  3135.   prev_tag = tag->next_;
  3136. }
  3137. else
  3138.   prev_tag->next_ = tag->next_;
  3139. next_tag = tag->next_;
  3140. if(pcl)
  3141.   --(pcl->num_tags_);
  3142. // Add this tag to neighbouring node
  3143. nbr_agent->AddMobileTag(tag);
  3144.       }
  3145.     }
  3146.     if(!removed_tag) {
  3147.       prev_tag = tag;
  3148.       tag = tag->next_;
  3149.     }
  3150.     else {
  3151.       tag = next_tag;
  3152.     }
  3153.   }
  3154.   // Trigger hierarchy advertisement if our taglist has changed
  3155.   if(our_tags_changed)
  3156.     SendChangedTagListUpdate(our_tags_changed,0);
  3157.   
  3158.   Scheduler::instance().schedule(tag_mobility_,tag_mobility_event_,tag_rng_->uniform(mobility_period_));
  3159. }
  3160. void
  3161. LandmarkAgent::AddMobileTag(void *mobile_tag)
  3162. {
  3163.   ParentChildrenList *pcl = parent_children_list_;
  3164.   compr_taglist *tag = NULL, *new_tag = (compr_taglist *)mobile_tag;
  3165.   // Make sure that this tag object is not pointing to next member on
  3166.   // the previous list that this tag was part of
  3167.   new_tag->next_ = NULL;
  3168.   if(pcl) {
  3169.     // Get level 0 pcl object
  3170.     while(pcl) {
  3171.       if(pcl->level_ == 0)
  3172. break;
  3173.       pcl = pcl->next_;
  3174.     }
  3175.     assert(pcl);
  3176.     ++(pcl->num_tags_);
  3177.     
  3178.     if(!pcl->tag_list_) {
  3179.       pcl->tag_list_ = new_tag;
  3180.     }
  3181.     else {
  3182.       tag = pcl->tag_list_;
  3183.       while(tag->next_) {
  3184. tag = tag->next_;
  3185.       }
  3186.       tag->next_ = new_tag;
  3187.     }
  3188.   }
  3189.   else {
  3190.     if(!mobile_tags_) {
  3191.       mobile_tags_ = new_tag;
  3192.     }
  3193.     else {
  3194.       tag = mobile_tags_;
  3195.       while(tag->next_) {
  3196. tag = tag->next_;
  3197.       }
  3198.       tag->next_ = new_tag;
  3199.     }
  3200.   }
  3201.   // Trigger hierarchy advertisements after a mean of 5 seconds if
  3202.   // the advt event has not already been scheduled
  3203.   if(tag_advt_event_->uid_ < 0)
  3204.     Scheduler::instance().schedule(tag_advt_handler_, tag_advt_event_, Random::uniform(10));
  3205. }
  3206. // new tag info received for specified level; Send updates if necessary
  3207. // i.e., if aggregates have changed etc.
  3208. void
  3209. LandmarkAgent::SendChangedTagListUpdate(int our_tag_changed, int level)
  3210. {
  3211.   ParentChildrenList *pcl = parent_children_list_;
  3212.   ParentChildrenList *child_pcl, *parent_pcl;
  3213.   compr_taglist *tag_ptr1 = NULL, *tag_ptr2 = NULL, *tag_list = NULL;
  3214.   compr_taglist *agg_tags = NULL;
  3215.   LMNode *lmnode;
  3216.   int upd_time, num_tags = 0;
  3217.   Scheduler &s = Scheduler::instance();
  3218.   double now = s.clock();
  3219.   if(node_dead_ || !pcl || level >= highest_level_)
  3220.     return;
  3221.   if(myaddr_ == 45)
  3222.     trace("Node %d: SendChangedTagListUpdate, level %d at time %f",myaddr_,level,now);
  3223.   while(pcl) {
  3224.     if(pcl->level_ == level)
  3225.       child_pcl = pcl;
  3226.     else if(pcl->level_ == level + 1) 
  3227.       parent_pcl = pcl;
  3228.     pcl = pcl->next_;
  3229.   }
  3230.   
  3231.   if(our_tag_changed) {
  3232.     assert(level == 0);
  3233.     upd_time = (int) now;
  3234.     upd_time = (upd_time << 16) | (parent_pcl->seqnum_ & 0xFFFF);
  3235.     ++(parent_pcl->seqnum_);
  3236.     parent_pcl->UpdatePotlChild(myaddr_, myaddr_,0,0,0,(int) node_->energy(),upd_time,IS_CHILD,FALSE,child_pcl->tag_list_);
  3237.     // Send out hierarchy advertisement since the tag list has changed
  3238.     Packet *newp = makeUpdate(child_pcl,HIER_ADVS,PERIODIC_ADVERTS);
  3239.     child_pcl->last_update_sent_ = now;
  3240.     s.schedule(target_,newp,0);
  3241.   }
  3242.   
  3243.   while(level < highest_level_) {
  3244.     if(myaddr_ == 45)
  3245.       trace("Node %d: Updating tag lists, level %d",myaddr_,level);
  3246.     
  3247.     lmnode = parent_pcl->pchildren_;
  3248.     tag_list = NULL;
  3249.     // Loop through all the children and add tags to tag_list
  3250.     while(lmnode) {
  3251.       if(lmnode->child_flag_ == IS_CHILD) {
  3252. tag_ptr1 = lmnode->tag_list_;
  3253.     
  3254. while(tag_ptr1) {
  3255.   if(!tag_list) {
  3256.     tag_list = new compr_taglist;
  3257.     tag_ptr2 = tag_list;
  3258.   }
  3259.   else {
  3260.     tag_ptr2->next_ = new compr_taglist;
  3261.     tag_ptr2 = tag_ptr2->next_;
  3262.   }
  3263.   //        trace("tag name: %d.%d.%d",(tag_ptr1->obj_name_ >> 24) & 0xFF,(tag_ptr1->obj_name_ >> 16) & 0xFF,(tag_ptr1->obj_name_) & 0xFFFF);
  3264.   tag_ptr2->obj_name_ = tag_ptr1->obj_name_;
  3265.   tag_ptr1 = tag_ptr1->next_;
  3266. }
  3267.       }
  3268.       lmnode = lmnode->next_;
  3269.     }
  3270.     
  3271.     // Aggregate tag_list
  3272.     agg_tags = aggregate_taginfo(tag_list,parent_pcl->level_,&num_tags);
  3273.     
  3274.     // Delete tag_list
  3275.     tag_ptr1 = tag_list;
  3276.     while(tag_ptr1) {
  3277.       tag_ptr2 = tag_ptr1;
  3278.       tag_ptr1 = tag_ptr1->next_;
  3279.       delete tag_ptr2;
  3280.     }
  3281.     
  3282.     if(!compare_tag_lists(parent_pcl->tag_list_,parent_pcl->num_tags_,agg_tags,num_tags)) {
  3283.       // Delete parent_pcl's tag_list and update with new tag_list
  3284.       tag_ptr1 = parent_pcl->tag_list_;
  3285.       while(tag_ptr1) {
  3286. tag_ptr2 = tag_ptr1;
  3287. tag_ptr1 = tag_ptr1->next_;
  3288. delete tag_ptr2;
  3289.       }
  3290.       parent_pcl->tag_list_ = agg_tags;
  3291.       parent_pcl->num_tags_ = num_tags;
  3292.       // Send out hierarchy advertisement since the tag list has changed
  3293.       Packet *newp = makeUpdate(parent_pcl,HIER_ADVS,PERIODIC_ADVERTS);
  3294.       parent_pcl->last_update_sent_ = now;
  3295.       s.schedule(target_,newp,0);
  3296.    
  3297.       ++level;
  3298.       // Update our tag list in the higher level pcl object
  3299.       pcl = parent_children_list_;
  3300.       parent_pcl = NULL;
  3301.       child_pcl = NULL;
  3302.       while(pcl) {
  3303. if(pcl->level_ == level)
  3304.   child_pcl = pcl;
  3305. else if(pcl->level_ == level + 1) 
  3306.   parent_pcl = pcl;
  3307. pcl = pcl->next_;
  3308.       }
  3309.       upd_time = (int) now;
  3310.       upd_time = (upd_time << 16) | (parent_pcl->seqnum_ & 0xFFFF);
  3311.       ++(parent_pcl->seqnum_);
  3312.       parent_pcl->UpdatePotlChild(myaddr_, myaddr_,0,0,0,(int) node_->energy(),upd_time,IS_CHILD,FALSE,child_pcl->tag_list_);
  3313.     }
  3314.     else {
  3315.       // Delete agg_tags
  3316.       tag_ptr1 = agg_tags;
  3317.       while(tag_ptr1) {
  3318. tag_ptr2 = tag_ptr1;
  3319. tag_ptr1 = tag_ptr1->next_;
  3320. delete tag_ptr2;
  3321.       }
  3322.       break;
  3323.     }
  3324.   }
  3325. }
  3326. int
  3327. LandmarkAgent::compare_tag_lists(compr_taglist *tag_list1, int num_tags1, compr_taglist *tag_list2, int num_tags2)
  3328. {
  3329.   compr_taglist *tag1 = tag_list1, *tag2 = tag_list2;
  3330.   int found;
  3331.   // if num_tags == -1, it means that the number of tags was not computed
  3332.   if(num_tags1 == -1) {
  3333.     num_tags1 = 0;
  3334.     while(tag1) {
  3335.       ++num_tags1;
  3336.       tag1 = tag1->next_;
  3337.     }
  3338.     tag1 = tag_list1;
  3339.   }
  3340.   if(num_tags2 == -1) {
  3341.     num_tags2 = 0;
  3342.     while(tag2) {
  3343.       ++num_tags2;
  3344.       tag2 = tag2->next_;
  3345.     }
  3346.     tag2 = tag_list2;
  3347.   }
  3348.   if(num_tags1 != num_tags2)
  3349.     return(FALSE);
  3350.   while(tag1) {
  3351.     found = 0;
  3352.     while(tag2) {
  3353.       if(tag1->obj_name_ == tag2->obj_name_) {
  3354. found = 1;
  3355. break;
  3356.       }
  3357.       tag2 = tag2->next_;
  3358.     }
  3359.     if(!found)
  3360.       return(FALSE);
  3361.     tag1 = tag1->next_;
  3362.   }
  3363.   return(TRUE);
  3364. }