?? patch.mac
字號:
diff -Naur --ignore-matching-lines='Version Date' --ignore-matching-lines=cvsroot --ignore-matching-lines=CVSROOT /home/rmerz/NS/ns-allinone-2.26/ns-2.26/mac/interference-phy.cc mac/interference-phy.cc--- /home/rmerz/NS/ns-allinone-2.26/ns-2.26/mac/interference-phy.cc 1970-01-01 01:00:00.000000000 +0100+++ mac/interference-phy.cc 2004-02-17 12:08:49.000000000 +0100@@ -0,0 +1,515 @@+/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- + *+ * Copyright (c) 1996 Regents of the University of California.+ * 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 Computer Systems+ * Engineering Group at Lawrence Berkeley Laboratory and the Daedalus+ * research group at UC Berkeley.+ * 4. Neither the name of the University nor of the Laboratory may be used+ * to endorse or promote products derived from this software without+ * specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.+ *+ * $Header: /usr/local/cvsroot/ns-2_26/mac/interference-phy.cc,v 1.9 2004/02/03 15:04:48 widmer Exp $+ *+ * Ported from CMU/Monarch's code, nov'98 -Padma Haldar.+ * wireless-phy.cc+ */++#include <math.h>+#include <phy.h>+#include <propagation.h>+#include <modulation.h>+#include <mod_codedppm.h>+#include <wireless-phy.h>+#include <interference-phy.h>+#include <packet.h>+#include <assert.h>+#include <random.h>+#include "mac-ifcontrol.h"+#include "mac.h" // for MAC_BROADCAST (code)++/* ======================================================================+ InterferencePhy TCL+ ====================================================================== */+static class InterferencePhyClass: public TclClass {+public:+ InterferencePhyClass() : TclClass("Phy/WirelessPhy/InterferencePhy") {}+ TclObject* create(int, const char*const*) {+ return (new InterferencePhy);+ }+} class_InterferencePhy;++/* ======================================================================+ Timers+ ====================================================================== */+void PhyIdleTimer::expire(Event *e)+{+ phy_->idle_handler();+}++void PhyRecvTimer::expire(Event *e)+{+ phy_->recv_handler();+}++/* ======================================================================+ InterferencePhy Interface+ ====================================================================== */+InterferencePhy::InterferencePhy() : WirelessPhy(), first_ifpkt(0), pktRx_(0), tx_ths_(-1), rx_ths_(-1),+ code_id_(MODULATION_NUM_CODES - 1), if_state(PHY_IDLE), idle_timer(this),+ recv_timer(this)+{+ bind("frequency_range_", &frequency_range_);+ bind("noise_factor_", &noise_factor_);+ bind("use_timehopping_", &use_timehopping_);+ bind("erasure_coefficient_", &erasure_coefficient_);+ bind_bw("bitrate_", &bitrate_);+}+ +int+InterferencePhy::command(int argc, const char*const* argv)+{+ TclObject *obj; ++ if(argc == 3) {+ if (strcmp(argv[1], "modulation") == 0) {+ assert(modulation_ == 0);+ obj = TclObject::lookup(argv[2]);+ modulation_ = (Modulation*) obj;+ return TCL_OK;+ }+ }+ return WirelessPhy::command(argc, argv);+}+++void+InterferencePhy::idle_handler()+{+ if_state = PHY_IDLE;+}++void+InterferencePhy::recv_handler()+{+ assert(pktRx_);+ if_state = PHY_IDLE;+ if (sendUp(pktRx_) == 0) {+ // hand over packets with errors -> should be dropped by MAC layer+ uptarget_->recv(pktRx_, (Handler*) 0);+ //Packet::free(pktRx_);+ } else {+ uptarget_->recv(pktRx_, (Handler*) 0);+ }+}++void+InterferencePhy::recv(Packet* p, Handler* h)+{+ struct hdr_cmn *hdr = HDR_CMN(p);+ struct hdr_mac_ifcontrol *hdr_ifc = HDR_MAC_IFControl(p);+ double now = Scheduler::instance().clock();++ /*+ * Handle outgoing packets+ */+ switch(hdr->direction()) {+ case hdr_cmn::DOWN :+ /*+ * The receiving PHY will handle EOT and take care of+ * interference. if_state is set to PHY_SEND for the+ * duration of the packet. The MAC should check before+ * handing over packets. When busy, they'll simply be+ * dropped!+ */+ if (!is_idle()) {+ Packet::free(p);+ } else {+ /* assume uncoded tx (no channel code) if txtime not set by upper layer */+ if (hdr->txtime() <= 0)+ hdr->txtime() = hdr->size() * 8.0 / bitrate_;++ // TH code+ if (use_timehopping_)+ hdr_ifc->tx_ths_ = tx_ths_;+ + // channel code+ hdr_ifc->code_id_ = code_id_;++ printf("%0.9f %i code rx%i tx%i pkt%i (PHY) send (channel code %i, psize %i, txtime %f)\n",+ now, index_, rx_ths_, tx_ths_, hdr_ifc->tx_ths_,+ hdr_ifc->code_id_, hdr->size(), hdr->txtime());++ if_state = PHY_SEND;+ idle_timer.resched(txtime(p));++ sendDown(p);+ }+ return;+ case hdr_cmn::UP :+ // fall through, default direction is up+ default:+ // if the node is in sleeping mode or the energy goes to ZERO, drop the packet+ int em_fail_ = em() && (em()->sleep() || (em()->node_on() != true) || (em()->energy() <= 0));++ // calculate receive power+ assert(propagation_);+ PacketStamp s;+ s.stamp((MobileNode*)node(), ant_, 0, lambda_);+ double Pr = propagation_->Pr(&p->txinfo_, &s, this);++ // JCW+ //printf("%0.9f Pr %e Thresh %e %e\n", Scheduler::instance().clock(), Pr, CSThresh_, RXThresh_);++ /*+ * We see the packet if we're idle, it's on the code+ * we're listening to (i.e., MAC addr matches) if+ * orthogonal_codes_ is true, we have enough power,+ * and power above detect threshold+ *+ * Assumption: nodes listen on their rx_ths and their own code simultaneously!+ *+ * CODING ASSUMPTIONS: (not explicitly modeled) packet+ * tx is on private code so that other tx to the same+ * receiver only create interference but no+ * "collisions", nodes are not synchronized, random TH+ * sequence, common code for broadcasts+ */++ int right_code = !use_timehopping_ || (hdr_ifc->tx_ths_ == rx_ths_) || (hdr_ifc->tx_ths_ == own_ths_) || ((u_int32_t)hdr_ifc->tx_ths_ == MAC_BROADCAST);+ //int right_code = !use_timehopping_ || (hdr_ifc->tx_ths_ == rx_ths_) || ((u_int32_t)hdr_ifc->tx_ths_ == MAC_BROADCAST);++ //if (is_idle() && right_code && !em_fail_ && Pr >= CSThresh_) {+ if (is_idle() && right_code && !em_fail_) {+ if_state = PHY_RECV;+ pktRx_ = p;+ rxStart = now;+ rxEnd = now + txtime(p);+ rxPower = Pr;+ /*+ * schedule reception of full packet+ */+ recv_timer.resched(txtime(p)); + printf("%0.9f %i rx-code %i tx-code %i, Packet %i (PHY) recv, power RX %f dBm TX %f dBm\n",+ now, index_, rx_ths_, tx_ths_, hdr_ifc->tx_ths_,+ 10.0*log10(Pr*1000), 10.0*log10(p->txinfo_.getTxPr()*1000));+ } else {+ /* while receiving/transmitting/sleeping we just+ * update the interference list */++ // pulse level interference depends on the+ // relative time shift between interfereing+ // senders and the receiver; we assume it's uniformly distributed+ double sync = Random::uniform();+ insertInterferenceListEntry(now, now + txtime(p), Pr, sync);+ //p->txinfo_.getAntenna()->release();+ Packet::free(p);+ }+ break;+ }++}++int +InterferencePhy::sendUp(Packet *p)+{+ hdr_cmn *hdr = HDR_CMN(p);+ struct hdr_mac_ifcontrol *hdr_ifc = HDR_MAC_IFControl(p);+ int pkt_recvd = 1;++ /*+ * Sanity Check+ */+ assert(initialized());++ if(modulation_) {+ // bitrate_ for noise calculation is coded bits, i.e. the T_f from modulation+ //double noise = POWER_SPECTRAL_DENSITY * pow(10, noise_factor_ / 10.0) * bitrate_;+ // -80dBm (from ST)+ double noise = 1e-11;+ // adjust interference by processing gain+ double interference = avgInterferencePower() / (frequency_range_ / bitrate_);+ double erasureProb = avgErasures(); + double erasures = 0;++ // XXX ulgy, but there seems to be no better way+ CodedPPM* cppm = dynamic_cast<CodedPPM*>(modulation_);+ if (erasure_coefficient_ <= 0 || cppm == 0) {+ hdr->errbitcnt() = modulation_->BitError(rxPower, interference, noise, p);+ } else {+ int code = hdr_ifc->code_id_;+ erasures = cppm->ppm_erasure(code) * erasureProb;+ hdr->errbitcnt() = cppm->BitError(rxPower, interference, noise, p, erasures);+ }++ hdr->error() = (hdr->errbitcnt() ? 1 : 0);+ if (hdr->error())+ pkt_recvd = 0;++ //printf("%.9f Pr %e PI %e N0 %e Erasures %f -> %i\n", Scheduler::instance().clock(), 10.0 * log10(rxPower*1000), 10.0 * log10(avgInterferencePower()*1000), 10.0 * log10(noise*1000), erasures, pkt_recvd);+ } else if (rxPower < RXThresh_ && rxPower / maxInterferencePower() < pow(10, CPThresh_ / 10.0)) {+ // This is the old 802.11 like code which has not been tested! Use at own risk.++ /*+ * We can detect, but not successfully receive+ * this packet.+ */+ hdr->error() = 1;+ pkt_recvd = 0;+ }+ + /*+ * Decrease energy if packet successfully received+ */+ if(pkt_recvd && em()) {+ double rcvtime = hdr_cmn::access(p)->txtime();++ double start_time = max(channel_idle_time_, NOW);+ double end_time = max(channel_idle_time_, NOW+rcvtime);+ double actual_rcvtime = end_time-start_time;++ if (start_time > update_energy_time_) {+ em()->DecrIdleEnergy(start_time-update_energy_time_,+ P_idle_);+ update_energy_time_ = start_time;+ }+ + em()->DecrRcvEnergy(actual_rcvtime,Pr_consume_);+ if (end_time > channel_idle_time_) {+ status_ = RECV;+ }++ channel_idle_time_ = end_time;+ update_energy_time_ = end_time;++ /*+ hdr_diff *dfh = HDR_DIFF(p);+ printf("Node %d receives (%d, %d, %d) energy %lf.\n",+ node()->address(), dfh->sender_id.addr_, + dfh->sender_id.port_, dfh->pk_num, node()->energy());+ */+ + if (em()->energy() <= 0) { + // saying node died+ em()->setenergy(0);+ ((MobileNode*)node())->log_energy(0);+ }+ }+ + return pkt_recvd;+}++double InterferencePhy::syncOverlap(double sync)+{+ // calculate how much interference power we get for+ // erasures. Overlap of pulses depends on the phase difference+ // of the receivers and the interferers clock++ // linear approximation++ assert(sync >= 0.0 && sync <= 1.0);+ double s = sync / (0.7 / 8);++ if (s <= 1)+ return 0.5 * s;+ --s;+ if (s <= 1)+ return 0.5 * (1 - s);+ --s;+ if (s <= 1)+ return 1.0 * s;+ --s;+ if (s <= 1)+ return 1.0 * (1 - s);+ --s;+ if (s <= 1)+ return 1.0 * s;+ --s;+ if (s <= 1)+ return 1.0 * (1 - s);+ --s;+ if (s <= 1)+ return 0.5 * s;+ --s;+ if (s <= 1)+ return 0.5 * (1 - s);++ return 0;+}++double InterferencePhy::avgInterferencePower()+{+ double avgPower = 0;+ InterferenceListEntry *i = first_ifpkt;++ while(i) {+ if (i->used) {+ if(i->rxEndTime > rxStart) {+ //The packet i collides with the useful packet:+ //we evaluate the duration of the collision++ // check if packet creates interferences or can be canceled as erasure+ // square coefficient since here it's power, not energy+ if (erasure_coefficient_ <= 0 || i->receivedPower * syncOverlap(i->syncCoefficient) < erasure_coefficient_ * erasure_coefficient_ * rxPower) {+ double interferingInterval = min(rxEnd, i->rxEndTime) - max(rxStart, i->rxStartTime);+ assert(interferingInterval > 0);++ //The two packets collide: we evaluate the contribution to the interference power+ double collisionTimeCoefficient = interferingInterval / (rxEnd - rxStart);+ avgPower += i->receivedPower * collisionTimeCoefficient;+ //printf("%12.11f interference if %f coeff %f\n", Scheduler::instance().clock(), 10.0 * log10(i->receivedPower * 1000), collisionTimeCoefficient);+ }+ } else {+ //printf("%12.11f remove\n", Scheduler::instance().clock());+ //The packet i can not cause collisions anymore: we free the slot+ i->used = 0;++ /*+ removeInterferenceListEntry(prev, i);+ // i is removed and the pointer updated+ if (prev)+ i = prev->next;+ else+ i = first_ifpkt;+ */+ }+ }+ i = i->next;+ } + return avgPower;+}++double InterferencePhy::avgErasures()+{+ // probability of "no erasure"+ double neProb = 1;+ InterferenceListEntry *i = first_ifpkt;++ // erasure detection switched off?+ if (erasure_coefficient_ <= 0)+ return 0;++ while(i) {+ if (i->used) {+ if(i->rxEndTime > rxStart) {+ // check if packet creates erasure+ if (i->receivedPower * syncOverlap(i->syncCoefficient) >= erasure_coefficient_ * erasure_coefficient_ * rxPower) {+ // we assume a linear relationship between #erasures and shift in SNR (in dB)+ // thus we can still calculate an average for the whole packet+ double interferingInterval = min(rxEnd, i->rxEndTime) - max(rxStart, i->rxStartTime);+ assert(interferingInterval > 0);++ double collisionTimeCoefficient = interferingInterval / (rxEnd - rxStart);+ // erasures are created indepedently of interference power+ neProb *= (1.0 - bitrate_/frequency_range_ * collisionTimeCoefficient);++ //printf("%12.11f erasure Tf %f coeff %f\n", Scheduler::instance().clock(), bitrate_/frequency_range_, collisionTimeCoefficient);+ }+ } else {+ i->used = 0;+ }+ }+ i = i->next;+ } + return (1.0 - neProb);+}++double InterferencePhy::maxInterferencePower()+{+ double totalInterferencePower = 0;+ InterferenceListEntry *i = first_ifpkt;++ while(i) {+ if (i->used) {+ if(i->rxEndTime > rxStart) {+ totalInterferencePower = max(totalInterferencePower, i->receivedPower);+ } else {+ i->used = 0;+ }+ }+ i = i->next;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -