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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
  2.  *
  3.  * Copyright (c) 1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaim
  13. er in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  * This product includes software developed by the Computer Systems
  18.  * Engineering Group at Lawrence Berkeley Laboratory.
  19.  * 4. Neither the name of the University nor of the Laboratory may be used
  20.  *    to endorse or promote products derived from this software without
  21.  *    specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  *
  35.  * $Header: /cvsroot/nsnam/ns-2/mobile/god.cc,v 1.20 2006/12/27 14:57:23 tom_henderson Exp $
  36.  */
  37. /* Ported from CMU/Monarch's code, nov'98 -Padma.*/
  38. /*
  39.  * god.cc
  40.  *
  41.  * General Operations Director
  42.  *
  43.  * perform operations requiring omnipotence in the simulation
  44.  *
  45.  * NOTE: Tcl node indexs are 0 based, NS C++ node IP addresses (and the
  46.  * node->index() are 1 based.
  47.  *
  48.  */
  49. #include <object.h>
  50. #include <packet.h>
  51. #include <ip.h>
  52. #include <god.h>
  53. #include <sys/param.h>  /* for MIN/MAX */
  54. #include "diffusion/hash_table.h"
  55. #include "mobilenode.h"
  56. God* God::instance_;
  57. static class GodClass : public TclClass {
  58. public:
  59.         GodClass() : TclClass("God") {}
  60.         TclObject* create(int, const char*const*) {
  61.                 return (new God);
  62.         }
  63. } class_God;
  64. God::God()
  65. {
  66.         min_hops = 0;
  67.         num_nodes = 0;
  68.         data_pkt_size = 64;
  69. mb_node = 0;
  70. next_hop = 0;
  71. prev_time = -1.0;
  72. num_alive_node = 0;
  73. num_connect = 0;
  74. num_recv = 0;
  75. num_compute = 0;
  76. num_data_types = 0;
  77. source_table = 0;
  78. sink_table = 0;
  79. num_send = 0;
  80. active = false;
  81. allowTostop = false;
  82. }
  83. // Added by Chalermek 12/1/99
  84. int God::NextHop(int from, int to)
  85. {
  86.   if (active == false) {
  87.     perror("God is off.n");
  88.     exit(-1);
  89.   }
  90.   if (from >= num_nodes) {
  91.     perror("index from higher than the maximum number of nodes.n");
  92.     return -1;
  93.   }
  94.   if (to >= num_nodes) {
  95.     perror("index to higher than the maximum number of nodes.n");
  96.     return -1;
  97.   }
  98.   return NEXT_HOP(from,to);
  99. }
  100. void God::ComputeNextHop()
  101. {
  102.   if (active == false) {
  103.     return;
  104.   }
  105.   int from, to, neighbor;
  106.   for (from=0; from<num_nodes; from++) {
  107.     for (to=0; to<num_nodes; to++) {
  108.       NEXT_HOP(from,to) = UNREACHABLE;
  109.       if (from==to) {
  110. NEXT_HOP(from,to) = from;     // next hop is itself.
  111.       }
  112.       if (MIN_HOPS(from, to) == UNREACHABLE) {
  113. continue;
  114.       }
  115.       for (neighbor=0; neighbor<num_nodes; neighbor++){
  116. if ( MIN_HOPS(from, neighbor) != 1) {
  117.   continue;
  118. }
  119. if ( MIN_HOPS(from, to) == (MIN_HOPS(neighbor,to) +1) ) {
  120.   NEXT_HOP(from, to) = neighbor;
  121.   break;
  122. }
  123.       }
  124.     }
  125.   }
  126. }
  127. void God::UpdateNodeStatus()
  128. {
  129.   int i,j;
  130.   int count, cur, sk, srcid, dt;
  131.    for (i=0; i<num_data_types; i++) {
  132.      for (j=0; j<num_nodes; j++) {
  133.        if (SRC_TAB(i,j) != NULL) {
  134.  node_status[j].is_source_ = true;
  135.        }
  136.      }
  137.    }
  138.    for (i=0; i<num_data_types; i++) {
  139.      for (j=0; j<num_nodes; j++) {
  140.        if (SK_TAB(i,j) > 0) {
  141.  node_status[j].is_sink_ = true;
  142.        }
  143.      }
  144.    }
  145.    for (dt=0; dt < num_data_types; dt++) {
  146.      for (srcid=0; srcid < num_nodes; srcid++) {
  147.        if (SRC_TAB(dt,srcid) == NULL) 
  148.  continue;
  149.        for (sk = 0; sk < num_nodes; sk++) {
  150.  if (SK_TAB(dt, sk) == 0)
  151.    continue;
  152.  cur = srcid;
  153.  count = 0;
  154.  node_status[cur].is_on_trees_ = true;
  155.  while (cur != sk) {
  156.    if (NextHop(cur, sk) == UNREACHABLE)
  157.      break;
  158.    assert(NextHop(cur,sk) >= 0 && NextHop(cur, sk) < num_nodes);
  159.    cur = NextHop(cur, sk);      
  160.    node_status[cur].is_on_trees_ = true;
  161.    count ++;
  162.    assert(count < num_nodes);
  163.  }
  164.        }
  165.      }
  166.    }
  167.    Dump();
  168.    DumpNodeStatus();
  169. }
  170. void God::DumpNodeStatus()
  171. {
  172.   for (int i=0; i < num_nodes; i++) {
  173.     printf("Node %d status (sink %d, source %d, on_tree %d)n", i, 
  174.    node_status[i].is_sink_, node_status[i].is_source_, 
  175.    node_status[i].is_on_trees_);
  176.   }
  177. }
  178. void God::DumpNumSend()
  179. {
  180. #ifdef DEBUG_OUTPUT
  181.   for (int i=0; i < num_data_types; i++) {
  182.     fprintf(stdout, "God: data type %d distinct events %dn", i, num_send[i]);
  183.   }
  184. #endif
  185. }
  186. void God::Dump()
  187. {
  188.    int i, j, k, l;
  189.    // Dump min_hops array
  190.    fprintf(stdout,"Dump min_hopsn");
  191.    for(i = 0; i < num_nodes; i++) {
  192.       fprintf(stdout, "%2d) ", i);
  193.       for(j = 0; j < num_nodes; j++)
  194.           fprintf(stdout, "%2d ", min_hops[i * num_nodes + j]);
  195.           fprintf(stdout, "n");
  196.   }
  197.    // How many times the god compute routes ?
  198.    fprintf(stdout, "God computes routes %d times.n", num_compute);
  199.    // The following information can be found only when god is active.
  200.    if (active == false) {
  201.      return;
  202.    }
  203.    // Dump next_hop array
  204.    fprintf(stdout, "Dump next_hopn");
  205.    for (i = 0; i < num_nodes; i++) {
  206.      for (j = 0; j < num_nodes; j++) {
  207.        fprintf(stdout,"NextHop(%d,%d):%dn",i,j,NEXT_HOP(i,j));
  208.      }
  209.    }
  210.    // What is inside SRC_TAB ?
  211.    fprintf(stdout, "Dump SRC_TABn");
  212.    for (i=0; i<num_data_types; i++) {
  213.      fprintf(stdout,"%2d) ",i);
  214.      for (j=0; j<num_nodes; j++) {
  215.        fprintf(stdout,"%2d ", SRC_TAB(i,j) ? 1:0);
  216.      }
  217.      fprintf(stdout,"n");
  218.    }
  219.    // What is inside OIF_MAP ?
  220.    int *oif_map;
  221.    fprintf(stdout, "Dump OIF_MAPn");
  222.    for (i=0; i<num_data_types; i++) {
  223.      for (j=0; j<num_nodes; j++) {
  224.        if (SRC_TAB(i,j)!=NULL) {
  225.  oif_map = SRC_TAB(i,j);
  226.  fprintf(stdout,"(%2d,%2d)n",i,j);
  227.  for (k=0; k<num_nodes; k++) {
  228.    for (l=0; l<num_nodes; l++) {
  229.      fprintf(stdout,"%2d ", oif_map[k*num_nodes +l]);
  230.    }
  231.    fprintf(stdout,"n");
  232.  }
  233.        }
  234.      }
  235.    }
  236.    // What is inside SK_TAB ?
  237.    fprintf(stdout, "Dump SK_TABn");
  238.    for (i=0; i<num_data_types; i++) {
  239.      fprintf(stdout,"%2d) ",i);
  240.      for (j=0; j<num_nodes; j++) {
  241.        fprintf(stdout,"%2d ", SK_TAB(i,j));
  242.      }
  243.      fprintf(stdout,"n");
  244.    }
  245. }
  246. void God::AddSink(int dt, int skid)
  247. {
  248.   if (active == false) {
  249.     return;
  250.   }
  251.   assert(num_data_types > 0);
  252.   assert(num_nodes > 0);
  253.   assert(dt >= 0 && dt < num_data_types);
  254.   assert(skid >= 0 && skid < num_nodes);
  255.   if (SK_TAB(dt,skid) == 1)
  256.      return;
  257.   SK_TAB(dt,skid) = 1;
  258.   Fill_for_Source(dt, skid);
  259. }
  260. void God::AddSource(int dt, int srcid)
  261. {
  262.   if (active == false) {
  263.     return;
  264.   }
  265.   assert(num_data_types > 0);
  266.   assert(num_nodes > 0);
  267.   assert(dt >= 0 && dt < num_data_types);
  268.   assert(srcid >= 0 && srcid < num_nodes);
  269.   if (SRC_TAB(dt,srcid) != 0)
  270.       return;
  271.   SRC_TAB(dt,srcid) = new int[num_nodes * num_nodes];
  272.   bzero((char*) SRC_TAB(dt, srcid), sizeof(int) * num_nodes * num_nodes);
  273.   Fill_for_Sink(dt, srcid);
  274.   //  Dump();
  275. }
  276. void God::Fill_for_Sink(int dt, int srcid)
  277. {
  278.   int sk, cur, count;
  279.   int *oif_map = SRC_TAB(dt, srcid);
  280.   assert(oif_map != NULL);
  281.   for (sk = 0; sk < num_nodes; sk++) {
  282.     if (SK_TAB(dt, sk) == 0)
  283.       continue;
  284.     cur = srcid;
  285.     count = 0;
  286.     while (cur != sk) {
  287.       if (NextHop(cur, sk) == UNREACHABLE)
  288. break;
  289.       assert(NextHop(cur,sk) >= 0 && NextHop(cur, sk) < num_nodes);
  290.       oif_map[cur*num_nodes + NextHop(cur, sk)] = 1;
  291.       cur = NextHop(cur, sk);      
  292.       count ++;
  293.       assert(count < num_nodes);
  294.     }
  295.   }
  296. }
  297. void God::Fill_for_Source(int dt, int skid)
  298. {
  299.   int src, cur, count;
  300.   int *oif_map;
  301.   for (src = 0; src < num_nodes; src++) {
  302.     if (SRC_TAB(dt, src) == 0)
  303.       continue;
  304.    
  305.     oif_map = SRC_TAB(dt, src);
  306.     cur = src;
  307.     count = 0;
  308.     while (cur != skid) {
  309.       if (NextHop(cur, skid) == UNREACHABLE)
  310. break;
  311.       assert(NextHop(cur,skid) >= 0 && NextHop(cur, skid) < num_nodes);
  312.       oif_map[cur*num_nodes + NextHop(cur, skid)] = 1;
  313.       cur = NextHop(cur, skid);      
  314.       count ++;
  315.       assert(count < num_nodes);
  316.     }
  317.   }
  318. }
  319. void God::Rewrite_OIF_Map()
  320. {
  321.   for (int dt = 0; dt < num_data_types; dt++) {
  322.     for (int src = 0; src < num_nodes; src++) {
  323.       if (SRC_TAB(dt, src) == NULL)
  324. continue;
  325.       memset(SRC_TAB(dt,src),'x00', sizeof(int) * num_nodes * num_nodes);
  326.       Fill_for_Sink(dt, src);
  327.     }
  328.   }
  329. }
  330. int *God::NextOIFs(int dt, int srcid, int curid, int *ret_num_oif) 
  331. {
  332.   if (active == false) {
  333.     perror("God is inactive.n");
  334.     exit(-1);
  335.   }  
  336.   int *oif_map = SRC_TAB(dt, srcid);
  337.   int count=0;
  338.   int i;
  339.   for (i=0; i<num_nodes; i++) {
  340.     if (oif_map[curid*num_nodes +i] == 1)
  341.       count++;
  342.   }
  343.   *ret_num_oif = count;
  344.   if (count == 0)
  345.     return NULL;
  346.   int *next_oifs = new int[count];
  347.   int j=0;
  348.   
  349.   for (i=0; i<num_nodes; i++) {
  350.     if (oif_map[curid*num_nodes +i] == 1) {
  351.       next_oifs[j] = i;
  352.       j++;    
  353.     }
  354.   }
  355.   return next_oifs;
  356. }
  357. bool God::IsReachable(int i, int j)
  358. {
  359. //  if (MIN_HOPS(i,j) < UNREACHABLE && MIN_HOPS(i,j) >= 0) 
  360.   if (NextHop(i,j) != UNREACHABLE)
  361.      return true;
  362.   else
  363.      return false;
  364. }
  365. bool God::IsNeighbor(int i, int j)
  366. {
  367.   assert(i<num_nodes && j<num_nodes);
  368.   //printf("i=%d, j=%dn", i,j);
  369.   if (mb_node[i]->energy_model()->node_on() == false ||
  370.       mb_node[j]->energy_model()->node_on() == false ||
  371.       mb_node[i]->energy_model()->energy() <= 0.0 ||
  372.       mb_node[j]->energy_model()->energy() <= 0.0 ) {
  373.     return false;
  374.   }
  375.   vector a(mb_node[i]->X(), mb_node[i]->Y(), mb_node[i]->Z());
  376.   vector b(mb_node[j]->X(), mb_node[j]->Y(), mb_node[j]->Z());
  377.   vector d = a - b;
  378.   if (d.length() < RANGE)
  379.     return true;
  380.   else
  381.     return false;  
  382. }
  383. void God::CountConnect()
  384. {
  385.   int i,j;
  386.   num_connect = 0;
  387.   for (i=0; i<num_nodes; i++) {
  388.     for (j=i+1; j<num_nodes; j++) {
  389.       if (MIN_HOPS(i,j) != UNREACHABLE) {
  390. num_connect++;
  391.       }
  392.     }
  393.   }
  394. }
  395. void God::CountAliveNode()
  396. {
  397.   int i;
  398.   num_alive_node = 0;
  399.   for (i=0; i<num_nodes; i++) {
  400.     if (mb_node[i]->energy_model()->energy() > 0.0) {
  401.       num_alive_node++;
  402.     }
  403.   }
  404. }
  405. bool God::ExistSource()
  406. {
  407.   int dtype, i;
  408.   for (dtype = 0; dtype < num_data_types; dtype++) {
  409.     for (i=0; i<num_nodes; i++) {
  410.       if (SRC_TAB(dtype, i) != 0)
  411. return true;
  412.     }
  413.   }
  414.   return false;
  415. }
  416. bool God::ExistSink()
  417. {
  418.   int dtype, i;
  419.   for (dtype = 0; dtype < num_data_types; dtype++) {
  420.     for (i=0; i<num_nodes; i++) {
  421.       if (SK_TAB(dtype, i) != 0)
  422. return true;
  423.     }
  424.   }
  425.   return false;
  426. }
  427. bool God::IsPartition()
  428. {
  429.   int dtype, i, j, k;
  430.   int *oif_map;
  431.   for (dtype = 0; dtype < num_data_types; dtype ++) {
  432.     for (i = 0; i < num_nodes; i++) {
  433.       if (SRC_TAB(dtype,i) == NULL)
  434. continue;
  435.       oif_map = SRC_TAB(dtype, i);
  436.       for (j = 0; j < num_nodes; j++) {
  437. for (k = 0; k < num_nodes; k++) {
  438.   if (oif_map[j*num_nodes + k] != 0)
  439.     return false;
  440. }
  441.       }
  442.     }
  443.   }
  444.   return true;
  445. }
  446. void God::ComputeRoute() 
  447. {
  448.   if (active == false) {
  449.     return;
  450.   }
  451.   floyd_warshall();
  452.   ComputeNextHop();
  453.   Rewrite_OIF_Map();
  454.   CountConnect();
  455.   CountAliveNode();
  456.   prev_time = NOW;
  457.   num_compute++;
  458.   if (allowTostop == false)
  459.     return;
  460.   if ( ExistSink() == true && ExistSource() == true && IsPartition() == true)
  461.     StopSimulation();
  462. }
  463. void God::CountNewData(int *attr)
  464. {
  465.   if (dtab.GetHash(attr) == NULL) {
  466.     num_send[attr[0]]++;
  467.     dtab.PutInHash(attr);
  468.   }
  469. }
  470. void God::IncrRecv()
  471. {
  472.   num_recv++;
  473.   //  printf("God: num_connect %d, num_alive_node %d at recv pkt %dn",
  474.   // num_connect, num_alive_node, num_recv);
  475. }
  476. void God::StopSimulation() 
  477. {
  478.   Tcl& tcl=Tcl::instance();
  479.   printf("Network parition !! Exiting... at time %fn", NOW);
  480.   tcl.evalf("[Simulator instance] at %lf "finish"", (NOW)+0.000001);
  481.   tcl.evalf("[Simulator instance] at %lf "[Simulator instance] halt"", (NOW)+0.000002);
  482. }
  483. // Modified from setdest.cc -- Chalermek 12/1/99
  484. void God::ComputeW()
  485. {
  486.   int i, j;
  487.   int *W = min_hops;
  488.   memset(W, 'xff', sizeof(int) * num_nodes * num_nodes);
  489.   for(i = 0; i < num_nodes; i++) {
  490.      W[i*num_nodes + i] = 0;     
  491.      for(j = i+1; j < num_nodes; j++) {
  492. W[i*num_nodes + j] = W[j*num_nodes + i] = 
  493.                      IsNeighbor(i,j) ? 1 : INFINITY;
  494.      }
  495.   }
  496. }
  497. void God::floyd_warshall()
  498. {
  499.   int i, j, k;
  500.   ComputeW(); // the connectivity matrix
  501.   for(i = 0; i < num_nodes; i++) {
  502.      for(j = 0; j < num_nodes; j++) {
  503.  for(k = 0; k < num_nodes; k++) {
  504.     MIN_HOPS(j,k) = MIN(MIN_HOPS(j,k), MIN_HOPS(j,i) + MIN_HOPS(i,k));
  505.  }
  506.      }
  507.   }
  508. #ifdef SANITY_CHECKS
  509.   for(i = 0; i < num_nodes; i++)
  510.      for(j = 0; j < num_nodes; j++) {
  511. assert(MIN_HOPS(i,j) == MIN_HOPS(j,i));
  512. assert(MIN_HOPS(i,j) <= INFINITY);
  513.      }
  514. #endif
  515. }
  516. // --------------------------
  517. int
  518. God::hops(int i, int j)
  519. {
  520.         return min_hops[i * num_nodes + j];
  521. }
  522. void
  523. God::stampPacket(Packet *p)
  524. {
  525.         hdr_cmn *ch = HDR_CMN(p);
  526.         struct hdr_ip *ih = HDR_IP(p);
  527.         nsaddr_t src = ih->saddr();
  528.         nsaddr_t dst = ih->daddr();
  529.         assert(min_hops);
  530.         if (!packet_info.data_packet(ch->ptype())) return;
  531.         if (dst > num_nodes || src > num_nodes) return; // broadcast pkt
  532.    
  533.         ch->opt_num_forwards() = min_hops[src * num_nodes + dst];
  534. }
  535. void 
  536. God::recv(Packet *, Handler *)
  537. {
  538.         abort();
  539. }
  540. int
  541. God::load_grid(int x, int y, int size)
  542. {
  543. maxX =  x;
  544. maxY =  y;
  545. gridsize_ = size;
  546. // how many gridx in X direction
  547. gridX = (int)maxX/size;
  548. if (gridX * size < maxX) gridX ++;
  549. // how many grid in Y direcion
  550. gridY = (int)maxY/size;
  551. if (gridY * size < maxY) gridY ++;
  552. printf("Grid info:%d %d %d (%d %d)n",maxX,maxY,gridsize_,
  553.        gridX, gridY);
  554. return 0;
  555. }
  556.  
  557. // return the grid that I am in
  558. // start from left bottom corner, 
  559. // from left to right, 0, 1, ...
  560. int
  561. God::getMyGrid(double x, double y)
  562. {
  563. int xloc, yloc;
  564. if (x > maxX || y >maxY) return(-1);
  565. xloc = (int) x/gridsize_;
  566. yloc = (int) y/gridsize_;
  567. return(yloc*gridX+xloc);
  568. }
  569. int
  570. God::getMyLeftGrid(double x, double y)
  571. {
  572. int xloc, yloc;
  573. if (x > maxX || y >maxY) return(-1);
  574. xloc = (int) x/gridsize_;
  575. yloc = (int) y/gridsize_;
  576. xloc--;
  577. // no left grid
  578. if (xloc < 0) return (-2);
  579. return(yloc*gridX+xloc);
  580. }
  581. int
  582. God::getMyRightGrid(double x, double y)
  583. {
  584. int xloc, yloc;
  585. if (x > maxX || y >maxY) return(-1);
  586. xloc = (int) x/gridsize_;
  587. yloc = (int) y/gridsize_;
  588. xloc++;
  589. // no left grid
  590. if (xloc > gridX) return (-2);
  591. return(yloc*gridX+xloc);
  592. }
  593. int
  594. God::getMyTopGrid(double x, double y)
  595. {
  596. int xloc, yloc;
  597. if (x > maxX || y >maxY) return(-1);
  598. xloc = (int) x/gridsize_;
  599. yloc = (int) y/gridsize_;
  600. yloc++;
  601. // no top grid
  602. if (yloc > gridY) return (-2);
  603. return(yloc*gridX+xloc);
  604. }
  605. int
  606. God::getMyBottomGrid(double x, double y)
  607. {
  608. int xloc, yloc;
  609. if (x > maxX || y >maxY) return(-1);
  610. xloc = (int) x/gridsize_;
  611. yloc = (int) y/gridsize_;
  612. yloc--;
  613. // no top grid
  614. if (yloc < 0 ) return (-2);
  615. return(yloc*gridX+xloc);
  616. }
  617. int 
  618. God::command(int argc, const char* const* argv)
  619. {
  620. Tcl& tcl = Tcl::instance(); 
  621. if ((instance_ == 0) || (instance_ != this))
  622.            instance_ = this; 
  623.         if (argc == 2) {
  624.         if(strcmp(argv[1], "update_node_status") == 0) {
  625.   UpdateNodeStatus();
  626.   return TCL_OK;
  627. }
  628.         if(strcmp(argv[1], "compute_route") == 0) {
  629.   ComputeRoute();
  630.   return TCL_OK;
  631. }
  632.                 if(strcmp(argv[1], "dump") == 0) {
  633.         Dump();
  634.                         return TCL_OK;
  635.                 }
  636. if (strcmp(argv[1], "dump_num_send") == 0) {
  637.   DumpNumSend();
  638.   return TCL_OK;
  639. }
  640. if (strcmp(argv[1], "on") == 0) {
  641.   active = true;
  642.   return TCL_OK;
  643. }
  644. if (strcmp(argv[1], "off") == 0) {
  645.   active = false;
  646.   return TCL_OK;
  647. }
  648. if (strcmp(argv[1], "allow_to_stop") == 0) {
  649.   allowTostop = true;
  650.   return TCL_OK;
  651. }
  652. if (strcmp(argv[1], "not_allow_to_stop") == 0) {
  653.   allowTostop = false;
  654.   return TCL_OK;
  655. }
  656. /*
  657.                 if(strcmp(argv[1], "dump") == 0) {
  658.                         int i, j;
  659.                         for(i = 1; i < num_nodes; i++) {
  660.                                 fprintf(stdout, "%2d) ", i);
  661.                                 for(j = 1; j < num_nodes; j++)
  662.                                         fprintf(stdout, "%2d ",
  663.                                                 min_hops[i * num_nodes + j]);
  664.                                 fprintf(stdout, "n");
  665.                         }
  666.                         return TCL_OK;
  667.                 }
  668. */
  669. if(strcmp(argv[1], "num_nodes") == 0) {
  670. tcl.resultf("%d", nodes());
  671. return TCL_OK;
  672. }
  673.         }
  674.         else if(argc == 3) {
  675.         if (strcasecmp(argv[1], "is_source") == 0) {
  676.   int node_id = atoi(argv[2]);
  677.   if (node_status[node_id].is_source_ == true) {
  678.     tcl.result("1");
  679.   } else {
  680.     tcl.result("0");
  681.   }
  682.   return TCL_OK;
  683.         }
  684.         if (strcasecmp(argv[1], "is_sink") == 0) {
  685.   int node_id = atoi(argv[2]);
  686.   if (node_status[node_id].is_sink_ == true) {
  687.     tcl.result("1");
  688.   } else {
  689.     tcl.result("0");
  690.   }
  691.   return TCL_OK;
  692.         }
  693.         if (strcasecmp(argv[1], "is_on_trees") == 0) {
  694.   int node_id = atoi(argv[2]);
  695.   if (node_status[node_id].is_on_trees_ == true) {
  696.     tcl.result("1");
  697.   } else {
  698.     tcl.result("0");
  699.   }
  700.   return TCL_OK;
  701.         }
  702.                 if (strcasecmp(argv[1], "num_nodes") == 0) {
  703.                         assert(num_nodes == 0);
  704.                         // index always starts from 0
  705.                         num_nodes = atoi(argv[2]);
  706. assert(num_nodes > 0);
  707. printf("num_nodes is set %dn", num_nodes);
  708.                         min_hops = new int[num_nodes * num_nodes];
  709. mb_node = new MobileNode*[num_nodes];
  710. node_status = new NodeStatus[num_nodes];
  711. next_hop = new int[num_nodes * num_nodes];
  712.                         bzero((char*) min_hops,
  713.                               sizeof(int) * num_nodes * num_nodes);
  714. bzero((char*) mb_node,
  715.       sizeof(MobileNode*) * num_nodes);
  716. bzero((char*) next_hop,
  717.       sizeof(int) * num_nodes * num_nodes);
  718.                         instance_ = this;
  719.                         return TCL_OK;
  720.                 }
  721. if (strcasecmp(argv[1], "num_data_types") == 0) {
  722.   assert(num_data_types == 0);
  723.                   num_data_types = atoi(argv[2]);
  724.   assert(num_nodes > 0);
  725.   assert(num_data_types > 0);
  726.                   source_table = new int*[num_data_types * num_nodes];
  727.   sink_table = new int[num_data_types * num_nodes];
  728.   num_send = new int[num_data_types];
  729.                   bzero((char*) source_table,
  730.                               sizeof(int *) * num_data_types * num_nodes);
  731.                   bzero((char*) sink_table,
  732.                               sizeof(int) * num_data_types * num_nodes);
  733.   bzero((char*) num_send, sizeof(int) * num_data_types);
  734.   return TCL_OK;
  735. }
  736. if (strcasecmp(argv[1], "new_node") == 0) {
  737.   assert(num_nodes > 0);
  738.   MobileNode *obj = (MobileNode *)TclObject::lookup(argv[2]);
  739.   assert(obj != 0);
  740.   assert(obj->address() < num_nodes);
  741.   mb_node[obj->address()] = obj; 
  742.   return TCL_OK;
  743. }
  744. /*
  745.                 if (strcasecmp(argv[1], "num_nodes") == 0) {
  746.                         assert(num_nodes == 0);
  747.                         // allow for 0 based to 1 based conversion
  748.                         num_nodes = atoi(argv[2]) + 1;
  749.                         min_hops = new int[num_nodes * num_nodes];
  750.                         bzero((char*) min_hops,
  751.                               sizeof(int) * num_nodes * num_nodes);
  752.                         instance_ = this;
  753.                         return TCL_OK;
  754.                 }
  755. */
  756.         }
  757. else if (argc == 4) {
  758.   if (strcasecmp(argv[1], "is_reachable") == 0) {
  759.     int n1 = atoi(argv[2]);
  760.     int n2 = atoi(argv[3]);
  761.     if (IsReachable(n1,n2) == true) {
  762.       tcl.result("1");
  763.     } else {
  764.       tcl.result("0");
  765.     }
  766.     return TCL_OK;
  767.   }
  768.   // We can add source from tcl script or call AddSource directly.
  769.   if (strcasecmp(argv[1], "add_source") == 0) {
  770.     int dt = atoi(argv[2]);
  771.     int srcid = atoi(argv[3]);
  772.     
  773.     AddSource(dt, srcid);
  774.     return TCL_OK;
  775.   }
  776.   // We can add sink from tcl script or call AddSink directly.
  777.   if (strcasecmp(argv[1], "add_sink") == 0) {
  778.     int dt = atoi(argv[2]);
  779.     int skid = atoi(argv[3]);
  780.     
  781.     AddSink(dt, skid);
  782.     return TCL_OK;
  783.   }
  784. }
  785.         else if(argc == 5) {
  786. /* load for grid-based adaptive fidelity */
  787. if (strcmp(argv[1], "load_grid") == 0) {
  788. if(load_grid(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])))
  789. return TCL_ERROR;
  790. return TCL_OK;
  791. }
  792.                 if (strcasecmp(argv[1], "set-dist") == 0) {
  793.                         int i = atoi(argv[2]);
  794.                         int j = atoi(argv[3]);
  795.                         int d = atoi(argv[4]);
  796.                         assert(i >= 0 && i < num_nodes);
  797.                         assert(j >= 0 && j < num_nodes);
  798. if (active == true) {
  799.   if (NOW > prev_time) {
  800.     ComputeRoute();
  801.   }
  802. }
  803. else {
  804.   min_hops[i*num_nodes+j] = d;
  805.   min_hops[j*num_nodes+i] = d;
  806. }
  807. // The scenario file should set the node positions
  808. // before calling set-dist !!
  809. assert(min_hops[i * num_nodes + j] == d);
  810.                         assert(min_hops[j * num_nodes + i] == d);
  811.                         return TCL_OK;
  812.                 }
  813. /*
  814.                 if (strcasecmp(argv[1], "set-dist") == 0) {
  815.                         int i = atoi(argv[2]);
  816.                         int j = atoi(argv[3]);
  817.                         int d = atoi(argv[4]);
  818.                         assert(i >= 0 && i < num_nodes);
  819.                         assert(j >= 0 && j < num_nodes);
  820.                         min_hops[i * num_nodes + j] = d;
  821.                         min_hops[j * num_nodes + i] = d;
  822.                         return TCL_OK;
  823.                 }
  824. */
  825.         } 
  826.         return BiConnector::command(argc, argv);
  827. }