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

📄 patch.mac

📁 ns2网络仿真中超宽带的实现
💻 MAC
📖 第 1 页 / 共 5 页
字号:
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 + -