Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

gaf.cc

Go to the documentation of this file.
00001 // Copyright (c) 2000 by the University of Southern California
00002 // All rights reserved.
00003 //
00004 // Permission to use, copy, modify, and distribute this software and its
00005 // documentation in source and binary forms for non-commercial purposes
00006 // and without fee is hereby granted, provided that the above copyright
00007 // notice appear in all copies and that both the copyright notice and
00008 // this permission notice appear in supporting documentation. and that
00009 // any documentation, advertising materials, and other materials related
00010 // to such distribution and use acknowledge that the software was
00011 // developed by the University of Southern California, Information
00012 // Sciences Institute.  The name of the University may not be used to
00013 // endorse or promote products derived from this software without
00014 // specific prior written permission.
00015 //
00016 // THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
00017 // the suitability of this software for any purpose.  THIS SOFTWARE IS
00018 // PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
00019 // INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 //
00022 // Other copyrights might apply to parts of this software and are so
00023 // noted when applicable.
00024 
00025 
00026 #include <template.h>
00027 #include <gaf/gaf.h>
00028 #include <random.h>
00029 #include <address.h>
00030 #include <mobilenode.h>
00031 #include <god.h>
00032 #include <phy.h>
00033 #include <wireless-phy.h>
00034 #include <energy-model.h>
00035 
00036 
00037 
00038 int hdr_gaf::offset_;
00039 static class GAFHeaderClass : public PacketHeaderClass {
00040 public:
00041         GAFHeaderClass() : PacketHeaderClass("PacketHeader/GAF",
00042                                              sizeof(hdr_gaf)) {
00043                 bind_offset(&hdr_gaf::offset_);
00044         }
00045 } class_gafhdr;
00046 
00047 static class GAFAgentClass : public TclClass {
00048 public:
00049         GAFAgentClass() : TclClass("Agent/GAF") {}
00050         TclObject* create(int argc, const char*const* argv) {
00051                 assert(argc == 5);
00052                 return (new GAFAgent((nsaddr_t) atoi(argv[4])));
00053         }
00054 } class_gafagent;
00055 
00056 static class GAFPartnerClass : public TclClass {
00057 public:
00058         GAFPartnerClass() : TclClass("GAFPartner") {}
00059         TclObject* create(int, const char*const*) {
00060                 return (new GAFPartner());
00061         }
00062 } class_gafparnter;
00063 
00064 
00065 static inline double 
00066 gafjitter (double max, int be_random_)
00067 {
00068   return (be_random_ ? Random::uniform(max) : max);
00069 }
00070 
00071 
00072 GAFAgent::GAFAgent(nsaddr_t id) : Agent(PT_GAF), beacon_(1), randomflag_(1), timer_(this), stimer_(this), dtimer_(this), maxttl_(5), state_(GAF_FREE),leader_settime_(0),adapt_mobility_(0)
00073 {
00074         double x = 0.0, y = 0.0, z = 0.0;
00075 
00076         seqno_ = -1;
00077         nid_ = id;
00078         thisnode = Node::get_node_by_address(nid_); 
00079         // gid_ = nid_; // temporary setting, MUST BE RESET
00080 
00081         // grid caculation
00082         // no need to update location becasue getLoc will do it
00083 
00084         ((MobileNode *)thisnode)->getLoc(&x, &y, &z);
00085         gid_ = God::instance()->getMyGrid(x,y);
00086         
00087         if (gid_ < 0) {
00088             printf("fatal error: node is outside topography\n");
00089         }
00090 }
00091 
00092 void GAFAgent::recv(Packet* p, Handler *)
00093 {
00094         hdr_gaf *gafh = hdr_gaf::access(p);
00095 
00096         switch (gafh->type_) {
00097 
00098         case GAF_DISCOVER:
00099 
00100           if (state_ != GAF_SLEEP)
00101               processDiscoveryMsg(p);
00102           Packet::free(p);
00103           break;
00104 
00105         default:
00106           Packet::free(p);
00107           break;
00108         }
00109 }
00110 
00111 
00112 void GAFAgent::processDiscoveryMsg(Packet* p)
00113 {
00114         struct DiscoveryMsg emsg;
00115         u_int32_t dst;
00116         unsigned char *w = p->accessdata ();
00117         double x = 0.0, y = 0.0, z = 0.0;
00118         int ttl;
00119 
00120 
00121         dst = *(w++);
00122         dst = dst << 8 | *(w++);
00123         dst = dst << 8 | *(w++);
00124         dst = dst << 8 | *(w++);
00125         
00126         emsg.gid = dst;
00127         
00128         dst = *(w++);
00129         dst = dst << 8 | *(w++);
00130         dst = dst << 8 | *(w++);
00131         dst = dst << 8 | *(w++);
00132 
00133         emsg.nid = dst;
00134 
00135         dst = *(w++);
00136         dst = dst << 8 | *(w++);
00137         dst = dst << 8 | *(w++);
00138         dst = dst << 8 | *(w++);
00139         
00140         emsg.state = dst;
00141 
00142         dst = *(w++);
00143         dst = dst << 8 | *(w++);
00144         dst = dst << 8 | *(w++);
00145         dst = dst << 8 | *(w++);
00146         
00147         emsg.ttl = dst;
00148         
00149         dst = *(w++);
00150         dst = dst << 8 | *(w++);
00151         dst = dst << 8 | *(w++);
00152         dst = dst << 8 | *(w++);
00153         
00154         emsg.stime = dst;
00155 
00156 
00157         // first, check if this node has changed its grid
00158         ((MobileNode *)thisnode)->getLoc(&x, &y, &z);
00159         gid_  = God::instance()->getMyGrid(x,y);
00160         
00161         // If the msg is not from my grid, ignore it
00162         if (((u_int32_t)gid_) != (u_int32_t)emsg.gid) return;
00163 
00164 
00165         switch (emsg.state) {
00166 
00167         case GAF_LEADER:
00168 
00169           // I receives a "whoami" msg from the leader in this grid
00170           // I am supposed to discard if I am in GAF_LEADER
00171           // state too, or put myself into sleep if I am in GAF_FREE
00172           
00173           switch (state_) {
00174           case GAF_LEADER:
00175 
00176             ttl = (int)(leader_settime_ - NOW);
00177             if (ttl < 0) ttl = 0;
00178 
00179             if ( ((u_int32_t)ttl) > (u_int32_t) emsg.ttl) {
00180                   //supress the partner
00181                   send_discovery();
00182                   return; 
00183             
00184             } else {
00185                   if (((u_int32_t)ttl) == emsg.ttl && (u_int32_t)nid_ < emsg.nid) {
00186                       send_discovery();
00187                       return;
00188                   }
00189                   // from LEADER to SLEEP, cancel my timer
00190                   stimer_.force_cancel();
00191                   leader_settime_ = 0;
00192 
00193                   // turn off my self
00194                   schedule_wakeup(emsg);
00195             }
00196 
00197             break;
00198           
00199           case GAF_FREE:
00200             schedule_wakeup(emsg);
00201 
00202             break;
00203           default:
00204             break;
00205 
00206           }
00207 
00208           break;
00209         case GAF_FREE:
00210           if (state_ == GAF_FREE) {
00211               if ((ttl = (int)myttl()) > MIN_LIFETIME) {
00212                  ttl = ttl/2;
00213               }
00214     
00215               if ( ttl > (int)emsg.ttl) {
00216                   //supress other node
00217                   send_discovery();
00218                   return; 
00219               } else {
00220                   if ((u_int32_t)ttl == emsg.ttl && (u_int32_t)nid_ < emsg.nid) {
00221                       send_discovery();
00222                       return;
00223                   }
00224     
00225                   schedule_wakeup(emsg);
00226 
00227               }             
00228           }
00229           
00230           if (state_ == GAF_LEADER) {
00231               send_discovery();
00232           }
00233 
00234           break;
00235         default:
00236           printf("%d gets wrong discovery msg\n",nid_ );;
00237           break;
00238         }
00239 
00240 }
00241 
00242 void GAFAgent::schedule_wakeup(struct DiscoveryMsg emsg) {
00243 
00244   int waketime;
00245   waketime = emsg.ttl;
00246  
00247   // control whether using mobility adaption
00248   if (adapt_mobility_ > 0 ) {
00249       if (emsg.stime < emsg.ttl) waketime = emsg.stime;
00250   }
00251 
00252   // node does not go switch to sleep if the lifetime
00253   // it senses is less than MIN_SWITCHTIME
00254 
00255   if (waketime > MIN_TURNOFFTIME ) { 
00256      node_off();
00257      dtimer_.resched(Random::uniform(waketime/2, waketime)); 
00258   }
00259 }
00260 
00261 double GAFAgent::myttl()
00262 {
00263   double ce,maxp;
00264   Phy *phyp; 
00265   double ttl; 
00266   
00267   ce = (thisnode->energy_model())->energy();
00268 
00269   phyp = (thisnode->ifhead()).lh_first;
00270 
00271   if (phyp) {
00272               maxp = ((WirelessPhy *)phyp)->getPtconsume();
00273   } 
00274 
00275   ttl = ce/maxp;
00276   
00277   return ttl;
00278 
00279 }
00280 
00281 // timeout process for discovery phase
00282 void GAFAgent::timeout(GafMsgType msgt)
00283 {
00284   
00285   int ttl;
00286 
00287 //printf ("Node (%d %d) get signal %d at %f\n",nid_, gid_, msgt, Scheduler::instance().clock());
00288 
00289     switch (msgt) {
00290     case GAF_DISCOVER:
00291 
00292       switch (state_) {
00293       case GAF_SLEEP:
00294         break;
00295        
00296       case GAF_FREE:
00297 
00298         if ((ttl = (int)myttl()) > MIN_LIFETIME) {
00299                 ttl = (int) ttl/2;
00300         }
00301         
00302         leader_settime_ = (int) (ttl + NOW);  
00303 
00304         // schdule to tell me that I can switch after ttl
00305 
00306         stimer_.resched(ttl); 
00307         
00308         setGAFstate(GAF_LEADER);
00309 
00310         send_discovery();
00311 
00312         //printf ("Node (%d %d) becomes a leader at %f\n",nid_, gid_, Scheduler::instance().clock());
00313 
00314          timer_.resched(Random::uniform(MAX_DISCOVERY_TIME-1,MAX_DISCOVERY_TIME));
00315         
00316         // fall through
00317          break; 
00318 
00319       case GAF_LEADER:
00320 
00321         send_discovery();
00322 
00323         timer_.resched(Random::uniform(MAX_DISCOVERY_TIME-1,MAX_DISCOVERY_TIME));
00324         break;
00325       default:
00326         break;
00327 
00328       }
00329 
00330       break;
00331 
00332     case GAF_SELECT:
00333         switch (state_) {
00334 
00335           case GAF_LEADER:
00336 
00337             // I just finish my LEADER role, put myself into FREE
00338             // state so that I have chance to go sleep
00339             // put myself into FREE does not hurt anything
00340 
00341             //printf("Node (%d %d) go BACK to FREE from LEADER at %f\n",nid_,gid_,Scheduler::instance().clock());
00342 
00343             duty_timeout();
00344 
00345             leader_settime_ = 0;
00346 
00347             break;
00348 
00349           case GAF_FREE:
00350           case GAF_SLEEP:
00351             break;
00352           default:
00353             break;
00354         }
00355         break;
00356     case GAF_DUTY:
00357         duty_timeout();
00358         break;
00359     default:
00360         printf("Wrong GAF msg time!\n");
00361     }
00362 
00363 }
00364 
00365 // adaptive fidelity timeout
00366 
00367 void GAFAgent::duty_timeout()
00368 {
00369     double x=0.0, y=0.0, z=0.0;
00370 
00371     // find where I am
00372     
00373     ((MobileNode *)thisnode)->getLoc(&x, &y, &z);
00374     gid_ = God::instance()->getMyGrid(x,y);
00375 
00376 
00377     // wake up myself
00378     node_on();
00379     
00380     // send discovery first to try to find whether
00381     // there is a leader around me
00382 
00383     send_discovery();
00384 
00385     // schedule the discovery timer randomly
00386     // can wait longer to get a chance to be replaced
00387 
00388     timer_.resched(gafjitter(GAF_NONSTART_JITTER, 1));
00389 
00390 }
00391 
00392 int GAFAgent::command(int argc, const char*const* argv)
00393 {
00394         if (argc == 2) {
00395           if (strcmp (argv[1], "start-gaf") == 0) {
00396             // schedule the discovery timer randomly
00397             timer_.resched(gafjitter(GAF_STARTUP_JITTER, 1));
00398             // schedule the select phase after certain time
00399             // of discovery msg exchange, as fast as possible
00400             // stimer_.resched(Random::uniform(GAF_LEADER_JITTER,GAF_LEADER_JITTER+1)); 
00401 
00402             return (TCL_OK); 
00403           }
00404               
00405         }
00406         if (argc == 3) {
00407             if (strcmp(argv[1], "adapt-mobility") == 0) {
00408                         adapt_mobility_ = atoi(argv[2]);
00409                         //timer_.resched(Random::uniform(0, beacon_));
00410                         return TCL_OK;
00411             }
00412         
00413             if (strcmp(argv[1], "maxttl") == 0) {
00414                 maxttl_ = atoi(argv[2]);
00415                 return TCL_OK;
00416             }
00417 
00418         }
00419         return (Agent::command(argc, argv));
00420 }
00421 
00422 void GAFAgent::send_discovery()
00423 {
00424         Packet *p = allocpkt();
00425         double x=0.0, y=0.0, z=0.0;
00426 
00427         hdr_gaf *h = hdr_gaf::access(p);
00428         //hdr_ip *iph = hdr_ip::access(p);
00429 
00430         h->type_ = GAF_DISCOVER;
00431         h->seqno_ = ++seqno_;
00432 
00433         // update my grid infomation
00434         
00435         ((MobileNode *)thisnode)->getLoc(&x, &y, &z);
00436         gid_ = God::instance()->getMyGrid(x,y);
00437     
00438         makeUpDiscoveryMsg(p);
00439 
00440         send(p,0);
00441 }
00442 
00443 void
00444 GAFAgent::makeUpDiscoveryMsg(Packet *p)
00445 {
00446   hdr_ip *iph = hdr_ip::access(p);
00447   hdr_cmn *hdrc = hdr_cmn::access(p);
00448   u_int32_t ttl,stime;
00449   unsigned char *walk;
00450   double gridsize, speed;
00451 
00452   // fill up the header
00453   hdrc->next_hop_ = IP_BROADCAST;
00454   hdrc->addr_type_ = NS_AF_INET;
00455   iph->daddr() = IP_BROADCAST << Address::instance().nodeshift();
00456   iph->dport() = 254;
00457 
00458   // hdrc->direction() = hdr_cmn::DOWN;
00459 
00460   // fill up the data
00461 
00462   p->allocdata(sizeof(DiscoveryMsg));
00463   walk = p->accessdata ();
00464   hdrc->size_ = sizeof(DiscoveryMsg) + IP_HDR_LEN; // Existence Msg + IP
00465 
00466   *(walk++) = gid_ >> 24;
00467   *(walk++) = (gid_ >> 16) & 0xFF;
00468   *(walk++) = (gid_ >> 8) & 0xFF;
00469   *(walk++) = (gid_ >> 0) & 0xFF;
00470   *(walk++) = nid_ >> 24;
00471   *(walk++) = (nid_ >> 16) & 0xFF;
00472   *(walk++) = (nid_ >> 8) & 0xFF;
00473   *(walk++) = (nid_ >> 0) & 0xFF;
00474 
00475   // access my state
00476 
00477   *(walk++) = state_ >> 24;
00478   *(walk++) = (state_ >> 16) & 0xFF;
00479   *(walk++) = (state_ >> 8) & 0xFF;
00480   *(walk++) = (state_ >> 0) & 0xFF;  
00481 
00482 
00483   // ttl tells the receiver that how much longer the sender can
00484   // survive, cut it into half for the purpose of load balance
00485 
00486   if (state_ == GAF_LEADER) {
00487       // must send real msg because I am the leader
00488         ttl = (int)(leader_settime_ - NOW);
00489         if (ttl < 0) ttl = 0;
00490 
00491   } else {
00492 
00493       if ((ttl = (u_int32_t)myttl()) > MIN_LIFETIME) {
00494           ttl = (u_int32_t) ttl/2;
00495       }
00496 
00497   }
00498   *(walk++) = ttl >> 24;
00499   *(walk++) = (ttl >> 16) & 0xFF;
00500   *(walk++) = (ttl >> 8) & 0xFF;
00501   *(walk++) = (ttl >> 0) & 0xFF;
00502   
00503 
00504   // fill my possible time of leaving this grid
00505   
00506   
00507   speed = ((MobileNode*)thisnode)->speed();
00508 
00509   if (speed == 0) {
00510     // make stime big enough
00511     stime = 2*ttl;
00512   } else {
00513     gridsize = God::instance()->getMyGridSize();
00514     stime = (u_int32_t) (gridsize/speed);
00515   }
00516 
00517   *(walk++) = stime >> 24;
00518   *(walk++) = (stime >> 16) & 0xFF;
00519   *(walk++) = (stime >> 8) & 0xFF;
00520   *(walk++) = (stime >> 0) & 0xFF;
00521 
00522   //printf("Node %d send out Exitence msg gid/nid %d %d\n", nid_, gid_, nid_);
00523 
00524 }
00525 
00526 
00527 void
00528 GAFAgent::node_off()
00529 {
00530     Phy *p;
00531     EnergyModel *em;
00532 
00533     //printf ("Node (%d %d) goes SLEEP from %d at %f\n",nid_, gid_, state_, Scheduler::instance().clock());
00534 
00535         
00536     // if I am in the data transfer state, do not turn off
00537 
00538     // if (state_ == GAF_TRAFFIC) return;
00539 
00540     // set node state
00541     em = thisnode->energy_model();
00542     em->node_on() = false;
00543     //((MobileNode *)thisnode->energy_model())->node_on() = false;
00544 
00545     // notify phy
00546     p  = (thisnode->ifhead()).lh_first;
00547     if (p) {
00548         ((WirelessPhy *)p)->node_off();
00549     }
00550     // change agent state
00551     setGAFstate(GAF_SLEEP);
00552 }
00553 
00554 void
00555 GAFAgent::node_on()
00556 {
00557     Phy *p;
00558     EnergyModel* em;
00559 
00560     // set node state
00561 
00562     em = thisnode->energy_model();
00563     em->node_on() = true;
00564 
00565     //(MobileNode *)thisnode->energy_model()->node_on() = true;
00566 
00567     // notify phy
00568 
00569     p = (thisnode->ifhead()).lh_first;
00570     if (p) {
00571         ((WirelessPhy *)p)->node_on();
00572     }
00573     
00574     setGAFstate(GAF_FREE);
00575 }
00576 
00577 void 
00578 GAFAgent::setGAFstate(GafNodeState gs)
00579 {
00580   //printf("Node (%d %d) changes state from %d to %d at %f\n", nid_, gid_, state_,gs,Scheduler::instance().clock());
00581 
00582    state_ = gs;
00583 }
00584 
00585 GAFPartner::GAFPartner() : Connector(), gafagent_(1),mask_(0xffffffff),
00586         shift_(8)
00587 {
00588         bind("addr_", (int*)&(here_.addr_));
00589         bind("port_", (int*)&(here_.port_));
00590         bind("shift_", &shift_);
00591         bind("mask_", &mask_);
00592 }
00593 
00594 void GAFPartner::recv(Packet* p, Handler *h)
00595 {
00596         hdr_ip* hdr = hdr_ip::access(p);
00597         hdr_cmn *hdrc = hdr_cmn::access(p);
00598 
00599         /* handle PT_GAF packet only */
00600         /* convert the dst ip if it is -1, change it into node's */
00601         /* own ip address */    
00602         if ( hdrc->ptype() == PT_GAF ) {
00603           if (gafagent_ == 1) {
00604             if (((u_int32_t)hdr->daddr()) == IP_BROADCAST) {
00605                 hdr->daddr() = here_.addr_;
00606             }       
00607           } else {
00608             /* if gafagent is not installed, drop the packet */
00609             drop (p);
00610             return;
00611           }
00612         }
00613         
00614         target_->recv(p,h);
00615 
00616 
00617 }
00618 
00619 int GAFPartner::command(int argc, const char*const* argv)
00620 {
00621         if (argc == 3) {
00622           if (strcmp (argv[1], "set-gafagent") == 0) {
00623             gafagent_ = atoi(argv[2]);
00624             return (TCL_OK); 
00625           }
00626         }
00627         return Connector::command(argc, argv); 
00628 }
00629 
00630 void GAFDiscoverTimer::expire(Event *) {
00631   a_->timeout(GAF_DISCOVER);
00632 }
00633 
00634 void GAFSelectTimer::expire(Event *) {
00635   a_->timeout(GAF_SELECT);
00636 }
00637 
00638 void GAFDutyTimer::expire(Event *) {
00639   a_->timeout(GAF_DUTY);
00640 }
00641 
00642 
00643 
00644 

Generated on Tue Apr 20 12:14:18 2004 for NS2.26SourcesOriginal by doxygen 1.3.3