00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 }
00103
00104
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);
00122
00123 if (rh->dst_rlc_id_ != src_rlc_id_)
00124 {
00125
00126 Packet::free(p);
00127 return;
00128 }
00129
00130 if (uh->data==FALSE)
00131 {
00132
00133 Packet::free(p);
00134 return;
00135 }
00136
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);
00151
00152
00153 if (rh->dst_rlc_id_ != dst_rlc_id_)
00154 {
00155
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
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
00193
00194 p = Packet::alloc();
00195 hdr_cmn* ch = hdr_cmn::access(p);
00196 ch->ptype() = PT_UMTSCTRL;
00197 ch->size() = CNTRL_PKT_SIZE;
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
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 }