00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <stdarg.h>
00052 #include <float.h>
00053
00054 #include "landmark.h"
00055 #include <random.h>
00056 #include <cmu-trace.h>
00057 #include <address.h>
00058
00059 static int lm_index = 0;
00060
00061
00062 void
00063 LMNode::copy_tag_list(compr_taglist *taglist)
00064 {
00065 compr_taglist *tags = NULL;
00066 compr_taglist *tag_ptr1, *tag_ptr2;
00067
00068
00069 if(tag_list_) {
00070 tag_ptr1 = tag_list_;
00071 while(tag_ptr1) {
00072 tag_ptr2 = tag_ptr1;
00073 tag_ptr1 = tag_ptr1->next_;
00074 delete tag_ptr2;
00075 }
00076 tag_list_ = NULL;
00077 }
00078
00079
00080 tag_ptr1 = taglist;
00081 while(tag_ptr1) {
00082 if(!tag_list_) {
00083 tag_list_ = new compr_taglist;
00084 tag_ptr2 = tag_list_;
00085 }
00086 else {
00087 tag_ptr2->next_ = new compr_taglist;
00088 tag_ptr2 = tag_ptr2->next_;
00089 }
00090 tag_ptr2->obj_name_ = tag_ptr1->obj_name_;
00091 tag_ptr1 = tag_ptr1->next_;
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100 inline double
00101 LandmarkAgent::jitter(double max, int be_random_)
00102 {
00103 return (be_random_ ? Random::uniform(max) : 0);
00104 }
00105
00106
00107
00108
00109 inline double
00110 LandmarkAgent::random_timer(double max, int be_random_)
00111 {
00112 return (be_random_ ? rn_->uniform(max) : 0);
00113 }
00114
00115
00116
00117 void
00118 LandmarkAgent::stop()
00119 {
00120 ParentChildrenList *pcl = parent_children_list_, *tmp_pcl;
00121
00122 trace("Node %d: LM Agent going down at time %f",myaddr_,NOW);
00123
00124
00125 if(promo_timer_running_) {
00126 promo_timer_running_ = 0;
00127 promo_timer_->cancel();
00128 }
00129 num_resched_ = 0;
00130 wait_state_ = 0;
00131 total_wait_time_ = 0;
00132
00133
00134 highest_level_ = 0;
00135
00136
00137 while(pcl) {
00138 tmp_pcl = pcl;
00139 pcl = pcl->next_;
00140 delete tmp_pcl;
00141 }
00142 parent_children_list_ = NULL;
00143
00144
00145 node_dead_ = 1;
00146
00147 global_lm_id_ = NO_GLOBAL_LM;
00148 global_lm_level_ = -1;
00149
00150
00151 if(tag_advt_event_->uid_ > 0) {
00152 Scheduler &s = Scheduler::instance();
00153 s.cancel(tag_advt_event_);
00154 }
00155 }
00156
00157
00158
00159
00160
00161 void LandmarkAgent::
00162 trace (char *fmt,...)
00163 {
00164 va_list ap;
00165
00166 if (!tracetarget_)
00167 return;
00168
00169
00170 va_start (ap, fmt);
00171
00172 vsprintf (tracetarget_->buffer (), fmt, ap);
00173 tracetarget_->dump ();
00174
00175 va_end (ap);
00176 }
00177
00178
00179
00180 static class LandmarkClass:public TclClass
00181 {
00182 public:
00183 LandmarkClass ():TclClass ("Agent/landmark")
00184 {
00185 }
00186 TclObject *create (int, const char *const *)
00187 {
00188 return (new LandmarkAgent ());
00189 }
00190 } class_landmark;
00191
00192
00193
00194
00195 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)
00196 {
00197
00198 promo_timer_ = new PromotionTimer(this);
00199
00200
00201 num_resched_ = 0;
00202 tag_dbase_ = NULL;
00203 node_ = NULL;
00204
00205 cache_ = 0;
00206 tag_cache_ = new TagCache[MAX_CACHE_ITEMS];
00207 num_cached_items_ = 0;
00208
00209 recent_demotion_msgs_ = new RecentMsgRecord[MAX_DEMOTION_RECORDS];
00210 num_demotion_msgs_ = 0;
00211
00212
00213 update_period_ = 400;
00214 update_timeout_ = update_period_ + 4 * LM_STARTUP_JITTER;
00215
00216 adverts_type_ = FLOOD;
00217 global_lm_ = 0;
00218 global_lm_id_ = NO_GLOBAL_LM;
00219 global_lm_level_ = -1;
00220
00221
00222 rn_ = new RNG(RNG::RAW_SEED_SOURCE,lm_index++);;
00223
00224 for(int i = 0; i < 128; ++i) {
00225 rn_->uniform(200);
00226 }
00227
00228 node_dead_ = 0;
00229
00230 bind ("be_random_", &be_random_);
00231
00232 bind ("debug_", &debug_);
00233
00234 num_nbrs_ = 0;
00235 nbrs_ = NULL;
00236
00237 tag_mobility_ = new TagMobilityHandler(this);
00238 tag_mobility_event_ = new Event;
00239
00240
00241 tag_rng_ = new RNG(RNG::RAW_SEED_SOURCE,lm_index++);;
00242
00243 for(int i = 0; i < 128; ++i) {
00244 tag_rng_->uniform(200);
00245 }
00246
00247 mobility_period_ = 60;
00248 mobile_tags_ = NULL;
00249
00250 tag_advt_handler_ = new TagAdvtHandler(this);
00251 tag_advt_event_ = new Event;
00252 }
00253
00254
00255
00256
00257 int
00258 LandmarkAgent::CheckDemotionMsg(nsaddr_t id, int level, int origin_time)
00259 {
00260 int i = 0;
00261
00262
00263 for(i = 0; i < num_demotion_msgs_; ++i) {
00264 if(recent_demotion_msgs_[i].id_ == id && recent_demotion_msgs_[i].level_ == level) {
00265 if(recent_demotion_msgs_[i].origin_time_ >= origin_time) {
00266 return(OLD_MESSAGE);
00267 }
00268 else {
00269 recent_demotion_msgs_[i].origin_time_ = origin_time;
00270 return(NEW_ENTRY);
00271 }
00272 }
00273 }
00274
00275 if(num_demotion_msgs_ < MAX_DEMOTION_RECORDS) {
00276 i = num_demotion_msgs_;
00277 ++num_demotion_msgs_;
00278 recent_demotion_msgs_[i].id_ = id;
00279 recent_demotion_msgs_[i].level_ = level;
00280 recent_demotion_msgs_[i].origin_time_ = origin_time;
00281 }
00282 else {
00283
00284 int replace_index = 0;
00285 int least_time = recent_demotion_msgs_[replace_index].origin_time_;
00286 for(i = 0; i < MAX_DEMOTION_RECORDS; ++i) {
00287 if(recent_demotion_msgs_[i].origin_time_ < least_time)
00288 replace_index = i;
00289 }
00290 recent_demotion_msgs_[replace_index].id_ = id;
00291 recent_demotion_msgs_[replace_index].level_ = level;
00292 recent_demotion_msgs_[replace_index].origin_time_ = origin_time;
00293 }
00294 return(NEW_ENTRY);
00295 }
00296
00297
00298
00299
00300 void
00301 ParentChildrenList::UpdateChildLMAddr(nsaddr_t id, int num_lm_addrs, int64_t *lm_addrs)
00302 {
00303 LMNode *potl_ch = NULL;
00304
00305 potl_ch = pchildren_;
00306 while(potl_ch) {
00307 if(potl_ch->id_ == id)
00308 break;
00309 potl_ch = potl_ch->next_;
00310 }
00311
00312 assert(potl_ch);
00313 (potl_ch->lmaddr_)->delete_lm_addrs();
00314 for(int i = 0; i < num_lm_addrs; ++i)
00315 (potl_ch->lmaddr_)->add_lm_addr(lm_addrs[i]);
00316 }
00317
00318
00319
00320
00321 int
00322 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)
00323 {
00324 LMNode *potl_parent, *list_ptr;
00325 double now = Scheduler::instance().clock();
00326
00327 int seqnum = origin_time & 0xFFFF;
00328 origin_time = origin_time >> 16;
00329
00330 assert(num_pparent_ >= 0);
00331
00332
00333 if(delete_flag && !pparent_)
00334 return(ENTRY_NOT_FOUND);
00335
00336
00337
00338
00339
00340 if(pparent_ == NULL) {
00341 pparent_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
00342 pparent_->last_upd_seqnum_ = seqnum;
00343 parent_ = pparent_;
00344 ++num_pparent_;
00345 return(NEW_ENTRY);
00346 }
00347
00348 list_ptr = pparent_;
00349 potl_parent = list_ptr;
00350 while(list_ptr != NULL) {
00351 if(list_ptr->id_ == id) {
00352
00353 if(list_ptr->last_upd_origin_time_ > origin_time || (list_ptr->last_upd_origin_time_ == origin_time && list_ptr->last_upd_seqnum_ >= seqnum)) {
00354
00355 if(list_ptr->num_hops_ > num_hops) {
00356 list_ptr->next_hop_ = next_hop;
00357 list_ptr->num_hops_ = num_hops;
00358 return(OLD_ENTRY);
00359 }
00360 return(OLD_MESSAGE);
00361 }
00362 if(!delete_flag) {
00363
00364 if(parent_->num_hops_ > num_hops + 10 || num_hops == 0) {
00365 parent_ = list_ptr;
00366 }
00367 list_ptr->next_hop_ = next_hop;
00368 list_ptr->num_hops_ = num_hops;
00369 list_ptr->level_ = level;
00370 list_ptr->num_children_ = num_children;
00371 list_ptr->energy_ = energy;
00372 list_ptr->last_upd_origin_time_ = origin_time;
00373 list_ptr->last_upd_seqnum_ = seqnum;
00374 list_ptr->last_update_rcvd_ = Scheduler::instance().clock();
00375 }
00376 else {
00377 if(num_pparent_)
00378 --(num_pparent_);
00379
00380 if(pparent_ == list_ptr)
00381 pparent_ = list_ptr->next_;
00382 else
00383 potl_parent->next_ = list_ptr->next_;
00384
00385 if(parent_->id_ == list_ptr->id_)
00386 assert(parent_ == list_ptr);
00387
00388
00389 if(pparent_ == NULL) {
00390 parent_ = NULL;
00391 }
00392 else if(parent_ == list_ptr) {
00393
00394
00395 LMNode *tmp = pparent_;
00396 int best_num_hops = pparent_->num_hops_;
00397 LMNode *best_parent = pparent_;
00398 while(tmp != NULL) {
00399 if(tmp->num_hops_ < best_num_hops) {
00400 best_num_hops = tmp->num_hops_;
00401 best_parent = tmp;
00402 }
00403 tmp = tmp->next_;
00404 }
00405 parent_ = best_parent;
00406 }
00407 delete list_ptr;
00408 }
00409 return(OLD_ENTRY);
00410 }
00411 potl_parent = list_ptr;
00412 list_ptr = list_ptr->next_;
00413 }
00414
00415 if(delete_flag)
00416 return(ENTRY_NOT_FOUND);
00417
00418 potl_parent->next_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
00419 (potl_parent->next_)->last_upd_seqnum_ = seqnum;
00420 ++num_pparent_;
00421
00422 if(parent_->num_hops_ > num_hops) {
00423 parent_ = potl_parent->next_;
00424 }
00425 return(NEW_ENTRY);
00426 }
00427
00428
00429
00430
00431 int
00432 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)
00433 {
00434 LMNode *potl_child, *list_ptr;
00435 double now = Scheduler::instance().clock();
00436 int new_child = 0;
00437 int tags_changed = 0;
00438 int seqnum = origin_time & 0xFFFF;
00439 origin_time = origin_time >> 16;
00440
00441
00442
00443
00444 if(delete_flag && !pchildren_) {
00445 return(ENTRY_NOT_FOUND);
00446 }
00447
00448 assert(num_potl_children_ >= 0);
00449 assert(num_children_ >= 0);
00450
00451 if(pchildren_ == NULL) {
00452 pchildren_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
00453 pchildren_->child_flag_ = child_flag;
00454 pchildren_->last_upd_seqnum_ = seqnum;
00455 if(child_flag == IS_CHILD) ++(num_children_);
00456 if(child_flag != NOT_POTL_CHILD) ++(num_potl_children_);
00457 ++(num_heard_);
00458 pchildren_->copy_tag_list(taglist);
00459 if(child_flag == IS_CHILD)
00460 return(NEW_CHILD);
00461 else
00462 return(NEW_ENTRY);
00463 }
00464
00465 list_ptr = pchildren_;
00466 potl_child = list_ptr;
00467 while(list_ptr != NULL) {
00468 if(list_ptr->id_ == id) {
00469
00470 if(list_ptr->last_upd_origin_time_ > origin_time || (list_ptr->last_upd_origin_time_ == origin_time && list_ptr->last_upd_seqnum_ >= seqnum)) {
00471
00472
00473
00474
00475 if(list_ptr->num_hops_ > num_hops) {
00476 list_ptr->next_hop_ = next_hop;
00477 list_ptr->num_hops_ = num_hops;
00478 return(OLD_ENTRY);
00479 }
00480
00481 return(OLD_MESSAGE);
00482 }
00483 if(!delete_flag) {
00484
00485
00486 if((list_ptr->child_flag_ == NOT_CHILD || list_ptr->child_flag_ == NOT_POTL_CHILD) && (child_flag == IS_CHILD)) {
00487 list_ptr->child_flag_ = child_flag;
00488 ++(num_children_);
00489 new_child = 1;
00490 }
00491 else if((list_ptr->child_flag_ == IS_CHILD) && (child_flag == NOT_CHILD || child_flag == NOT_POTL_CHILD)) {
00492 list_ptr->child_flag_ = child_flag;
00493 --(num_children_);
00494 }
00495 list_ptr->next_hop_ = next_hop;
00496 list_ptr->num_hops_ = num_hops;
00497 list_ptr->level_ = level;
00498 list_ptr->num_children_ = num_children;
00499 list_ptr->energy_ = energy;
00500 list_ptr->last_upd_origin_time_ = origin_time;
00501 list_ptr->last_upd_seqnum_ = seqnum;
00502 list_ptr->last_update_rcvd_ = Scheduler::instance().clock();
00503 if(!a_->compare_tag_lists(list_ptr->tag_list_,-1,taglist,-1)) {
00504 tags_changed = 1;
00505
00506 list_ptr->copy_tag_list(taglist);
00507 }
00508 }
00509 else {
00510 if(pchildren_ == list_ptr)
00511 pchildren_ = list_ptr->next_;
00512 else
00513 potl_child->next_ = list_ptr->next_;
00514
00515 if(list_ptr->child_flag_ == IS_CHILD) --num_children_;
00516 if(list_ptr->child_flag_ != NOT_POTL_CHILD) --num_potl_children_;
00517 --num_heard_;
00518 delete list_ptr;
00519 }
00520 if(new_child)
00521 return(NEW_CHILD);
00522 else if(tags_changed && child_flag == IS_CHILD)
00523 return(OLD_CHILD_TAGS_CHANGED);
00524 else
00525 return(OLD_ENTRY);
00526 }
00527 potl_child = list_ptr;
00528 list_ptr = list_ptr->next_;
00529 }
00530
00531
00532
00533 if(delete_flag) {
00534 return(ENTRY_NOT_FOUND);
00535 }
00536
00537 potl_child->next_ = new LMNode(id, next_hop, num_hops, level, num_children, energy, origin_time, now);
00538 (potl_child->next_)->copy_tag_list(taglist);
00539 (potl_child->next_)->child_flag_ = child_flag;
00540 (potl_child->next_)->last_upd_seqnum_ = seqnum;
00541 if(child_flag == IS_CHILD) ++(num_children_);
00542 if(child_flag != NOT_POTL_CHILD) ++(num_potl_children_);
00543 ++(num_heard_);
00544 if(child_flag == IS_CHILD)
00545 return(NEW_CHILD);
00546 else
00547 return(NEW_ENTRY);
00548 }
00549
00550
00551
00552
00553
00554 void
00555 LandmarkAgent::ProcessHierUpdate(Packet *p)
00556 {
00557 hdr_ip *iph = HDR_IP(p);
00558 hdr_cmn *hdrc = HDR_CMN(p);
00559 Scheduler &s = Scheduler::instance();
00560 double now = s.clock();
00561 int origin_time = 0;
00562 unsigned char *walk;
00563 nsaddr_t origin_id, parent, next_hop;
00564 int i, level, vicinity_radius, num_hops, potl_parent_flag = FALSE;
00565 int action, energy = 0;
00566 nsaddr_t *potl_children;
00567 int num_children = 0;
00568 int num_potl_children = 0;
00569 int num_lm_addrs = 0;
00570 int num_advert_lm_addrs = 0;
00571 int64_t *advert_lm_addrs = NULL;
00572 int64_t *lm_addrs = NULL;
00573
00574
00575 int num_tags = 0;
00576 compr_taglist *adv_tags = NULL, *tag_ptr;
00577 compr_taglist *tag_ptr1, *tag_ptr2;
00578 Packet *newp;
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 walk = p->accessdata();
00590
00591
00592 origin_id = iph->saddr();
00593
00594
00595 if(origin_id == myaddr_) {
00596 Packet::free(p);
00597 return;
00598 }
00599
00600
00601 action = *walk++;
00602
00603 num_advert_lm_addrs = *walk++;
00604 if(num_advert_lm_addrs)
00605 advert_lm_addrs = new int64_t[num_advert_lm_addrs];
00606 for(int j = 0; j < num_advert_lm_addrs; ++j) {
00607 advert_lm_addrs[j] = *walk++;
00608 advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
00609 advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
00610 advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
00611 advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
00612 advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
00613 advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
00614 advert_lm_addrs[j] = (advert_lm_addrs[j] << 8) | *walk++;
00615 }
00616
00617
00618 level = *walk++;
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 energy = *walk++;
00631 energy = (energy << 8) | *walk++;
00632 energy = (energy << 8) | *walk++;
00633 energy = (energy << 8) | *walk++;
00634
00635
00636 next_hop = *walk++;
00637 next_hop = (next_hop << 8) | *walk;
00638
00639
00640 --walk;
00641 (*walk++) = (myaddr_ >> 8) & 0xFF;
00642 (*walk++) = (myaddr_) & 0xFF;
00643
00644
00645 vicinity_radius = *walk++;
00646 vicinity_radius = (vicinity_radius << 8) | *walk++;
00647
00648 num_hops = vicinity_radius - (iph->ttl_ - 1);
00649
00650
00651
00652
00653
00654 origin_time = *walk++;
00655 origin_time = (origin_time << 8) | *walk++;
00656 origin_time = (origin_time << 8) | *walk++;
00657 origin_time = (origin_time << 8) | *walk++;
00658
00659
00660
00661
00662
00663
00664 parent = *walk++;
00665 parent = parent << 8 | *walk++;
00666
00667
00668
00669 if(level > 0 && (action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT || action == UNICAST_ADVERT_CHILD || action == UNICAST_ADVERT_PARENT)) {
00670
00671 num_children = *walk++;
00672 num_children = num_children << 8 | *walk++;
00673
00674
00675 num_potl_children = *walk++;
00676 num_potl_children = num_potl_children << 8 | *walk++;
00677
00678
00679
00680 if(num_potl_children) {
00681 potl_children = new nsaddr_t[num_potl_children];
00682 for(i = 0; i < num_potl_children; ++i) {
00683 potl_children[i] = *walk++;
00684 potl_children[i] = potl_children[i] << 8 | *walk++;
00685 int tmp_num_addrs = *walk++;
00686 if(potl_children[i] == myaddr_) {
00687 potl_parent_flag = TRUE;
00688 num_lm_addrs = tmp_num_addrs;
00689 if(num_lm_addrs) {
00690 lm_addrs = new int64_t[num_lm_addrs];
00691 for(int j = 0; j < num_lm_addrs; ++j) {
00692 lm_addrs[j] = *walk++;
00693 lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
00694 lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
00695 lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
00696 lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
00697 lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
00698 lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
00699 lm_addrs[j] = (lm_addrs[j] << 8) | *walk++;
00700 }
00701 }
00702 }
00703 else
00704 walk = walk + tmp_num_addrs*8;
00705 }
00706 }
00707 }
00708
00709 num_tags = 0;
00710 if(action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT || action == UNICAST_ADVERT_CHILD || action == UNICAST_ADVERT_PARENT) {
00711 num_tags = *walk++;
00712 num_tags = (num_tags << 8) | *walk++;
00713 }
00714
00715
00716 adv_tags = NULL;
00717
00718
00719 if(num_tags && level < highest_level_) {
00720 adv_tags = new compr_taglist;
00721 tag_ptr = adv_tags;
00722 i = 0;
00723 while(i < num_tags) {
00724 if(i) {
00725 tag_ptr->next_ = new compr_taglist;
00726 tag_ptr = tag_ptr->next_;
00727 }
00728 tag_ptr->obj_name_ = *walk++;
00729 tag_ptr->obj_name_ = (tag_ptr->obj_name_ << 8) | *walk++;
00730 tag_ptr->obj_name_ = (tag_ptr->obj_name_ << 8) | *walk++;
00731 tag_ptr->obj_name_ = (tag_ptr->obj_name_ << 8) | *walk++;
00732 ++i;
00733
00734 }
00735 }
00736
00737
00738
00739
00740 ParentChildrenList **pcl1 = NULL;
00741 ParentChildrenList **pcl2 = NULL;
00742 int found1 = FALSE;
00743 int found2 = FALSE;
00744 ParentChildrenList **pcl = &parent_children_list_;
00745
00746
00747 while((*pcl) != NULL) {
00748 if((*pcl)->level_ == (level-1)) {
00749 found1 = TRUE;
00750 pcl1 = pcl;
00751 }
00752 if((*pcl)->level_ == (level+1)) {
00753 found2 = TRUE;
00754 pcl2 = pcl;
00755 }
00756 pcl = &((*pcl)->next_);
00757 }
00758
00759
00760
00761 if(!found1 && level) {
00762 *pcl = new ParentChildrenList(level-1, this);
00763 pcl1 = pcl;
00764 pcl = &((*pcl)->next_);
00765 }
00766
00767 if(!found2) {
00768 *pcl = new ParentChildrenList(level+1, this);
00769 pcl2 = pcl;
00770 pcl = &((*pcl)->next_);
00771 }
00772
00773
00774
00775
00776
00777 int delete_flag = FALSE;
00778 if(action == DEMOTION) delete_flag = TRUE;
00779 int child_flag = NOT_CHILD;
00780 if(parent == myaddr_)
00781 child_flag = IS_CHILD;
00782 else if(action == GLOBAL_ADVERT && num_hops > vicinity_radius)
00783
00784
00785 child_flag = NOT_POTL_CHILD;
00786
00787 int ret_value = (*pcl2)->UpdatePotlChild(origin_id, next_hop, num_hops, level, num_children, energy, origin_time, child_flag, delete_flag,adv_tags);
00788
00789
00790
00791 if(ret_value == OLD_MESSAGE && action != UNICAST_ADVERT_CHILD && action != UNICAST_ADVERT_PARENT) {
00792 if(num_potl_children) delete[] potl_children;
00793 if(num_lm_addrs) delete[] lm_addrs;
00794 if(num_advert_lm_addrs) delete[] advert_lm_addrs;
00795
00796 tag_ptr1 = adv_tags;
00797 while(tag_ptr1) {
00798 tag_ptr2 = tag_ptr1;
00799 tag_ptr1 = tag_ptr1->next_;
00800 delete tag_ptr2;
00801 }
00802 Packet::free(p);
00803 return;
00804 }
00805
00806
00807
00808 if(ret_value == NEW_CHILD || ret_value == OLD_CHILD_TAGS_CHANGED)
00809 SendChangedTagListUpdate(0,level);
00810
00811
00812
00813
00814
00815
00816 if((ret_value == NEW_ENTRY) && (level == highest_level_) && (action == PERIODIC_ADVERTS || action == UNICAST_ADVERT_CHILD || action == UNICAST_ADVERT_PARENT) && (num_hops < radius(level))) {
00817
00818 if(promo_timer_running_ && !wait_state_) {
00819 double resched_time = promo_timeout_ - (now - promo_start_time_) - promo_timeout_decr_;
00820 if(resched_time < 0) resched_time = 0;
00821
00822 promo_timer_->resched(resched_time);
00823 }
00824 }
00825
00826
00827
00828 if(action == DEMOTION) {
00829 (*pcl1)->UpdatePotlParent(origin_id, next_hop, num_hops, level, num_children, energy, origin_time, TRUE);
00830 if(((*pcl1)->parent_ == NULL) && (!promo_timer_running_ || (promo_timer_running_ && wait_state_)) && (highest_level_ == level-1)) {
00831
00832 ParentChildrenList *tmp_pcl = parent_children_list_;
00833 while(tmp_pcl) {
00834 if(tmp_pcl->level_ == level) break;
00835 tmp_pcl = tmp_pcl->next_;
00836 }
00837 assert(tmp_pcl);
00838
00839 num_resched_ = tmp_pcl->num_heard_ - 1;
00840 if(num_resched_) {
00841
00842 if(promo_timer_running_)
00843 promo_timer_->cancel();
00844 promo_timer_running_ = 1;
00845 wait_state_ = 0;
00846 total_wait_time_ = 0;
00847 promo_timeout_ = random_timer(double(CONST_TIMEOUT + PROMO_TIMEOUT_MULTIPLES * radius(level) + MAX_TIMEOUT/((num_resched_+1) * pow(2,highest_level_+1))), be_random_);
00848 trace("Node %d: Promotion timeout after wait period in ProcessHierUpdate: %f", myaddr_,promo_timeout_);
00849 num_resched_ = 0;
00850 promo_start_time_ = s.clock();
00851 promo_timer_->resched(promo_timeout_);
00852 }
00853 else if(!promo_timer_running_) {
00854 double wait_time = PERIODIC_WAIT_TIME;
00855 promo_timer_running_ = 1;
00856 wait_state_ = 1;
00857 total_wait_time_ += wait_time;
00858 trace("Node %d: Entering wait state in ProcessHierUpdate because of no parent: %f", myaddr_,now);
00859 promo_timer_->resched(wait_time);
00860 }
00861 }
00862 }
00863
00864
00865 else if(potl_parent_flag) {
00866 LMNode *old_parent = (*pcl1)->parent_;
00867 (*pcl1)->UpdatePotlParent(origin_id, next_hop, num_hops, level, num_children, energy, origin_time, FALSE);
00868
00869
00870
00871 if((((*pcl1)->parent_)->id_ == origin_id) && (level-1 == highest_level_)) {
00872
00873
00874
00875
00876 ((*pcl1)->mylmaddrs_)->delete_lm_addrs();
00877 assign_lmaddress(lm_addrs, num_lm_addrs, (*pcl1)->level_);
00878 }
00879
00880
00881 int new_advert = 0;
00882
00883 if((*pcl1)->parent_ == old_parent && old_parent) {
00884 if(((*pcl1)->parent_)->id_ != old_parent->id_)
00885 new_advert = 1;
00886 }
00887 else if((*pcl1)->parent_ != old_parent && (*pcl1)->parent_ && old_parent) {
00888 if(((*pcl1)->parent_)->id_ != old_parent->id_)
00889 new_advert = 1;
00890 }
00891 else if((*pcl1)->parent_ != old_parent)
00892 new_advert = 1;
00893
00894
00895 if(new_advert && (level-1 <= highest_level_)) {
00896 newp = makeUpdate((*pcl1), HIER_ADVS, PERIODIC_ADVERTS);
00897 s.schedule(target_,newp,0);
00898 (*pcl1)->last_update_sent_ = now;
00899 }
00900
00901
00902
00903 if((level == (highest_level_ + 1)) && ((*pcl1)->parent_ != NULL)) {
00904 if(promo_timer_running_ && !wait_state_) {
00905 trace("Node %d: Promotion timer cancelled at time %f in ProcessHierUpdate\n",myaddr_,s.clock());
00906 promo_timer_->cancel();
00907 total_wait_time_ = 0;
00908 wait_state_ = 1;
00909 double wait_time = PERIODIC_WAIT_TIME;
00910 total_wait_time_ += wait_time;
00911 promo_timer_->sched(wait_time);
00912 }
00913 }
00914 else if(level > 0 && level == highest_level_) {
00915
00916
00917
00918 pcl = &parent_children_list_;
00919 while((*pcl) != NULL) {
00920 if((*pcl)->level_ == level) {
00921 break;
00922 }
00923 pcl = &((*pcl)->next_);
00924 }
00925 assert(*pcl);
00926
00927 LMNode *lm = (*pcl)->pchildren_;
00928 int is_subset = TRUE;
00929 if((*pcl)->num_potl_children_ > num_potl_children) {
00930 is_subset = FALSE;
00931 lm = NULL;
00932 }
00933
00934 int is_element = FALSE;
00935 while(lm) {
00936 is_element = FALSE;
00937 for(i = 0; i < num_potl_children; ++i)
00938 if(lm->id_ == potl_children[i] && lm->child_flag_ != NOT_POTL_CHILD) {
00939 is_element = TRUE;
00940 break;
00941 }
00942 if(is_element == FALSE && lm->child_flag_ != NOT_POTL_CHILD) {
00943 is_subset = FALSE;
00944 break;
00945 }
00946 lm = lm->next_;
00947 }
00948
00949 if(is_subset == TRUE) {
00950 --(highest_level_);
00951 delete_flag = TRUE;
00952 if((*pcl1)->parent_)
00953 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);
00954 trace("Node %d: Parent before demotion: %d, msg from %d at time %f",myaddr_, ((*pcl1)->parent_)->id_,origin_id,now);
00955
00956 int upd_time = (int)now;
00957 upd_time = (upd_time << 16) | ((*pcl1)->seqnum_ & 0xFFFF);
00958 ++((*pcl1)->seqnum_);
00959 (*pcl1)->UpdatePotlParent(myaddr_, 0, 0, 0, 0, 0, upd_time, delete_flag);
00960
00961 if((*pcl1)->parent_)
00962 trace("Node %d: Parent after demotion: %d",myaddr_, ((*pcl1)->parent_)->id_);
00963
00964 upd_time = (int) now;
00965 upd_time = (upd_time << 16) | ((*pcl2)->seqnum_ & 0xFFFF);
00966 ++((*pcl2)->seqnum_);
00967 (*pcl2)->UpdatePotlChild(myaddr_, 0, 0, 0, 0, 0, upd_time, IS_CHILD, delete_flag,NULL);
00968
00969
00970 newp = makeUpdate(*pcl, HIER_ADVS, DEMOTION);
00971 s.schedule(target_, newp, 0);
00972
00973 if(promo_timer_running_ && !wait_state_) {
00974 trace("Node %d: Promotion timer cancelled due to demotion at time %d\n",myaddr_,(int)now);
00975 promo_timer_->cancel();
00976 total_wait_time_ = 0;
00977 wait_state_ = 1;
00978 double wait_time = PERIODIC_WAIT_TIME;
00979 total_wait_time_ += wait_time;
00980 promo_timer_->sched(wait_time);
00981 }
00982 }
00983 }
00984 }
00985
00986
00987
00988 if(ret_value == NEW_ENTRY) {
00989 ParentChildrenList *tmp_pcl = parent_children_list_;
00990 while(tmp_pcl) {
00991
00992 if(tmp_pcl->level_ <= highest_level_ && tmp_pcl->level_ >= level && (now - tmp_pcl->last_update_sent_) > 0.1) {
00993 newp = makeUpdate(tmp_pcl, HIER_ADVS, PERIODIC_ADVERTS);
00994 s.schedule(target_,newp,0);
00995 tmp_pcl->last_update_sent_ = now;
00996 }
00997 tmp_pcl = tmp_pcl->next_;
00998 }
00999 }
01000
01001 if(num_potl_children) delete[] potl_children;
01002 if(num_lm_addrs) delete[] lm_addrs;
01003 if(num_advert_lm_addrs) delete[] advert_lm_addrs;
01004
01005 tag_ptr1 = adv_tags;
01006 while(tag_ptr1) {
01007 tag_ptr2 = tag_ptr1;
01008 tag_ptr1 = tag_ptr1->next_;
01009 delete tag_ptr2;
01010 }
01011
01012
01013 if(action == DEMOTION) {
01014
01015
01016 if(CheckDemotionMsg(origin_id, level, (int)origin_time) == OLD_MESSAGE) {
01017 Packet::free(p);
01018 return;
01019 }
01020 }
01021
01022
01023
01024 if(--iph->ttl_ == 0 && action != GLOBAL_ADVERT) {
01025
01026 Packet::free(p);
01027 return;
01028 }
01029
01030
01031 if((iph->daddr() >> 8) == myaddr_) {
01032
01033 Packet::free(p);
01034 return;
01035 }
01036
01037 if(action == UNICAST_ADVERT_CHILD) {
01038 hdrc->next_hop() = get_next_hop(iph->daddr(),level);
01039
01040
01041 }
01042 else if(action == UNICAST_ADVERT_PARENT) {
01043
01044 hdrc->next_hop() = get_next_hop(iph->daddr(),level+2);
01045 }
01046
01047 assert(hdrc->next_hop() != NO_NEXT_HOP);
01048
01049
01050
01051
01052
01053
01054
01055 hdrc->direction() = hdr_cmn::DOWN;
01056
01057
01058 s.schedule(target_, p, 0);
01059 }
01060
01061
01062
01063
01064 void
01065 LandmarkAgent::assign_lmaddress(int64_t *lmaddr, int num_lm_addrs, int root_level)
01066 {
01067 ParentChildrenList *tmp_pcl, *cur_pcl = NULL, *child_pcl = NULL;
01068 ParentChildrenList *parent_pcl = NULL;
01069 LMNode *pchild;
01070 int i;
01071 int level = root_level;
01072
01073
01074
01075 while(level >= 0) {
01076 tmp_pcl = parent_children_list_;
01077 while(tmp_pcl) {
01078 if(tmp_pcl->level_ == level)
01079 cur_pcl = tmp_pcl;
01080 if(tmp_pcl->level_ == (level-1))
01081 child_pcl = tmp_pcl;
01082 if(tmp_pcl->level_ == (level+1))
01083 parent_pcl = tmp_pcl;
01084 tmp_pcl = tmp_pcl->next_;
01085 }
01086
01087 assert(cur_pcl);
01088 if(level) assert(child_pcl);
01089 assert(parent_pcl);
01090
01091
01092 if(level == root_level) {
01093 (cur_pcl->mylmaddrs_)->delete_lm_addrs();
01094 if(num_lm_addrs) {
01095 for(i = 0; i < num_lm_addrs; ++i) {
01096 (cur_pcl->mylmaddrs_)->add_lm_addr(lmaddr[i]);
01097 }
01098 parent_pcl->UpdateChildLMAddr(myaddr_,num_lm_addrs,lmaddr);
01099 }
01100 }
01101
01102 int num_addrs = 0;
01103 int64_t *assigned_addrs = NULL;
01104 (cur_pcl->mylmaddrs_)->get_lm_addrs(&num_addrs,&assigned_addrs);
01105
01106 if(num_addrs == 0) {
01107 pchild = cur_pcl->pchildren_;
01108 while(pchild) {
01109 if(pchild->child_flag_ == IS_CHILD) {
01110 (pchild->lmaddr_)->delete_lm_addrs();
01111 if(pchild->id_ == myaddr_ && level)
01112 (child_pcl->mylmaddrs_)->delete_lm_addrs();
01113 }
01114 pchild = pchild->next_;
01115 }
01116 }
01117 else if(cur_pcl->num_children_) {
01118
01119 for(i = 0; i < num_addrs; ++i) {
01120 int64_t j = 1;
01121 int64_t addr = assigned_addrs[i] + (j << ((cur_pcl->level_-1)*8));
01122
01123
01124
01125 pchild = cur_pcl->pchildren_;
01126 assert(cur_pcl->num_children_ <= MAX_CHILDREN);
01127
01128 while(pchild) {
01129 if(pchild->child_flag_ == IS_CHILD) {
01130 (pchild->lmaddr_)->delete_lm_addrs();
01131 (pchild->lmaddr_)->add_lm_addr(addr);
01132 if(pchild->id_ == myaddr_ && level) {
01133 (child_pcl->mylmaddrs_)->delete_lm_addrs();
01134 (child_pcl->mylmaddrs_)->add_lm_addr(addr);
01135 }
01136 ++j;
01137 addr = assigned_addrs[i] + (j << ((cur_pcl->level_-1)*8));
01138
01139 assert(j <= MAX_CHILDREN);
01140 }
01141 pchild = pchild->next_;
01142
01143 }
01144 }
01145 }
01146 if(num_addrs) delete[] assigned_addrs;
01147 --level;
01148 }
01149 }
01150
01151
01152
01153
01154 void
01155 LandmarkAgent::periodic_callback(Event *e, int level)
01156 {
01157
01158 Scheduler &s = Scheduler::instance();
01159 double now = Scheduler::instance().clock(), next_update_delay;
01160 int energy = (int)(node_->energy());
01161 int unicast_flag = FALSE, suppress_flag = FALSE;
01162 Packet *newp;
01163 hdr_ip *iph, *new_iph;
01164 hdr_cmn *cmh, *new_cmh;
01165 int action = PERIODIC_ADVERTS, parent_changed = 0, child_changed = 0;
01166 int upd_time = (int) now;
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177 assert(parent_children_list_ != NULL);
01178 ParentChildrenList *pcl = parent_children_list_;
01179 ParentChildrenList *cur_pcl = NULL;
01180 ParentChildrenList *new_pcl = NULL;
01181 ParentChildrenList *pcl1 = NULL;
01182 ParentChildrenList *pcl2 = NULL;
01183
01184
01185 if(highest_level_ < level)
01186 return;
01187
01188 while(pcl != NULL) {
01189 new_pcl = pcl;
01190 if(pcl->level_ == level){
01191 cur_pcl = pcl;
01192 }
01193 if(pcl->level_ == (level - 1)){
01194 pcl1 = pcl;
01195 }
01196 if(pcl->level_ == (level + 1)){
01197 pcl2 = pcl;
01198 }
01199 pcl = pcl->next_;
01200 }
01201
01202 assert(cur_pcl);
01203 if(level)
01204 assert(pcl1);
01205
01206
01207 if(!pcl2) {
01208 new_pcl->next_ = new ParentChildrenList(level+1, this);
01209 pcl2 = new_pcl->next_;
01210 }
01211
01212 assert(pcl2);
01213
01214
01215 LMNode *lmnode = cur_pcl->pparent_;
01216 LMNode *tmp_lmnode;
01217 int delete_flag = TRUE;
01218 LMNode *old_parent = cur_pcl->parent_;
01219 while(lmnode) {
01220
01221 tmp_lmnode = lmnode->next_;
01222 if(((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_)) {
01223
01224 upd_time = (int) now;
01225 upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_ + 1) & 0xFFFF);
01226 cur_pcl->UpdatePotlParent(lmnode->id_, 0, 0, 0, 0, 0, upd_time, delete_flag);
01227 }
01228 lmnode = tmp_lmnode;
01229 }
01230
01231
01232 if(cur_pcl->parent_ == old_parent && old_parent) {
01233 if((cur_pcl->parent_)->id_ != old_parent->id_)
01234 parent_changed = 1;
01235 }
01236 else if(cur_pcl->parent_ != old_parent && cur_pcl->parent_ && old_parent) {
01237 if((cur_pcl->parent_)->id_ != old_parent->id_)
01238 parent_changed = 1;
01239 }
01240 else if(cur_pcl->parent_ != old_parent)
01241 parent_changed = 1;
01242
01243
01244
01245 lmnode = cur_pcl->pchildren_;
01246 delete_flag = TRUE;
01247 int demotion = FALSE;
01248 while(lmnode) {
01249
01250 tmp_lmnode = lmnode->next_;
01251 if((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_) {
01252 if(lmnode->child_flag_ == IS_CHILD)
01253 child_changed = 1;
01254 assert(level && lmnode->id_ != myaddr_);
01255 upd_time = (int) now;
01256 upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_ + 1) & 0xFFFF);
01257 cur_pcl->UpdatePotlChild(lmnode->id_, 0, 0, 0, 0, 0, upd_time, lmnode->child_flag_, delete_flag,NULL);
01258 }
01259 lmnode = tmp_lmnode;
01260 }
01261
01262
01263 if(child_changed)
01264 SendChangedTagListUpdate(0,level-1);
01265
01266
01267 if(demotion) {
01268 trace("Node %d: Demotion due to lesser energy than child",myaddr_);
01269 highest_level_ = level - 1;
01270 Packet *p = makeUpdate(cur_pcl, HIER_ADVS, DEMOTION);
01271 s.schedule(target_, p, 0);
01272 }
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 if(parent_changed && (cur_pcl->parent_ == NULL) && !demotion) {
01284
01285
01286
01287 if(promo_timer_running_ && level <= highest_level_) {
01288 wait_state_ = 0;
01289 total_wait_time_ = 0;
01290 promo_timer_running_ = 0;
01291 promo_timer_->cancel();
01292 }
01293
01294 num_resched_ = pcl2->num_heard_ - 1;
01295 if(num_resched_) {
01296 promo_timer_running_ = 1;
01297 wait_state_ = 0;
01298 total_wait_time_ = 0;
01299 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_);
01300 trace("Node %d: Promotion timeout after wait period in periodic_callback: %f", myaddr_,promo_timeout_);
01301 num_resched_ = 0;
01302 promo_start_time_ = s.clock();
01303 promo_timer_->resched(promo_timeout_);
01304 }
01305 else {
01306 double wait_time = PERIODIC_WAIT_TIME;
01307 promo_timer_running_ = 1;
01308 wait_state_ = 1;
01309 total_wait_time_ += wait_time;
01310
01311 promo_timer_->resched(wait_time);
01312 }
01313 }
01314
01315
01316
01317 if(!demotion) {
01318 if(level) {
01319 upd_time = (int) now;
01320 upd_time = (upd_time << 16) | (pcl1->seqnum_ & 0xFFFF);
01321 ++(pcl1->seqnum_);
01322 pcl1->UpdatePotlParent(myaddr_, myaddr_, 0, level, cur_pcl->num_children_, energy, upd_time, FALSE);
01323 }
01324 upd_time = (int) now;
01325 upd_time = (upd_time << 16) | (pcl2->seqnum_ & 0xFFFF);
01326 ++(pcl2->seqnum_);
01327 pcl2->UpdatePotlChild(myaddr_, myaddr_, 0, level, cur_pcl->num_children_, energy, upd_time, IS_CHILD, FALSE,cur_pcl->tag_list_);
01328 }
01329
01330
01331
01332
01333
01334 if(!(cur_pcl->parent_) && (total_wait_time_ >= (2*PERIODIC_WAIT_TIME)) && wait_state_) {
01335 if(adverts_type_ == UNICAST) {
01336 unicast_flag = TRUE;
01337 }
01338 else if(adverts_type_ == SUPPRESS) {
01339 suppress_flag = TRUE;
01340 }
01341
01342
01343
01344 int64_t *lmaddr = new int64_t[1];
01345 lmaddr[0] = 1;
01346 lmaddr[0] = (lmaddr[0] << (cur_pcl->level_ * 8));
01347 int num_lm_addrs = 1;
01348 assign_lmaddress(lmaddr, num_lm_addrs, cur_pcl->level_);
01349
01350
01351 delete[] lmaddr;
01352 if(global_lm_)
01353 action = GLOBAL_ADVERT;
01354 }
01355 else if(cur_pcl->parent_) {
01356 if(adverts_type_ == UNICAST) {
01357 unicast_flag = TRUE;
01358 }
01359 else if(adverts_type_ == SUPPRESS) {
01360 suppress_flag = TRUE;
01361 }
01362 }
01363
01364
01365 if(!demotion && !suppress_flag) {
01366
01367 Packet *p = makeUpdate(cur_pcl, HIER_ADVS, action);
01368 unsigned char *walk;
01369 if(unicast_flag) {
01370 if(level) {
01371
01372 lmnode = cur_pcl->pchildren_;
01373 while(lmnode) {
01374 if(lmnode->id_ != myaddr_) {
01375 newp = p->copy();
01376 new_iph = HDR_IP(newp);
01377 new_cmh = HDR_CMN(newp);
01378 walk = newp->accessdata();
01379
01380
01381 new_iph->daddr() = lmnode->id_ << 8;
01382 new_iph->dport() = ROUTER_PORT;
01383 new_cmh->next_hop() = lmnode->next_hop_;
01384 new_cmh->addr_type() = NS_AF_INET;
01385 if(cur_pcl->level_)
01386 new_cmh->size() = new_cmh->size() - 4 * (cur_pcl->num_potl_children_ - 1);
01387 (*walk) = (UNICAST_ADVERT_CHILD) & 0xFF;
01388 walk++;
01389 int num_addrs = (*walk);
01390 walk += (10 + 8*num_addrs);
01391
01392
01393
01394 (*walk++) = (cur_pcl->seqnum_ >> 24) & 0xFF;
01395 (*walk++) = (cur_pcl->seqnum_ >> 16) & 0xFF;
01396 (*walk++) = (cur_pcl->seqnum_ >> 8) & 0xFF;
01397 (*walk++) = (cur_pcl->seqnum_) & 0xFF;
01398 ++(cur_pcl->seqnum_);
01399
01400 s.schedule(target_,newp,0);
01401 }
01402 lmnode = lmnode->next_;
01403 }
01404 }
01405 if(cur_pcl->parent_) {
01406 if((cur_pcl->parent_)->id_ != myaddr_) {
01407 iph = HDR_IP(p);
01408 cmh = HDR_CMN(p);
01409 walk = p->accessdata();
01410
01411
01412 iph->daddr() = (cur_pcl->parent_)->id_;
01413 iph->dport() = ROUTER_PORT;
01414 cmh->next_hop() = (cur_pcl->parent_)->next_hop_;
01415 cmh->addr_type() = NS_AF_INET;
01416 cmh->size() = cmh->size() - 4 * (cur_pcl->num_potl_children_);
01417
01418 (*walk) = (UNICAST_ADVERT_PARENT) & 0xFF;
01419 walk++;
01420 int num_addrs = (*walk);
01421 walk += (10 + 8*num_addrs);
01422
01423
01424
01425 (*walk++) = (cur_pcl->seqnum_ >> 24) & 0xFF;
01426 (*walk++) = (cur_pcl->seqnum_ >> 16) & 0xFF;
01427 (*walk++) = (cur_pcl->seqnum_ >> 8) & 0xFF;
01428 (*walk++) = (cur_pcl->seqnum_) & 0xFF;
01429 ++(cur_pcl->seqnum_);
01430
01431 s.schedule(target_,p,0);
01432 }
01433 else
01434 Packet::free(p);
01435 }
01436 else
01437 Packet::free(p);
01438 }
01439 else {
01440
01441 s.schedule(target_, p, 0);
01442 }
01443 cur_pcl->last_update_sent_ = now;
01444 }
01445
01446
01447 if(cur_pcl->last_update_sent_ == now || suppress_flag)
01448 next_update_delay = cur_pcl->update_period_ + jitter(LM_STARTUP_JITTER, be_random_);
01449 else
01450 next_update_delay = cur_pcl->update_period_ - (now - cur_pcl->last_update_sent_) + jitter(LM_STARTUP_JITTER, be_random_);
01451
01452
01453 if(!demotion)
01454 s.schedule(cur_pcl->periodic_handler_, cur_pcl->periodic_update_event_, next_update_delay);
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 if(level == highest_level_) {
01467 cur_pcl = parent_children_list_;
01468 while(cur_pcl) {
01469 if(cur_pcl->level_ > highest_level_) {
01470 lmnode = cur_pcl->pparent_;
01471 delete_flag = TRUE;
01472 while(lmnode) {
01473
01474
01475
01476 tmp_lmnode = lmnode->next_;
01477 if(((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_)) {
01478
01479 upd_time = (int) now;
01480 upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_+1) & 0xFFFF);
01481 cur_pcl->UpdatePotlParent(lmnode->id_, 0, 0, 0, 0, 0, upd_time, delete_flag);
01482 }
01483 lmnode = tmp_lmnode;
01484 }
01485
01486
01487 lmnode = cur_pcl->pchildren_;
01488 while(lmnode) {
01489
01490 tmp_lmnode = lmnode->next_;
01491 if((now - lmnode->last_update_rcvd_) > cur_pcl->update_timeout_) {
01492 upd_time = (int) now;
01493 upd_time = (upd_time << 16) | ((lmnode->last_upd_seqnum_+1) & 0xFFFF);
01494
01495
01496 if(cur_pcl->level_ == global_lm_level_+1 && lmnode->id_ == global_lm_id_) {
01497 global_lm_level_ = -1;
01498 global_lm_id_ = NO_GLOBAL_LM;
01499 }
01500
01501 cur_pcl->UpdatePotlChild(lmnode->id_, 0, 0, 0, 0, 0, upd_time, lmnode->child_flag_, delete_flag,NULL);
01502 }
01503 lmnode = tmp_lmnode;
01504 }
01505 }
01506 cur_pcl = cur_pcl->next_;
01507 }
01508 }
01509 }
01510
01511
01512
01513
01514 Packet *
01515 LandmarkAgent::makeUpdate(ParentChildrenList *pcl, int pkt_type, int action)
01516 {
01517 Packet *p = allocpkt();
01518 hdr_ip *iph = HDR_IP(p);
01519 hdr_cmn *hdrc = HDR_CMN(p);
01520 unsigned char *walk;
01521 compr_taglist *adv_tags = NULL;
01522 double now = Scheduler::instance().clock();
01523 int64_t *lmaddrs;
01524 int num_lm_addrs = 0;
01525
01526 hdrc->next_hop_ = IP_BROADCAST;
01527 hdrc->addr_type_ = NS_AF_INET;
01528 iph->daddr() = IP_BROADCAST;
01529 iph->dport() = ROUTER_PORT;
01530 iph->ttl_ = radius(pcl->level_);
01531
01532 iph->saddr() = myaddr_;
01533 iph->sport() = ROUTER_PORT;
01534
01535 if(action == GLOBAL_ADVERT)
01536 trace("Node %d: Generating global LM message at time %f",myaddr_,now);
01537
01538 assert(pcl->num_tags_ >= 0);
01539
01540 if(pkt_type == HIER_ADVS) {
01541
01542 if(pcl->level_ == 0) {
01543
01544 assert(action != DEMOTION);
01545
01546
01547
01548
01549
01550 lmaddrs = NULL;
01551 num_lm_addrs = 0;
01552 (pcl->mylmaddrs_)->get_lm_addrs(&num_lm_addrs, &lmaddrs);
01553
01554 p->allocdata(12 + (4 * pcl->num_tags_) + 2 + 4 + 1 + (8*num_lm_addrs));
01555 walk = p->accessdata();
01556
01557
01558 (*walk++) = (action) & 0xFF;
01559
01560
01561 (*walk++) = (num_lm_addrs) & 0xFF;
01562
01563
01564 for(int i = 0; i < num_lm_addrs; ++i) {
01565
01566 (*walk++) = (lmaddrs[i] >> 56) & 0xFF;
01567 (*walk++) = (lmaddrs[i] >> 48) & 0xFF;
01568 (*walk++) = (lmaddrs[i] >> 40) & 0xFF;
01569 (*walk++) = (lmaddrs[i] >> 32) & 0xFF;
01570 (*walk++) = (lmaddrs[i] >> 24) & 0xFF;
01571 (*walk++) = (lmaddrs[i] >> 16) & 0xFF;
01572 (*walk++) = (lmaddrs[i] >> 8) & 0xFF;
01573 (*walk++) = (lmaddrs[i]) & 0xFF;
01574 }
01575 if(num_lm_addrs)
01576 delete[] lmaddrs;
01577
01578
01579 (*walk++) = (pcl->level_) & 0xFF;
01580
01581
01582 int energy = (int)(node_->energy());
01583 (*walk++) = (energy >> 24) & 0xFF;
01584 (*walk++) = (energy >> 16) & 0xFF;
01585 (*walk++) = (energy >> 8) & 0xFF;
01586 (*walk++) = (energy) & 0xFF;
01587
01588
01589 (*walk++) = (myaddr_ >> 8) & 0xFF;
01590 (*walk++) = (myaddr_) & 0xFF;
01591
01592
01593
01594 (*walk++) = (radius(pcl->level_) >> 8) & 0xFF;
01595 (*walk++) = (radius(pcl->level_)) & 0xFF;
01596
01597
01598
01599
01600
01601
01602 int origin_time = (int)now;
01603 (*walk++) = (origin_time >> 8) & 0xFF;
01604 (*walk++) = (origin_time) & 0xFF;
01605 (*walk++) = (pcl->seqnum_ >> 8) & 0xFF;
01606 (*walk++) = (pcl->seqnum_) & 0xFF;
01607 ++(pcl->seqnum_);
01608
01609
01610 if(pcl->parent_ == NULL) {
01611 (*walk++) = (NO_PARENT >> 8) & 0xFF;
01612 (*walk++) = (NO_PARENT) & 0xFF;
01613 }
01614 else {
01615 (*walk++) = ((pcl->parent_)->id_ >> 8) & 0xFF;
01616 (*walk++) = ((pcl->parent_)->id_) & 0xFF;
01617 }
01618
01619 (*walk++) = (pcl->num_tags_ >> 8) & 0xFF;
01620 (*walk++) = (pcl->num_tags_) & 0xFF;
01621 if(pcl->num_tags_) {
01622 adv_tags = pcl->tag_list_;
01623 while(adv_tags) {
01624 (*walk++) = (adv_tags->obj_name_ >> 24) & 0xFF;
01625 (*walk++) = (adv_tags->obj_name_ >> 16) & 0xFF;
01626 (*walk++) = (adv_tags->obj_name_ >> 8) & 0xFF;
01627 (*walk++) = (adv_tags->obj_name_) & 0xFF;
01628 adv_tags = adv_tags->next_;
01629 }
01630 }
01631
01632
01633
01634
01635 hdrc->size_ = 20 + 20 + 4 + (4 * pcl->num_tags_) + 4 + 1 + (8*num_lm_addrs);
01636 }
01637 else {
01638
01639
01640
01641
01642
01643 int pkt_size = 0;
01644 lmaddrs = NULL;
01645 num_lm_addrs = 0;
01646 if(action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT) {
01647 LMNode *pch = pcl->pchildren_;
01648
01649
01650 int size = 0;
01651 while(pch) {
01652 int64_t *addrs;
01653 int num_addrs = 0;
01654 (pch->lmaddr_)->get_lm_addrs(&num_addrs,&addrs);
01655 if(num_addrs) delete[] addrs;
01656 size += (1 + num_addrs*8);
01657 pch = pch->next_;
01658 }
01659
01660
01661
01662
01663 (pcl->mylmaddrs_)->get_lm_addrs(&num_lm_addrs, &lmaddrs);
01664
01665 pkt_size = 12 + 4 + (2 * pcl->num_potl_children_) + size + (4 * pcl->num_tags_) + 2 + 4 + 1 + (8*num_lm_addrs);
01666 }
01667 else
01668 pkt_size = 17;
01669
01670 p->allocdata(pkt_size);
01671 walk = p->accessdata();
01672
01673
01674 (*walk++) = (action) & 0xFF;
01675
01676
01677
01678
01679
01680 (*walk++) = (num_lm_addrs) & 0xFF;
01681 for(int i = 0; i < num_lm_addrs; ++i) {
01682
01683 (*walk++) = (lmaddrs[i] >> 56) & 0xFF;
01684 (*walk++) = (lmaddrs[i] >> 48) & 0xFF;
01685 (*walk++) = (lmaddrs[i] >> 40) & 0xFF;
01686 (*walk++) = (lmaddrs[i] >> 32) & 0xFF;
01687 (*walk++) = (lmaddrs[i] >> 24) & 0xFF;
01688 (*walk++) = (lmaddrs[i] >> 16) & 0xFF;
01689 (*walk++) = (lmaddrs[i] >> 8) & 0xFF;
01690 (*walk++) = (lmaddrs[i]) & 0xFF;
01691 }
01692 if(num_lm_addrs)
01693 delete[] lmaddrs;
01694
01695
01696
01697 (*walk++) = (pcl->level_) & 0xFF;
01698
01699
01700 int energy = (int)(node_->energy());
01701 (*walk++) = (energy >> 24) & 0xFF;
01702 (*walk++) = (energy >> 16) & 0xFF;
01703 (*walk++) = (energy >> 8) & 0xFF;
01704 (*walk++) = (energy) & 0xFF;
01705
01706
01707 (*walk++) = (myaddr_ >> 8) & 0xFF;
01708 (*walk++) = (myaddr_) & 0xFF;
01709
01710
01711 (*walk++) = (radius(pcl->level_) >> 8) & 0xFF;
01712 (*walk++) = (radius(pcl->level_)) & 0xFF;
01713
01714
01715
01716 int origin_time = (int)now;
01717 (*walk++) = (origin_time >> 8) & 0xFF;
01718 (*walk++) = (origin_time) & 0xFF;
01719 (*walk++) = (pcl->seqnum_ >> 8) & 0xFF;
01720 (*walk++) = (pcl->seqnum_) & 0xFF;
01721 ++(pcl->seqnum_);
01722
01723 if(origin_time > now) {
01724 printf("Node %d: id %d, level %d, vicinity_radius %d",myaddr_,myaddr_,pcl->level_,radius(pcl->level_));
01725 assert(origin_time < now);
01726 }
01727
01728
01729 if(pcl->parent_ == NULL) {
01730 (*walk++) = (NO_PARENT >> 8) & 0xFF;
01731 (*walk++) = (NO_PARENT) & 0xFF;
01732 }
01733 else {
01734 (*walk++) = ((pcl->parent_)->id_ >> 8) & 0xFF;
01735 (*walk++) = ((pcl->parent_)->id_) & 0xFF;
01736 }
01737
01738 if(action == PERIODIC_ADVERTS || action == GLOBAL_ADVERT) {
01739
01740 (*walk++) = (pcl->num_children_ >> 8) & 0xFF;
01741 (*walk++) = (pcl->num_children_) & 0xFF;
01742
01743
01744 (*walk++) = (pcl->num_potl_children_ >> 8) & 0xFF;
01745 (*walk++) = (pcl->num_potl_children_) & 0xFF;
01746
01747 LMNode *potl_ch = pcl->pchildren_;
01748 while(potl_ch) {
01749 if(potl_ch->child_flag_ != NOT_POTL_CHILD) {
01750 (*walk++) = (potl_ch->id_ >> 8) & 0xFF;
01751 (*walk++) = (potl_ch->id_) & 0xFF;
01752 int64_t *addrs = NULL;
01753 int num_addrs = 0;
01754 ((potl_ch)->lmaddr_)->get_lm_addrs(&num_addrs, &addrs);
01755
01756
01757
01758
01759
01760 (*walk++) = (num_addrs) & 0xFF;
01761 for(int i = 0; i < num_addrs; ++i) {
01762
01763 (*walk++) = (addrs[i] >> 56) & 0xFF;
01764 (*walk++) = (addrs[i] >> 48) & 0xFF;
01765 (*walk++) = (addrs[i] >> 40) & 0xFF;
01766 (*walk++) = (addrs[i] >> 32) & 0xFF;
01767 (*walk++) = (addrs[i] >> 24) & 0xFF;
01768 (*walk++) = (addrs[i] >> 16) & 0xFF;
01769 (*walk++) = (addrs[i] >> 8) & 0xFF;
01770 (*walk++) = (addrs[i]) & 0xFF;
01771 }
01772 if(num_addrs)
01773 delete[] addrs;
01774 }
01775 potl_ch = potl_ch->next_;
01776 }
01777
01778 (*walk++) = (pcl->num_tags_ >> 8) & 0xFF;
01779 (*walk++) = (pcl->num_tags_) & 0xFF;
01780 if(pcl->num_tags_) {
01781 adv_tags = pcl->tag_list_;
01782 while(adv_tags) {
01783 (*walk++) = (adv_tags->obj_name_ >> 24) & 0xFF;
01784 (*walk++) = (adv_tags->obj_name_ >> 16) & 0xFF;
01785 (*walk++) = (adv_tags->obj_name_ >> 8) & 0xFF;
01786 (*walk++) = (adv_tags->obj_name_) & 0xFF;
01787 adv_tags = adv_tags->next_;
01788 }
01789 }
01790
01791
01792
01793
01794
01795
01796 hdrc->size_ = 20 + 8 + ((4+8) * pcl->num_potl_children_) + 20 + 4 + (4 * pcl->num_tags_) + 4 + 1 + (8 * num_lm_addrs);
01797
01798
01799
01800
01801 }
01802 else if(action == DEMOTION) {
01803 hdrc->size_ = 20 + 20;
01804 }
01805 }
01806 }
01807
01808
01809
01810
01811
01812
01813
01814 if(action == DEMOTION && pcl->periodic_update_event_->uid_)
01815 Scheduler::instance().cancel(pcl->periodic_update_event_);
01816
01817 hdrc->direction() = hdr_cmn::DOWN;
01818 return p;
01819 }
01820
01821
01822
01823
01824 int
01825 LandmarkAgent::radius(int level)
01826 {
01827
01828 return((int(pow(2,level+1) + pow(2,level) - 1)));
01829
01830
01831
01832 }
01833
01834
01835
01836
01837 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)
01838 {
01839 level_ = level;
01840 periodic_update_event_ = new Event;
01841 periodic_handler_ = new LMPeriodicAdvtHandler(this);
01842 a_ = a;
01843 tag_list_ = NULL;
01844 num_tags_ = 0;
01845 adverts_type_ = FLOOD;
01846 mylmaddrs_ = new LMAddrs;
01847 }
01848
01849
01850
01851
01852 void
01853 PromotionTimer::expire(Event *e) {
01854 ParentChildrenList *pcl = a_->parent_children_list_;
01855 ParentChildrenList *new_pcl, *higher_level_pcl = NULL, *lower_level_pcl;
01856 ParentChildrenList *pcl1 = NULL;
01857 ParentChildrenList *pcl2 = NULL;
01858 ParentChildrenList *cur_pcl = NULL;
01859 int found = FALSE, has_parent = FALSE;
01860 int64_t *my_lm_addrs = NULL;
01861 int num_my_lm_addrs = 0;
01862 int num_potl_ch = 0;
01863 int addr_changed = 0;
01864 Scheduler &s = Scheduler::instance();
01865 double now = s.clock();
01866 Packet *p, *newp;
01867
01868
01869
01870
01871
01872
01873 while(pcl != NULL) {
01874 if(pcl->level_ == (a_->highest_level_ + 1)) {
01875
01876 higher_level_pcl = pcl;
01877 a_->num_resched_ = pcl->num_heard_ - 1;
01878 num_potl_ch = pcl->num_potl_children_;
01879 }
01880 else if(pcl->level_ == a_->highest_level_) {
01881 cur_pcl = pcl;
01882 if(pcl->parent_) {
01883 has_parent = TRUE;
01884 }
01885 }
01886 else if(pcl->level_ == (a_->highest_level_-1)) {
01887 lower_level_pcl = pcl;
01888 }
01889 pcl = pcl->next_;
01890 }
01891
01892 assert(higher_level_pcl);
01893 if(a_->highest_level_)
01894 assert(lower_level_pcl);
01895 assert(cur_pcl);
01896
01897 if(a_->wait_state_) {
01898
01899 if(a_->num_resched_ && !has_parent) {
01900 a_->wait_state_ = 0;
01901 a_->total_wait_time_ = 0;
01902
01903
01904
01905
01906
01907 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_);
01908
01909
01910
01911 a_->trace("Node %d: Promotion timeout after wait period in expire1: %f at time %f", a_->myaddr_,a_->promo_timeout_,s.clock());
01912 a_->num_resched_ = 0;
01913 a_->promo_start_time_ = s.clock();
01914 a_->promo_timer_->resched(a_->promo_timeout_);
01915 }
01916 else {
01917 double wait_time = PERIODIC_WAIT_TIME;
01918 a_->total_wait_time_ += wait_time;
01919
01920 a_->promo_timer_->resched(wait_time);
01921
01922
01923
01924 if(a_->highest_level_ && (a_->total_wait_time_ > (a_->update_period_*1.5))) {
01925
01926
01927
01928
01929
01930
01931 if(cur_pcl->num_children_ == 1 && lower_level_pcl->num_pparent_ > 1) {
01932 a_->trace("Node %d: Demoting from level %d because of no children at time %f",a_->myaddr_,a_->highest_level_,s.clock());
01933
01934
01935 int delete_flag = TRUE;
01936 int upd_time = (int) now;
01937 upd_time = (upd_time << 16) | (lower_level_pcl->seqnum_ & 0xFFFF);
01938 ++(lower_level_pcl->seqnum_);
01939 lower_level_pcl->UpdatePotlParent(a_->myaddr_, 0, 0, 0, 0, 0, upd_time, delete_flag);
01940
01941 upd_time = (int) now;
01942 upd_time = (upd_time << 16) | (higher_level_pcl->seqnum_ & 0xFFFF);
01943 ++(higher_level_pcl->seqnum_);
01944 higher_level_pcl->UpdatePotlChild(a_->myaddr_, 0, 0, 0, 0, 0, upd_time, IS_CHILD, delete_flag,NULL);
01945
01946 --(a_->highest_level_);
01947 Packet *p = a_->makeUpdate(cur_pcl, HIER_ADVS, DEMOTION);
01948 s.schedule(a_->target_,p,0);
01949 }
01950 }
01951 else if(!(cur_pcl->parent_) && (a_->total_wait_time_ >= (2*PERIODIC_WAIT_TIME))) {
01952
01953 a_->global_lm_id_ = a_->myaddr_;
01954 a_->global_lm_level_ = a_->highest_level_;
01955
01956
01957 (cur_pcl->mylmaddrs_)->get_lm_addrs(&num_my_lm_addrs,&my_lm_addrs);
01958
01959
01960
01961 int64_t *lmaddr = new int64_t[1];
01962 lmaddr[0] = 1;
01963 lmaddr[0] = (lmaddr[0] << (cur_pcl->level_ * 8));
01964 int num_lm_addrs = 1;
01965
01966 assert(num_my_lm_addrs <= 1);
01967 if(num_my_lm_addrs == 0) {
01968 addr_changed = 1;
01969 }
01970 else {
01971 if(my_lm_addrs[0] != lmaddr[0])
01972 addr_changed = 1;
01973 }
01974
01975 if(num_my_lm_addrs) delete[] my_lm_addrs;
01976
01977 if(addr_changed) {
01978 a_->trace("Node %d: LM addrs being assigned by global LM at time %f, level %d",a_->myaddr_,now,a_->highest_level_);
01979 a_->assign_lmaddress(lmaddr, num_lm_addrs, cur_pcl->level_);
01980 if(a_->global_lm_)
01981 p = a_->makeUpdate(cur_pcl, HIER_ADVS, GLOBAL_ADVERT);
01982 else
01983 p = a_->makeUpdate(cur_pcl, HIER_ADVS, PERIODIC_ADVERTS);
01984 a_->trace("Node %d: Generating ReHash msg at time %f",a_->myaddr_,NOW);
01985 a_->GenerateReHashMsg(lmaddr[0],NOW);
01986
01987
01988 ParentChildrenList *tmp_pcl = a_->parent_children_list_;
01989 while(tmp_pcl) {
01990 if(tmp_pcl->level_ < cur_pcl->level_) {
01991 a_->trace("Node %d: Generating level %d update at time %f",a_->myaddr_,tmp_pcl->level_,now);
01992 newp = a_->makeUpdate(tmp_pcl, HIER_ADVS, PERIODIC_ADVERTS);
01993 s.schedule(a_->target_,newp,0);
01994 tmp_pcl->last_update_sent_ = now;
01995 }
01996 tmp_pcl = tmp_pcl->next_;
01997 }
01998 s.schedule(a_->target_, p, 0);
01999 cur_pcl->last_update_sent_ = now;
02000 }
02001
02002
02003
02004 if(num_lm_addrs) delete[] lmaddr;
02005 }
02006 }
02007 return;
02008 }
02009
02010
02011 a_->promo_timer_running_ = 0;
02012
02013
02014
02015
02016
02017 higher_level_pcl = NULL;
02018 pcl = a_->parent_children_list_;
02019 while(pcl != NULL) {
02020 new_pcl = pcl;
02021 if(pcl->level_ == a_->highest_level_+1){
02022 found = TRUE;
02023 higher_level_pcl = pcl;
02024 }
02025 if(pcl->level_ == (a_->highest_level_)){
02026 pcl1 = pcl;
02027 }
02028 if(pcl->level_ == (a_->highest_level_+2)){
02029 pcl2 = pcl;
02030 }
02031 pcl = pcl->next_;
02032 }
02033
02034
02035 assert(pcl1);
02036
02037 if(pcl1->parent_ != NULL) {
02038 a_->trace("Node %d: Not promoted to higher level %d\n", a_->myaddr_, a_->highest_level_+1);
02039 return;
02040 }
02041
02042 ++(a_->highest_level_);
02043 assert(a_->highest_level_ < MAX_LEVELS);
02044
02045 if(!found) {
02046 new_pcl->next_ = new ParentChildrenList(a_->highest_level_, a_);
02047 higher_level_pcl = new_pcl->next_;
02048 new_pcl = new_pcl->next_;
02049 }
02050
02051
02052 if(!pcl2) {
02053 new_pcl->next_ = new ParentChildrenList((a_->highest_level_)+1, a_);
02054 pcl2 = new_pcl->next_;
02055 }
02056
02057 assert(pcl2);
02058
02059 if(a_->debug_) {
02060 a_->trace("Node %d: Promoted to level %d, num_potl_children %d at time %f", a_->myaddr_, a_->highest_level_, num_potl_ch, now);
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075 }
02076
02077
02078
02079 a_->SendChangedTagListUpdate(0,a_->highest_level_-1);
02080
02081
02082 s.schedule(higher_level_pcl->periodic_handler_, higher_level_pcl->periodic_update_event_, 0);
02083
02084
02085
02086 int num_hops = 0;
02087 int energy = (int)((a_->node_)->energy());
02088 int child_flag = IS_CHILD;
02089 int delete_flag = FALSE;
02090
02091 int upd_time = (int) now;
02092 upd_time = (upd_time << 16) | (pcl1->seqnum_ & 0xFFFF);
02093 ++(pcl1->seqnum_);
02094 pcl1->UpdatePotlParent(a_->myaddr_, a_->myaddr_, num_hops, a_->highest_level_, higher_level_pcl->num_children_, energy, upd_time, delete_flag);
02095
02096
02097
02098
02099 upd_time = (int) now;
02100 upd_time = (upd_time << 16) | (pcl2->seqnum_ & 0xFFFF);
02101 ++(pcl2->seqnum_);
02102 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_);
02103
02104
02105
02106 a_->num_resched_ = pcl2->num_heard_ - 1;
02107 if(higher_level_pcl->parent_ == NULL && a_->num_resched_) {
02108
02109
02110
02111
02112 a_->promo_timer_running_ = 1;
02113 a_->wait_state_ = 0;
02114 a_->total_wait_time_ = 0;
02115 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_);
02116 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());
02117 a_->num_resched_ = 0;
02118 a_->promo_start_time_ = s.clock();
02119 a_->promo_timer_->resched(a_->promo_timeout_);
02120 }
02121 else {
02122 double wait_time = PERIODIC_WAIT_TIME;
02123 a_->promo_timer_running_ = 1;
02124 a_->total_wait_time_ = 0;
02125 a_->wait_state_ = 1;
02126 a_->total_wait_time_ += wait_time;
02127
02128 a_->promo_timer_->resched(wait_time);
02129 }
02130
02131
02132
02133
02134
02135
02136
02137 }
02138
02139
02140
02141
02142
02143 int
02144 LandmarkAgent::command (int argc, const char *const *argv)
02145 {
02146 if (argc == 2)
02147 {
02148 if (strcmp (argv[1], "start") == 0)
02149 {
02150 startUp();
02151 return (TCL_OK);
02152 }
02153 if (strcmp (argv[1], "stop") == 0)
02154 {
02155 stop();
02156 return (TCL_OK);
02157 }
02158
02159 if (strcmp (argv[1], "print-nbrs") == 0)
02160 {
02161 get_nbrinfo();
02162 return (TCL_OK);
02163 }
02164 if (strcmp (argv[1], "enable-caching") == 0)
02165 {
02166 cache_ = 1;
02167 return (TCL_OK);
02168 }
02169 if (strcmp (argv[1], "unicast-adverts") == 0)
02170 {
02171 adverts_type_ = UNICAST;
02172 return (TCL_OK);
02173 }
02174 if (strcmp (argv[1], "hard-state-adverts") == 0)
02175 {
02176 adverts_type_ = SUPPRESS;
02177
02178 update_timeout_ = 1000000;
02179 return (TCL_OK);
02180 }
02181 if (strcmp (argv[1], "enable-global-landmark") == 0)
02182 {
02183 global_lm_ = 1;
02184 return (TCL_OK);
02185 }
02186 else if (strcmp (argv[1], "dumprtab") == 0)
02187 {
02188 Packet *p2 = allocpkt ();
02189 hdr_ip *iph2 = HDR_IP(p2);
02190
02191
02192 trace ("Table Dump %d[%d]\n----------------------------------\n",
02193 myaddr_, iph2->sport());
02194 trace ("VTD %.5f %d:%d\n", Scheduler::instance ().clock (),
02195 myaddr_, iph2->sport());
02196 trace ("Remaining energy: %f", node_->energy());
02197
02198
02199
02200
02201
02202
02203 trace("Highest Level: %d", highest_level_);
02204 Packet::free (p2);
02205 ParentChildrenList *pcl = parent_children_list_;
02206 LMNode *pch;
02207 while(pcl) {
02208 trace("Level %d:", pcl->level_);
02209 if(pcl->parent_)
02210 trace("Parent: %d", (pcl->parent_)->id_);
02211 else
02212 trace("Parent: NULL");
02213 int num_lm_addrs = 0;
02214 int64_t *lmaddrs = NULL;
02215 (pcl->mylmaddrs_)->get_lm_addrs(&num_lm_addrs,&lmaddrs);
02216 for( int i = 0; i < num_lm_addrs; ++i) {
02217 int i1,i2,i3,i4,i5,i6,i7,i8;
02218 i1 = (lmaddrs[i] >> 56) & 0xFF;
02219 i2 = (lmaddrs[i] >> 48) & 0xFF;
02220 i3 = (lmaddrs[i] >> 40) & 0xFF;
02221 i4 = (lmaddrs[i] >> 32) & 0xFF;
02222 i5 = (lmaddrs[i] >> 24) & 0xFF;
02223 i6 = (lmaddrs[i] >> 16) & 0xFF;
02224 i7 = (lmaddrs[i] >> 8) & 0xFF;
02225 i8 = (lmaddrs[i]) & 0xFF;
02226 trace("Landmark Address: %d.%d.%d.%d.%d.%d.%d.%d",i1,i2,i3,i4,i5,i6,i7,i8);
02227 }
02228 if(num_lm_addrs) delete[] lmaddrs;
02229 if(myaddr_ == 134) {
02230 pch = pcl->pchildren_;
02231 while(pch) {
02232 int num_addrs = 0;
02233 int64_t *addrs = NULL;
02234 (pch->lmaddr_)->get_lm_addrs(&num_addrs,&addrs);
02235
02236 int j1=0,j2=0,j3=0,j4=0,j5=0,j6=0,j7=0,j8=0;
02237 if(num_addrs) {
02238 j1 = (addrs[0] >> 56) & 0xFF;
02239 j2 = (addrs[0] >> 48) & 0xFF;
02240 j3 = (addrs[0] >> 40) & 0xFF;
02241 j4 = (addrs[0] >> 32) & 0xFF;
02242 j5 = (addrs[0] >> 24) & 0xFF;
02243 j6 = (addrs[0] >> 16) & 0xFF;
02244 j7 = (addrs[0] >> 8) & 0xFF;
02245 j8 = (addrs[0]) & 0xFF;
02246 }
02247 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_);
02248 if(num_addrs) delete[] addrs;
02249 pch = pch->next_;
02250 }
02251 }
02252 trace("Number of potl children: %d\n", pcl->num_potl_children_);
02253 if(myaddr_ == 166) {
02254 trace("Number of children: %d\n", pcl->num_children_);
02255 trace("Number of level %d nodes heard: %d\n", (pcl->level_)-1, pcl->num_heard_);
02256
02257 trace("Number of potl parent: %d\n", pcl->num_pparent_);
02258 if(pcl->level_ >= 1 && highest_level_ >= 1) {
02259 pch = pcl->pchildren_;
02260 trace("Potential Children (radius %d):",radius(pcl->level_));
02261 while(pch) {
02262 if(pch->child_flag_ != NOT_POTL_CHILD)
02263 trace("Node %d (%d hops away)",pch->id_,pch->num_hops_);
02264 pch = pch->next_;
02265 }
02266
02267 pch = pcl->pparent_;
02268 trace("Potential parent:");
02269 while(pch) {
02270 trace("Node %d (%d hops away)",pch->id_,pch->num_hops_);
02271 pch = pch->next_;
02272 }
02273 }
02274 }
02275 pcl = pcl->next_;
02276 }
02277
02278 Packet::free(p2);
02279 return (TCL_OK);
02280 }
02281 }
02282 else if (argc == 3)
02283 {
02284 if (strcasecmp (argv[1], "tracetarget") == 0)
02285 {
02286 TclObject *obj;
02287 if ((obj = TclObject::lookup (argv[2])) == 0)
02288 {
02289 fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
02290 argv[2]);
02291 return TCL_ERROR;
02292 }
02293 tracetarget_ = (Trace *) obj;
02294 return TCL_OK;
02295 }
02296 else if (strcasecmp (argv[1], "addr") == 0) {
02297 int temp;
02298 temp = Address::instance().str2addr(argv[2]);
02299 myaddr_ = temp;
02300 return TCL_OK;
02301 }
02302 else if (strcasecmp (argv[1], "set-update-period") == 0) {
02303 update_period_ = atof(argv[2]);
02304 if(adverts_type_ != SUPPRESS)
02305 update_timeout_ = update_period_ + 4 * LM_STARTUP_JITTER;
02306 return TCL_OK;
02307 }
02308 else if (strcasecmp (argv[1], "set-update-timeout") == 0) {
02309 update_timeout_ = atof(argv[2]);
02310 return TCL_OK;
02311 }
02312 else if (strcasecmp (argv[1], "start-tag-motion") == 0) {
02313 mobility_period_ = atof(argv[2]);
02314 Scheduler::instance().schedule(tag_mobility_,tag_mobility_event_,Random::uniform(mobility_period_));
02315 return (TCL_OK);
02316 }
02317 else if (strcasecmp (argv[1], "attach-tag-dbase") == 0)
02318 {
02319 TclObject *obj;
02320 if ((obj = TclObject::lookup (argv[2])) == 0)
02321 {
02322 fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
02323 argv[2]);
02324 return TCL_ERROR;
02325 }
02326 tag_dbase_ = (tags_database *) obj;
02327 return TCL_OK;
02328 }
02329 else if (strcasecmp (argv[1], "node") == 0)
02330 {
02331 assert(node_ == NULL);
02332 TclObject *obj;
02333 if ((obj = TclObject::lookup (argv[2])) == 0)
02334 {
02335 fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
02336 argv[2]);
02337 return TCL_ERROR;
02338 }
02339 node_ = (MobileNode *) obj;
02340 return TCL_OK;
02341 }
02342 else if (strcmp (argv[1], "query-debug") == 0)
02343 {
02344 qry_debug_ = atoi(argv[2]);
02345 return (TCL_OK);
02346 }
02347 else if (strcasecmp (argv[1], "ll-queue") == 0)
02348 {
02349 if (!(ll_queue = (PriQueue *) TclObject::lookup (argv[2])))
02350 {
02351 fprintf (stderr, "Landmark_Agent: ll-queue lookup of %s failed\n", argv[2]);
02352 return TCL_ERROR;
02353 }
02354
02355 return TCL_OK;
02356 }
02357 }
02358
02359 return (Agent::command (argc, argv));
02360 }
02361
02362
02363
02364
02365 void
02366 LandmarkAgent::startUp()
02367 {
02368 int i,ntags, j = 0, read_new_mobile_tags = 0;
02369 Scheduler &s = Scheduler::instance();
02370 compr_taglist *local_tags0, *local_tags1, *local_tags2, *t_ptr;
02371 compr_taglist *tag_ptr1, *tag_ptr2;
02372 God *gd = God::instance();
02373
02374 int *nbrs;
02375 int num_nbrs = 0, num_nodes = 0;
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401 trace("Node %d: LM Agent starting up at time %f",myaddr_,NOW);
02402
02403
02404 node_dead_ = 0;
02405
02406 double x,y,z;
02407 node_->getLoc(&x,&y,&z);
02408
02409
02410
02411
02412
02413 double r = 60;
02414
02415 local_tags0 = tag_dbase_->Gettags(x,y,r);
02416
02417
02418 t_ptr = local_tags0;
02419 ntags = 0;
02420 while(t_ptr) {
02421
02422 ++ntags;
02423 if(!(t_ptr->next_) && mobile_tags_ && !read_new_mobile_tags) {
02424
02425
02426
02427 read_new_mobile_tags = 1;
02428 t_ptr->next_ = mobile_tags_;
02429 mobile_tags_ = NULL;
02430 }
02431 t_ptr = t_ptr->next_;
02432 }
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475 assert(highest_level_ == 0);
02476 assert(parent_children_list_ == NULL);
02477 parent_children_list_ = new ParentChildrenList(highest_level_, this);
02478 ParentChildrenList **pcl = &parent_children_list_;
02479
02480
02481 assert(highest_level_ == 0);
02482 s.schedule((*pcl)->periodic_handler_, (*pcl)->periodic_update_event_, INITIAL_WAIT_TIME + jitter(LM_STARTUP_JITTER, be_random_));
02483 (*pcl)->tag_list_ = local_tags0;
02484 (*pcl)->num_tags_ = ntags;
02485
02486
02487
02488 promo_timer_running_ = 1;
02489 num_resched_ = 0;
02490
02491
02492
02493
02494 total_wait_time_ = 0;
02495 wait_state_ = 1;
02496 double wait_time = WAIT_TIME * radius(highest_level_) + INITIAL_WAIT_TIME + LM_STARTUP_JITTER;
02497 total_wait_time_ += wait_time;
02498
02499 promo_timer_->sched(wait_time);
02500
02501
02502 }
02503
02504
02505
02506
02507 compr_taglist *
02508 LandmarkAgent::aggregate_taginfo(compr_taglist *unagg_tags, int agg_level, int *num_tags)
02509 {
02510 compr_taglist *agg_tags, *agg_ptr1, *agg_ptr2, *last_agg_ptr;
02511 int found;
02512
02513 *num_tags = 0;
02514
02515
02516 agg_ptr1 = unagg_tags;
02517 agg_tags = NULL;
02518
02519 while(agg_ptr1) {
02520 if(agg_level == 1) {
02521 found = FALSE;
02522 if(agg_tags) {
02523 agg_ptr2 = agg_tags;
02524 while(agg_ptr2) {
02525 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))) {
02526 found = TRUE;
02527 break;
02528 }
02529 last_agg_ptr = agg_ptr2;
02530 agg_ptr2 = agg_ptr2->next_;
02531 }
02532 }
02533
02534 if(!found) {
02535 ++(*num_tags);
02536 if(!agg_tags) {
02537 agg_tags = new compr_taglist;
02538 last_agg_ptr = agg_tags;
02539 }
02540 else {
02541 last_agg_ptr->next_ = new compr_taglist;
02542 last_agg_ptr = last_agg_ptr->next_;
02543 }
02544 last_agg_ptr->obj_name_ = (agg_ptr1->obj_name_ & 0xFFFF0000);
02545 }
02546 }
02547 else if(agg_level >= 2) {
02548 found = FALSE;
02549 if(agg_tags) {
02550 agg_ptr2 = agg_tags;
02551 while(agg_ptr2) {
02552 if(((agg_ptr2->obj_name_ >> 24) & 0xFF) == ((agg_ptr1->obj_name_ >> 24) & 0xFF)) {
02553 found = TRUE;
02554 break;
02555 }
02556 last_agg_ptr = agg_ptr2;
02557 agg_ptr2 = agg_ptr2->next_;
02558 }
02559 }
02560
02561 if(!found) {
02562 ++(*num_tags);
02563 if(!agg_tags) {
02564 agg_tags = new compr_taglist;
02565 last_agg_ptr = agg_tags;
02566 }
02567 else {
02568 last_agg_ptr->next_ = new compr_taglist;
02569 last_agg_ptr = last_agg_ptr->next_;
02570 }
02571 last_agg_ptr->obj_name_ = (agg_ptr1->obj_name_ & 0xFF000000);
02572 }
02573 }
02574 agg_ptr1 = agg_ptr1->next_;
02575 }
02576 return(agg_tags);
02577 }
02578
02579
02580
02581
02582
02583 compr_taglist *
02584 LandmarkAgent::aggregate_tags(compr_taglist *unagg_tags, int agg_level, int *num_tags)
02585 {
02586 compr_taglist *agg_tags = NULL, *tag_ptr;
02587 aggreg_taglist *t1, *t2, *t3, *tmp_ptr;
02588 aggreg_taglist *list1 = NULL, *list2 = NULL, *list3 = NULL, *list = NULL;
02589 aggreg_taglist *prev_tag, *next_tag, *old_list;
02590 int found;
02591 int p1,p2,p3,q1,q2,q3,object_name;
02592
02593
02594
02595
02596
02597
02598
02599 tag_ptr = unagg_tags;
02600 while(tag_ptr) {
02601 p1 = (tag_ptr->obj_name_ >> 24) & 0xFF;
02602 p2 = (tag_ptr->obj_name_ >> 16) & 0xFF;
02603 p3 = tag_ptr->obj_name_ & 0xFFFF;
02604 found = 0;
02605
02606 if(p1 && p2 && p3) {
02607
02608
02609 object_name = (int)((p1 * pow(2,24)) + (p2 * pow(2,16))) ;
02610 old_list = list2;
02611 while(old_list) {
02612 if(old_list->obj_name_ == object_name) {
02613 found = TRUE;
02614 break;
02615 }
02616 old_list = old_list->next_;
02617 }
02618
02619
02620 old_list = list1;
02621 while(old_list) {
02622 q1 = (old_list->obj_name_ >> 24) & 0xFF;
02623 if(p1 == q1) {
02624 found = TRUE;
02625 break;
02626 }
02627 old_list = old_list->next_;
02628 }
02629
02630 tmp_ptr = list3;
02631 while(tmp_ptr && !found) {
02632 q1 = (tmp_ptr->obj_name_ >> 24) & 0xFF;
02633 q2 = (tmp_ptr->obj_name_ >> 16) & 0xFF;
02634 q3 = tmp_ptr->obj_name_ & 0xFFFF;
02635
02636
02637
02638 if(p1 == q1 && p2 == q2 && p3 != q3) {
02639 if(!list2) {
02640 list2 = new aggreg_taglist;
02641 t2 = list2;
02642 }
02643 else {
02644 t2->next_ = new aggreg_taglist;
02645 t2 = t2->next_;
02646 }
02647 t2->obj_name_ = object_name;
02648
02649
02650 t2->marked_ = 1;
02651
02652
02653 tmp_ptr->obj_name_ = -1;
02654 found = TRUE;
02655 break;
02656 }
02657 else if(p1 == q1 && p2 == q2 && p3 == q3) {
02658 found = TRUE;
02659 break;
02660 }
02661 tmp_ptr = tmp_ptr->next_;
02662 }
02663
02664 if(found) {
02665 tag_ptr = tag_ptr->next_;
02666 continue;
02667 }
02668
02669 if(!list3) {
02670 list3 = new aggreg_taglist;
02671 t3 = list3;
02672 }
02673 else {
02674 t3->next_ = new aggreg_taglist;
02675 t3 = t3->next_;
02676 }
02677 t3->obj_name_ = tag_ptr->obj_name_;
02678 }
02679 else if(p1 && p2 && !p3) {
02680
02681
02682 object_name = (int)(p1 * pow(2,24)) ;
02683 if(list1) {
02684 old_list = list1;
02685 while(old_list) {
02686 if(old_list->obj_name_ == object_name) {
02687 found = TRUE;
02688 break;
02689 }
02690 old_list = old_list->next_;
02691 }
02692 }
02693
02694 tmp_ptr = list2;
02695 while(tmp_ptr && !found) {
02696 q1 = (tmp_ptr->obj_name_ >> 24) & 0xFF;
02697 q2 = (tmp_ptr->obj_name_ >> 16) & 0xFF;
02698
02699
02700 if(p1 == q1 && p2 != q2 && !tmp_ptr->marked_) {
02701 if(!list1) {
02702 list1 = new aggreg_taglist;
02703 t1 = list1;
02704 }
02705 else {
02706 t1->next_ = new aggreg_taglist;
02707 t1 = t1->next_;
02708 }
02709 t1->obj_name_ = object_name;
02710
02711
02712 t1->marked_ = 1;
02713
02714
02715 tmp_ptr->obj_name_ = -1;
02716
02717
02718 old_list = list3;
02719 while(old_list) {
02720 q1 = (old_list->obj_name_ >> 24) & 0xFF;
02721 if(p1 == q1)
02722 old_list->obj_name_ = -1;
02723 old_list = old_list->next_;
02724 }
02725
02726 found = TRUE;
02727 break;
02728 }
02729 else if(p1 == q1 && p2 == q2) {
02730 found = TRUE;
02731 break;
02732 }
02733 tmp_ptr = tmp_ptr->next_;
02734 }
02735
02736 if(found) {
02737 tag_ptr = tag_ptr->next_;
02738 continue;
02739 }
02740
02741 if(!list2) {
02742 list2 = new aggreg_taglist;
02743 t2 = list2;
02744 }
02745 else {
02746 t2->next_ = new aggreg_taglist;
02747 t2 = t2->next_;
02748 }
02749 t2->obj_name_ = tag_ptr->obj_name_;
02750
02751
02752 old_list = list3;
02753 while(old_list) {
02754 q1 = (old_list->obj_name_ >> 24) & 0xFF;
02755 q2 = (old_list->obj_name_ >> 16) & 0xFF;
02756 if(p1 == q1 && p2 == q2)
02757 old_list->obj_name_ = -1;
02758 old_list = old_list->next_;
02759 }
02760 }
02761 else if(p1 && !p2 && !p3) {
02762
02763 tmp_ptr = list1;
02764 while(tmp_ptr) {
02765 if(tmp_ptr->obj_name_ == tag_ptr->obj_name_) {
02766 found = TRUE;
02767 break;
02768 }
02769 tmp_ptr = tmp_ptr->next_;
02770 }
02771
02772
02773 if(!found) {
02774 if(!list1) {
02775 list1 = new aggreg_taglist;
02776 t1 = list1;
02777 }
02778 else {
02779 t1->next_ = new aggreg_taglist;
02780 t1 = t1->next_;
02781 }
02782 t1->obj_name_ = tag_ptr->obj_name_;
02783 }
02784
02785
02786 old_list = list2;
02787 while(old_list) {
02788 q1 = (old_list->obj_name_ >> 24) & 0xFF;
02789 if(p1 == q1)
02790 old_list->obj_name_ = -1;
02791 old_list = old_list->next_;
02792 }
02793
02794
02795 old_list = list3;
02796 while(old_list) {
02797 q1 = (old_list->obj_name_ >> 24) & 0xFF;
02798 if(p1 == q1)
02799 old_list->obj_name_ = -1;
02800 old_list = old_list->next_;
02801 }
02802 }
02803 else
02804 assert(0);
02805 tag_ptr = tag_ptr->next_;
02806 }
02807
02808
02809 list = NULL;
02810 if(list3) {
02811 list = list3;
02812 if(list2) {
02813 t3->next_ = list2;
02814 if(list1) {
02815 t2->next_ = list1;
02816 }
02817 }
02818 else if(list1)
02819 t3->next_ = list1;
02820 }
02821 else if(list2) {
02822 list = list2;
02823 if(list1)
02824 t2->next_ = list1;
02825 }
02826 else if(list1)
02827 list = list1;
02828
02829
02830
02831
02832 *num_tags = 0;
02833 agg_tags = NULL;
02834 tmp_ptr = list;
02835 while(tmp_ptr) {
02836 if(tmp_ptr->obj_name_ != -1) {
02837 if(!agg_tags) {
02838 agg_tags = new compr_taglist;
02839 tag_ptr = agg_tags;
02840 }
02841 else {
02842 tag_ptr->next_ = new compr_taglist;
02843 tag_ptr = tag_ptr->next_;
02844 }
02845 ++(*num_tags);
02846 tag_ptr->obj_name_ = tmp_ptr->obj_name_;
02847 }
02848 tmp_ptr = tmp_ptr->next_;
02849 }
02850
02851
02852 list1 = NULL;
02853 list2 = NULL;
02854 list1 = list;
02855 while(list1) {
02856 list2 = list1;
02857 list1 = list1->next_;
02858 delete list2;
02859 }
02860
02861 return(agg_tags);
02862 }
02863
02864
02865
02866
02867
02868
02869 void
02870 LandmarkAgent::recv(Packet *p, Handler *)
02871 {
02872 hdr_ip *iph = HDR_IP(p);
02873 hdr_cmn *cmh = HDR_CMN(p);
02874
02875
02876
02877
02878
02879 if(node_dead_) {
02880 Packet::free(p);
02881 return;
02882 }
02883
02884 if(iph->saddr() == myaddr_ && iph->sport() == 0) {
02885
02886
02887
02888 cmh->size() += IP_HDR_LEN;
02889
02890 }
02891
02892
02893
02894
02895 else if(iph->saddr() == myaddr_) {
02896 Packet::free(p);
02897
02898 return;
02899 }
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911 cmh->direction_ = hdr_cmn::DOWN;
02912
02913 unsigned char *walk = p->accessdata();
02914 int action = *walk++;
02915
02916 int data_pkt = 0;
02917 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)
02918 data_pkt = 1;
02919
02920 if ((iph->saddr() != myaddr_) && (iph->dport() == ROUTER_PORT) && !data_pkt)
02921 {
02922 ProcessHierUpdate(p);
02923 }
02924 else
02925 {
02926 ForwardPacket(p);
02927 }
02928 }
02929
02930 void
02931 LandmarkAgent::ForwardPacket(Packet *p)
02932 {
02933 hdr_ip *iph = HDR_IP(p);
02934 hdr_cmn *cmh = HDR_CMN(p);
02935 Packet *newp;
02936 hdr_ip *new_iph;
02937 hdr_cmn *new_cmh;
02938 unsigned char *walk, *X_ptr, *Y_ptr, *level_ptr, *num_src_hops_ptr;
02939 unsigned char *last_hop_ptr, *pkt_end_ptr;
02940 int X, Y, next_hop_level, prev_hop_level, obj_name, num_src_hops;
02941 double local_x, local_y, local_z;
02942 int num_dst = 0, action, origin_time;
02943 NodeIDList *dst_nodes = NULL, *dst_ptr = NULL;
02944 int query_for_us = FALSE;
02945 Scheduler &s = Scheduler::instance();
02946 double now = s.clock();
02947 nsaddr_t last_hop_id;
02948 int cache_index = -1;
02949 int found = FALSE;
02950
02951 walk = p->accessdata();
02952
02953
02954 action = *walk++;
02955
02956 X = 0;
02957 X_ptr = walk;
02958 X = *walk++;
02959 X = (X << 8) | *walk++;
02960
02961 Y_ptr = walk;
02962 Y = *walk++;
02963 Y = (Y << 8) | *walk++;
02964
02965
02966 level_ptr = walk;
02967 next_hop_level = *walk++;
02968
02969 obj_name = *walk++;
02970 obj_name = (obj_name << 8) | *walk++;
02971 obj_name = (obj_name << 8) | *walk++;
02972 obj_name = (obj_name << 8) | *walk++;
02973
02974
02975 origin_time = *walk++;
02976 origin_time = (origin_time << 8) | *walk++;
02977 origin_time = (origin_time << 8) | *walk++;
02978 origin_time = (origin_time << 8) | *walk++;
02979
02980 num_src_hops_ptr = walk;
02981 num_src_hops = *walk++;
02982 num_src_hops = (num_src_hops << 8) | *walk++;
02983
02984 assert(num_src_hops <= 30);
02985
02986 last_hop_ptr = NULL;
02987 for(int i = 0; i < num_src_hops; ++i) {
02988 last_hop_ptr = walk;
02989 walk += 3;
02990 }
02991
02992 if(last_hop_ptr) {
02993 prev_hop_level = *(last_hop_ptr+2);
02994 last_hop_id = *last_hop_ptr;
02995 last_hop_id = (last_hop_id << 8) | *(last_hop_ptr+1);
02996 }
02997 else {
02998 prev_hop_level = 0;
02999 last_hop_id = NO_NEXT_HOP;
03000 }
03001
03002
03003 pkt_end_ptr = walk;
03004
03005
03006 if(cache_) {
03007 if(X != 65000 && Y != 65000) {
03008 if(num_cached_items_ < MAX_CACHE_ITEMS) {
03009
03010 int replace_index = num_cached_items_;
03011
03012 for(int i = 0; i < num_cached_items_; ++i) {
03013 if(tag_cache_[i].obj_name_ == obj_name && tag_cache_[i].origin_time_ < origin_time) {
03014 replace_index = i;
03015 break;
03016 }
03017 }
03018
03019 tag_cache_[replace_index].obj_name_ = obj_name;
03020 tag_cache_[replace_index].origin_time_ = origin_time;
03021 tag_cache_[replace_index].X_ = X;
03022 tag_cache_[replace_index].Y_ = Y;
03023 ++num_cached_items_;
03024 }
03025 else {
03026
03027 int replace_index = 0;
03028 int least_time = tag_cache_[replace_index].origin_time_;
03029 for(int i = 0; i < MAX_CACHE_ITEMS; ++i) {
03030 if(tag_cache_[i].origin_time_ < least_time)
03031 replace_index = i;
03032 }
03033 tag_cache_[replace_index].obj_name_ = obj_name;
03034 tag_cache_[replace_index].origin_time_ = origin_time;
03035 tag_cache_[replace_index].X_ = X;
03036 tag_cache_[replace_index].Y_ = Y;
03037 }
03038 }
03039 else {
03040
03041
03042 found = FALSE;
03043 for(int i = 0; i < num_cached_items_; ++i) {
03044 if(tag_cache_[i].obj_name_ == obj_name && tag_cache_[i].origin_time_ > origin_time - 600) {
03045 found = TRUE;
03046 cache_index = i;
03047 break;
03048 }
03049 }
03050 }
03051 }
03052
03053
03054
03055
03056
03057
03058
03059
03060 cmh->direction() = hdr_cmn::DOWN;
03061 if(iph->daddr() == myaddr_)
03062 query_for_us = TRUE;
03063
03064
03065 if(X == 65000 && Y == 65000) {
03066
03067 if(query_for_us || found) {
03068 if(qry_debug_)
03069 trace("Node %d: Rcved qry for us from node %d at time %f",myaddr_,last_hop_id,s.clock());
03070 if(!found)
03071 dst_nodes = search_tag(obj_name,prev_hop_level,next_hop_level,last_hop_id,&num_dst);
03072
03073 if((num_dst == 0 && dst_nodes) || found) {
03074 delete dst_nodes;
03075
03076
03077
03078 if(found) {
03079 (*X_ptr++) = ((int)tag_cache_[cache_index].X_ >> 8) & 0xFF;
03080 (*X_ptr) = ((int)tag_cache_[cache_index].X_) & 0xFF;
03081 (*Y_ptr++) = ((int)tag_cache_[cache_index].Y_ >> 8) & 0xFF;
03082 (*Y_ptr) = ((int)tag_cache_[cache_index].Y_) & 0xFF;
03083 }
03084 else {
03085 node_->getLoc(&local_x, &local_y, &local_z);
03086 (*X_ptr++) = ((int)local_x >> 8) & 0xFF;
03087 (*X_ptr) = ((int)local_x) & 0xFF;
03088 (*Y_ptr++) = ((int)local_y >> 8) & 0xFF;
03089 (*Y_ptr) = ((int)local_y) & 0xFF;
03090 }
03091
03092
03093 iph->ttl_ = 1000;
03094
03095 cmh->size() += 50;
03096
03097 if(!num_src_hops) {
03098 iph->daddr() = myaddr_;
03099 iph->dport() = 0;
03100 cmh->next_hop_ = myaddr_;
03101 }
03102 else {
03103 --num_src_hops;
03104 *num_src_hops_ptr = (num_src_hops >> 8) & 0xFF;
03105 *(num_src_hops_ptr + 1) = num_src_hops & 0xFF;
03106
03107 cmh->size() -= 4;
03108
03109 iph->daddr() = *last_hop_ptr++;
03110 iph->daddr() = (iph->daddr() << 8) | *last_hop_ptr++;
03111 if(!num_src_hops)
03112 iph->dport() = 0;
03113 else
03114 iph->dport() = ROUTER_PORT;
03115
03116 int relevant_level = *last_hop_ptr;
03117 cmh->next_hop_ = get_next_hop(iph->daddr(),relevant_level);
03118
03119 if(cmh->next_hop_ == NO_NEXT_HOP) {
03120 Packet::free(p);
03121 trace("Node %d: Packet dropped because of no next hop info",myaddr_);
03122 return;
03123 }
03124 *level_ptr = *last_hop_ptr;
03125 }
03126
03127
03128
03129
03130
03131
03132 if(!num_src_hops && iph->daddr() == myaddr_) {
03133
03134
03135 Packet::free(p);
03136 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());
03137 return;
03138 }
03139 else if(iph->daddr() == myaddr_) {
03140 ForwardPacket(p);
03141 }
03142 else {
03143 s.schedule(target_,p,0);
03144 }
03145 }
03146 else if(num_dst >= 1) {
03147
03148 if(--iph->ttl_ == 0) {
03149 drop(p, DROP_RTR_TTL);
03150 return;
03151 }
03152
03153
03154
03155 ++num_src_hops;
03156 *num_src_hops_ptr = (num_src_hops >> 8) & 0xFF;
03157 *(num_src_hops_ptr+1) = num_src_hops & 0xFF;
03158 *pkt_end_ptr++ = (myaddr_ >> 8) & 0xFF;
03159 *pkt_end_ptr++ = myaddr_ & 0xFF;
03160
03161
03162 *pkt_end_ptr = (next_hop_level+1) & 0xFF;
03163
03164 cmh->size() += 4;
03165
03166 dst_ptr = dst_nodes;
03167
03168 iph->daddr() = dst_ptr->dst_node_;
03169 iph->dport() = ROUTER_PORT;
03170 cmh->next_hop_ = dst_ptr->dst_next_hop_;
03171 cmh->addr_type_ = NS_AF_INET;
03172
03173
03174 int tmp_next_hop_level = dst_ptr->next_hop_level_;
03175
03176 if(qry_debug_)
03177 trace("Node %d: Forwarding qry to node %d at time %f",myaddr_,dst_ptr->dst_node_,s.clock());
03178
03179 dst_ptr = dst_ptr->next_;
03180 delete dst_nodes;
03181 dst_nodes = dst_ptr;
03182
03183 for(int i = 1; i < num_dst; ++i) {
03184 if(qry_debug_)
03185 trace("Node %d: Forwarding qry to node %d at time %f",myaddr_,dst_ptr->dst_node_,s.clock());
03186
03187
03188 *level_ptr = dst_ptr->next_hop_level_;
03189
03190 newp = p->copy();
03191
03192 new_iph = HDR_IP(newp);
03193 new_cmh = HDR_CMN(newp);
03194
03195 new_iph->daddr() = dst_ptr->dst_node_;
03196 new_iph->dport() = ROUTER_PORT;
03197 new_cmh->next_hop_ = dst_ptr->dst_next_hop_;
03198 new_cmh->addr_type_ = NS_AF_INET;
03199
03200 if(new_iph->daddr() == myaddr_)
03201 ForwardPacket(newp);
03202 else
03203 s.schedule(target_,newp,0);
03204
03205 dst_ptr = dst_ptr->next_;
03206 delete dst_nodes;
03207 dst_nodes = dst_ptr;
03208 }
03209
03210 *level_ptr = tmp_next_hop_level;
03211
03212 if(iph->daddr() == myaddr_) {
03213 ForwardPacket(p);
03214 }
03215 else
03216 s.schedule(target_,p,0);
03217 }
03218 else if(num_dst == 0) {
03219
03220 if(qry_debug_)
03221 trace("Node %d: Dropping query from %d at time %f,num_src_hops %d",myaddr_,iph->saddr(),s.clock(),num_src_hops);
03222
03223 Packet::free(p);
03224 return;
03225 }
03226 }
03227 else {
03228
03229 if(qry_debug_)
03230 trace("Node %d: Forwarding query to node %d at time %f,num_src_hops %d",myaddr_,iph->daddr(),s.clock(),num_src_hops);
03231
03232 if(--iph->ttl_ == 0) {
03233 drop(p, DROP_RTR_TTL);
03234 return;
03235 }
03236
03237 cmh->next_hop_ = get_next_hop(iph->daddr(),next_hop_level+1);
03238
03239 if(cmh->next_hop_ == NO_NEXT_HOP) {
03240 Packet::free(p);
03241 trace("Node %d: Packet dropped because of no next hop info",myaddr_);
03242 return;
03243 }
03244 s.schedule(target_,p,0);
03245 }
03246 }
03247 else {
03248
03249 if(qry_debug_)
03250 trace("Node %d: Forwarding response to node %d at time %f,num_src_hops %d",myaddr_,iph->daddr(),s.clock(),num_src_hops);
03251 if(--iph->ttl_ == 0) {
03252 drop(p, DROP_RTR_TTL);
03253 return;
03254 }
03255
03256
03257 if(query_for_us) {
03258 if(!num_src_hops) {
03259 iph->daddr() = myaddr_;
03260 iph->dport() = 0;
03261 cmh->next_hop_ = myaddr_;
03262 }
03263 else {
03264 --num_src_hops;
03265 *num_src_hops_ptr = (num_src_hops >> 8) & 0xFF;
03266 *(num_src_hops_ptr + 1) = num_src_hops & 0xFF;
03267
03268 cmh->size() -= 4;
03269
03270 iph->daddr() = *last_hop_ptr++;
03271 iph->daddr() = (iph->daddr() << 8) | *last_hop_ptr++;
03272
03273 if(!num_src_hops)
03274 iph->dport() = 0;
03275 else
03276 iph->dport() = ROUTER_PORT;
03277
03278 int relevant_level = *last_hop_ptr;
03279 cmh->next_hop_ = get_next_hop(iph->daddr(),relevant_level);
03280
03281 if(cmh->next_hop_ == NO_NEXT_HOP) {
03282 Packet::free(p);
03283 trace("Node %d: Packet dropped because of no next hop info",myaddr_);
03284 return;
03285 }
03286
03287 *level_ptr = *last_hop_ptr;
03288 }
03289 if(!num_src_hops && iph->daddr() == myaddr_) {
03290
03291
03292 Packet::free(p);
03293 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());
03294 return;
03295 }
03296 else if(iph->daddr() == myaddr_)
03297 ForwardPacket(p);
03298 else
03299 s.schedule(target_,p,0);
03300 }
03301 else {
03302 cmh->next_hop_ = get_next_hop(iph->daddr(),next_hop_level);
03303
03304 if(cmh->next_hop_ == NO_NEXT_HOP) {
03305 Packet::free(p);
03306 trace("Node %d: Packet dropped because of no next hop info",myaddr_);
03307 return;
03308 }
03309 s.schedule(target_,p,0);
03310 }
03311 }
03312 }
03313
03314
03315
03316
03317 NodeIDList *
03318 LandmarkAgent::search_tag(int obj_name, int prev_hop_level, int next_hop_level,nsaddr_t last_hop_id, int *num_dst)
03319 {
03320 ParentChildrenList *pcl = parent_children_list_;
03321 LMNode *child;
03322 compr_taglist *tag_ptr;
03323 int forward = FALSE;
03324 NodeIDList *nlist = NULL, *nlist_ptr = NULL;
03325 int p1, p2, p3, q1, q2, q3;
03326 int match = 0, exact_match = 0;
03327
03328 *num_dst = 0;
03329
03330
03331 while(pcl) {
03332 if(pcl->level_ == 0)
03333 break;
03334 pcl = pcl->next_;
03335 }
03336
03337 if(!pcl)
03338 return(NULL);
03339
03340
03341
03342 tag_ptr = pcl->tag_list_;
03343 while(tag_ptr) {
03344 if(tag_ptr->obj_name_ == obj_name) {
03345 nlist = new NodeIDList;
03346 nlist->dst_node_ = myaddr_;
03347 nlist->dst_next_hop_ = myaddr_;
03348 return(nlist);
03349 }
03350 tag_ptr = tag_ptr->next_;
03351 }
03352
03353
03354
03355
03356
03357
03358
03359 p1 = (obj_name >> 24) & 0xFF;
03360 p2 = (obj_name >> 16) & 0xFF;
03361 p3 = obj_name & 0xFFFF;
03362
03363 pcl = parent_children_list_;
03364 while(pcl) {
03365 if(pcl->level_ == next_hop_level)
03366 break;
03367 pcl = pcl->next_;
03368 }
03369
03370 if(!pcl)
03371 return(NULL);
03372
03373
03374 child = pcl->pchildren_;
03375 while(child) {
03376
03377
03378
03379 forward = FALSE;
03380 if(next_hop_level < prev_hop_level || (child->id_ != last_hop_id && next_hop_level >= prev_hop_level))
03381 forward = TRUE;
03382 if(child->child_flag_ == IS_CHILD && forward) {
03383 tag_ptr = child->tag_list_;
03384 match = 0;
03385 exact_match = 0;
03386 while(tag_ptr) {
03387 q1 = (tag_ptr->obj_name_ >> 24) & 0xFF;
03388 q2 = (tag_ptr->obj_name_ >> 16) & 0xFF;
03389 q3 = tag_ptr->obj_name_ & 0xFFFF;
03390 if(p1 == q1 && p2 == q2 && p3 == q3)
03391 exact_match = 1;
03392 else if((p1 == q1 && p2 == q2 && !q3) || (p1 == q1 && !q2 && !q3))
03393 match = 1;
03394 if(match) {
03395 if(!nlist) {
03396 nlist = new NodeIDList;
03397 nlist_ptr = nlist;
03398 }
03399 else {
03400 nlist_ptr->next_ = new NodeIDList;
03401 nlist_ptr = nlist_ptr->next_;
03402 }
03403 nlist_ptr->dst_node_ = child->id_;
03404 nlist_ptr->dst_next_hop_ = child->next_hop_;
03405 nlist_ptr->next_hop_level_= next_hop_level - 1;
03406 ++(*num_dst);
03407 break;
03408 }
03409 else if(exact_match) {
03410
03411 NodeIDList *n1, *n2;
03412 n1 = nlist;
03413 while(n1) {
03414 n2 = n1;
03415 n1 = n1->next_;
03416 delete n2;
03417 }
03418
03419
03420 nlist = new NodeIDList;
03421 nlist->dst_node_ = child->id_;
03422 nlist->dst_next_hop_ = child->next_hop_;
03423 nlist->next_hop_level_= next_hop_level - 1;
03424 (*num_dst) = 1;
03425 return(nlist);
03426 }
03427 tag_ptr = tag_ptr->next_;
03428 }
03429 }
03430 child = child->next_;
03431 }
03432
03433
03434 if(next_hop_level >= prev_hop_level && pcl->parent_) {
03435 if(!nlist) {
03436 nlist = new NodeIDList;
03437 nlist_ptr = nlist;
03438 }
03439 else {
03440 nlist_ptr->next_ = new NodeIDList;
03441 nlist_ptr = nlist_ptr->next_;
03442 }
03443 nlist_ptr->dst_node_ = (pcl->parent_)->id_;
03444 nlist_ptr->dst_next_hop_ = (pcl->parent_)->next_hop_;
03445 nlist_ptr->next_hop_level_= next_hop_level + 1;
03446 ++(*num_dst);
03447 }
03448
03449 return(nlist);
03450 }
03451
03452
03453
03454 nsaddr_t
03455 LandmarkAgent::get_next_hop(nsaddr_t dst, int next_hop_level)
03456 {
03457 ParentChildrenList *pcl = parent_children_list_;
03458 LMNode *pchild;
03459
03460 while(pcl->level_ != next_hop_level) {
03461 pcl = pcl->next_;
03462 }
03463
03464 assert(pcl);
03465 pchild = pcl->pchildren_;
03466 while(pchild) {
03467 if(pchild->id_ == dst)
03468 return(pchild->next_hop_);
03469 pchild = pchild->next_;
03470 }
03471
03472 return(NO_NEXT_HOP);
03473 }
03474
03475
03476 void
03477 LandmarkAgent::get_nbrinfo()
03478 {
03479 ParentChildrenList *pcl;
03480 LMNode *pchild;
03481 int num_nbrs = 0;
03482
03483 pcl = parent_children_list_;
03484
03485 if(!pcl) {
03486 trace("Node %d: Neighbour info not available; perhaps the node is down");
03487 return;
03488 }
03489
03490 while(pcl) {
03491 if(pcl->level_ == 1)
03492 break;
03493 pcl = pcl->next_;
03494 }
03495
03496
03497
03498 if(!pcl) {
03499 trace("Node %d: Neighbour info not available; perhaps the node is down");
03500 return;
03501 }
03502
03503 pchild = pcl->pchildren_;
03504
03505
03506 while(pchild) {
03507 if(pchild->num_hops_ == 1)
03508 ++num_nbrs;
03509 pchild = pchild->next_;
03510 }
03511
03512 trace("Node %d: Number of neighbours: %d",myaddr_,num_nbrs);
03513 }
03514
03515
03516
03517
03518 void
03519 LandmarkAgent::MoveTags() {
03520 ParentChildrenList *pcl = parent_children_list_;
03521 compr_taglist *tag = NULL, *prev_tag, *next_tag;
03522 int removed_tag = 0, our_tags_changed = 0;
03523
03524 trace("Node %d: Moving tags at time %f", myaddr_,NOW);
03525
03526 if(!pcl && !mobile_tags_) {
03527 Scheduler::instance().schedule(tag_mobility_,tag_mobility_event_,tag_rng_->uniform(mobility_period_));
03528 return;
03529 }
03530
03531 if(pcl) {
03532
03533 while(pcl) {
03534 if(pcl->level_ == 0)
03535 break;
03536 pcl = pcl->next_;
03537 }
03538 assert(pcl);
03539 }
03540
03541
03542
03543 if(pcl)
03544 tag = pcl->tag_list_;
03545 else
03546 tag = mobile_tags_;
03547
03548 prev_tag = tag;
03549 while(tag) {
03550 removed_tag = 0;
03551
03552 if((tag->obj_name_ & 0xFFFF) > 30) {
03553
03554 int n = tag_rng_->uniform(10);
03555 if(n <= 2) {
03556 assert(nbrs_);
03557 int nbr_index = tag_rng_->uniform(num_nbrs_);
03558 LandmarkAgent *nbr_agent = (LandmarkAgent *)AgentList::instance()->GetAgent(nbrs_[nbr_index]);
03559 assert(nbr_agent);
03560
03561 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]);
03562
03563
03564 removed_tag = 1;
03565 our_tags_changed = 1;
03566 if(prev_tag == tag) {
03567 if(pcl)
03568 pcl->tag_list_ = tag->next_;
03569 else if(mobile_tags_)
03570 mobile_tags_ = tag->next_;
03571 prev_tag = tag->next_;
03572 }
03573 else
03574 prev_tag->next_ = tag->next_;
03575
03576 next_tag = tag->next_;
03577
03578 if(pcl)
03579 --(pcl->num_tags_);
03580
03581
03582 nbr_agent->AddMobileTag(tag);
03583 }
03584 }
03585 if(!removed_tag) {
03586 prev_tag = tag;
03587 tag = tag->next_;
03588 }
03589 else {
03590 tag = next_tag;
03591 }
03592 }
03593
03594
03595 if(our_tags_changed)
03596 SendChangedTagListUpdate(our_tags_changed,0);
03597
03598 Scheduler::instance().schedule(tag_mobility_,tag_mobility_event_,tag_rng_->uniform(mobility_period_));
03599 }
03600
03601
03602
03603
03604
03605 void
03606 LandmarkAgent::AddMobileTag(void *mobile_tag)
03607 {
03608 ParentChildrenList *pcl = parent_children_list_;
03609 compr_taglist *tag = NULL, *new_tag = (compr_taglist *)mobile_tag;
03610
03611
03612
03613 new_tag->next_ = NULL;
03614
03615 if(pcl) {
03616
03617 while(pcl) {
03618 if(pcl->level_ == 0)
03619 break;
03620 pcl = pcl->next_;
03621 }
03622 assert(pcl);
03623
03624 ++(pcl->num_tags_);
03625
03626 if(!pcl->tag_list_) {
03627 pcl->tag_list_ = new_tag;
03628 }
03629 else {
03630 tag = pcl->tag_list_;
03631 while(tag->next_) {
03632 tag = tag->next_;
03633 }
03634 tag->next_ = new_tag;
03635 }
03636 }
03637 else {
03638 if(!mobile_tags_) {
03639 mobile_tags_ = new_tag;
03640 }
03641 else {
03642 tag = mobile_tags_;
03643 while(tag->next_) {
03644 tag = tag->next_;
03645 }
03646 tag->next_ = new_tag;
03647 }
03648 }
03649
03650
03651
03652 if(tag_advt_event_->uid_ < 0)
03653 Scheduler::instance().schedule(tag_advt_handler_, tag_advt_event_, Random::uniform(10));
03654 }
03655
03656
03657
03658
03659
03660
03661
03662 void
03663 LandmarkAgent::SendChangedTagListUpdate(int our_tag_changed, int level)
03664 {
03665 ParentChildrenList *pcl = parent_children_list_;
03666 ParentChildrenList *child_pcl, *parent_pcl;
03667 compr_taglist *tag_ptr1 = NULL, *tag_ptr2 = NULL, *tag_list = NULL;
03668 compr_taglist *agg_tags = NULL;
03669 LMNode *lmnode;
03670 int upd_time, num_tags = 0;
03671 Scheduler &s = Scheduler::instance();
03672 double now = s.clock();
03673
03674 if(node_dead_ || !pcl || level >= highest_level_)
03675 return;
03676
03677 if(myaddr_ == 45)
03678 trace("Node %d: SendChangedTagListUpdate, level %d at time %f",myaddr_,level,now);
03679
03680 while(pcl) {
03681 if(pcl->level_ == level)
03682 child_pcl = pcl;
03683 else if(pcl->level_ == level + 1)
03684 parent_pcl = pcl;
03685 pcl = pcl->next_;
03686 }
03687
03688 if(our_tag_changed) {
03689 assert(level == 0);
03690 upd_time = (int) now;
03691 upd_time = (upd_time << 16) | (parent_pcl->seqnum_ & 0xFFFF);
03692 ++(parent_pcl->seqnum_);
03693 parent_pcl->UpdatePotlChild(myaddr_, myaddr_,0,0,0,(int) node_->energy(),upd_time,IS_CHILD,FALSE,child_pcl->tag_list_);
03694
03695
03696 Packet *newp = makeUpdate(child_pcl,HIER_ADVS,PERIODIC_ADVERTS);
03697 child_pcl->last_update_sent_ = now;
03698 s.schedule(target_,newp,0);
03699 }
03700
03701 while(level < highest_level_) {
03702
03703 if(myaddr_ == 45)
03704 trace("Node %d: Updating tag lists, level %d",myaddr_,level);
03705
03706 lmnode = parent_pcl->pchildren_;
03707 tag_list = NULL;
03708
03709
03710 while(lmnode) {
03711 if(lmnode->child_flag_ == IS_CHILD) {
03712 tag_ptr1 = lmnode->tag_list_;
03713
03714 while(tag_ptr1) {
03715 if(!tag_list) {
03716 tag_list = new compr_taglist;
03717 tag_ptr2 = tag_list;
03718 }
03719 else {
03720 tag_ptr2->next_ = new compr_taglist;
03721 tag_ptr2 = tag_ptr2->next_;
03722 }
03723
03724 tag_ptr2->obj_name_ = tag_ptr1->obj_name_;
03725 tag_ptr1 = tag_ptr1->next_;
03726 }
03727 }
03728 lmnode = lmnode->next_;
03729 }
03730
03731
03732 agg_tags = aggregate_taginfo(tag_list,parent_pcl->level_,&num_tags);
03733
03734
03735 tag_ptr1 = tag_list;
03736 while(tag_ptr1) {
03737 tag_ptr2 = tag_ptr1;
03738 tag_ptr1 = tag_ptr1->next_;
03739 delete tag_ptr2;
03740 }
03741
03742 if(!compare_tag_lists(parent_pcl->tag_list_,parent_pcl->num_tags_,agg_tags,num_tags)) {
03743
03744 tag_ptr1 = parent_pcl->tag_list_;
03745 while(tag_ptr1) {
03746 tag_ptr2 = tag_ptr1;
03747 tag_ptr1 = tag_ptr1->next_;
03748 delete tag_ptr2;
03749 }
03750
03751 parent_pcl->tag_list_ = agg_tags;
03752 parent_pcl->num_tags_ = num_tags;
03753
03754
03755 Packet *newp = makeUpdate(parent_pcl,HIER_ADVS,PERIODIC_ADVERTS);
03756 parent_pcl->last_update_sent_ = now;
03757 s.schedule(target_,newp,0);
03758
03759 ++level;
03760
03761 pcl = parent_children_list_;
03762 parent_pcl = NULL;
03763 child_pcl = NULL;
03764 while(pcl) {
03765 if(pcl->level_ == level)
03766 child_pcl = pcl;
03767 else if(pcl->level_ == level + 1)
03768 parent_pcl = pcl;
03769 pcl = pcl->next_;
03770 }
03771 upd_time = (int) now;
03772 upd_time = (upd_time << 16) | (parent_pcl->seqnum_ & 0xFFFF);
03773 ++(parent_pcl->seqnum_);
03774 parent_pcl->UpdatePotlChild(myaddr_, myaddr_,0,0,0,(int) node_->energy(),upd_time,IS_CHILD,FALSE,child_pcl->tag_list_);
03775 }
03776 else {
03777
03778
03779 tag_ptr1 = agg_tags;
03780 while(tag_ptr1) {
03781 tag_ptr2 = tag_ptr1;
03782 tag_ptr1 = tag_ptr1->next_;
03783 delete tag_ptr2;
03784 }
03785 break;
03786 }
03787 }
03788 }
03789
03790
03791
03792
03793 int
03794 LandmarkAgent::compare_tag_lists(compr_taglist *tag_list1, int num_tags1, compr_taglist *tag_list2, int num_tags2)
03795 {
03796 compr_taglist *tag1 = tag_list1, *tag2 = tag_list2;
03797 int found;
03798
03799
03800 if(num_tags1 == -1) {
03801 num_tags1 = 0;
03802 while(tag1) {
03803 ++num_tags1;
03804 tag1 = tag1->next_;
03805 }
03806 tag1 = tag_list1;
03807 }
03808
03809 if(num_tags2 == -1) {
03810 num_tags2 = 0;
03811 while(tag2) {
03812 ++num_tags2;
03813 tag2 = tag2->next_;
03814 }
03815 tag2 = tag_list2;
03816 }
03817
03818 if(num_tags1 != num_tags2)
03819 return(FALSE);
03820
03821 while(tag1) {
03822 found = 0;
03823 while(tag2) {
03824 if(tag1->obj_name_ == tag2->obj_name_) {
03825 found = 1;
03826 break;
03827 }
03828 tag2 = tag2->next_;
03829 }
03830 if(!found)
03831 return(FALSE);
03832 tag1 = tag1->next_;
03833 }
03834
03835 return(TRUE);
03836 }
03837