?? mac-gprs.cc
字號:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* By Richa Jain, * Indian Institute of Technology, Bombay. * June, 2001.*/ /* Copyright (c) 2001 Indian Insitute of Technology, Bombay. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code and binary code must contain * the above copyright notice, this list of conditions and the following * disclaimer. * * 2. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed at Indian Insitute of * Technology, Bombay. * * 3. The name of the Institute may not be used to endorse or promote * products derived from this software without specific prior written * permission. * INDIAN INSTITUTE OF TECHNOLOGY, BOMBAY, MAKES NO REPRESENTATIONS * CONCERNING EITHER THE MERCHANTABILITY OF THIS SOFTWARE OR THE * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software * is provided "as is" without express or implied warranty of any kind.*//* A special slotted Aloha based MAC for GPRS/GSM */ #include "delay.h"#include "connector.h"#include "packet.h"#include "random.h"#include "mobilenode.h"#include "address.h" // #define DEBUG//#include <debug.h>#include "arp.h"#include "ll.h"#include "rlc.h"#include "queue.h" #include "mac.h"#include "mac-gprs.h"#include "cmu-trace.h"/* Phy specs similar to 802.11 */static PHY_MIB PMIB = { DSSS_CWMin, DSSS_CWMax, DSSS_SlotTime, DSSS_CCATime, DSSS_RxTxTurnaroundTime, DSSS_SIFSTime, DSSS_PreambleLength, DSSS_PLCPHeaderLength}; /* Timers */void MacGprsTimer::start(Packet *p, double time){ Scheduler &s = Scheduler::instance(); assert(busy_ == 0); busy_ = 1; paused_ = 0; stime = s.clock(); rtime = time; assert(rtime >= 0.0); s.schedule(this, p, rtime);}void MacGprsTimer::stop(Packet *p) { Scheduler &s = Scheduler::instance(); assert(busy_); if(paused_ == 0) s.cancel((Event *)p); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void BackoffGprsTimer::start(double time){ Scheduler &s = Scheduler::instance(); assert(busy_ == 0); busy_ = 1; paused_ = 0; stime = s.clock(); rtime = time; assert(rtime >= 0.0); s.schedule(this, &intr, rtime); } void BackoffGprsTimer::stop(void) { Scheduler &s = Scheduler::instance(); assert(busy_); if(paused_ == 0) s.cancel(&intr); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void BackoffGprsTimer::handle(Event *e){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->backoffHandler();} void SlotReleaseTimer::start(double time){ Scheduler &s = Scheduler::instance(); assert(busy_ == 0); busy_ = 1; paused_ = 0; stime = s.clock(); rtime = time; assert(rtime >= 0.0); s.schedule(this, &intr, rtime); } void SlotReleaseTimer::stop(void) { Scheduler &s = Scheduler::instance(); assert(busy_); if(paused_ == 0) s.cancel(&intr); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void SlotReleaseTimer::handle(Event *e){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->releaseHandler();}void WaitTimer::start(double time){ Scheduler &s = Scheduler::instance(); assert(busy_ == 0); busy_ = 1; paused_ = 0; stime = s.clock(); rtime = time; assert(rtime >= 0.0); s.schedule(this, &intr, rtime); } void WaitTimer::stop(void) { Scheduler &s = Scheduler::instance(); assert(busy_); if(paused_ == 0) s.cancel(&intr); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void WaitTimer::handle(Event *e){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->waitHandler();}/* Slot timer for TDMA scheduling - the downslot */void DownSlotGprsTimer::handle(Event *e){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->downslotHandler(e);}void UpSlotGprsTimer::handle(Event *e){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->upslotHandler(e);}/* Receive Timer */void RxPktGprsTimer::handle(Event *e) { busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->recvHandler(e);}/* Send Timer */void TxPktGprsTimer::handle(Event *e) { busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; mac->sendHandler(e);}/* ====================================================================== TCL Hooks for the simulator ====================================================================== */static class MacGprsClass : public TclClass {public: MacGprsClass() : TclClass("Mac/Gprs") {} TclObject* create(int, const char*const*) { return (new MacGprs(&PMIB)); }} class_mac_gprs;//for the static variables:Packet * MacGprs::rxQ[MAX_NUM_FREQ][SLOTS_PER_FRAME]={NULL};Packet * MacGprs::txQ[MAX_NUM_FREQ][SLOTS_PER_FRAME]={NULL}; struct data_at_bs MacGprs::vlr_ = {0};int MacGprs:: tx_rate = {0};int MacGprs:: max_num_ms_ = {0};int MacGprs:: max_num_freq_ = {0};int MacGprs:: slot_packet_len_ = {0};int MacGprs:: gprs_slots_per_frame_ = {0};double MacGprs::slot_time_ = 0;double MacGprs::start_time_ = 0;int MacGprs::chan0_0 = {0};int MacGprs::coll_count = {0}; int MacGprs::active_node_ = {0};int MacGprs::verbose_ = {0};//static variables for rlc_errorint MacGprs::rlc_error_ ={0};int MacGprs::error_rate_ ={0};int MacGprs::drop_gap_ ={0};int MacGprs::drop_counter_ ={0};int MacGprs::next_drop_ ={0};//constructorMacGprs::MacGprs(PHY_MIB* p) : Mac(), mhDownSlot_(this), mhUpSlot_(this), mhTxPkt_(this), mhRxPkt_(this), mhRel_(this), mhBackoff_(this),mhwait_(this){ int i,j; phymib_ = p; bind("slot_packet_len_", &slot_packet_len_); bind("max_num_ms_", &max_num_ms_); bind("max_num_freq_", &max_num_freq_); bind("gprs_", &gprs_); bind("verbose_", &verbose_); bind("gprs_slots_per_frame_", &gprs_slots_per_frame_); bind("rlc_error_", &rlc_error_); bind("error_rate_", &error_rate_); slot_time_= 0.000577 ;//gprs slot is of 576.9 microseconds tx_rate = (int) ((8*slot_packet_len_) / slot_time_) ; //printf("slot_time=%f, gprs_=%d tx_rate=%d \n", slot_time_, gprs_, tx_rate); active_node_++; //max_num_ms shud be less that MAX_NUM_MS if (max_num_ms_ > MAX_NUM_MS) { if (verbose_==1) printf("Too many nodes taking part. shud be less than %d \n", MAX_NUM_MS); exit (-1); } if (active_node_ > max_num_ms_) { if (verbose_==1) printf("Too many nodes taking part in the simulations, aborting...\n"); exit(-1); } radio_active_ = 0; wait_for_res=0; first_round_=1; down_slot_=0; up_slot_=0; for ( j=0 ; j< SLOTS_PER_FRAME ; j++) { pktTx[j] =NULL; pktRx[j] =NULL; tx_chan[j] = -10; rx_chan[j] = -10; //-10 => no channel } tx_chan[0]=0; // freq 0, slot 0 reserved. for broadcasts/isgnalling rx_chan[0]=0; // in either direction. txQ[0][0]=0; temp_reply=0; // initialising data_at_bs for ( j=0; j<max_num_ms_ ; j++) { vlr_.hier_addr_[j]=-10; } for ( j=0; j<SLOTS_PER_FRAME ; j++) { for (i=0; i<max_num_freq_ ; i++) { //this freq/slot hasnt been alloted to any MS yet vlr_.up_table[i][j]=-10; vlr_.down_table[i][j]=-10; } } if (rlc_error_==1 && index_==0) { drop_gap_ = Random::integer(error_rate_); next_drop_ = drop_gap_; if (verbose_==1) printf("<%d> %f first drop will be at %d \n", index_, NOW, next_drop_ ); } if (verbose_==1) printf("<%d> %f initialised...; \n",index_, NOW); intr1_ = intr_ ; //reqd for the slot timers intr = intr_ ; mhDownSlot_.start((Packet *) (& intr_), 0); }// similar to 802.11int MacGprs::command(int argc, const char*const* argv){ if (argc == 3) { if (strcmp(argv[1], "log-target") == 0) { logtarget_ = (NsObject*) TclObject::lookup(argv[2]); if(logtarget_ == 0) return TCL_ERROR; return TCL_OK; } } return Mac::command(argc, argv);}/* ====================================================================== Debugging Routines ====================================================================== */void MacGprs::trace_pkt(Packet *p) { struct hdr_cmn *ch = HDR_CMN(p); struct hdr_mac_gprs* dh = HDR_MAC_GPRS(p); u_int16_t *t = (u_int16_t*) &dh->dh_fc; fprintf(stderr, "\t[ %2x %2x %2x %2x ] %x %s %d\n", *t, dh->dh_duration, ETHER_ADDR(dh->dh_da), ETHER_ADDR(dh->dh_sa), index_, packet_info.name(ch->ptype()), ch->size());}void MacGprs::dump(char *fname){ fprintf(stderr, "\n%s --- (INDEX: %d, time: %2.9f)\n", fname, index_, Scheduler::instance().clock()); fprintf(stderr, "\tpktTx_: %x, pktRx_: %x, callback: %x\n", (int) pktTx_, (int) pktRx_, (int) callback_);}/* ====================================================================== Packet Headers Routines ====================================================================== */int MacGprs::hdr_dst(char* hdr, int dst ){ struct hdr_mac_gprs *dh = (struct hdr_mac_gprs*) hdr; if(dst > -2) STORE4BYTE(&dst, (dh->dh_da)); return ETHER_ADDR(dh->dh_da);}int MacGprs::hdr_src(char* hdr, int src ){ struct hdr_mac_gprs *dh = (struct hdr_mac_gprs*) hdr; if(src > -2) STORE4BYTE(&src, (dh->dh_sa)); return ETHER_ADDR(dh->dh_sa);}int MacGprs::hdr_type(char* hdr, u_int16_t type) { struct hdr_mac_gprs *dh = (struct hdr_mac_gprs*) hdr; if(type) STORE2BYTE(&type,(dh->dh_body)); return GET2BYTE(dh->dh_body);}/*double DATA_Time(int len) { double return (8*(len) / tx_rate);} */ double MacGprs::TX_Time(Packet *p) { int len= (HDR_CMN(p))->size(); double t = (double)(len*8)/tx_rate;// printf("< >, %f len=%d tx_time = %f \n", NOW,len, t); if(t < 0.0) { drop(p, "XXX"); exit(1); } return t;} /* Resource allocation:*/void MacGprs::slot_allot( int ms_, int &freq, int &slot){ // Allocation is sequential - first empty slot is alloted. int i,j; start_time_ = NOW; if (gprs_==1) { //ie its a gprs node //fnd the first free slot/freq for ( i=0; i<max_num_freq_ ; i++) { for ( j=1; j<(gprs_slots_per_frame_+1) ; j++){ //slot0 resv for signalling on ALL freqs if (vlr_.up_table[i][j] == -10) { //ie this slot's not been alloted to anyone break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -