sensor-query.cc

Go to the documentation of this file.
00001 
00002 /*
00003  * sensor-query.cc
00004  * Copyright (C) 2000 by the University of Southern California
00005  * $Id: sensor-query.cc,v 1.5 2005/08/25 18:58:12 johnh Exp $
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  *
00020  *
00021  * The copyright of this module includes the following
00022  * linking-with-specific-other-licenses addition:
00023  *
00024  * In addition, as a special exception, the copyright holders of
00025  * this module give you permission to combine (via static or
00026  * dynamic linking) this module with free software programs or
00027  * libraries that are released under the GNU LGPL and with code
00028  * included in the standard release of ns-2 under the Apache 2.0
00029  * license or under otherwise-compatible licenses with advertising
00030  * requirements (or modified versions of such code, with unchanged
00031  * license).  You may copy and distribute such a system following the
00032  * terms of the GNU GPL for this module and the licenses of the
00033  * other code concerned, provided that you include the source code of
00034  * that other code when and as the GNU GPL requires distribution of
00035  * source code.
00036  *
00037  * Note that people who make modified versions of this module
00038  * are not obligated to grant this special exception for their
00039  * modified versions; it is their choice whether to do so.  The GNU
00040  * General Public License gives permission to release a modified
00041  * version without this exception; this exception also makes it
00042  * possible to release a modified version which carries forward this
00043  * exception.
00044  *
00045  */
00046 
00047 // $Header: /nfs/jade/vint/CVSROOT/ns-2/sensor-nets/sensor-query.cc,v 1.5 2005/08/25 18:58:12 johnh Exp $
00048 
00049 #include <stdarg.h>
00050 #include <float.h>
00051 
00052 #include "sensor-query.h"
00053 #include "landmark.h"
00054 #include <random.h>
00055 
00056 #define CONST_INTERVAL 30
00057 
00058 static class SensorQueryClass:public TclClass
00059 {
00060   public:
00061   SensorQueryClass ():TclClass ("Agent/SensorQuery")
00062   {
00063   }
00064   TclObject *create (int, const char *const *)
00065   {
00066     return (new SensorQueryAgent ());
00067   }
00068 } class_sensor_query;
00069 
00070 
00071 
00072 
00073 void SensorQueryAgent::
00074 trace (char *fmt,...)
00075 {
00076   va_list ap; // Define a variable ap that will refer to each argument in turn
00077 
00078   if (!tracetarget_)
00079     return;
00080 
00081   // Initializes ap to first argument
00082   va_start (ap, fmt); 
00083   // Prints the elements in turn
00084   vsprintf (tracetarget_->buffer (), fmt, ap); 
00085   tracetarget_->dump ();
00086   // Does the necessary clean-up before returning
00087   va_end (ap); 
00088 }
00089 
00090 
00091 
00092 
00093 void
00094 SensorQueryAgent::stop()
00095 {
00096   trace("Node %d: SensorQueryAgent going down at time %f",myaddr_,NOW);
00097 
00098   // Event id > 0 implies presence on the event queue
00099   if(gen_query_event_->uid_) {
00100     Scheduler &s = Scheduler::instance();
00101     s.cancel(gen_query_event_);
00102   }
00103   node_dead_ = 1;
00104 }
00105 
00106 
00107 
00108 
00109 int 
00110 SensorQueryAgent::command (int argc, const char *const *argv)
00111 {
00112   if (argc == 2)
00113     {
00114       if (strcmp (argv[1], "start") == 0)
00115         {
00116           startUp();
00117           return (TCL_OK);
00118         }
00119       if (strcmp (argv[1], "stop") == 0)
00120     {
00121       stop();
00122       return (TCL_OK);
00123     }
00124       if (strcmp (argv[1], "generate-query") == 0)
00125         {
00126           generate_query(-1,-1,-1);
00127           return (TCL_OK);
00128         }
00129     }
00130   else if (argc == 3)
00131     {
00132       if (strcasecmp (argv[1], "tracetarget") == 0)
00133         {
00134           TclObject *obj;
00135       if ((obj = TclObject::lookup (argv[2])) == 0)
00136             {
00137               fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
00138                        argv[2]);
00139               return TCL_ERROR;
00140             }
00141           tracetarget_ = (Trace *) obj;
00142           return TCL_OK;
00143         }
00144       else if (strcasecmp (argv[1], "addr") == 0) {
00145         int temp;
00146         temp = Address::instance().str2addr(argv[2]);
00147         myaddr_ = temp;
00148         return TCL_OK;
00149       }
00150       else if (strcasecmp (argv[1], "attach-tag-dbase") == 0)
00151         {
00152           TclObject *obj;
00153           if ((obj = TclObject::lookup (argv[2])) == 0)
00154             {
00155               fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
00156                        argv[2]);
00157               return TCL_ERROR;
00158             }
00159           tag_dbase_ = (tags_database *) obj;
00160           return TCL_OK;
00161         }
00162     }
00163   else if (argc == 5) {
00164     if (strcmp (argv[1], "generate-query") == 0)
00165       {
00166     int p1 = atoi(argv[2]);
00167     int p2 = atoi(argv[3]);
00168     int p3 = atoi(argv[4]);
00169     generate_query(p1,p2,p3);
00170     return (TCL_OK);
00171       }
00172   }
00173   
00174   return (Agent::command (argc, argv));
00175 }
00176 
00177 
00178 
00179 
00180 
00181 void
00182 SensorQueryAgent::startUp()
00183 {
00184   //  Scheduler &s = Scheduler::instance();
00185   //  double sched_time = CONST_INTERVAL + Random::uniform(query_interval_);
00186   //  trace("Node %d: Scheduling query gen at %f from now %f",myaddr_,sched_time,s.clock());
00187   //  s.schedule(query_handler_, gen_query_event_, Random::uniform(query_interval_));
00188   trace("Node %d: SensorQueryAgent starting up at time %f",myaddr_,NOW);
00189   node_dead_ = 0;
00190 }
00191 
00192 //void
00193 //SensorQueryAgent::handle(Event *) {
00194 //  Scheduler &s = Scheduler::instance();
00195 //  generate_query();
00196 //  double sched_time = Random::uniform(query_interval_);
00197 //  trace("Node %d: Scheduling query gen at %f from now %f",myaddr_,sched_time,s.clock());
00198 //  s.schedule(this, gen_query_event_, Random::uniform(query_interval_));
00199 //}
00200 
00201 void
00202 SensorQueryAgent::generate_query(int p1, int p2, int p3)
00203 {
00204   Packet *p = allocpkt();
00205   hdr_ip *iph = HDR_IP(p);
00206   hdr_cmn *hdrc = HDR_CMN(p);
00207   unsigned char *walk;
00208   Scheduler &s = Scheduler::instance();
00209   int obj_name;
00210   int next_hop_level = 0, num_src_hops = 0;
00211   int X = 65000, Y = 65000;
00212   int action = QUERY_PKT;
00213 
00214   if(node_dead_) {
00215     trace("Node %d: node failed, cannot generate query");
00216     return;
00217   }
00218 
00219   // Need to ask our routing module to direct the packet
00220   hdrc->next_hop_ = myaddr_;
00221   hdrc->addr_type_ = NS_AF_INET;
00222   iph->daddr() = myaddr_;
00223   iph->dport() = ROUTER_PORT;
00224   iph->ttl_ = 300;   // since only 300 ids in source route in packet
00225 
00226   iph->saddr() = myaddr_;
00227   iph->sport() = 0;
00228 
00229   // LM agent checks if the source port is 0 to identify a query packet  
00230   // 2 bytes each for X and Y co-ords
00231   // 1 byte for level - used in next hop lookup
00232   // 4 bytes for object name; 2 byte for number of hops in src route
00233   // 4 bytes for origin_time
00234   // 90 bytes to store 30 source route ids and their levels (1 byte each)
00235   // (assuming max_levels = 15) 
00236   p->allocdata(105);
00237   walk = p->accessdata();
00238 
00239   (*walk++) = action & 0xFF;
00240 
00241   // X coord = 65000 initially
00242   (*walk++) = (X >> 8) & 0xFF;
00243   (*walk++) = X & 0xFF;
00244 
00245   // Y coord = 65000 initially
00246   (*walk++) = (Y >> 8) & 0xFF;
00247   (*walk++) = Y & 0xFF;
00248 
00249   // Indicates next hop level
00250   (*walk++) = next_hop_level & 0xFF;
00251 
00252   if(p1 != -1 && p2 != -1 && p3 != -1)
00253     obj_name = (int) ((p1 * pow(2,24)) + (p2 * pow(2,16)) + p3) ;
00254   else
00255     obj_name = tag_dbase_->get_random_tag();
00256 
00257   //  p1 = Random::integer(10);
00258   //  p2 = Random::integer(10);
00259   //  p3 = Random::integer(50);
00260 
00261   (*walk++) = (obj_name >> 24) & 0xFF;
00262   (*walk++) = (obj_name >> 16) & 0xFF;
00263   (*walk++) = (obj_name >> 8) & 0xFF;
00264   (*walk++) = (obj_name) & 0xFF;
00265 
00266   double now = Scheduler::instance().clock();
00267   trace("Node %d: Generating query for object %d.%d.%d at time %f",myaddr_,(obj_name >> 24) & 0xFF,(obj_name >> 16) & 0xFF, obj_name & 0xFFFF,now);
00268   
00269 
00270   int origin_time = (int) now;
00271   (*walk++) = (origin_time >> 24) & 0xFF;
00272   (*walk++) = (origin_time >> 16) & 0xFF;
00273   (*walk++) = (origin_time >> 8) & 0xFF;
00274   (*walk++) = (origin_time) & 0xFF;
00275 
00276   // Number of source route hops in packet (= 0); 2 bytes
00277   (*walk++) = (num_src_hops >> 8) & 0xFF;
00278   (*walk++) = (num_src_hops) & 0xFF;
00279 
00280   // Above fields will be 4 bytes each. 20 bytes for the IP header will be
00281   // added in LM agent. No source route hops on query creation.
00282   hdrc->size_ = 24; 
00283   hdrc->direction() = hdr_cmn::DOWN;
00284 
00285   s.schedule(target_,p,0);
00286   //  double sched_time = CONST_INTERVAL + Random::uniform(query_interval_);
00287   //  trace("Node %d: Scheduling query gen at %f from now %f",myaddr_,sched_time,s.clock());
00288   //  s.schedule(query_handler_, gen_query_event_, sched_time);
00289   //  s.schedule(this, gen_query_event_, Random::uniform(query_interval_));
00290 }
00291 
00292 
00293 
00294 void
00295 SensorQueryAgent::recv(Packet *p, Handler *)
00296 {
00297   unsigned char *walk = p->accessdata();
00298   int X = 0, Y = 0, obj_name = -1;
00299 
00300   if(node_dead_) {
00301     Packet::free(p);
00302     return;
00303   }
00304 
00305   ++walk;
00306   X = *walk++;
00307   X = (X << 8) | *walk++;
00308 
00309   Y = *walk++;
00310   Y = (Y << 8) | *walk++;
00311   
00312   ++walk;
00313   obj_name = *walk++;
00314   obj_name = (obj_name << 8) | *walk++;
00315   obj_name = (obj_name << 8) | *walk++;
00316   obj_name = (obj_name << 8) | *walk++;
00317 
00318   double now = Scheduler::instance().clock();
00319   trace("Node %d: SensorQueryAgent 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,now);
00320 
00321   Packet::free(p);
00322 }
00323 
00324 
00325 
00326 SensorQueryAgent::SensorQueryAgent() : Agent(PT_MESSAGE) { 
00327     query_interval_ = 120;
00328     gen_query_event_ = new Event;
00329     query_handler_ = new SensorQueryHandler(this);
00330     node_dead_ = 0;
00331 }
00332 
00333 

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