📄 mac-802_16-base.cc
字号:
/*************************************************************************** * WiMAX module * * Copyright (C) 2008 Juliana Freitag Borin, Flavio Kubota and Nelson L. * S. da Fonseca - wimaxgroup@lrc.ic.unicamp.br * * This program is a free result: you can redistribute it and/or modify * it under the terms of the UOL Public License Version 1 or (at your * option) any later version. The license terms are available at * http://bolsapesquisa.uol.com.br/lpu.jhtm. * * This file contains methods for the base Mac802_16 class * * Revisions: * $A0: 4/2/03: we drop the packet here when a collision occurs... * $A1: 9/28/04: ClassifyDataMgt had a path where it returned garbage. * $A2: 3/28/05: match needed to look at PT_PING * $A3: 2/16/06: (J. Freitag) the node address was compared to the node id, * thus, the traffic did not match any connection and was * always assigned to the default conection. **************************************************************************//*! \file mac-802_16-base.cc This file contains methods for the base Mac802_16 class. */#include "mac-802_16.h"#include "mobilenode.h"//#define TRACE 0/*=============================Timer handlers=======================*//*************************************************************************Constructor function*************************************************************************//*! Constructor function */Mac802_16::Mac802_16() : Mac(), mhTxPkt_(this), mhRxPkt_(this){ avg_pkts = 0; avg_bytes = 0; num_pkts = 0; num_bytes = 0; last_rtime = 0.0; avg_mgmtpkts = 0; num_mgmtpkts = 0; last_mmgmttime = 0; /* Initial channel / transceiver states. */ tx_state_ = rx_state_ = MAC_IDLE; tx_active_ = 0; }/**************************************************************************************************************************************************/int Mac802_16::command(int argc, const char*const* argv){ if (argc == 7) { if (strcmp(argv[1],"configure-upstream")==0) { upchannel.data_rate = (double)atof(argv[2]); upchannel.data_rate /= 8; upchannel.physlots_p_minislot = (u_int16_t)atoi(argv[3]); upchannel.max_burst_size = (u_int32_t)atoi(argv[4]); upchannel.overhead_bytes = (u_int16_t)atoi(argv[5]); upchannel.prop_delay = atof(argv[6]);// upchannel.prop_delay = upchannel.prop_delay/1000000; upchannel.overhead_bytes /= 8;#ifdef TRACE //--------------------------------------------------------- printf("Upstream channel\n"); printf("data-rate (bytes/s)= %lf\n",upchannel.data_rate); printf("physlots = %d\n",upchannel.physlots_p_minislot); printf("max-burst = %d\n",upchannel.max_burst_size); printf("overhead = %d\n",upchannel.overhead_bytes); printf("prop_delay = %f\n",upchannel.prop_delay);#endif //--------------------------------------------------------------- configure_upstream(); return TCL_OK; } } else if (argc == 5) { if (strcmp(argv[1], "configure-downstream")==0) { downchannel.data_rate = (double)atof(argv[2]); downchannel.data_rate /= 8; downchannel.overhead_bytes = (u_int16_t)atoi(argv[3]); downchannel.prop_delay = atof(argv[4]);// downchannel.prop_delay = downchannel.prop_delay/1000000; downchannel.overhead_bytes /= 8;#ifdef TRACE //--------------------------------------------------------- printf("Downstream channel\n"); printf("data-rate (bytes/s) = %lf\n",downchannel.data_rate); printf("overhead = %d\n",downchannel.overhead_bytes); printf("prop_delay = %f\n",downchannel.prop_delay);#endif //--------------------------------------------------------------- return TCL_OK; } } return Mac::command(argc,argv);}/************************************************************************* To configure the mini-slot parameters*************************************************************************//*! To configure the mini-slot parameters*/void Mac802_16::configure_upstream(){ double n; int frsize; n = upchannel.physlots_p_minislot * 6.25; /*mini-slot duration (microseconds)*/ size_mslots = n / ((double)(10*10*10*10*10*10)); minislots_psec = (u_int32_t)((10*10*10*10*10*10)/n); //bytes_pminislot = //(u_int16_t)((upchannel.data_rate * size_mslots)/(10*10*10*10*10*10)); bytes_pminislot = (u_int16_t)(upchannel.data_rate * size_mslots); frsize = 6 + upchannel.overhead_bytes; size_ureqgrant = (frsize) / (bytes_pminislot); if (( frsize % bytes_pminislot) != 0) size_ureqgrant++;#ifdef TRACE //--------------------------------------------------------- printf("Slot details\n"); printf("size_mslots = %lf\n",size_mslots); printf("minislots_psec = %d\n",minislots_psec); printf("bytes_pminislot = %d (upchannel data rate:%f, size_mslots:%f\n\n", bytes_pminislot,upchannel.data_rate,size_mslots); printf("size_reqgrant %d\n",size_ureqgrant);#endif //---------------------------------------------------------------}/*************************************************************************Test if the channel is idle.*************************************************************************//*! Test if the channel is idle. */int Mac802_16::is_idle() { if(rx_state_ != MAC_IDLE) return 0; if(tx_state_ != MAC_IDLE) return 0; return 1;}/************************************************************************* To handle incoming packet.*************************************************************************//*! To handle incoming packet. */void Mac802_16::recv(Packet* p, Handler* h) { struct hdr_cmn *ch = HDR_CMN(p); /* Incoming packets from phy layer, send UP to ll layer. Now, it is in receiving mode. */ if (ch->direction() == hdr_cmn::UP) { #ifdef TRACE //--------------------------------------------------------- printf("802_16-Base:recv(%lf): sending packet up to LL \n", Scheduler::instance().clock());#endif //--------------------------------------------------------------- sendUp(p); return; } /* Packets coming down from ll layer (from ifq actually), send them to phy layer. Now, it is in transmitting mode. */ #ifdef TRACE //--------------------------------------------------------- printf("\n802_16-Base:recv(%lf): sending packet down to PHY \n", Scheduler::instance().clock());#endif //--------------------------------------------------------------- callback_ = h; sendDown(p); /*Let SS and BS decide inside sendDown() whether they want to unlock IFQ or not */ return;}/**************************************************************************************************************************************************/void Mac802_16::recvHandler(Event *e) { u_int32_t dst, src; int size; SET_RX_STATE(MAC_IDLE); /* Now forward packet upwards. */#ifdef TRACE //--------------------------------------------------------- printf("802_16-Base:recvHandler(%lf): Invoke RecvFrame ... \n", Scheduler::instance().clock());#endif //--------------------------------------------------------------- if (!collision) /* No collision while rx this pkt */ RecvFrame(pktRx_,0); else { //$A0 NO need to count this as a drop as the SS will treat it as a collision#ifdef TRACE //------------------------------------------------------------------ printf("802_16-Base:recvHandler(%lf):collision occured... drop frame ... \n", Scheduler::instance().clock());#endif //------------------------------------------------------------------------- Packet::free(pktRx_); pktRx_ = 0; collision = 0; } /* Classify will be called from receive frame functions of SS and BS respectively*/}/**************************************************************************************************************************************************/void Mac802_16::sendHandler(Event *e) { SET_TX_STATE(MAC_IDLE); Packet::free((Packet *)e); /* unlock IFQ. */ if(callback_) { Handler *h = callback_; callback_ = 0; h->handle((Event*) 0); } } /*************************************************************************This returns a 0 if this frame contains dataelse it returns a 1 in which case it contains a MAC specific header (i.e., request)*************************************************************************//*!This returns a 0 if this frame contains dataelse it returns a 1 in which case it contains a MAC specific header (i.e., request)*/char Mac802_16::ClassifyDataMgmt(Packet* p){ struct hdr_mac802_16 *ds = HDR_MAC802_16(p); if (ds->dshdr_.fc_type == 0) { return 0; } else if (ds->dshdr_.fc_type == 3) { return 1; } //$A1 return 1;}/**************************************************************************************************************************************************/int Mac802_16::match(Packet* p, struct flow_classifier cl){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *chip = HDR_IP(p);#ifdef TRACE printf("match:(%lf): Packet type = %d src-ip = %d dst-ip = %d(PT_UDP:%d, PT_CBR:%d)\n", Scheduler::instance().clock(), ch->ptype(),chip->saddr(),chip->daddr(),PT_UDP,PT_CBR);#endif //$A2 //First make sure it's one of these packet types... if ((ch->ptype() == PT_UDP) || (ch->ptype() == PT_TCP) || (ch->ptype() == PT_HTTP) || (ch->ptype() == PT_PING) || (ch->ptype() == PT_RTP) || (ch->ptype() == PT_CBR) || (ch->ptype() == PT_EXP) || (ch->ptype() == PT_VOIP_EVRC) || (ch->ptype() == PT_ACK)) {#ifdef TRACE printf("match: Try to match pkt: (src,dst,type):%d,%d,%d) with flow %d,%d,%d\n", chip->saddr(), chip->daddr(), ch->ptype(), cl.src_ip,cl.dst_ip,cl.pkt_type);#endif //$A3 Node* node_src = Node::get_node_by_address(chip->saddr()); Node* node_dst = Node::get_node_by_address(chip->daddr()); if ((ch->ptype() == cl.pkt_type) && (node_src->nodeid() == cl.src_ip) && (node_dst->nodeid() == cl.dst_ip)) return 1; else return 0; } return 0;}/**************************************************************************************************************************************************/int Mac802_16::bit_on(u_char flag, int pos){ switch(pos) { case FRAG_ENABLE_BIT: if (flag & 128) return 1; else return 0; break; case CONCAT_ENABLE_BIT: if (flag & 64) return 1; else return 0; break; case FRAG_ON_BIT: if (flag & 32) return 1; else return 0; break; case CONCAT_ON_BIT: if (flag & 16) return 1; else return 0; break; case PIGGY_ENABLE_BIT: if (flag & 8) return 1; else return 0; break; case NO_PIGGY_BIT: if (flag & 4) return 1; else return 0; break; case PIGGY_NOT_SEND: if (flag & 2) return 1; else return 0; break; }}/**************************************************************************************************************************************************/void Mac802_16::set_bit(u_char * flag, int pos, int op){ switch (pos) { case FRAG_ENABLE_BIT: if (op == ON) *flag |= 128; else *flag &= 127; break; case CONCAT_ENABLE_BIT: if (op == ON) *flag |= 64; else *flag &= 191; break; case FRAG_ON_BIT: if (op == ON) *flag |= 32; else *flag &= 223; break; case CONCAT_ON_BIT: if (op == ON) *flag |= 16; else *flag &= 239; break; case PIGGY_ENABLE_BIT: if (op == ON) *flag |= 8; else *flag &= 247; break; case NO_PIGGY_BIT: if (op == ON) *flag |= 4; else *flag &= 251; break; case PIGGY_NOT_SEND: if (op == ON) *flag |= 2; else *flag &= 253; break; }}/**************************************************************************************************************************************************/Packet* Mac802_16::AllocPkt(int n){ Packet* q = Packet::alloc(); if (n > 0) q->allocdata(n); return q;}/**************************************************************************************************************************************************/ double Mac802_16::TX_Time(Packet* p, int dir){ struct hdr_cmn *ch = HDR_CMN(p); double t; if (dir == UPSTREAM) t = (double)((double)ch->size()/upchannel.data_rate); else t = (double)((double)ch->size()/downchannel.data_rate); return t;}/**************************************************************************************************************************************************/void Mac802_16::dump_pkt(Packet* p){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *chip = HDR_IP(p); printf("Packet header:\n"); printf("Src-ip = %d Dst-ip = %d Pkt-type = %d Pkt-size = %d\n", chip->saddr(),chip->daddr(),ch->ptype(),ch->size());}/*************************************************************************Calculate bs raised to in*************************************************************************//*! Calculate bs raised to in */u_int32_t Mac802_16::power(u_int32_t bs, u_int32_t in){ u_int32_t product = 1; for (int i = 0; i < in; i++) product *= bs; return product;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -