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

📄 bcast_mac.h

📁 大名鼎鼎的传感器网络仿真实验室平台SENSE
💻 H
📖 第 1 页 / 共 2 页
字号:
  send_timer.Set(m_tx_end);  m_state=MAC_SEND;  Printf((DumpPackets,"mac%d sends %s until %f\n",(int)MyEtherAddr,np->dump().c_str(),m_tx_end));  to_phy(np);  SentPackets++;}template <class PLD>void BcastMAC<PLD>::SendTimer(trigger_t&){  m_state=MAC_IDLE;  to_network_ack(!m_sr_collision);}template <class PLD>void BcastMAC<PLD>::AckTimer(  bool		&flag){  m_state=MAC_IDLE;  to_network_ack(flag);  return;}template <class PLD>void BcastMAC<PLD>::cancel(){  if(m_state==MAC_DEFER)  {    defer_timer.Cancel();    m_state=MAC_IDLE;    packet_t::free_pld(m_pldinf.pld);    assert(ack_timer.Active()==false);    ack_timer.Set(true,SimTime());  }}template <class PLD>void BcastMAC<PLD>::from_phy(  packet_t	*pkt,  bool		errflag,  double	power){  RecvPackets++;  m_sr_collision=true;  // A packet has arrived from the physical layer. At this time, the  // first bit of the packet is just starting transmission  // if the recv timer is active then another receive is in progress  if( recv_timer.Active() )  {    packet_t* rx_packet = m_rxinf.packet;	    // if the power of the new packet is high enough, discard the old packet    if( power > m_rxinf.power * CPThreshold)    {      DropPacket(m_rxinf.packet,"power too weak");      m_rxinf.packet=pkt;      m_rxinf.errflag=errflag;      m_rxinf.power=power;      recv_timer.Set(SimTime()+pkt->hdr.tx_time);    }    // otherwise, if the old packet was powerful enough, drop the new packet    else if (m_rxinf.power > power * CPThreshold)    {      DropPacket(pkt, "power too weak");    }    // otherwise, power levels are too close, so drop both packets    else    {      packet_t	*p1 = pkt, *p2 = m_rxinf.packet;      simtime_t end_time = SimTime() + pkt->hdr.tx_time;      // to decide which lasts longer. The longer one takes the recv timer.      if( end_time > recv_timer.GetTime() )      {	recv_timer.Set(end_time);	DropPacket(rx_packet, "receive-receive collision");	m_rxinf.packet=pkt;	m_rxinf.errflag=errflag;	m_rxinf.power=power;      }      else      {	DropPacket(pkt,"receive-receive collision");      }      rrCollisions++;      m_rxinf.errflag = true;		// set the error flag to true      to_network_recv_recv_coll( p1->pld, p2->pld);	// pass collision to routing layer//      to_network_recv_recv_coll( pkt->pld, m_rxinf.packet->pld);	// pass collision to routing layer    }  }  else  {    m_rxinf.packet=pkt;    m_rxinf.errflag=errflag;    m_rxinf.power=power;    // the recv timer expires as soon as the receive is done    recv_timer.Set(pkt->hdr.tx_time + SimTime());    if(m_state==MAC_DEFER)    {      // if it is in the MAC_DEFER state, defer_timer must be      // active. Have to defer it.      assert(defer_timer.Active());      // pt is the elapsed time after deferral starts      defer_timer.Cancel();      m_pldinf.delay -= SimTime() - m_defer_start;    }  }}template <class PLD>void BcastMAC<PLD>::RecvTimer(  trigger_t	&){  // recv timer expires, meaning a packet has just been completely  // received.  Previously in the FromPhy function if there are  // outgoing backoff activity then it had been suspended  // (deferred). Therefore on every exit of this function, it must  // be checked by calling ResumeDefer() whether there is any  // outgoing payload packet to be sent  packet_t* p=m_rxinf.packet;  Printf((DumpPackets,"mac%d receives %s (%e,%d)\n",(int)MyEtherAddr,p->dump().c_str(),m_rxinf.power,m_rxinf.errflag));  if(m_rxinf.errflag==1)  // if there is any error  {      DropPacket(p, "frame error");    ResumeDefer();    return ;  }  simtime_t now = SimTime();  // m_tx_end is the time last packet had been sent  if( now - p->hdr.tx_time < m_tx_end )  {    // receive-send collision    DropPacket(p,"receive-send collision");    ResumeDefer();    return;  }  u_int8_t type = p->hdr.dh_fc.fc_type;  u_int8_t subtype = p->hdr.dh_fc.fc_subtype;    switch(type)  {    case MAC_Type_Management:      DropPacket(p, "unknown MAC packet");      break;    case MAC_Type_Control:      DropPacket(p, "not a DATA packet");      break;    case MAC_Type_Data:      switch(subtype)      {        case MAC_Subtype_Data:	  ResumeDefer();	  RecvData(p);	  return;        default:	  fprintf(stderr, "mac%d recv_timer(2):Invalid MAC Data Subtype %x\n",(int)MyEtherAddr,		  subtype);	  break;      }      break;    default:      fprintf(stderr, "mac%d recv_timer(3):Invalid MAC Type %x\n", (int)MyEtherAddr,subtype);      break;  }  ResumeDefer();}template <class PLD>void BcastMAC<PLD>::RecvData(  packet_t	*p){  // maintain a database of latest sequence numbers received  // from each neighbor  cache_t::iterator src=m_recv_cache.find(p->hdr.dh_sa);  if(src!=m_recv_cache.end())  {    // src->second is the latest sequence number    // recently seen from the same source    if(src->second==p->hdr.dh_scontrol)    {      // duplicate data packets. It seems that the source      // did not receive the ack in the last round of       // transmissions      DropPacket(p,"duplicated DATA packet");      return;    }    else    {      // update the sequence number      src->second=p->hdr.dh_scontrol;    }  }  else  {    // source not found in the neighbor list, so add it to the cache    m_recv_cache.insert(make_pair(p->hdr.dh_sa,p->hdr.dh_scontrol));  }  // increase the reference count of the payload by one. This is to  // claim that I now partly own the payload. The ownership will be  // transferred to the hight layer.  p->inc_pld_ref();  // forward the payload contained in the data packet to higher layer.  to_network_data(p->pld,m_rxinf.power);  p->free(); // discard the data packet;}template <class PLD>void BcastMAC<PLD>::StartDefer(){  // if the state is MAC_DEFER then ResumeDefer instead of this function must be called  assert(m_state==MAC_IDLE);  assert(defer_timer.Active()==false);  Printf((DumpPackets, "mac%d deferring\n",(int)MyEtherAddr));  // if the recv timer is active then do nothing except changing   // the state to MAC_DEFER, because it is guaranteed that at the  // end of RecvTimer, backoff must be resumed.  if(!recv_timer.Active())                      {    m_defer_start = SimTime();    defer_timer.Set( m_defer_start+m_pldinf.delay);  }  m_state=MAC_DEFER;}template <class PLD>void BcastMAC<PLD>::ResumeDefer(){  if(m_state!=MAC_DEFER)return;  assert(defer_timer.Active()==false);  m_defer_start=SimTime();  defer_timer.Set(m_defer_start+m_pldinf.delay+IFS);  Printf((DumpPackets, "mac%d resumes deferring: %f \n",(int)MyEtherAddr,m_pldinf.delay));}template <class PLD>void BcastMAC<PLD>::DropPacket(  packet_t	*p,  const char	*reason){  Printf((DumpPackets,"mac%d drops %s (%s)\n",(int)MyEtherAddr,p->dump().c_str(),reason));  p->free();}template <class PLD>bool BcastMAC_Struct<PLD>::hdr_struct::dump(  std::string	&str) const{  std::string type;  bool payload=false;  switch(dh_fc.fc_type)  {    case BcastMAC_Struct<PLD>::MAC_Type_Control:      switch(dh_fc.fc_subtype)      {	case BcastMAC_Struct<PLD>::MAC_Subtype_RTS:	  type="RTS";	  break;	case BcastMAC_Struct<PLD>::MAC_Subtype_CTS:	  type="CST";	  break;	case BcastMAC_Struct<PLD>::MAC_Subtype_ACK:	  type="ACK";	  break;	default:	  type="UNKNOWN";      }      break;    case BcastMAC_Struct<PLD>::MAC_Type_Data:      if(dh_fc.fc_subtype == BcastMAC_Struct<PLD>::MAC_Subtype_Data)      {	payload=true;	if(dh_da!=ether_addr_t::BROADCAST)	  type="DATA";	else	  type="BROADCAST";      }      else	type="UNKNOWN";      break;    default:      type="UNKNOWN";      break;  }  char buffer[100];  sprintf(buffer,"%f %s %d -> %d", tx_time, type.c_str(), (int)(dh_sa), (int)(dh_da));  str=buffer;  return payload;}#endif /* broadcast_mac_h */

⌨️ 快捷键说明

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