📄 p802_15_4phy.cc
字号:
(trx_state == p_TRX_OFF)?"TRX_OFF":"???", (state == p_RX_ON)?"RX_ON": (state == p_TX_ON)?"TX_ON": (state == p_TRX_OFF)?"TRX_OFF": (state == p_FORCE_TRX_OFF)?"FORCE_TRX_OFF":"???", (t_status == p_RX_ON)?"RX_ON": (t_status == p_TX_ON)?"TX_ON": (t_status == p_TRX_OFF)?"TRX_OFF": (t_status == p_BUSY_TX)?"BUSY_TX": (t_status == p_BUSY_RX)?"BUSY_RX": (t_status == p_SUCCESS)?"SUCCESS":"???");#endif}void Phy802_15_4::PLME_SET_request(PPIBAenum PIBAttribute,PHY_PIB *PIBAttributeValue){ PHYenum t_status; t_status = p_SUCCESS; switch(PIBAttribute) { case phyCurrentChannel: if (!channelSupported(PIBAttributeValue->phyCurrentChannel)) t_status = p_INVALID_PARAMETER; if (ppib.phyCurrentChannel != PIBAttributeValue->phyCurrentChannel) { //any packet in transmission or reception will be corrupted if (rxPkt) {#ifdef DEBUG802_15_4 hdr_cmn *ch = HDR_CMN(rxPkt); hdr_lrwpan *wph = HDR_LRWPAN(rxPkt); fprintf(stdout,"[%s::%s][%f](node %d) SET phy channel sets error bit for incoming pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(rxPkt),p802_15_4macSA(rxPkt),p802_15_4macDA(rxPkt),ch->uid(),wph->uid,ch->size());#endif HDR_CMN(rxPkt)->error() = 1; } if (tx_state == p_BUSY) {#ifdef DEBUG802_15_4 hdr_cmn *ch = HDR_CMN(txPkt); hdr_lrwpan *wph = HDR_LRWPAN(txPkt); fprintf(stdout,"[%s::%s][%f](node %d) SET phy channel sets error bit for outgoing pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(txPkt),p802_15_4macSA(txPkt),p802_15_4macDA(txPkt),ch->uid(),wph->uid,ch->size());#endif HDR_CMN(txPkt)->error() = 1; sendOverH.cancel(); Packet::free(txPktCopy); tx_state = p_IDLE; mac->PD_DATA_confirm(p_TRX_OFF); if (trx_state_defer_set != p_IDLE) trx_state_defer_set = p_IDLE; } ppib.phyCurrentChannel = PIBAttributeValue->phyCurrentChannel; } break; case phyChannelsSupported: if ((PIBAttributeValue->phyChannelsSupported&0xf8000000) != 0) //5 MSBs reserved t_status = p_INVALID_PARAMETER; else ppib.phyChannelsSupported = PIBAttributeValue->phyChannelsSupported; break; case phyTransmitPower: if (PIBAttributeValue->phyTransmitPower > 0xbf) t_status = p_INVALID_PARAMETER; else ppib.phyTransmitPower = PIBAttributeValue->phyTransmitPower; break; case phyCCAMode: if ((PIBAttributeValue->phyCCAMode < 1) || (PIBAttributeValue->phyCCAMode > 3)) t_status = p_INVALID_PARAMETER; else ppib.phyCCAMode = PIBAttributeValue->phyCCAMode; break; default: t_status = p_UNSUPPORT_ATTRIBUTE; break; } mac->PLME_SET_confirm(t_status,PIBAttribute);}UINT_8 Phy802_15_4::measureLinkQ(Packet *p){ //Link quality measurement is somewhat simulation/implementation specific; //here's our way: int lq,lq2; //consider energy /* Linux floating number compatibility lq = (int)((p->txinfo_.RxPr/RXThresh_)*128); */ { double tmpf; tmpf = p->txinfo_.RxPr/RXThresh_; lq = (int)(tmpf * 128); } if (lq > 255) lq = 255; //consider signal-to-noise /* Linux floating number compatibility lq2 = (int)((p->txinfo_.RxPr/HDR_LRWPAN(p)->rxTotPower)*255); */ { double tmpf; tmpf = p->txinfo_.RxPr/HDR_LRWPAN(p)->rxTotPower; lq2 = (int)(tmpf * 255); } if (lq > lq2) lq = lq2; //use worst value return (UINT_8) lq;}void Phy802_15_4::recv(Packet *p, Handler *h){ hdr_lrwpan* wph = HDR_LRWPAN(p); hdr_cmn *ch = HDR_CMN(p); FrameCtrl frmCtrl; switch(ch->direction()) { case hdr_cmn::DOWN:#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) outgoing pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif PD_DATA_request((UINT_8) ch->size(),p); break; case hdr_cmn::UP: default: if (sendUp(p) == 0) { Packet::free(p); return; } if (updateNFailLink(fl_oper_est,index_) == 0) { Packet::free(p); return; } if (updateLFailLink(fl_oper_est,p802_15_4macSA(p),index_) == 0) //broadcast packets can still reach here { Packet::free(p); return; } frmCtrl.FrmCtrl = wph->MHR_FrmCtrl; frmCtrl.parse(); //tap out if (mac->tap() && frmCtrl.frmType == defFrmCtrl_Type_Data) mac->tap()->tap(p); if (node()->energy_model() && node()->energy_model()->adaptivefidelity()) node()->energy_model()->add_neighbor(p802_15_4macSA(p)); //Under whatever condition, we should mark the media as busy. // --no matter the packet(s) is for this node or not, no matter // what state the transceiver is in, RX_ON,TX_ON or TRX_OFF, and // no matter which channel is being used. //Note that current WirelessPhy->sendUp() prevents packets with (Pr < CSThresh_) //from reaching here --. need to modify.WirelessPhy->sendUp() if we want to see //all the packets here (but seems no reason to do that). // in dB as can be seen from following: // not very clear (now CPThresh_ is just a ratio, not in dB?) rxTotPower[wph->phyCurrentChannel] += p->txinfo_.RxPr; rxTotNum[wph->phyCurrentChannel]++; if (EDH.active) if(rxEDPeakPower < rxTotPower[ppib.phyCurrentChannel]) rxEDPeakPower = rxTotPower[ppib.phyCurrentChannel]; if ((p802_15_4macDA(p) == index_) //packet for this node ||(p802_15_4macDA(p) == MAC_BROADCAST)) //broadcast packet rxThisTotNum[wph->phyCurrentChannel]++; if (trx_state == p_RX_ON) if (wph->phyCurrentChannel == ppib.phyCurrentChannel) //current channel if ((p802_15_4macDA(p) == index_) //packet for this node ||(p802_15_4macDA(p) == MAC_BROADCAST)) //broadcast packet if (wph->SHR_SFD == defSHR_SFD) //valid SFD {#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) incoming pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif wph->colFlag = false; if (rxPkt == 0) { rxPkt = p; HDR_LRWPAN(rxPkt)->rxTotPower = rxTotPower[wph->phyCurrentChannel]; } else {#ifdef DEBUG802_15_4 fprintf(stdout,"[D][COL][%s::%s][%f](node %d) COLLISION:\n\t First (power:%f): type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n\tSecond (power:%f): type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n", __FILE__,__FUNCTION__,CURRENT_TIME,index_, rxPkt->txinfo_.RxPr,wpan_pName(rxPkt),p802_15_4macSA(rxPkt),p802_15_4macDA(rxPkt),HDR_CMN(rxPkt)->uid(),HDR_LRWPAN(rxPkt)->uid,HDR_CMN(rxPkt)->size(), p->txinfo_.RxPr,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif wph->colFlag = true; HDR_LRWPAN(rxPkt)->colFlag = true; mac->nam->flashNodeColor(CURRENT_TIME); if (p->txinfo_.RxPr > rxPkt->txinfo_.RxPr) { //What should we do if there is a transceiver state set pending? // 1. continue defering (could be unbounded delay) //..2. set transceiver state now (the incoming packet ignored) //We select choice 1, as the traffic rate is supposed to be low. rxPkt = p; HDR_LRWPAN(rxPkt)->rxTotPower = rxTotPower[wph->phyCurrentChannel]; } } } if (rxPkt) if (HDR_LRWPAN(rxPkt)->rxTotPower < rxTotPower[HDR_LRWPAN(rxPkt)->phyCurrentChannel]) HDR_LRWPAN(rxPkt)->rxTotPower = rxTotPower[HDR_LRWPAN(rxPkt)->phyCurrentChannel]; assert(ch->size() > 0); if (ch->direction() != hdr_cmn::UP) { printf("Packet-flow direction not specified: sending up the stack on default.\n\n"); ch->direction() = hdr_cmn::UP; //we don't want MAC to handle the same problem } Scheduler::instance().schedule(&recvOverH, (Event *)p, trxTime(p,true)); break; }}void Phy802_15_4::CCAHandler(void){ PHYenum t_status; //refer to sec 6.7.9 for CCA details // 1. CCA will be affected by outgoing packets, // incoming packets (both destined for this device // and not destined for this device) and other // interferences. // 2. In implementation, we don't care about the details // and just need to perform an actual measurement. if ((tx_state == p_BUSY)||(rxTotNum[ppib.phyCurrentChannel] > 0)) { t_status = p_BUSY; } else if (ppib.phyCCAMode == 1) //ED detection { //sec 6.5.3.3 and 6.6.3.4 // -- receiver sensitivity: -85 dBm or better for 2.4G // -- receiver sensitivity: -92 dBm or better for 868M/915M //sec 6.7.9 // -- ED threshold at most 10 dB above receiver sensitivity. //For simulations, we simply compare with CSThresh_ t_status = (rxTotPower[ppib.phyCurrentChannel] >= CSThresh_)?p_BUSY:p_IDLE; } else if (ppib.phyCCAMode == 2) //carrier sense only { t_status = (rxTotNum[ppib.phyCurrentChannel] > 0)?p_BUSY:p_IDLE; } else //if (ppib.phyCCAMode == 3) //both { t_status = ((rxTotPower[ppib.phyCurrentChannel] >= CSThresh_)&&(rxTotNum[ppib.phyCurrentChannel] > 0))?p_BUSY:p_IDLE; } mac->PLME_CCA_confirm(t_status);}void Phy802_15_4::EDHandler(void){ int energy; UINT_8 t_EnergyLevel; //refer to sec 6.7.7 for ED implementation details //ED is somewhat simulation/implementation specific; here's our way: /* Linux floating number compatibility energy = (int)((rxEDPeakPower/RXThresh_)*128); */ { double tmpf; tmpf = rxEDPeakPower/RXThresh_; energy = (int)(tmpf * 128); } t_EnergyLevel = (energy > 255)?255:energy; mac->PLME_ED_confirm(p_SUCCESS,t_EnergyLevel);}void Phy802_15_4::TRXHandler(void){ trx_state = trx_state_turnaround; //send a confirm mac->PLME_SET_TRX_STATE_confirm(trx_state);}void Phy802_15_4::recvOverHandler(Packet *p){ UINT_8 lq; hdr_lrwpan* wph = HDR_LRWPAN(p); hdr_cmn *ch = HDR_CMN(p); rxTotPower[wph->phyCurrentChannel] -= p->txinfo_.RxPr; rxTotNum[wph->phyCurrentChannel]--; if (rxTotNum[wph->phyCurrentChannel] == 0) rxTotPower[wph->phyCurrentChannel] = 0.0; if ((p802_15_4macDA(p) != index_) &&(p802_15_4macDA(p) != MAC_BROADCAST)) //packet not for this node (interference) Packet::free(p); else if (p != rxPkt) //packet corrupted (not the strongest one) or un-detectable {#ifdef DEBUG802_15_4 fprintf(stdout,"[D][%s][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",(wph->phyCurrentChannel != ppib.phyCurrentChannel)?"CHN":"NOT",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif rxThisTotNum[wph->phyCurrentChannel]--; drop(p,(wph->phyCurrentChannel != ppib.phyCurrentChannel)?"CHN":"NOT"); } else { rxThisTotNum[wph->phyCurrentChannel]--; //measure (here calculate) the link quality lq = measureLinkQ(p); ch->size() -= defPHY_HEADER_LEN; rxPkt = 0; if ((ch->size() <= 0) ||(ch->size() > aMaxPHYPacketSize) ||ch->error()) //incomplete reception (due to FORCE_TRX_OFF),data packet received during ED or other errors {#ifdef DEBUG802_15_4 fprintf(stdout,"[D][ERR][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,__LINE__,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif drop(p,"ERR"); } else {#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) incoming pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d --> PD_DATA_indication()\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif PD_DATA_indication(ch->size(),p,lq); //MAC sublayer need to further check if the packet //is really received successfully or not. } if (trx_state_defer_set != p_IDLE) { trx_state_turnaround = trx_state_defer_set; trx_state_defer_set = p_IDLE; if (trx_state_turnaround == p_TRX_OFF) { trx_state = trx_state_turnaround; mac->PLME_SET_TRX_STATE_confirm(trx_state); } else { //we need to delay <aTurnaroundTime> symbols for Rx2Tx trx_state = p_TRX_OFF; //should be disabled immediately (further reception will not succeed) TRXH.start(aTurnaroundTime/getRate('s')); } } }}void Phy802_15_4::sendOverHandler(void){#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) sending over: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(txPktCopy),p802_15_4macSA(txPktCopy),p802_15_4macDA(txPktCopy),HDR_CMN(txPktCopy)->uid(),HDR_LRWPAN(txPktCopy)->uid,HDR_CMN(txPktCopy)->size());#endif assert(tx_state == p_BUSY); assert(txPktCopy); Packet::free(txPktCopy); tx_state = p_IDLE; mac->PD_DATA_confirm(p_SUCCESS); if (trx_state_defer_set != p_IDLE) { trx_state_turnaround = trx_state_defer_set; trx_state_defer_set = p_IDLE; if (trx_state_turnaround == p_TRX_OFF) { trx_state = trx_state_turnaround; mac->PLME_SET_TRX_STATE_confirm(trx_state); } else { //we need to delay <aTurnaroundTime> symbols for Rx2Tx trx_state = p_TRX_OFF; //should be disabled immediately (further transmission will not succeed) TRXH.start(aTurnaroundTime/getRate('s')); } }}// End of file: p802_15_4phy.cc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -