god.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
00002  *
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaim
00013 er in the
00014  *    documentation and/or other materials provided with the distribution.
00015  * 3. All advertising materials mentioning features or use of this software
00016  *    must display the following acknowledgement:
00017  *  This product includes software developed by the Computer Systems
00018  *  Engineering Group at Lawrence Berkeley Laboratory.
00019  * 4. Neither the name of the University nor of the Laboratory may be used
00020  *    to endorse or promote products derived from this software without
00021  *    specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00024  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00027  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00028  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00029  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00032  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00033  * SUCH DAMAGE.
00034  *
00035  * $Header: /nfs/jade/vint/CVSROOT/ns-2/mobile/god.cc,v 1.19 2004/12/10 22:07:13 johnh Exp $
00036  */
00037 
00038 /* Ported from CMU/Monarch's code, nov'98 -Padma.*/
00039 
00040 /*
00041  * god.cc
00042  *
00043  * General Operations Director
00044  *
00045  * perform operations requiring omnipotence in the simulation
00046  *
00047  * NOTE: Tcl node indexs are 0 based, NS C++ node IP addresses (and the
00048  * node->index() are 1 based.
00049  *
00050  */
00051 
00052 #include <object.h>
00053 #include <packet.h>
00054 #include <ip.h>
00055 #include <god.h>
00056 
00057 #include "diffusion/hash_table.h"
00058 #include "mobilenode.h"
00059 
00060 God* God::instance_;
00061 
00062 static class GodClass : public TclClass {
00063 public:
00064         GodClass() : TclClass("God") {}
00065         TclObject* create(int, const char*const*) {
00066                 return (new God);
00067         }
00068 } class_God;
00069 
00070 
00071 God::God()
00072 {
00073         min_hops = 0;
00074         num_nodes = 0;
00075 
00076         data_pkt_size = 64;
00077     mb_node = 0;
00078     next_hop = 0;
00079     prev_time = -1.0;
00080     num_alive_node = 0;
00081     num_connect = 0;
00082     num_recv = 0;
00083     num_compute = 0;
00084     num_data_types = 0;
00085     source_table = 0;
00086     sink_table = 0;
00087     num_send = 0;
00088     active = false;
00089     allowTostop = false;
00090 }
00091 
00092 
00093 // Added by Chalermek 12/1/99
00094 
00095 int God::NextHop(int from, int to)
00096 {
00097   if (active == false) {
00098     perror("God is off.\n");
00099     exit(-1);
00100   }
00101 
00102   if (from >= num_nodes) {
00103     perror("index from higher than the maximum number of nodes.\n");
00104     return -1;
00105   }
00106 
00107   if (to >= num_nodes) {
00108     perror("index to higher than the maximum number of nodes.\n");
00109     return -1;
00110   }
00111 
00112   return NEXT_HOP(from,to);
00113 }
00114 
00115 
00116 void God::ComputeNextHop()
00117 {
00118   if (active == false) {
00119     return;
00120   }
00121 
00122   int from, to, neighbor;
00123 
00124   for (from=0; from<num_nodes; from++) {
00125     for (to=0; to<num_nodes; to++) {
00126 
00127       NEXT_HOP(from,to) = UNREACHABLE;
00128 
00129       if (from==to) {
00130     NEXT_HOP(from,to) = from;     // next hop is itself.
00131       }
00132 
00133       if (MIN_HOPS(from, to) == UNREACHABLE) {
00134     continue;
00135       }
00136 
00137       for (neighbor=0; neighbor<num_nodes; neighbor++){
00138     if ( MIN_HOPS(from, neighbor) != 1) {
00139       continue;
00140     }
00141 
00142     if ( MIN_HOPS(from, to) == (MIN_HOPS(neighbor,to) +1) ) {
00143       NEXT_HOP(from, to) = neighbor;
00144       break;
00145     }
00146       }
00147 
00148     }
00149   }
00150 }
00151 
00152 
00153 void God::UpdateNodeStatus()
00154 {
00155   int i,j;
00156   int count, cur, sk, srcid, dt;
00157 
00158    for (i=0; i<num_data_types; i++) {
00159      for (j=0; j<num_nodes; j++) {
00160        if (SRC_TAB(i,j) != NULL) {
00161      node_status[j].is_source_ = true;
00162        }
00163      }
00164    }
00165 
00166    for (i=0; i<num_data_types; i++) {
00167      for (j=0; j<num_nodes; j++) {
00168        if (SK_TAB(i,j) > 0) {
00169      node_status[j].is_sink_ = true;
00170        }
00171      }
00172    }
00173 
00174    for (dt=0; dt < num_data_types; dt++) {
00175      for (srcid=0; srcid < num_nodes; srcid++) {
00176        if (SRC_TAB(dt,srcid) == NULL) 
00177      continue;
00178        for (sk = 0; sk < num_nodes; sk++) {
00179      if (SK_TAB(dt, sk) == 0)
00180        continue;
00181      cur = srcid;
00182      count = 0;
00183      node_status[cur].is_on_trees_ = true;
00184      while (cur != sk) {
00185        if (NextHop(cur, sk) == UNREACHABLE)
00186          break;
00187 
00188        assert(NextHop(cur,sk) >= 0 && NextHop(cur, sk) < num_nodes);
00189 
00190        cur = NextHop(cur, sk);      
00191        node_status[cur].is_on_trees_ = true;
00192 
00193        count ++;
00194        assert(count < num_nodes);
00195      }
00196        }
00197      }
00198    }
00199 
00200    Dump();
00201    DumpNodeStatus();
00202 }
00203 
00204 
00205 void God::DumpNodeStatus()
00206 {
00207   for (int i=0; i < num_nodes; i++) {
00208     printf("Node %d status (sink %d, source %d, on_tree %d)\n", i, 
00209        node_status[i].is_sink_, node_status[i].is_source_, 
00210        node_status[i].is_on_trees_);
00211   }
00212 }
00213 
00214 void God::DumpNumSend()
00215 {
00216 #ifdef DEBUG_OUTPUT
00217   for (int i=0; i < num_data_types; i++) {
00218     fprintf(stdout, "God: data type %d distinct events %d\n", i, num_send[i]);
00219   }
00220 #endif
00221 }
00222 
00223 
00224 void God::Dump()
00225 {
00226    int i, j, k, l;
00227 
00228    // Dump min_hops array
00229 
00230    fprintf(stdout,"Dump min_hops\n");
00231    for(i = 0; i < num_nodes; i++) {
00232       fprintf(stdout, "%2d) ", i);
00233       for(j = 0; j < num_nodes; j++)
00234           fprintf(stdout, "%2d ", min_hops[i * num_nodes + j]);
00235           fprintf(stdout, "\n");
00236   }
00237 
00238    // How many times the god compute routes ?
00239 
00240    fprintf(stdout, "God computes routes %d times.\n", num_compute);
00241 
00242 
00243    // The following information can be found only when god is active.
00244 
00245    if (active == false) {
00246      return;
00247    }
00248 
00249    // Dump next_hop array
00250 
00251    fprintf(stdout, "Dump next_hop\n");
00252    for (i = 0; i < num_nodes; i++) {
00253      for (j = 0; j < num_nodes; j++) {
00254        fprintf(stdout,"NextHop(%d,%d):%d\n",i,j,NEXT_HOP(i,j));
00255      }
00256    }
00257 
00258 
00259    // What is inside SRC_TAB ?
00260 
00261    fprintf(stdout, "Dump SRC_TAB\n");
00262    for (i=0; i<num_data_types; i++) {
00263      fprintf(stdout,"%2d) ",i);
00264      for (j=0; j<num_nodes; j++) {
00265        fprintf(stdout,"%2d ", SRC_TAB(i,j) ? 1:0);
00266      }
00267      fprintf(stdout,"\n");
00268    }
00269 
00270 
00271    // What is inside OIF_MAP ?
00272 
00273    int *oif_map;
00274 
00275    fprintf(stdout, "Dump OIF_MAP\n");
00276    for (i=0; i<num_data_types; i++) {
00277      for (j=0; j<num_nodes; j++) {
00278        if (SRC_TAB(i,j)!=NULL) {
00279      oif_map = SRC_TAB(i,j);
00280      fprintf(stdout,"(%2d,%2d)\n",i,j);
00281      for (k=0; k<num_nodes; k++) {
00282        for (l=0; l<num_nodes; l++) {
00283          fprintf(stdout,"%2d ", oif_map[k*num_nodes +l]);
00284        }
00285        fprintf(stdout,"\n");
00286      }
00287        }
00288      }
00289    }
00290 
00291 
00292 
00293    // What is inside SK_TAB ?
00294 
00295    fprintf(stdout, "Dump SK_TAB\n");
00296    for (i=0; i<num_data_types; i++) {
00297      fprintf(stdout,"%2d) ",i);
00298      for (j=0; j<num_nodes; j++) {
00299        fprintf(stdout,"%2d ", SK_TAB(i,j));
00300      }
00301      fprintf(stdout,"\n");
00302    }
00303 
00304 }
00305 
00306 
00307 void God::AddSink(int dt, int skid)
00308 {
00309   if (active == false) {
00310     return;
00311   }
00312 
00313   assert(num_data_types > 0);
00314   assert(num_nodes > 0);
00315   assert(dt >= 0 && dt < num_data_types);
00316   assert(skid >= 0 && skid < num_nodes);
00317 
00318   if (SK_TAB(dt,skid) == 1)
00319      return;
00320 
00321   SK_TAB(dt,skid) = 1;
00322   Fill_for_Source(dt, skid);
00323 }
00324 
00325 
00326 void God::AddSource(int dt, int srcid)
00327 {
00328   if (active == false) {
00329     return;
00330   }
00331 
00332   assert(num_data_types > 0);
00333   assert(num_nodes > 0);
00334   assert(dt >= 0 && dt < num_data_types);
00335   assert(srcid >= 0 && srcid < num_nodes);
00336 
00337   if (SRC_TAB(dt,srcid) != 0)
00338       return;
00339 
00340   SRC_TAB(dt,srcid) = new int[num_nodes * num_nodes];
00341   bzero((char*) SRC_TAB(dt, srcid), sizeof(int) * num_nodes * num_nodes);
00342   Fill_for_Sink(dt, srcid);
00343   //  Dump();
00344 }
00345 
00346 
00347 void God::Fill_for_Sink(int dt, int srcid)
00348 {
00349   int sk, cur, count;
00350   int *oif_map = SRC_TAB(dt, srcid);
00351 
00352   assert(oif_map != NULL);
00353 
00354   for (sk = 0; sk < num_nodes; sk++) {
00355     if (SK_TAB(dt, sk) == 0)
00356       continue;
00357     cur = srcid;
00358     count = 0;
00359     while (cur != sk) {
00360       if (NextHop(cur, sk) == UNREACHABLE)
00361     break;
00362 
00363       assert(NextHop(cur,sk) >= 0 && NextHop(cur, sk) < num_nodes);
00364 
00365       oif_map[cur*num_nodes + NextHop(cur, sk)] = 1;
00366       cur = NextHop(cur, sk);      
00367       count ++;
00368       assert(count < num_nodes);
00369     }
00370   }
00371 }
00372 
00373 
00374 void God::Fill_for_Source(int dt, int skid)
00375 {
00376   int src, cur, count;
00377   int *oif_map;
00378 
00379   for (src = 0; src < num_nodes; src++) {
00380     if (SRC_TAB(dt, src) == 0)
00381       continue;
00382    
00383     oif_map = SRC_TAB(dt, src);
00384     cur = src;
00385     count = 0;
00386     while (cur != skid) {
00387       if (NextHop(cur, skid) == UNREACHABLE)
00388     break;
00389 
00390       assert(NextHop(cur,skid) >= 0 && NextHop(cur, skid) < num_nodes);
00391 
00392       oif_map[cur*num_nodes + NextHop(cur, skid)] = 1;
00393       cur = NextHop(cur, skid);      
00394       count ++;
00395       assert(count < num_nodes);
00396     }
00397 
00398   }
00399 }
00400 
00401 
00402 void God::Rewrite_OIF_Map()
00403 {
00404   for (int dt = 0; dt < num_data_types; dt++) {
00405     for (int src = 0; src < num_nodes; src++) {
00406       if (SRC_TAB(dt, src) == NULL)
00407     continue;
00408 
00409       memset(SRC_TAB(dt,src),'\x00', sizeof(int) * num_nodes * num_nodes);
00410       Fill_for_Sink(dt, src);
00411     }
00412   }
00413 }
00414 
00415 
00416 int *God::NextOIFs(int dt, int srcid, int curid, int *ret_num_oif) 
00417 {
00418 
00419   if (active == false) {
00420     perror("God is inactive.\n");
00421     exit(-1);
00422   }  
00423 
00424   int *oif_map = SRC_TAB(dt, srcid);
00425   int count=0;
00426   int i;
00427 
00428   for (i=0; i<num_nodes; i++) {
00429     if (oif_map[curid*num_nodes +i] == 1)
00430       count++;
00431   }
00432 
00433   *ret_num_oif = count;
00434 
00435   if (count == 0)
00436     return NULL;
00437 
00438   int *next_oifs = new int[count];
00439   int j=0;
00440   
00441   for (i=0; i<num_nodes; i++) {
00442     if (oif_map[curid*num_nodes +i] == 1) {
00443       next_oifs[j] = i;
00444       j++;    
00445     }
00446   }
00447 
00448   return next_oifs;
00449 }
00450 
00451 
00452 
00453 bool God::IsReachable(int i, int j)
00454 {
00455 
00456 //  if (MIN_HOPS(i,j) < UNREACHABLE && MIN_HOPS(i,j) >= 0) 
00457   if (NextHop(i,j) != UNREACHABLE)
00458      return true;
00459   else
00460      return false;
00461 }
00462 
00463 
00464 bool God::IsNeighbor(int i, int j)
00465 {
00466   assert(i<num_nodes && j<num_nodes);
00467 
00468   //printf("i=%d, j=%d\n", i,j);
00469   if (mb_node[i]->energy_model()->node_on() == false ||
00470       mb_node[j]->energy_model()->node_on() == false ||
00471       mb_node[i]->energy_model()->energy() <= 0.0 ||
00472       mb_node[j]->energy_model()->energy() <= 0.0 ) {
00473     return false;
00474   }
00475 
00476   vector a(mb_node[i]->X(), mb_node[i]->Y(), mb_node[i]->Z());
00477   vector b(mb_node[j]->X(), mb_node[j]->Y(), mb_node[j]->Z());
00478   vector d = a - b;
00479 
00480   if (d.length() < RANGE)
00481     return true;
00482   else
00483     return false;  
00484 }
00485 
00486 
00487 void God::CountConnect()
00488 {
00489   int i,j;
00490 
00491   num_connect = 0;
00492 
00493   for (i=0; i<num_nodes; i++) {
00494     for (j=i+1; j<num_nodes; j++) {
00495       if (MIN_HOPS(i,j) != UNREACHABLE) {
00496     num_connect++;
00497       }
00498     }
00499   }
00500 }
00501 
00502 
00503 void God::CountAliveNode()
00504 {
00505   int i;
00506 
00507   num_alive_node = 0;
00508 
00509   for (i=0; i<num_nodes; i++) {
00510     if (mb_node[i]->energy_model()->energy() > 0.0) {
00511       num_alive_node++;
00512     }
00513   }
00514 
00515 }
00516 
00517 
00518 bool God::ExistSource()
00519 {
00520   int dtype, i;
00521 
00522   for (dtype = 0; dtype < num_data_types; dtype++) {
00523     for (i=0; i<num_nodes; i++) {
00524       if (SRC_TAB(dtype, i) != 0)
00525     return true;
00526     }
00527   }
00528 
00529   return false;
00530 }
00531 
00532 
00533 bool God::ExistSink()
00534 {
00535   int dtype, i;
00536 
00537   for (dtype = 0; dtype < num_data_types; dtype++) {
00538     for (i=0; i<num_nodes; i++) {
00539       if (SK_TAB(dtype, i) != 0)
00540     return true;
00541     }
00542   }
00543 
00544   return false;
00545 }
00546 
00547 
00548 bool God::IsPartition()
00549 {
00550   int dtype, i, j, k;
00551   int *oif_map;
00552 
00553   for (dtype = 0; dtype < num_data_types; dtype ++) {
00554     for (i = 0; i < num_nodes; i++) {
00555       if (SRC_TAB(dtype,i) == NULL)
00556     continue;
00557       oif_map = SRC_TAB(dtype, i);
00558       for (j = 0; j < num_nodes; j++) {
00559     for (k = 0; k < num_nodes; k++) {
00560       if (oif_map[j*num_nodes + k] != 0)
00561         return false;
00562     }
00563       }
00564     }
00565   }
00566 
00567   return true;
00568 }
00569 
00570 
00571 void God::ComputeRoute() 
00572 {
00573   if (active == false) {
00574     return;
00575   }
00576 
00577   floyd_warshall();
00578   ComputeNextHop();
00579   Rewrite_OIF_Map();
00580   CountConnect();
00581   CountAliveNode();
00582   prev_time = NOW;
00583   num_compute++;
00584 
00585   if (allowTostop == false)
00586     return;
00587 
00588   if ( ExistSink() == true && ExistSource() == true && IsPartition() == true)
00589     StopSimulation();
00590 }
00591 
00592 
00593 void God::CountNewData(int *attr)
00594 {
00595   if (dtab.GetHash(attr) == NULL) {
00596     num_send[attr[0]]++;
00597     dtab.PutInHash(attr);
00598   }
00599 }
00600 
00601 
00602 void God::IncrRecv()
00603 {
00604   num_recv++;
00605 
00606   //  printf("God: num_connect %d, num_alive_node %d at recv pkt %d\n",
00607   // num_connect, num_alive_node, num_recv);
00608 }
00609 
00610 
00611 void God::StopSimulation() 
00612 {
00613   Tcl& tcl=Tcl::instance();
00614 
00615   printf("Network parition !! Exiting... at time %f\n", NOW);
00616   tcl.evalf("[Simulator instance] at %lf \"finish\"", (NOW)+0.000001);
00617   tcl.evalf("[Simulator instance] at %lf \"[Simulator instance] halt\"", (NOW)+0.000002);
00618 }
00619 
00620 
00621 // Modified from setdest.cc -- Chalermek 12/1/99
00622 
00623 void God::ComputeW()
00624 {
00625   int i, j;
00626   int *W = min_hops;
00627 
00628   memset(W, '\xff', sizeof(int) * num_nodes * num_nodes);
00629 
00630   for(i = 0; i < num_nodes; i++) {
00631      W[i*num_nodes + i] = 0;     
00632      for(j = i+1; j < num_nodes; j++) {
00633     W[i*num_nodes + j] = W[j*num_nodes + i] = 
00634                          IsNeighbor(i,j) ? 1 : INFINITY;
00635      }
00636   }
00637 }
00638 
00639 void God::floyd_warshall()
00640 {
00641   int i, j, k;
00642 
00643   ComputeW();   // the connectivity matrix
00644 
00645   for(i = 0; i < num_nodes; i++) {
00646      for(j = 0; j < num_nodes; j++) {
00647      for(k = 0; k < num_nodes; k++) {
00648         MIN_HOPS(j,k) = MIN(MIN_HOPS(j,k), MIN_HOPS(j,i) + MIN_HOPS(i,k));
00649      }
00650      }
00651   }
00652 
00653 
00654 #ifdef SANITY_CHECKS
00655 
00656   for(i = 0; i < num_nodes; i++)
00657      for(j = 0; j < num_nodes; j++) {
00658     assert(MIN_HOPS(i,j) == MIN_HOPS(j,i));
00659     assert(MIN_HOPS(i,j) <= INFINITY);
00660      }
00661 #endif
00662 
00663 }
00664 
00665 // --------------------------
00666 
00667 
00668 int
00669 God::hops(int i, int j)
00670 {
00671         return min_hops[i * num_nodes + j];
00672 }
00673 
00674 
00675 void
00676 God::stampPacket(Packet *p)
00677 {
00678         hdr_cmn *ch = HDR_CMN(p);
00679         struct hdr_ip *ih = HDR_IP(p);
00680         nsaddr_t src = ih->saddr();
00681         nsaddr_t dst = ih->daddr();
00682 
00683         assert(min_hops);
00684 
00685         if (!packet_info.data_packet(ch->ptype())) return;
00686 
00687         if (dst > num_nodes || src > num_nodes) return; // broadcast pkt
00688    
00689         ch->opt_num_forwards() = min_hops[src * num_nodes + dst];
00690 }
00691 
00692 
00693 void 
00694 God::recv(Packet *, Handler *)
00695 {
00696         abort();
00697 }
00698 
00699 int
00700 God::load_grid(int x, int y, int size)
00701 {
00702     maxX =  x;
00703     maxY =  y;
00704     gridsize_ = size;
00705     
00706     // how many gridx in X direction
00707     gridX = (int)maxX/size;
00708     if (gridX * size < maxX) gridX ++;
00709     
00710     // how many grid in Y direcion
00711     gridY = (int)maxY/size;
00712     if (gridY * size < maxY) gridY ++;
00713 
00714     printf("Grid info:%d %d %d (%d %d)\n",maxX,maxY,gridsize_,
00715            gridX, gridY);
00716 
00717     return 0;
00718 }
00719  
00720 // return the grid that I am in
00721 // start from left bottom corner, 
00722 // from left to right, 0, 1, ...
00723 
00724 int
00725 God::getMyGrid(double x, double y)
00726 {
00727     int xloc, yloc;
00728     
00729     if (x > maxX || y >maxY) return(-1);
00730     
00731     xloc = (int) x/gridsize_;
00732     yloc = (int) y/gridsize_;
00733     
00734     return(yloc*gridX+xloc);
00735 }
00736 
00737 int
00738 God::getMyLeftGrid(double x, double y)
00739 {
00740 
00741     int xloc, yloc;
00742     
00743     if (x > maxX || y >maxY) return(-1);
00744     
00745     xloc = (int) x/gridsize_;
00746     yloc = (int) y/gridsize_;
00747 
00748     xloc--;
00749     // no left grid
00750     if (xloc < 0) return (-2);
00751     return(yloc*gridX+xloc);
00752 }
00753 
00754 int
00755 God::getMyRightGrid(double x, double y)
00756 {
00757 
00758     int xloc, yloc;
00759     
00760     if (x > maxX || y >maxY) return(-1);
00761     
00762     xloc = (int) x/gridsize_;
00763     yloc = (int) y/gridsize_;
00764 
00765     xloc++;
00766     // no left grid
00767     if (xloc > gridX) return (-2);
00768     return(yloc*gridX+xloc);
00769 }
00770 
00771 int
00772 God::getMyTopGrid(double x, double y)
00773 {
00774 
00775     int xloc, yloc;
00776     
00777     if (x > maxX || y >maxY) return(-1);
00778     
00779     xloc = (int) x/gridsize_;
00780     yloc = (int) y/gridsize_;
00781 
00782     yloc++;
00783     // no top grid
00784     if (yloc > gridY) return (-2);
00785     return(yloc*gridX+xloc);
00786 }
00787 
00788 int
00789 God::getMyBottomGrid(double x, double y)
00790 {
00791 
00792     int xloc, yloc;
00793     
00794     if (x > maxX || y >maxY) return(-1);
00795     
00796     xloc = (int) x/gridsize_;
00797     yloc = (int) y/gridsize_;
00798 
00799     yloc--;
00800     // no top grid
00801     if (yloc < 0 ) return (-2);
00802     return(yloc*gridX+xloc);
00803 }
00804 
00805 int 
00806 God::command(int argc, const char* const* argv)
00807 {
00808     Tcl& tcl = Tcl::instance(); 
00809     if ((instance_ == 0) || (instance_ != this))
00810             instance_ = this; 
00811 
00812         if (argc == 2) {
00813 
00814             if(strcmp(argv[1], "update_node_status") == 0) {
00815           UpdateNodeStatus();
00816           return TCL_OK;
00817         }
00818 
00819             if(strcmp(argv[1], "compute_route") == 0) {
00820           ComputeRoute();
00821           return TCL_OK;
00822         }
00823 
00824                 if(strcmp(argv[1], "dump") == 0) {
00825                 Dump();
00826                         return TCL_OK;
00827                 }
00828         
00829         if (strcmp(argv[1], "dump_num_send") == 0) {
00830           DumpNumSend();
00831           return TCL_OK;
00832         }
00833 
00834         if (strcmp(argv[1], "on") == 0) {
00835           active = true;
00836           return TCL_OK;
00837         }
00838 
00839         if (strcmp(argv[1], "off") == 0) {
00840           active = false;
00841           return TCL_OK;
00842         }
00843 
00844         if (strcmp(argv[1], "allow_to_stop") == 0) {
00845           allowTostop = true;
00846           return TCL_OK;
00847         }
00848 
00849         if (strcmp(argv[1], "not_allow_to_stop") == 0) {
00850           allowTostop = false;
00851           return TCL_OK;
00852         }
00853 
00854         /*
00855                 if(strcmp(argv[1], "dump") == 0) {
00856                         int i, j;
00857 
00858                         for(i = 1; i < num_nodes; i++) {
00859                                 fprintf(stdout, "%2d) ", i);
00860                                 for(j = 1; j < num_nodes; j++)
00861                                         fprintf(stdout, "%2d ",
00862                                                 min_hops[i * num_nodes + j]);
00863                                 fprintf(stdout, "\n");
00864                         }
00865                         return TCL_OK;
00866                 }
00867         */
00868 
00869         if(strcmp(argv[1], "num_nodes") == 0) {
00870             tcl.resultf("%d", nodes());
00871             return TCL_OK;
00872         }
00873         }
00874         else if(argc == 3) {
00875 
00876             if (strcasecmp(argv[1], "is_source") == 0) {
00877           int node_id = atoi(argv[2]);
00878 
00879           if (node_status[node_id].is_source_ == true) {
00880             tcl.result("1");
00881           } else {
00882             tcl.result("0");
00883           }
00884           return TCL_OK;
00885             }
00886 
00887             if (strcasecmp(argv[1], "is_sink") == 0) {
00888           int node_id = atoi(argv[2]);
00889 
00890           if (node_status[node_id].is_sink_ == true) {
00891             tcl.result("1");
00892           } else {
00893             tcl.result("0");
00894           }
00895           return TCL_OK;
00896             }
00897 
00898             if (strcasecmp(argv[1], "is_on_trees") == 0) {
00899           int node_id = atoi(argv[2]);
00900 
00901           if (node_status[node_id].is_on_trees_ == true) {
00902             tcl.result("1");
00903           } else {
00904             tcl.result("0");
00905           }
00906           return TCL_OK;
00907             }
00908 
00909                 if (strcasecmp(argv[1], "num_nodes") == 0) {
00910                         assert(num_nodes == 0);
00911 
00912                         // index always starts from 0
00913                         num_nodes = atoi(argv[2]);
00914 
00915             assert(num_nodes > 0);
00916             
00917             printf("num_nodes is set %d\n", num_nodes);
00918             
00919                         min_hops = new int[num_nodes * num_nodes];
00920             mb_node = new MobileNode*[num_nodes];
00921             node_status = new NodeStatus[num_nodes];
00922             next_hop = new int[num_nodes * num_nodes];
00923 
00924                         bzero((char*) min_hops,
00925                               sizeof(int) * num_nodes * num_nodes);
00926             bzero((char*) mb_node,
00927                   sizeof(MobileNode*) * num_nodes);
00928             bzero((char*) next_hop,
00929                   sizeof(int) * num_nodes * num_nodes);
00930 
00931                         instance_ = this;
00932 
00933                         return TCL_OK;
00934                 }
00935 
00936         if (strcasecmp(argv[1], "num_data_types") == 0) {
00937           assert(num_data_types == 0);
00938 
00939                   num_data_types = atoi(argv[2]);
00940 
00941           assert(num_nodes > 0);
00942           assert(num_data_types > 0);
00943             
00944                   source_table = new int*[num_data_types * num_nodes];
00945           sink_table = new int[num_data_types * num_nodes];
00946           num_send = new int[num_data_types];
00947 
00948                   bzero((char*) source_table,
00949                               sizeof(int *) * num_data_types * num_nodes);
00950                   bzero((char*) sink_table,
00951                               sizeof(int) * num_data_types * num_nodes);
00952           bzero((char*) num_send, sizeof(int) * num_data_types);
00953 
00954           return TCL_OK;
00955         }
00956 
00957         if (strcasecmp(argv[1], "new_node") == 0) {
00958           assert(num_nodes > 0);
00959           MobileNode *obj = (MobileNode *)TclObject::lookup(argv[2]);
00960           assert(obj != 0);
00961           assert(obj->address() < num_nodes);
00962 
00963           mb_node[obj->address()] = obj; 
00964           return TCL_OK;
00965         }
00966 
00967         /*
00968                 if (strcasecmp(argv[1], "num_nodes") == 0) {
00969                         assert(num_nodes == 0);
00970 
00971                         // allow for 0 based to 1 based conversion
00972                         num_nodes = atoi(argv[2]) + 1;
00973 
00974                         min_hops = new int[num_nodes * num_nodes];
00975                         bzero((char*) min_hops,
00976                               sizeof(int) * num_nodes * num_nodes);
00977 
00978                         instance_ = this;
00979 
00980                         return TCL_OK;
00981                 }
00982         */
00983 
00984         }
00985     else if (argc == 4) {
00986 
00987       if (strcasecmp(argv[1], "is_reachable") == 0) {
00988         int n1 = atoi(argv[2]);
00989         int n2 = atoi(argv[3]);
00990 
00991         if (IsReachable(n1,n2) == true) {
00992           tcl.result("1");
00993         } else {
00994           tcl.result("0");
00995         }
00996 
00997         return TCL_OK;
00998       }
00999 
01000 
01001       // We can add source from tcl script or call AddSource directly.
01002 
01003       if (strcasecmp(argv[1], "add_source") == 0) {
01004         int dt = atoi(argv[2]);
01005         int srcid = atoi(argv[3]);
01006         
01007         AddSource(dt, srcid);
01008         return TCL_OK;
01009       }
01010 
01011       // We can add sink from tcl script or call AddSink directly.
01012 
01013       if (strcasecmp(argv[1], "add_sink") == 0) {
01014         int dt = atoi(argv[2]);
01015         int skid = atoi(argv[3]);
01016         
01017         AddSink(dt, skid);
01018         return TCL_OK;
01019       }
01020 
01021     }
01022         else if(argc == 5) {
01023 
01024         /* load for grid-based adaptive fidelity */
01025         if (strcmp(argv[1], "load_grid") == 0) {
01026             if(load_grid(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])))
01027                 return TCL_ERROR;
01028             return TCL_OK;
01029         }
01030 
01031                 if (strcasecmp(argv[1], "set-dist") == 0) {
01032                         int i = atoi(argv[2]);
01033                         int j = atoi(argv[3]);
01034                         int d = atoi(argv[4]);
01035 
01036                         assert(i >= 0 && i < num_nodes);
01037                         assert(j >= 0 && j < num_nodes);
01038 
01039             if (active == true) {
01040               if (NOW > prev_time) {
01041                 ComputeRoute();
01042               }
01043             }
01044             else {
01045               min_hops[i*num_nodes+j] = d;
01046               min_hops[j*num_nodes+i] = d;
01047             }
01048 
01049             // The scenario file should set the node positions
01050             // before calling set-dist !!
01051 
01052             assert(min_hops[i * num_nodes + j] == d);
01053                         assert(min_hops[j * num_nodes + i] == d);
01054                         return TCL_OK;
01055                 }
01056 
01057         /*
01058                 if (strcasecmp(argv[1], "set-dist") == 0) {
01059                         int i = atoi(argv[2]);
01060                         int j = atoi(argv[3]);
01061                         int d = atoi(argv[4]);
01062 
01063                         assert(i >= 0 && i < num_nodes);
01064                         assert(j >= 0 && j < num_nodes);
01065 
01066                         min_hops[i * num_nodes + j] = d;
01067                         min_hops[j * num_nodes + i] = d;
01068                         return TCL_OK;
01069                 }
01070         */
01071 
01072         } 
01073         return BiConnector::command(argc, argv);
01074 }
01075 
01076 
01077 
01078 
01079 
01080 
01081 
01082 

Generated on Tue Mar 6 16:47:45 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6