⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac-802_16-base.cc

📁 OPNET 中的Wimax模块, 主要用于wimax 无线网络仿真,以及普通无线网络仿真.
💻 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 + -