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

📄 mac802_16.cc

📁 This documentation is based on the following versions:- pre-release of the wimax model developed by
💻 CC
📖 第 1 页 / 共 3 页
字号:
 */void Mac802_16::nextChannel (){  debug ("At %f in Mac %d Going to channel %d\n", NOW, index_, (phymib_.channel+1)%nbFreq);  setChannel ((phymib_.channel+1)%nbFreq);}/** * Add a flow * @param qos The QoS required * @param handler The entity that requires to add a flow */void Mac802_16::addFlow (ServiceFlowQoS * qos, void * handler) {}/** * Backup the state of the Mac */state_info* Mac802_16::backup_state (){  state_info *backup_state = (state_info*) malloc (sizeof (state_info));  backup_state->bs_id = bs_id_;  backup_state->state = state_;  backup_state->frameduration = getFrameDuration();  backup_state->frame_number = frame_number_;  backup_state->channel = getChannel();  backup_state->connectionManager = connectionManager_;  connectionManager_ = new ConnectionManager (this);  init_default_connections ();  backup_state->serviceFlowHandler = serviceFlowHandler_;  serviceFlowHandler_ = new ServiceFlowHandler();  backup_state->peer_list = peer_list_;  peer_list_ = (struct peerNode *) malloc (sizeof(struct peerNode));  LIST_INIT(peer_list_);  return backup_state;}/** * Restore the state of the Mac */void Mac802_16::restore_state (state_info *backup_state){  bs_id_ = backup_state->bs_id;  state_ = backup_state->state;  setFrameDuration(backup_state->frameduration);  frame_number_ = backup_state->frame_number;  setChannel (backup_state->channel);  delete (connectionManager_);  connectionManager_ = backup_state->connectionManager;  delete (serviceFlowHandler_);  serviceFlowHandler_ = backup_state->serviceFlowHandler;  while (getPeerNode_head()!=NULL) {    removePeerNode (getPeerNode_head());  }  peer_list_ = backup_state->peer_list;}  /** * Set the variable used to find out if upper layers * must be notified to send packets. During scanning we * do not want upper layers to send packet to the mac. */void Mac802_16::setNotify_upper (bool notify) {   notify_upper_ = notify;   if (notify_upper_ && pktBuf_) {    sendDown (pktBuf_);    pktBuf_ = NULL;  }}/**** Packet processing methods ****//* * Process packets going out * @param p The packet to send out */void Mac802_16::sendDown(Packet *p){  //We first send it through the CS  int cid = -1;  if (!notify_upper_) {    assert (!pktBuf_);    pktBuf_ = p;    return;  }   for (SDUClassifier *n=classifier_list_.lh_first; n && cid==-1; n=n->next_entry()) {    cid = n->classify (p);  }  if (cid == -1) {    debug ("At %f in Mac %d drop packet because no classification were found\n", \	    NOW, index_);    drop(p, "CID");    //Packet::free (p);  } else {    //enqueue the packet     Connection *connection = connectionManager_->get_connection (cid, type_ == STA_MN);    if (connection == NULL) {      debug ("Warning: At %f in Mac %d connection with cid = %d does not exist. Please check classifiers\n",\	      NOW, index_, cid);      //Packet::free (p);      update_watch (&loss_watch_, 1);      drop(p, "CID");    }    else {      if (connection->queueLength ()==macmib_.queue_length) {	//queue full 	update_watch (&loss_watch_, 1);	drop (p, "QWI");      } else {	//update mac header information	//set header information	hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p);	wimaxHdr->header.ht = 0;	wimaxHdr->header.ec = 1;	wimaxHdr->header.type = 0; //no subheader	wimaxHdr->header.ci = 0;	wimaxHdr->header.eks = 0;	wimaxHdr->header.cid = cid; //default	wimaxHdr->header.hcs = 0;	HDR_CMN(p)->size() += HDR_MAC802_16_SIZE;	HDR_CMN(p)->timestamp() = NOW; //set timestamp for delay	connection ->enqueue (p);	//printf ("At %f in Mac %d Enqueue packet to cid=%d queue size=%d(max=%d)\n", NOW, index_, cid,connection->queueLength (), macmib_.queue_length);      }    }  }  //inform upper layer that it can send another packet  //if (notify_upper_)   resume (NULL);  }/* * Transmit a packet to the physical layer * @param p The packet to send out */void Mac802_16::transmit(Packet *p){  if (NOW < last_tx_time_+last_tx_duration_) {    //still sending    //printf ("MAC is already transmitting. Drop packet.\n");    Packet::free (p);    return;  }  struct hdr_cmn *ch = HDR_CMN(p);  /*  debug ("At %f in Mac %d sending packet (type=%s, size=%d) ", NOW, index_, packet_info.name(ch->ptype()), ch->size());  if (ch->ptype()==PT_MAC) {    if (HDR_MAC802_16(p)->header.ht == 0)      debug ("mngt=%d\n", ((mac802_16_dl_map_frame*) p->accessdata())->type);    else      debug ("bwreq\n");  } else {    debug ("\n");  }  */  //update stats for delay and jitter  double delay = NOW-ch->timestamp();  update_watch (&delay_watch_, delay);  double jitter = fabs (delay - last_tx_delay_);  update_watch (&jitter_watch_, jitter);  last_tx_delay_ = delay;  if (ch->ptype()!=PT_MAC) {    update_throughput (&tx_data_watch_, 8*ch->size());  }   update_throughput (&tx_traffic_watch_, 8*ch->size());    last_tx_time_ = NOW;  last_tx_duration_ = ch->txtime();  downtarget_->recv (p, (Handler*)NULL);}/* * Process incoming packets * @param p The incoming packet */void Mac802_16::sendUp (Packet *p){  struct hdr_cmn *ch = HDR_CMN(p);#ifdef DEBUG_WIMAX  debug ("At %f in Mac %d receive first bit..over at %f(txtime=%f) (type=%s) ", NOW, index_, NOW+ch->txtime(),ch->txtime(), packet_info.name(ch->ptype()));  if (ch->ptype()==PT_MAC) {    if (HDR_MAC802_16(p)->header.ht == 0)      debug ("mngt=%d\n", ((mac802_16_dl_map_frame*) p->accessdata())->type);    else      debug ("bwreq\n");  } else {    debug ("\n");  }#endif  if (pktRx_ !=NULL) {    /*     *  If the power of the incoming packet is smaller than the     *  power of the packet currently being received by at least     *  the capture threshold, then we ignore the new packet.     */    if(pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) {      Packet::free(p);    } else {      /*       *  Since a collision has occurred, figure out       *  which packet that caused the collision will       *  "last" the longest.  Make this packet,       *  pktRx_ and reset the Recv Timer if necessary.       */      if(txtime(p) > rxTimer_.expire()) {	rxTimer_.stop();	//printf ("\t drop pktRx..collision\n");	drop(pktRx_, "COL");	update_watch (&loss_watch_, 1);	pktRx_ = p;	//mark the packet with error	ch->error() = 1;	collision_ = true;	rxTimer_.start(ch->txtime()-0.000000001);      }      else {	//printf ("\t drop new packet..collision\n");	drop(p, "COL");	//mark the packet with error	HDR_CMN(pktRx_)->error() = 1;	collision_ = true;      }    }    return;  }  assert (pktRx_==NULL);  assert (rxTimer_.busy()==0);  pktRx_ = p;  //create a timer to wait for the end of reception  //since the packets are received by burst, the beginning of the new packet   //is the same time as the end of this packet..we process this packet 1ns   //earlier to make room for the new packet.  rxTimer_.start(ch->txtime()-0.000000001);}/** * Process the fully received packet */void Mac802_16::receive (){  assert (pktRx_);  struct hdr_cmn *ch = HDR_CMN(pktRx_);#ifdef DEBUG_WIMAX  printf ("At %f in Mac %d packet received (type=%s) ", NOW, index_, packet_info.name(ch->ptype()));  if (ch->ptype()==PT_MAC) {    if (HDR_MAC802_16(pktRx_)->header.ht == 0)      printf ("mngt=%d\n", ((mac802_16_dl_map_frame*) pktRx_->accessdata())->type);    else      printf ("bwreq\n");  } else {    printf ("\n");  }#endif      //drop the packet if corrupted  if (ch->error()) {    if (collision_) {      //printf ("\t drop new pktRx..collision\n");      drop (pktRx_, "COL");      collision_ = false;    } else {      //error in the packet, the Mac does not process      Packet::free(pktRx_);    }    //update drop stat    update_watch (&loss_watch_, 1);    pktRx_ = NULL;    return;  }  //process packet  hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(pktRx_);  gen_mac_header_t header = wimaxHdr->header;  int cid = header.cid;  Connection *con = connectionManager_->get_connection (cid, type_==STA_BS);  mac802_16_dl_map_frame *frame;  if (con == NULL) {    //This packet is not for us    //printf ("At %f in Mac %d Connection null\n", NOW, index_);    update_watch (&loss_watch_, 1);    Packet::free(pktRx_);    pktRx_=NULL;    return;  }  //printf ("CID=%d\n", cid);  //update rx time of last packet received  PeerNode *peer;  if (type_ == STA_MN)    peer = getPeerNode_head(); //MN only has one peer  else    peer = con->getPeerNode(); //BS can have multiple peers  if (peer) {    peer->setRxTime (NOW);        //collect receive signal strength stats    peer->getStatWatch()->update(10*log10(pktRx_->txinfo_.RxPr*1e3));    //debug ("At %f in Mac %d weighted RXThresh: %e rxp average %e\n", NOW, index_, macmib_.lgd_factor_*macmib_.RXThreshold_, pow(10,peer->getStatWatch()->average()/10)/1e3);    double avg_w = pow(10,(peer->getStatWatch()->average()/10))/1e3;        if ( avg_w < (macmib_.lgd_factor_*macmib_.RXThreshold_)) {      if (!peer->isGoingDown () && type_ == STA_MN && state_==MAC802_16_CONNECTED) {	((SSscheduler*) scheduler_)->send_scan_request ();      }      peer->setGoingDown (true);      debug ("At %f Mac %d link going down trigger\n", NOW, index_);#ifdef USE_802_21      double probability = 1;      if(type_ == STA_MN) {	Mac::send_link_going_down (addr(), getPeerNode_head()->getPeerNode(), -1, (int)(100*probability), eventId_++);      } else {	Mac::send_link_going_down (peer->getPeerNode(), addr(), -1, (int)(100*probability), eventId_++);      }#endif    }    else {      if (peer->isGoingDown()) {#ifdef USE_802_21	Mac::send_link_rollback (addr(), eventId_-1);#endif	peer->setGoingDown (false);      }    }  }    //process reassembly  if (wimaxHdr->frag_subheader) {    bool drop_pkt = true;    //printf ("Frag type = %d\n",wimaxHdr->fc & 0x3);    switch (wimaxHdr->fc & 0x3) {    case FRAG_NOFRAG:       if (con->getFragmentationStatus()!=FRAG_NOFRAG)	con->updateFragmentation (FRAG_NOFRAG, 0, 0); //reset      drop_pkt = false;      break;     case FRAG_FIRST:       //when it is the first fragment, it does not matter if we previously      //received other fragments, since we reset the information      assert (wimaxHdr->fsn == 0);      //printf ("\tReceived first fragment\n");      con->updateFragmentation (FRAG_FIRST, 0, ch->size()-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE));      break;     case FRAG_CONT:       if ( (con->getFragmentationStatus()!=FRAG_FIRST	    && con->getFragmentationStatus()!=FRAG_CONT)	   || ((wimaxHdr->fsn&0x7) != (con->getFragmentNumber ()+1)%8) ) {	con->updateFragmentation (FRAG_NOFRAG, 0, 0); //reset      } else {	//printf ("\tReceived cont fragment\n");	con->updateFragmentation (FRAG_CONT, wimaxHdr->fsn&0x7, con->getFragmentBytes()+ch->size()-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE));	      }      break;     case FRAG_LAST:       if ( (con->getFragmentationStatus()==FRAG_FIRST	    || con->getFragmentationStatus()==FRAG_CONT)	   && ((wimaxHdr->fsn&0x7) == (con->getFragmentNumber ()+1)%8) ) {	//printf ("\tReceived last fragment\n");	ch->size() += con->getFragmentBytes()-HDR_MAC802_16_FRAGSUB_SIZE;	drop_pkt = false;      } else {	//printf ("Error with last frag seq=%d (expected=%d)\n", wimaxHdr->fsn&0x7, (con->getFragmentNumber ()+1)%8);      }           con->updateFragmentation (FRAG_NOFRAG, 0, 0); //reset      break;     default:      fprintf (stderr,"Error, unknown fragmentation type\n");      exit (-1);    }    //if we got an error, or it is a fragment that is not the last, free the packet    if (drop_pkt) {      //update drop stat      update_watch (&loss_watch_, 1);      Packet::free(pktRx_);      pktRx_=NULL;      return;    }   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -