📄 p802_15_4phy.cc
字号:
/********************************************//* NS2 Simulator for IEEE 802.15.4 *//* (per P802.15.4/D18) *//*------------------------------------------*//* by: Jianliang Zheng *//* (zheng@ee.ccny.cuny.edu) *//* Myung J. Lee *//* (lee@ccny.cuny.edu) *//* ~~~~~~~~~~~~~~~~~~~~~~~~~ *//* SAIT-CUNY Joint Lab *//********************************************/// File: p802_15_4phy.cc// Mode: C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t// $Header: p802_15_4phy.cc,v 1.1 2004/10/15 17:32:08 zheng Exp $/* * Copyright (c) 2003-2004 Samsung Advanced Institute of Technology and * The City University of New York. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Joint Lab of Samsung * Advanced Institute of Technology and The City University of New York. * 4. Neither the name of Samsung Advanced Institute of Technology nor of * The City University of New York may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE JOINT LAB OF SAMSUNG ADVANCED INSTITUTE * OF TECHNOLOGY AND THE CITY UNIVERSITY OF NEW YORK ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL SAMSUNG ADVANCED INSTITUTE OR THE CITY UNIVERSITY OF NEW YORK * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "p802_15_4pkt.h"#include "p802_15_4phy.h"#include "p802_15_4mac.h"#include "p802_15_4sscs.h"#include "p802_15_4const.h"#include "p802_15_4timer.h"#include "p802_15_4trace.h"#include "p802_15_4fail.h"#include "p802_15_4nam.h"PHY_PIB Phy802_15_4::PPIB ={ def_phyCurrentChannel, def_phyChannelsSupported, def_phyTransmitPower, def_phyCCAMode};void Phy802_15_4Timer::start(double wtime){ active = true; nullEvent.uid_ = 0; Scheduler::instance().schedule(this,&nullEvent,wtime);}void Phy802_15_4Timer::cancel(void){ active = false; Scheduler::instance().cancel(&nullEvent);}void Phy802_15_4Timer::handle(Event* e){ active = false; if (type == phyCCAHType) phy->CCAHandler(); else if(type == phyEDHType) phy->EDHandler(); else if(type == phyTRXHType) phy->TRXHandler(); else if(type == phyRecvOverHType) phy->recvOverHandler((Packet *)e); else if(type == phySendOverHType) phy->sendOverHandler(); else assert(0);}static class Phy802_15_4Class : public TclClass {public: Phy802_15_4Class() : TclClass("Phy/WirelessPhy/802_15_4") {} TclObject* create(int, const char*const*) { return (new Phy802_15_4(&(Phy802_15_4::PPIB))); }} class_Phy802_15_4;Phy802_15_4::Phy802_15_4(PHY_PIB *pp): WirelessPhy(), CCAH(this, phyCCAHType), EDH(this, phyEDHType), TRXH(this, phyTRXHType), recvOverH(this, phyRecvOverHType), sendOverH(this, phySendOverHType){ int i; ppib = *pp; trx_state = p_RX_ON; trx_state_defer_set = p_IDLE; tx_state = p_IDLE; rxPkt = 0; for (i=0;i<27;i++) { rxTotPower[i] = 0.0; rxTotNum[i] = 0; rxThisTotNum[i] = 0; } mac = 0;}void Phy802_15_4::macObj(Mac802_15_4 *m){ mac = m;}bool Phy802_15_4::channelSupported(UINT_8 channel){ return ((ppib.phyChannelsSupported & (1 << channel)) != 0);}double Phy802_15_4::getRate(char dataOrSymbol){ double rate; if (ppib.phyCurrentChannel == 0) { if (dataOrSymbol == 'd') rate = BR_868M; else rate = SR_868M; } else if (ppib.phyCurrentChannel <= 10) { if (dataOrSymbol == 'd') rate = BR_915M; else rate = SR_915M; } else { if (dataOrSymbol == 'd') rate = BR_2_4G; else rate = SR_2_4G; } return (rate*1000);}double Phy802_15_4::trxTime(Packet *p,bool phyPkt){ int phyHeaderLen; double trx; hdr_cmn* ch = HDR_CMN(p); phyHeaderLen = (phyPkt)?0:defPHY_HEADER_LEN; trx = ((ch->size() + phyHeaderLen)*8/getRate('d')); return trx;}void Phy802_15_4::construct_PPDU(UINT_8 psduLength,Packet *psdu){ //not really a new packet in simulation, but just update some packet header fields. hdr_lrwpan* wph = HDR_LRWPAN(psdu); hdr_cmn* ch = HDR_CMN(psdu); wph->SHR_PreSeq = defSHR_PreSeq; wph->SHR_SFD = defSHR_SFD; wph->PHR_FrmLen = psduLength; //also set channel (for filtering in simulation) wph->phyCurrentChannel = ppib.phyCurrentChannel; ch->size() = psduLength + defPHY_HEADER_LEN; ch->txtime() = trxTime(psdu,true); }void Phy802_15_4::PD_DATA_request(UINT_8 psduLength,Packet *psdu){ hdr_cmn* ch = HDR_CMN(psdu); //check packet length if (psduLength > aMaxPHYPacketSize) { fprintf(stdout,"[%s::%s][%f](node %d) Invalid PSDU/MPDU length: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(psdu),p802_15_4macSA(psdu),p802_15_4macDA(psdu),ch->uid(),HDR_LRWPAN(psdu)->uid,ch->size()); Packet::free(psdu); mac->PD_DATA_confirm(p_UNDEFINED); return; } if (trx_state == p_TX_ON) { if (tx_state == p_IDLE) {#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) sending pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(psdu),p802_15_4macSA(psdu),p802_15_4macDA(psdu),ch->uid(),HDR_LRWPAN(psdu)->uid,ch->size());#endif //construct a PPDU packet (not really a new packet in simulation, but still <psdu>) construct_PPDU(psduLength,psdu); //somehow the packet size is set to 0 after sendDown() -- ok, the packet is out and anything can happen (we shouldn't care once it's out) //so we have to calculate the transmission time before sendDown() double trx_time = trxTime(psdu,true); //send the packet to Radio (channel target) for transmission txPkt = psdu; txPktCopy = psdu->copy(); //for debug purpose, we still want to access the packet after transmission is done sendDown(psdu); //WirelessPhy::sendDown() tx_state = p_BUSY; //for carrier sense sendOverH.start(trx_time); } else //impossible assert(0); } else {#ifdef DEBUG802_15_4 fprintf(stdout,"[D][TRX][%s::%s][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(psdu),p802_15_4macSA(psdu),p802_15_4macDA(psdu),ch->uid(),HDR_LRWPAN(psdu)->uid,ch->size());#endif Packet::free(psdu); mac->PD_DATA_confirm(trx_state); }}void Phy802_15_4::PD_DATA_indication(UINT_8 psduLength,Packet *psdu,UINT_8 ppduLinkQuality){ //refer to sec 6.7.8 for LQI details hdr_lrwpan* wph = HDR_LRWPAN(psdu); wph->ppduLinkQuality = ppduLinkQuality; if (sendUp(psdu) == 0) Packet::free(psdu); else uptarget_->recv(psdu, (Handler*) 0);}void Phy802_15_4::PLME_CCA_request(){ if (trx_state == p_RX_ON) { //perform CCA //refer to sec 6.7.9 for CCA details //we need to delay 8 symbols CCAH.start(8/getRate('s')); } else mac->PLME_CCA_confirm(trx_state);}void Phy802_15_4::PLME_ED_request(){ if (trx_state == p_RX_ON) { //perform ED //refer to sec 6.7.7 for ED implementation details //we need to delay 8 symbols rxEDPeakPower = rxTotPower[ppib.phyCurrentChannel]; EDH.start(8/getRate('s')); } else mac->PLME_ED_confirm(trx_state,0);}void Phy802_15_4::PLME_GET_request(PPIBAenum PIBAttribute){ PHYenum t_status; switch(PIBAttribute) { case phyCurrentChannel: case phyChannelsSupported: case phyTransmitPower: case phyCCAMode: t_status = p_SUCCESS; break; default: t_status = p_UNSUPPORT_ATTRIBUTE; break; } mac->PLME_GET_confirm(t_status,PIBAttribute,&ppib);}void Phy802_15_4::PLME_SET_TRX_STATE_request(PHYenum state){ bool delay; PHYenum t_status; //ignore any pending request if (trx_state_defer_set != p_IDLE) trx_state_defer_set = p_IDLE; else if (TRXH.active) { TRXH.cancel(); } t_status = trx_state; if (state != trx_state) { delay = false; if (((state == p_RX_ON)||(state == p_TRX_OFF))&&(tx_state == p_BUSY)) { t_status = p_BUSY_TX; trx_state_defer_set = state; } else if (((state == p_TX_ON)||(state == p_TRX_OFF)) &&(rxPkt)&&(!HDR_CMN(rxPkt)->error())) //if after received a valid SFD { t_status = p_BUSY_RX; trx_state_defer_set = state; } else if (state == p_FORCE_TRX_OFF) { t_status = (trx_state == p_TRX_OFF)?p_TRX_OFF:p_SUCCESS; trx_state = p_TRX_OFF; //terminate reception if needed 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) FORCE_TRX_OFF 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; //incomplete reception -- force packet discard } //terminate transmission if needed 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) FORCE_TRX_OFF 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; } } else { t_status = p_SUCCESS; if (((state == p_RX_ON)&&(trx_state == p_TX_ON)) ||((state == p_TX_ON)&&(trx_state == p_RX_ON))) { trx_state_turnaround = state; delay = true; } else trx_state = state; } //we need to delay <aTurnaroundTime> symbols if Tx2Rx or Rx2Tx if (delay) { trx_state = p_TRX_OFF; //should be disabled immediately (further transmission/reception will not succeed) TRXH.start(aTurnaroundTime/getRate('s')); } else mac->PLME_SET_TRX_STATE_confirm(t_status); } else mac->PLME_SET_TRX_STATE_confirm(t_status);#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) SET TRX: old = %s req = %s ret = %s\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_, (trx_state == p_RX_ON)?"RX_ON": (trx_state == p_TX_ON)?"TX_ON":
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -