rlc-module.cc

00001 /*
00002  * Copyright (c) 2007 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 
00030 #include"rlc-module.h"
00031 #include<iostream>
00032 
00033 class ModuleRlcClass : public TclClass {
00034 public:
00035         ModuleRlcClass() : TclClass("Module/UMTS/RLC") {}
00036         TclObject* create(int, const char*const*) {
00037         return (new RlcModule());
00038         }
00039 } class_module_rlc;
00040 
00041 
00042 RlcModule::RlcModule() 
00043 {
00044   rlc_id_counter++;
00045   rlc_id_ = rlc_id_counter;
00046   bind("ipAddr_",&ipAddr_);
00047   bind("destIpAddr_",&destIpAddr_);
00048 }
00049 
00050 
00051 
00052 RlcModule::~RlcModule()
00053 {
00054 
00055 
00056 }
00057 
00058 
00059 int RlcModule::rlc_id_counter = 0;
00060 
00061 
00062 int RlcModule::command (int argc, const char *const *argv)
00063 {
00064 
00065 
00066   Tcl& tcl = Tcl::instance();
00067   
00068   if(argc == 2)
00069     {
00070       if (strcasecmp(argv[1],"getRlcId")==0)
00071         {
00072           tcl.resultf("%d",rlc_id_);
00073           return TCL_OK;               
00074         }
00075       if (strcasecmp(argv[1],"getRlc")==0)
00076         {
00077           if(rlc_)
00078             {
00079             tcl.result(rlc_->name());
00080             return TCL_OK;
00081             }
00082           else return TCL_ERROR;            
00083         }
00084     }
00085   else if(argc == 3)
00086     {
00087       if(strcasecmp(argv[1], "setRlc")==0)
00088         {
00089           rlc_ = dynamic_cast<RLC*>(TclObject::lookup(argv[2]));
00090             
00091           if(!rlc_) 
00092             return TCL_ERROR;
00093 
00094           tcl.evalf("%s down-target %s",rlc_->name(), name());    
00095           tcl.evalf("%s up-target %s",rlc_->name(), name());      
00096           
00097           return TCL_OK;                  
00098         }
00099       if (strcasecmp(argv[1],"setDestRlcId")==0)
00100         {
00101           int id = atoi(argv[2]);
00102           assert(id>0);
00103           assert(id<=rlc_id_counter);
00104           assert(id != rlc_id_);
00105           dst_rlc_id_ = id;
00106           return TCL_OK;               
00107         }
00108       if (strcasecmp(argv[1],"setMeCodeId")==0)
00109         {
00110           int id = atoi(argv[2]);
00111           me_code_id_ = id;
00112           return TCL_OK;               
00113         }
00114     }
00115       
00116   /* If command is unknown, fallback to parent command intepreter */      
00117   return  Module::command(argc,argv);
00118   
00119 }
00120 
00121 
00122 
00123 
00124 void RlcModule::recv(Packet* p)
00125 {
00126         hdr_cmn *ch = HDR_CMN(p);
00127         hdr_rlc *rh = HDR_RLC(p);
00128         hdr_ip *iph = HDR_IP(p);
00129         if (ch->direction() == hdr_cmn::UP) 
00130         {
00131                 // discarding packets going UP which are not for this RLC
00132                 if (rh->dst_rlc_id_ != rlc_id_)
00133                 {
00134                 //        drop(p, 10, "NFM");
00135                         Packet::free(p);
00136                         return;
00137                 }
00138                 // discarding packets going UP which have not been received correctly
00139                 if (ch->error())
00140                         {
00141                         if (debug_) 
00142                                 std::cerr << "RlcModule::recv(p,h) packet with errors" << std::endl;      
00143                         
00144                         drop(p, 1, "ERR");
00145                         return;
00146                 }
00147         }
00148         if (ch->direction() == hdr_cmn::DOWN)
00149         {
00150                 // discarding packets going DOWN which are not for the destination
00151                 if ((iph->daddr() != destIpAddr_)
00152                     &&(ch->next_hop_ != destIpAddr_)
00153                     &&(iph->daddr() != IP_BROADCAST))
00154                 {
00155                   //drop(p, 10, "NFM");
00156                   if (debug_>1)
00157                     cerr << NOW << "RlcModule::recv()" 
00158                          << " iph->daddr()=" << iph->daddr()
00159                          << " ch->next_hop_=" << ch->next_hop_
00160                          << " destIpAddr_=" << destIpAddr_
00161                          << endl;
00162                   Packet::free(p);
00163                   return;
00164                 }
00165         }
00166 //      if (ch->direction() == hdr_cmn::DOWN)
00167 //              printf("RlcModule::recv(p) DOWN myIp %d daddr %d destIpAddr_ %d\n", ipAddr_, iph->daddr(), destIpAddr_);
00168 //      else
00169 //              printf("RlcModule::recv(p) UP myIp %d daddr %d destIpAddr_ %d\n", ipAddr_, iph->daddr(), destIpAddr_);
00170 
00171         if (debug_>1) std::cerr << "RlcModule::recv(p) Received Packet " << std::endl;
00172 
00173         assert(rlc_);
00174 
00175         // this is called for packets going both UP and DOWN
00176         // since RLC is able to distinguish packet direction
00177         rlc_->recv(p, (Handler*) 0);
00178 }
00179 
00180 
00181 
00182 
00183 
00195 void RlcModule::recv(Packet* p, Handler* callback)
00196 {
00197   hdr_cmn *ch = HDR_CMN(p);
00198   hdr_rlc *rh = HDR_RLC(p);
00199   hdr_umtsphy *uh = HDR_UMTSPHY(p);
00200 
00201   if(ch->direction() == hdr_cmn::DOWN)
00202     {
00203 
00204       rh->src_rlc_id_ = rlc_id_;
00205       assert(dst_rlc_id_>0);  // Fails if RLC is not connected
00206       rh->dst_rlc_id_ = dst_rlc_id_;
00207 
00208       uh->me_code_id = me_code_id_; // Only useful if we're the BS
00209       
00210       if (debug_>1) std::cerr << "RlcModule::recv(p,h) Forwarding packet to lower modules" << std::endl;
00211       uh->data = TRUE;
00212       sendDown(p);
00213     }
00214   else 
00215     {  
00216       assert(ch->direction() == hdr_cmn::UP);
00217         
00218       if (debug_>1) std::cerr << "RlcModule::recv(p,h) Forwarding packet to upper modules" << std::endl;
00219       sendUp(p);
00220         
00221     }
00222 }
00223 
00224 AM* RlcModule::getAM()
00225 {
00226   AM* ptr = dynamic_cast<AM*>(rlc_);
00227   assert(ptr); /* fails if rlc_ is not an AM RLC */
00228   return ptr;
00229 }
00230 
00231 int RlcModule::getTotPDUs()
00232 {
00233   return (getAM()->getTotPDUs());
00234 }
00235 
00236 int RlcModule::getErrPDUs()
00237 {
00238   return (getAM()->getErrPDUs());
00239 }
00240 
00241 int RlcModule::getAckPDUs()
00242 {
00243   return (getAM()->getAckPDUs());
00244 }
00245 
00246 int RlcModule::getAckSDUs()
00247 {
00248   return (getAM()->getAckSDUs());
00249 }
00250 
00251 int RlcModule::getDropPDUs()
00252 {
00253   return (getAM()->getDropPDUs());
00254 }
00255 
00256 int RlcModule::getDropSDUs()
00257 {
00258   return (getAM()->getDropSDUs());
00259 }
00260 
00261 

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