mac-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"mac-module.h"
00031 #include"umts-phy.h"
00032 #include"umts-headers.h"
00033 #include"umts-packet.h"
00034 #include<iostream>
00035 
00036 class ModuleUmtsMacClass : public TclClass {
00037 public:
00038         ModuleUmtsMacClass() : TclClass("Module/UMTS/MAC") {}
00039         TclObject* create(int, const char*const*) {
00040         return (new UmtsMacModule());
00041         }
00042 } class_module_umts_mac;
00043 
00044 
00045 UmtsMacModule::UmtsMacModule() 
00046   : tx_timer(this),
00047     initslotoffset_(-1)
00048 {
00049   bind("src_rlc_id_",&src_rlc_id_);
00050   bind("dst_rlc_id_",&dst_rlc_id_);
00051   bind("me_code_id_",&me_code_id_);
00052   bind("slot_duration_",&slot_duration_);
00053   bind("TTI_PDUs_",&TTI_PDUs_);
00054   bind("TTI_",&TTI_);
00055   bind("interleaving_",&interleaving_);
00056   bind("initslotoffset_",&initslotoffset_);
00057 
00058 }
00059 
00060 
00061 
00062 UmtsMacModule::~UmtsMacModule()
00063 {
00064 
00065 
00066 }
00067 
00068 
00069 int UmtsMacModule::command (int argc, const char *const *argv)
00070 {
00071 
00072 
00073   Tcl& tcl = Tcl::instance();
00074   
00075   if(argc == 2)
00076     {
00077       if (strcasecmp(argv[1],"start")==0)
00078         {         
00079           assert(initslotoffset_>0);
00080           Scheduler::instance().schedule(&tx_timer, &tx_event, initslotoffset_ * slot_duration_);                   
00081           return TCL_OK;               
00082         }
00083 
00084     }
00085   else if(argc == 3)
00086     {
00087       
00088   //     if (strcasecmp(argv[1],"setDestRlcId")==0)
00089 //      {
00090 //        int id = atoi(argv[2]);
00091 //        assert(id>0);
00092 //        dst_rlc_id_ = id;
00093 //        return TCL_OK;               
00094 //      }
00095 //       if (strcasecmp(argv[1],"setSrcRlcId")==0)
00096 //      {
00097 //        int id = atoi(argv[2]);
00098 //        assert(id>0);
00099 //        src_rlc_id_ = id;
00100 //        return TCL_OK;               
00101 //      }
00102     }
00103       
00104   /* If command is unknown, fallback to parent command intepreter */      
00105   return  Module::command(argc,argv);
00106   
00107 }
00108 
00109 
00110 
00111 
00112 void UmtsMacModule::recv(Packet* p)
00113 {
00114   hdr_cmn *ch = HDR_CMN(p);
00115   hdr_rlc *rh = HDR_RLC(p);
00116   hdr_umtsphy* uh = HDR_UMTSPHY(p);
00117 
00118 
00119   if (ch->direction() == hdr_cmn::UP) 
00120     {
00121       assert(src_rlc_id_>0);  // Fails if MAC not initialized
00122       // discarding packets going UP which are not for the RCL connected to this MAC
00123       if (rh->dst_rlc_id_ != src_rlc_id_)
00124         {
00125           //      drop(p, 10, "NFM");
00126           Packet::free(p);
00127           return;
00128         }
00129 
00130         if (uh->data==FALSE)
00131         {
00132                 //discard packet without data, used only to exchange control signalling (i.e., power control commands)
00133                 Packet::free(p);
00134                 return;
00135         }
00136       // discarding packets going UP which have not been received correctly
00137       if (ch->error())
00138         {
00139           if (debug_) 
00140             std::cerr << "UmtsMacModule::recv(p) packet with errors" << std::endl;      
00141           
00142           drop(p, 1, "ERR");
00143           return;
00144         }
00145       sendUp(p);
00146     }
00147   else
00148     {
00149       assert(ch->direction() == hdr_cmn::DOWN); 
00150       assert(dst_rlc_id_>0);  // Fails if MAC not initialized
00151       // discarding packets going DOWN which are not for the peer RLC
00152       // connected to the RCL connected above this MAC
00153       if (rh->dst_rlc_id_ != dst_rlc_id_)
00154         {
00155           //      drop(p, 10, "NFM");
00156           Packet::free(p);
00157           return;
00158         }
00159      
00160       schedule(p);
00161     }
00162 
00163 }
00164 
00165 
00166 
00167 void UmtsMacModule::schedule(Packet* p)
00168 {
00171   assert(Q.size() < 2*TTI_PDUs_);
00172   Q.push(p);
00173 }
00174 
00175 
00176 
00177 void UmtsMacModule::transmit()
00178 {
00179         Packet* p;
00180         bool data = false;
00181         if (! Q.empty())
00182         {
00183                 // has a PDU to trasmit
00184                 p = Q.front();
00185                 hdr_MPhy*    ph = HDR_MPHY(p);
00186                 hdr_umtsphy* uh = HDR_UMTSPHY(p);
00187                 uh->data = true;
00188                 uh->powerUp = true;
00189                 Q.pop();
00190                 sendDown(p, interleaving_);
00191         }else{
00192                 // does not have any SDU to transmit -> tx an empty packet to 
00193                 // simulate control channel parameters transmission
00194                 p = Packet::alloc();
00195                 hdr_cmn* ch = hdr_cmn::access(p);
00196                 ch->ptype() = PT_UMTSCTRL;
00197                 ch->size() = CNTRL_PKT_SIZE;            // non influential, i.e., the phy send the packet within the whole frame anyway
00198                 hdr_rlc *rh = HDR_RLC(p);
00199                 rh->dst_rlc_id_ = dst_rlc_id_;
00200                 rh->src_rlc_id_ = src_rlc_id_;
00201                 hdr_umtsphy* uh = HDR_UMTSPHY(p);
00202                 uh->me_code_id = me_code_id_;
00203                 hdr_MPhy*    ph = HDR_MPHY(p);
00204                 uh->data = false;
00205                 uh->powerUp = true;
00206                 sendDown(p, interleaving_);
00207         }
00208         
00209         // Schedule next transmission slot
00210         Scheduler::instance().schedule(&tx_timer, &tx_event, slot_duration_);
00211 }
00212 
00213 
00214 
00215 
00216 
00217 
00218 void UmtsMacTimer::handle(Event*)
00219 {
00220   mac->transmit(); 
00221 }

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