node-core.cc

00001 /*
00002  * Copyright (c) 2006 Regents of the SIGNET lab, University of Padova.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University of Padova (SIGNET lab) nor the 
00014  *    names of its contributors may be used to endorse or promote products 
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00018  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
00019  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00020  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00021  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00023  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00024  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00026  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00027  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 #include "node-core.h"
00030 
00031 #include<iostream>
00032 
00033 /* ======================================================================
00034    TCL Hooks for the simulator
00035    ====================================================================== */
00036 static class PositionClass : public TclClass {
00037 public:
00038         PositionClass() : TclClass("Position") {}
00039         TclObject* create(int, const char*const*) {
00040                 return (new Position());
00041         }
00042 } class_position;
00043 
00044 Position::Position()
00045   : x_(0.0), y_(0.0), z_(0.0)
00046 {
00047 }
00048 
00049 Position::~Position()
00050 {
00051 }
00052 
00053 int Position::command(int argc, const char*const* argv)
00054 {
00055         Tcl& tcl = Tcl::instance();
00056         if(argc == 2)
00057         {
00058                 if(strcasecmp(argv[1], "getX_") == 0)
00059                 {
00060                         tcl.resultf("%f",getX());
00061                         return TCL_OK;
00062                 }
00063                 else if(strcasecmp(argv[1], "getY_") == 0)
00064                 {
00065                         tcl.resultf("%f",getY());
00066                         return TCL_OK;
00067                 }
00068                 else if(strcasecmp(argv[1], "getZ_") == 0)
00069                 {
00070                         tcl.resultf("%f",getZ());
00071                         return TCL_OK;
00072                 }
00073         }
00074         else if(argc == 3)
00075         {
00076                 if(strcasecmp(argv[1], "setX_") == 0)
00077                 {
00078                         setX(atof(argv[2]));
00079                         return TCL_OK;
00080                 }
00081                 else if(strcasecmp(argv[1], "setY_") == 0)
00082                 {
00083                         setY(atof(argv[2]));
00084                         return TCL_OK;
00085                 }
00086                 else if(strcasecmp(argv[1], "setZ_") == 0)
00087                 {
00088                         setZ(atof(argv[2]));
00089                         return TCL_OK;
00090                 }
00091         }
00092         return TclObject::command(argc, argv);
00093 }
00094 
00095 double Position::getX()
00096 {
00097         return x_;
00098 }
00099 
00100 double Position::getY()
00101 {
00102         return y_;
00103 }
00104 
00105 double Position::getZ()
00106 {
00107         return z_;
00108 }
00109 
00110 double Position::getDist(Position* p)
00111 {
00112   assert(p);
00113   double dx = getX() - p->getX();
00114   double dy = getY() - p->getY();
00115   double dz = getZ() - p->getZ();
00116   return (sqrt(dx*dx + dy*dy + dz*dz));
00117 }
00118 
00119 double Position::getRelAzimuth(Position* p)
00120 {
00121   assert(p);
00122   double dx = p->getX() - getX();
00123   double dy = p->getY() - getY();
00124   return (atan2(dy, dx));
00125 }
00126 
00127 double Position::getRelZenith(Position* p)
00128 {
00129   assert(p);
00130   double dx = p->getX() - getX();
00131   double dy = p->getY() - getY();
00132   double dz = p->getZ() - getZ();
00133   return (atan(sqrt(dx*dx + dy*dy)/  dz));
00134 }
00135 
00136 void Position::setX(double x)
00137 {
00138         x_ = x;
00139 }
00140 
00141 void Position::setY(double y)
00142 {
00143         y_ = y;
00144 }
00145 
00146 
00147 void Position::setZ(double z)
00148 {
00149         z_ = z;
00150 }
00151 
00152 /* ======================================================================
00153    TCL Hooks for the simulator
00154    ====================================================================== */
00155 static class NodeCoreClass : public TclClass {
00156 public:
00157         NodeCoreClass() : TclClass("NodeCore") {}
00158         TclObject* create(int, const char*const*) {
00159                 return (new NodeCore());
00160         }
00161 } class_node_core;
00162 
00163 NodeCore::NodeCore() : crossLayerSAPlist_(0), nLayer_(-1), clsapPerLayer_(0), pluginLayer_(0), pluginIdInLayer_(0), pluginNum_(0), position_(0)
00164 {
00165         bind("battery_", &battery_);
00166 }
00167 
00168 NodeCore::~NodeCore()
00169 {
00170         for(int i = 0; i<nLayer_; i++)
00171         {
00172                 delete [] crossLayerSAPlist_[i];
00173         }
00174         delete [] crossLayerSAPlist_;
00175         delete [] clsapPerLayer_;
00176 }
00177 
00178 // retrun the current value of the battery
00179 void NodeCore::battery(double battery) 
00180 {
00181         battery_ = battery;
00182 }
00183 
00184 
00185 // function to add a new ClSAP in the requested level
00186 int NodeCore::addClSAP(ClSAP *clsap, int level)
00187 {
00188         if (level<0) return 0;
00189 //      printf("request to add a clsap at level %d (nLayer %d)\n",level,nLayer_);
00190         if (nLayer_<level)
00191         {
00192                 // the level requested is not yet implemented -> implement it (and, evetually
00193                 // the intermediates ones)
00194                 int *n = new int[level + 1];
00195                 for(int i = 0; i <= level; i++)
00196                 {
00197                         if(i<=nLayer_)
00198                                 n[i] = clsapPerLayer_[i];
00199                         else
00200                                 n[i] = 0;
00201                 }
00202                 if (clsapPerLayer_!=0)
00203                         delete [] clsapPerLayer_;
00204                 clsapPerLayer_ = n;
00205                 ClSAP*** temp = new ClSAP**[level + 1];
00206                 memset(temp, 0, sizeof(ClSAP**)*(level + 1));
00207                 nLayer_ = level;
00208                 for(int i = 0; i<=nLayer_; i++)
00209                 {
00210                         //if (i==level) clsapPerLayer_[i]++;
00211                         if (clsapPerLayer_[i]!=0 || i==level)
00212                         {
00213                                 if(i==level)
00214                                 {
00215                                         clsapPerLayer_[i]++;
00216                                         temp[i] = new ClSAP*[clsapPerLayer_[i]];
00217                                         for (int j = 0; i < clsapPerLayer_[i]-1; j++)
00218                                         {
00219                                                 temp[i][j] = crossLayerSAPlist_[i][j];
00220                                         }// end for on clsapPerLayer
00221                                         temp[i][clsapPerLayer_[i]-1] = clsap;
00222                                         if(clsapPerLayer_[i]-1 != 0)
00223                                                 delete [] crossLayerSAPlist_[i];
00224                                 }
00225                                 else
00226                                         temp[i] = crossLayerSAPlist_[i];
00227                         }
00228                         
00229                         
00230                 }// end for on layer
00231                 if (crossLayerSAPlist_!=0)
00232                         delete [] crossLayerSAPlist_;
00233                 crossLayerSAPlist_ = temp;
00234         }// end if getNLayer < level
00235         else
00236         {
00237                 ClSAP** temp = new ClSAP*[++clsapPerLayer_[level]];
00238                 for (int j = 0; j < clsapPerLayer_[level]-1; j++)
00239                 {
00240                         temp[j] = crossLayerSAPlist_[level][j];
00241                 }// end for on clsapPerLayer
00242                 temp[clsapPerLayer_[level]-1] = clsap;
00243                 delete [] crossLayerSAPlist_[level];
00244                 crossLayerSAPlist_[level] = temp;
00245         }
00246         int pluginId = clsap->getPluginId();
00247         // update pluginId to modules in node matrix structures
00248         if (pluginId>=pluginNum_)
00249         {
00250                 // have to resize the structure
00251                 int* temp1 = new int[pluginId+1];
00252                 memset(temp1, -1, sizeof(int)*(pluginId+1));
00253                 int* temp2 = new int[pluginId+1];
00254                 memset(temp2, -1, sizeof(int)*(pluginId+1));
00255                 if (pluginLayer_!=0)
00256                 {
00257                         for(int i=0; i<=pluginId; i++)
00258                         {
00259                                 temp1[i] = pluginLayer_[i];
00260                                 temp2[i] = pluginIdInLayer_[i];
00261                         }
00262                         delete [] pluginLayer_;
00263                         delete [] pluginIdInLayer_;
00264                 }
00265                 pluginLayer_ = temp1;
00266                 pluginIdInLayer_ = temp2;
00267                 pluginNum_ = pluginId;
00268         }
00269         pluginLayer_[pluginId] = level;
00270         pluginIdInLayer_[pluginId] = clsapPerLayer_[level]-1;
00271 //      printf("pluginIdInLayer_[%d]=%d\n",pluginId, clsapPerLayer_[level]);
00272         return 1;
00273 }
00274 
00275 
00276 // TCL command interpreter
00277 int NodeCore::command(int argc, const char*const* argv)
00278 {
00279         if (argc == 2)
00280         {
00281                 Tcl& tcl = Tcl::instance();
00282                 if(strcasecmp(argv[1], "position") == 0)
00283                 {
00284                         if(!position_)
00285                                 return TCL_ERROR;
00286                         tcl.result(position_->name());
00287                         return TCL_OK;
00288                 }
00289         }
00290         else if(argc ==3)
00291         {
00292                 Tcl& tcl = Tcl::instance();
00293                 if(strcasecmp(argv[1], "position") == 0)
00294                 {
00295                         position_ = dynamic_cast<Position*>(tcl.lookup(argv[2]));
00296                         if(!position_)
00297                                 return (TCL_ERROR);
00298                         return TCL_OK;
00299                 }
00300         }
00301         else if(argc==4)
00302         {
00303                 if(strcasecmp(argv[1], "addclsap") == 0)
00304                 {
00305                         ClSAP *clsap = dynamic_cast<ClSAP*>(TclObject::lookup(argv[2]));
00306                         int level = atoi(argv[3]);
00307                         if(!clsap || level < 0)
00308                                 return (TCL_ERROR);
00309                         if(addClSAP(clsap, level))
00310                                 return (TCL_OK);
00311                         return (TCL_ERROR);
00312                 }
00313         }
00314         return TclObject::command(argc, argv);
00315 }
00316 
00317 
00318 // send a cross-layer message to i-level j-module
00319 void NodeCore::sendClSAP(int level, int j, ClMessage *m)
00320 {
00321         crossLayerSAPlist_[level][j]->sendModule(m, 0);
00322 }
00323 
00324 // send a cross-layer message to i-level j-module
00325 void NodeCore::sendSynchronousClSAP(int level, int j, ClMessage *m)
00326 {
00327         crossLayerSAPlist_[level][j]->sendSynchronousModule(m);
00328 }
00329 
00330 // return the number of the layer current implemented
00331 int NodeCore::getNLayer()
00332 {
00333         return nLayer_;
00334 }
00335 
00336 // return the number of ClSAP installed at layer
00337 int NodeCore::getNClSAP(int layer)
00338 {
00339         return clsapPerLayer_[layer];
00340 }
00341 
00342 // return the j-plugin id at level indicated
00343 int NodeCore::getPluginID(int level, int j)
00344 {
00345         return crossLayerSAPlist_[level][j]->getPluginId();
00346 }
00347 
00348 // return the layer in which the module specified is installed
00349 int NodeCore::getLayer(int pluginId)
00350 {
00351         if ((pluginId<0)||(pluginId>pluginNum_)||(pluginLayer_[pluginId]<0))
00352         {
00353                 fprintf(stderr, "Error, NodeCore.getLayer: plugin specified does not exist\n");
00354                 exit(1);
00355         }
00356         return (pluginLayer_[pluginId]);
00357 }
00358 
00359 // return the id within a layer of the specified module
00360 int NodeCore::getIdInLayer(int pluginId)
00361 {
00362         if ((pluginId<0)||(pluginId>pluginNum_)||(pluginIdInLayer_[pluginId]<0))
00363         {
00364                 fprintf(stderr, "Error, NodeCore.getIdInLayer: plugin specified does not exist\n");
00365                 exit(1);
00366         }
00367         return (pluginIdInLayer_[pluginId]);
00368 }
00369 
00370 
00371 
00372 // cross layer message command interpreter
00373 int NodeCore::crLayCommand(ClMessage* m)
00374 {
00375         // send a clMessage to its destination
00376         int dest = m->getDest();
00377         int src = m->getSource();
00378         if(m->getDestType() == UNICAST)
00379         {
00380                 if ((dest<0)||(dest>pluginNum_))
00381                 {
00382                         cerr << __PRETTY_FUNCTION__ 
00383                              << " ClMsg dest (" << dest 
00384                              << ") does not exist, discarding message " << endl;
00385                         delete m;
00386                         return 1;
00387                 }
00388 
00389                 if (dest == src)
00390                 {
00391                         cerr << __PRETTY_FUNCTION__ 
00392                              << " ClMsg dest == src (" << dest 
00393                              << "), discarding message " << endl;
00394                         delete m;
00395                         return 1;
00396                 }
00397 
00398                 int layer = getLayer(dest);
00399                 int idLayer = getIdInLayer(dest);
00400                 sendClSAP(layer, idLayer, m->copy());
00401         
00402         }
00403         else
00404         {
00405                 /*
00406                 It is a broadcast message
00407                 */
00408                 if ((dest < 0 && dest != CLBROADCASTADDR)||(dest>nLayer_))
00409                 {
00410                         fprintf(stderr, "Error, NodeCore.crLayCommand: clMessage destination does not exist\n");
00411                         exit(1);
00412                 }
00413                 if(dest != CLBROADCASTADDR)
00414                 {
00415                         /*
00416                         We send the message to all the modules in layer dest
00417                         */
00418                         for(int j = 0; j < getNClSAP(dest); j++)
00419                                 if(getPluginID(dest, j) != src)
00420                                         sendClSAP(dest, j, m->copy());
00421                 }
00422                 else
00423                 {
00424                         /*
00425                         We send the message to all the modules
00426                         */
00427 //                      printf("send a broadcast clmsg nlayer %d\n ",getNLayer());
00428                         int i,j;
00429                         // layer 0 is the "plugin" layer, layers > 0 are ordinary layers                
00430                         for(i = 0; i <= getNLayer(); i++)
00431                         {
00432 //                              printf("nclasp %d\n",getNClSAP(i));
00433                                 for(j = 0; j < getNClSAP(i); j++)
00434                                 {
00435 //                                      printf("try with %d,%d id = %d (src=%i)\n",i,j,getPluginID(i, j), src);
00436                                         if(getPluginID(i, j) != src)
00437                                         {
00438                                                 sendClSAP(i, j, m->copy());
00439 //                                              printf("send to %d\n", getPluginID(i, j));
00440                                         }
00441                                 }
00442                         }
00443                 }
00444         }
00445         delete m;
00446         return 0;
00447 }
00448 
00449 // cross layer message command interpreter
00450 int NodeCore::synchronousCrLayCommand(ClMessage* m)
00451 {
00452         // send a clMessage to its destination
00453         int dest = m->getDest();
00454         if(m->getDestType() == UNICAST)
00455         {
00456                 if ((dest<0)||(dest>pluginNum_))
00457                 {
00458                         fprintf(stderr, "Error, NodeCore.crLayCommand: clMessage destination does not exist\n");
00459                         exit(1);
00460                 }
00461                 int layer = getLayer(dest);
00462                 int idLayer = getIdInLayer(dest);
00463                 sendSynchronousClSAP(layer, idLayer, m);
00464                 // OLD basic version: send to all the ClSAP installed on modules
00465         /*      for(int i = 1; i <= getNLayer(); i++)
00466                         for(int j = 0; j < getNClSAP(i); j++)
00467                                 sendClSAP(i, j, m->copy());*/
00468         
00469         }
00470         else
00471         {
00472                 /*
00473                 It is a broadcast message
00474                 */
00475                 if ((dest < 0 && dest != CLBROADCASTADDR)||(dest>nLayer_))
00476                 {
00477                         fprintf(stderr, "Error, NodeCore.crLayCommand: clMessage destination does not exist\n");
00478                         exit(1);
00479                 }
00480                 int src = m->getSource();
00481                 if(dest != CLBROADCASTADDR)
00482                 {
00483                         /*
00484                         We send the message to all the modules in layer dest
00485                         */
00486                         for(int j = 0; j < getNClSAP(dest); j++)
00487                                 if(getPluginID(dest, j) != src)
00488                                         sendSynchronousClSAP(dest, j, m);
00489                 }
00490                 else
00491                 {
00492                         /*
00493                         We send the message to all the modules
00494                         */
00495                   // fprintf(stderr,"%s send a broadcast clmsg nlayer %d\n ", __PRETTY_FUNCTION__, getNLayer());
00496                         int i,j;
00497 
00498                         // layer 0 is the "plugin" layer, layers > 0 are ordinary layers
00499                         for(i = 0; i <= getNLayer(); i++)
00500                         {
00501 //                              printf("nclasp %d\n",getNClSAP(i));
00502                                 for(j = 0; j < getNClSAP(i); j++)
00503                                 {
00504 //                                      printf("try with %d,%d id = %d (src=%i)\n",i,j,getPluginID(i, j), src);
00505                                         if(getPluginID(i, j) != src)
00506                                         {
00507                                           //fprintf(stderr, "%s send to %d\n", __PRETTY_FUNCTION__,  getPluginID(i, j));
00508                                                 sendSynchronousClSAP(i, j, m);
00509                                         }
00510                                 }
00511                         }
00512                 }
00513         }
00514         //delete m;
00515         return 1;
00516 }
00517 
00518 void NodeCore::handle(Event* e)
00519 {
00520         crLayCommand((ClMessage*)e);
00521 }
00522 
00523 Position *NodeCore::getPosition()
00524 {
00525         return position_;
00526 }

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2