wireless-phyExt.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:15k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2007 
  3.  * Mercedes-Benz Research & Development North America, Inc. and
  4.  * University of Karlsruhe (TH)
  5.  * All rights reserved.
  6.  *
  7.  * This program is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License,
  9.  * version 2, as published by the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License along
  17.  * with this program; if not, write to the Free Software Foundation, Inc.,
  18.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  19.  *
  20.  *
  21.  * The copyright of this module includes the following
  22.  * linking-with-specific-other-licenses addition:
  23.  *
  24.  * In addition, as a special exception, the copyright holders of
  25.  * this module give you permission to combine (via static or
  26.  * dynamic linking) this module with free software programs or
  27.  * libraries that are released under the GNU LGPL and with code
  28.  * included in the standard release of ns-2 under the Apache 2.0
  29.  * license or under otherwise-compatible licenses with advertising
  30.  * requirements (or modified versions of such code, with unchanged
  31.  * license).  You may copy and distribute such a system following the
  32.  * terms of the GNU GPL for this module and the licenses of the
  33.  * other code concerned, provided that you include the source code of
  34.  * that other code when and as the GNU GPL requires distribution of
  35.  * source code.
  36.  *
  37.  * Note that people who make modified versions of this module
  38.  * are not obligated to grant this special exception for their
  39.  * modified versions; it is their choice whether to do so.  The GNU
  40.  * General Public License gives permission to release a modified
  41.  * version without this exception; this exception also makes it
  42.  * possible to release a modified version which carries forward this
  43.  * exception.
  44.  *
  45.  */
  46.  
  47. /*
  48.  * This code was designed and developed by:
  49.  * 
  50.  * Qi Chen                 : qi.chen@daimler.com
  51.  * Felix Schmidt-Eisenlohr : felix.schmidt-eisenlohr@kit.edu
  52.  * Daniel Jiang            : daniel.jiang@daimler.com
  53.  * 
  54.  * For further information see: 
  55.  * http://dsn.tm.uni-karlsruhe.de/english/Overhaul_NS-2.php
  56.  */
  57. #include <math.h>
  58. #include <functional>
  59. #include <wireless-phyExt.h>
  60. #include <ip.h>
  61. #include <agent.h>
  62. #include <trace.h>
  63. #include "mac-802_11Ext.h"
  64. #include <map>
  65. #include <iostream>
  66. #include <ranvar.h>
  67. /* ======================================================================
  68.  WirelessPhyExt Interface
  69.  ====================================================================== */
  70. static class WirelessPhyExtClass : public TclClass {
  71. public:
  72. WirelessPhyExtClass() :
  73. TclClass("Phy/WirelessPhyExt") {
  74. }
  75. TclObject* create(int, const char*const*) {
  76. return (new WirelessPhyExt);
  77. }
  78. } class_WirelessPhyExt;
  79. WirelessPhyExt::WirelessPhyExt() :
  80. WirelessPhy(), tX_Timer(this), rX_Timer(this), preRX_Timer(this) {
  81. bind("CPThresh_", &CPThresh_); //not used at the moment, BPSK_SNR_ is used in preamble capture
  82. bind("RXThresh_", &RXThresh_); //not used at the moment
  83. bind("CSThresh_", &CSThresh_);
  84. bind("Pt_", &Pt_);
  85. bind("freq_", &freq_);
  86. bind("L_", &L_);
  87. bind("PreambleCaptureSwitch_", &PreambleCaptureSwitch_);
  88. bind("DataCaptureSwitch_", &DataCaptureSwitch_);
  89. bind("SINR_PreambleCapture_", &SINR_PreambleCapture_);
  90. bind("SINR_DataCapture_", &SINR_DataCapture_);
  91. bind("HeaderDuration_", &HeaderDuration_);
  92. bind("PHY_DBG_", &PHY_DBG);
  93. bind("BasicModulationScheme_", &BasicModulationScheme_);
  94. bind("trace_dist_", &trace_dist_);
  95. bind("noise_floor_", &noise_floor_);
  96. bind("PowerMonitorThresh_", &PowerMonitorThresh_);
  97. lambda_ = SPEED_OF_LIGHT / freq_;
  98. node_ = 0;
  99. ant_ = 0;
  100. propagation_ = 0;
  101. powerMonitor = new PowerMonitor(this);
  102. //channel state
  103. state = SEARCHING;
  104. pkt_RX = 0;
  105. power_RX = 0;
  106. }
  107. int WirelessPhyExt::command(int argc, const char*const* argv) {
  108. TclObject *obj;
  109. if (argc == 3) {
  110. if (strcasecmp(argv[1], "setMacAddr")==0) {
  111. return TCL_OK;
  112. } else if ( (obj = TclObject::lookup(argv[2])) == 0) {
  113. fprintf(stderr,"WirelessPhyExt: %s lookup of %s failedn",
  114. argv[1], argv[2]);
  115. return TCL_ERROR;
  116. } else if (strcmp(argv[1], "propagation") == 0) {
  117. assert(propagation_ == 0);
  118. propagation_ = (Propagation*) obj;
  119. return TCL_OK;
  120. } else if (strcasecmp(argv[1], "antenna") == 0) {
  121. ant_ = (Antenna*) obj;
  122. return TCL_OK;
  123. } else if (strcasecmp(argv[1], "node") == 0) {
  124. assert(node_ == 0);
  125. node_ = (Node *)obj;
  126. return TCL_OK;
  127. }
  128. }
  129. return WirelessPhy::command(argc, argv);
  130. }
  131. void WirelessPhyExt::sendDown(Packet *p) {
  132. /*
  133.  * Sanity Check
  134.  */
  135. assert(initialized());
  136. if (PHY_DBG)
  137. log("SendDown", "");
  138. switch (state) {
  139. case TXing:
  140. cout << "wrong in MAC logic case 1"<<endl;
  141. exit(1);
  142. break;
  143. case RXing:
  144. rX_Timer.cancel();
  145. // case 7
  146. discard(pkt_RX, power_RX, "INT");
  147. pkt_RX=0;
  148. power_RX=0;
  149. break;
  150. case PreRXing:
  151. preRX_Timer.cancel();
  152. // case 6
  153. discard(pkt_RX, power_RX, "INT");
  154. pkt_RX=0;
  155. power_RX=0;
  156. break;
  157. case SEARCHING:
  158. break;
  159. default:
  160. cout << "Only four states valid"<<endl;
  161. exit(1);
  162. }
  163. /*
  164.  *  Stamp the packet with the interface arguments
  165.  */
  166. p->txinfo_.stamp((MobileNode*)node(), ant_->copy(), Pt_, lambda_);
  167. // Send the packet &  set sender timer
  168. struct hdr_cmn * cmh = HDR_CMN(p);
  169. setState(TXing);
  170. tX_Timer.sched(cmh->txtime());
  171. powerMonitor->recordPowerLevel(Pt_, cmh->txtime());
  172. downtarget_->recv(p, this);
  173. }
  174. int WirelessPhyExt::sendUp(Packet *p) {
  175. /*
  176.  * Sanity Check
  177.  */
  178. assert(initialized());
  179. int pkt_recvd = 0;
  180. assert(p);
  181. // struct hdr_mac802_11* dh = HDR_MAC802_11(p);
  182. struct hdr_cmn * cmh = HDR_CMN(p);
  183. PacketStamp s;
  184. double Pr;
  185. if (propagation_) {
  186. s.stamp((MobileNode*)node(), ant_, 0, lambda_);
  187. // pass the packet to RF model for the calculation of Pr
  188. Pr = propagation_->Pr(&p->txinfo_, &s, this);
  189. powerMonitor->recordPowerLevel(Pr, cmh->txtime());
  190. if (PHY_DBG) {
  191. char msg[1000];
  192. sprintf(msg, "Id: %d Pr: %f PL: %f SINR: %f TXTIME: %f", cmh->uid(), Pr
  193. *1e9, powerMonitor->getPowerLevel()*1e9, Pr
  194. /(powerMonitor->getPowerLevel()-Pr), cmh->txtime());
  195. log("Sendup", msg);
  196. }
  197. switch (state) {
  198. case TXing:
  199. //case 12
  200. pkt_recvd = discard(p, Pr, "TXB");
  201. setState(TXing);
  202. break;
  203. case SEARCHING:
  204. if ((Pr >= CSThresh_) && (powerMonitor->SINR(Pr)
  205. >= modulation_table[BasicModulationScheme_].SINR_ratio)) {
  206. power_RX = Pr;
  207. pkt_RX=p->copy();
  208. setState(PreRXing);
  209. preRX_Timer.sched(HeaderDuration_); // preamble and PCLP header
  210. break;
  211. } else {
  212. //case 1
  213. //pkt_recvd =discard(p,Pr,"");
  214. pkt_recvd =discard(p, Pr, "SXB");
  215. setState(SEARCHING);
  216. break;
  217. }
  218. case PreRXing:
  219. if (powerMonitor->SINR(power_RX)
  220. >= modulation_table[BasicModulationScheme_].SINR_ratio) {
  221. //case 4
  222. pkt_recvd = discard(p, Pr, "PXB");
  223. if (PHY_DBG)
  224. log("PCAP 1st SUCC", "");
  225. setState(PreRXing);
  226. break;
  227. } else {
  228. // the preamble of pkt_RX is corrupted
  229. // case 2
  230. pkt_recvd = discard(pkt_RX, power_RX, "PXB");
  231. Packet::free(pkt_RX);
  232. power_RX=0;
  233. preRX_Timer.cancel();
  234. pkt_RX=0;
  235. if (PHY_DBG)
  236. log("PCAP 1st FAIL", "");
  237. if (PreambleCaptureSwitch_) {
  238. if (powerMonitor->SINR(Pr) >= SINR_PreambleCapture_) {
  239. pkt_RX=p->copy();
  240. power_RX =Pr;
  241. if (PHY_DBG)
  242. log("PCAP 2nd SUCC", "");
  243. setState(PreRXing);
  244. preRX_Timer.sched(HeaderDuration_);
  245. break;
  246. } else {
  247. //case 3
  248. pkt_recvd = discard(p, Pr, "PXB");
  249. if (PHY_DBG)
  250. log("PCAP 2nd FAIL", "");
  251. setState(SEARCHING);
  252. break;
  253. }
  254. } else {
  255. pkt_recvd = discard(p, Pr, "PXB");
  256. if (PHY_DBG)
  257. log("PCAP 2nd FAIL N/A", "");
  258. setState(SEARCHING);
  259. break;
  260. }
  261. }
  262. case RXing:
  263. if (powerMonitor->SINR(power_RX) >= SINR_Th_RX) {
  264. //case 8
  265. pkt_recvd = discard(p, Pr, "RXB");
  266. if (PHY_DBG)
  267. log("DCAP 1st SUCC", "");
  268. setState(RXing);
  269. break;
  270. } else {
  271. if (PHY_DBG)
  272. log("DCAP 1st FAIL", "");
  273. HDR_CMN(pkt_RX)->error()=1;
  274. if (DataCaptureSwitch_) {
  275. if (powerMonitor->SINR(Pr) >= SINR_DataCapture_) {
  276. // case 9
  277. rX_Timer.cancel();
  278. discard(pkt_RX, power_RX, "RXB");
  279. pkt_RX=0;
  280. //------ start the prerx of this new packet p---//
  281. pkt_RX=p->copy();
  282. power_RX =Pr;
  283. if (PHY_DBG)
  284. log("DCAP 2nd SUCC", "");
  285. setState(PreRXing);
  286. preRX_Timer.sched(HeaderDuration_);
  287. } else {
  288. // case 10
  289. pkt_recvd = discard(p, Pr, "RXB");
  290. if (PHY_DBG)
  291. log("DCAP 2nd FAIL", "");
  292. setState(RXing);
  293. }
  294. } else {
  295. // case 11
  296. pkt_recvd = discard(p, Pr, "RXB");
  297. if (PHY_DBG)
  298. log("DCAP 2nd FAIL N/A", "");
  299. setState(RXing);
  300. }
  301. break;
  302. }
  303. default:
  304. cout<<"packet arrive from chanel at invalid PHY state"<<endl;
  305. exit(-1);
  306. }
  307. }
  308. return 0; // the incoming MAC frame will be freed by phy.cc.
  309. }
  310. double WirelessPhyExt::SINR_Th(int modulationScheme) {
  311. if (PHY_DBG) {
  312. char msg[1000];
  313. sprintf(msg, ": = %s threshold %f ",
  314. modulation_table[modulationScheme].schemeName,
  315. modulation_table[modulationScheme].SINR_ratio);
  316. log("Mod_Scheme", msg);
  317. }
  318. return modulation_table[modulationScheme].SINR_ratio;
  319. }
  320. void WirelessPhyExt::handle_TXtimeout() {
  321. assert(state==TXing);
  322. Mac802_11Ext * mac_ = (Mac802_11Ext*)(uptarget_);
  323. mac_->handleTXEndIndication();
  324. setState(SEARCHING);
  325. }
  326. void WirelessPhyExt::handle_RXtimeout() {
  327. assert(state==RXing);
  328. setState(SEARCHING);
  329. struct hdr_cmn * cmh = HDR_CMN(pkt_RX);
  330. Mac802_11Ext * mac_ = (Mac802_11Ext*)(uptarget_);
  331. if (cmh->error()) {
  332. //case 5, 9 
  333. discard(pkt_RX, power_RX, "RXB");
  334. pkt_RX=0;
  335. power_RX=0;
  336. mac_->handleRXEndIndication(0);
  337. } else {
  338. mac_->handleRXEndIndication(pkt_RX);
  339. pkt_RX=0;
  340. power_RX=0;
  341. }
  342. }
  343. void WirelessPhyExt::handle_PreRXtimeout() {
  344. assert(state==PreRXing);
  345. assert(pkt_RX);
  346. struct hdr_cmn * cmh = HDR_CMN(pkt_RX);
  347. SINR_Th_RX = SINR_Th(cmh->mod_scheme_);
  348. // cout<<"sinr"<<SINR_Th_RX<<endl;
  349. if (powerMonitor->SINR(power_RX) < SINR_Th_RX) {
  350. if (PHY_DBG)
  351. log("PreRxTimeout", "BodyError");
  352. cmh->error() = 1;
  353. }
  354. setState(RXing);
  355. rX_Timer.sched(cmh->txtime()-HeaderDuration_); //receiving rest of the MAC frame
  356. Mac802_11Ext * myUpMAC = (Mac802_11Ext*)(uptarget_);
  357. myUpMAC->handleRXStartIndication();
  358. }
  359. void WirelessPhyExt::sendCSBusyIndication() {
  360. Mac802_11Ext * myUpMAC = (Mac802_11Ext*)(uptarget_);
  361. myUpMAC->handlePHYBusyIndication();
  362. }
  363. void WirelessPhyExt::sendCSIdleIndication() {
  364. Mac802_11Ext * myUpMAC = (Mac802_11Ext*)(uptarget_);
  365. myUpMAC->handlePHYIdleIndication();
  366. }
  367. int WirelessPhyExt::discard(Packet *p, double power, char* reason) {
  368. struct hdr_cmn *ch = HDR_CMN(p);
  369. double modulation_SINR =SINR_Th(ch->mod_scheme_);
  370. double Xt, Yt, Zt; // location of transmitter
  371. double Xr, Yr, Zr; // location of receiver
  372. PacketStamp s;
  373. s.stamp((MobileNode*)node(), ant_, 0, lambda_);
  374. s.getNode()->getLoc(&Xt, &Yt, &Zt);
  375. p->txinfo_.getNode()->getLoc(&Xr, &Yr, &Zr);
  376. Xr += p->txinfo_.getAntenna()->getX();
  377. Yr += p->txinfo_.getAntenna()->getY();
  378. Zr += p->txinfo_.getAntenna()->getZ();
  379. Xt += s.getAntenna()->getX();
  380. Yt += s.getAntenna()->getY();
  381. Zt += s.getAntenna()->getZ();
  382. double dX = Xr - Xt;
  383. double dY = Yr - Yt;
  384. double dZ = Zr - Zt;
  385. double d = sqrt(dX * dX + dY * dY + dZ * dZ);
  386. if (d < trace_dist_) {
  387. if (power < modulation_SINR * noise_floor_)
  388. reason = "DND";
  389. if (power < CSThresh_ )
  390. reason = "PND";
  391. drop(p, reason);
  392. } else {
  393. Packet::free(p);
  394. }
  395. return 0;
  396. }
  397. void WirelessPhyExt::dump(void) const {
  398. }
  399. void WirelessPhyExt::log(char * event, char* additional) {
  400. if (PHY_DBG)
  401. cout<<"L "<<Scheduler::instance().clock()<<" "<<node_->nodeid()<<" "<<"PHY"<<" "<<event<<" "
  402. <<additional<<endl;
  403. }
  404. void WirelessPhyExt::setState(int newstate) {
  405. if (PHY_DBG) {
  406. char msg[1000];
  407. sprintf(msg, "%d -> %d", state, newstate);
  408. log("PHYState", msg);
  409. }
  410. state = newstate;
  411. }
  412. void TX_Timer::expire(Event *e) {
  413. wirelessPhyExt->handle_TXtimeout();
  414. return;
  415. }
  416. void RX_Timer::expire(Event *e) {
  417. wirelessPhyExt->handle_RXtimeout();
  418. return;
  419. }
  420. void PreRX_Timer::expire(Event *e) {
  421. wirelessPhyExt->handle_PreRXtimeout();
  422. return;
  423. }
  424. //***************************************************************
  425. PowerTimer::PowerTimer(double power, double duration, PowerMonitor * pMonitor) :
  426. TimerHandler() {
  427. powerMonitor = pMonitor;
  428. signalPower = power;
  429. sched(duration);
  430. }
  431. void PowerTimer::expire(Event *e) {
  432. // when the entry timer expires, subtract the power from the additive_noise,
  433. // because the tranmission of that MAC frame is over,
  434. double pre_power = powerMonitor->getPowerLevel();
  435. double post_power = powerMonitor->getPowerLevel() - signalPower;
  436. char msg[1000];
  437. sprintf(msg, "Power: %f -> %f", pre_power*1e9, post_power*1e9);
  438. (powerMonitor->wirelessPhyExt)->log("PMX", msg);
  439. powerMonitor->setPowerLevel(post_power);
  440. // check if the channel becomes idle ( busy -> idle )
  441. if (powerMonitor->state == BUSY && post_power < powerMonitor->CS_Thresh) {
  442. powerMonitor->state = IDLE;
  443. (powerMonitor->wirelessPhyExt)->sendCSIdleIndication();
  444. }
  445. //remove the PowerTimerEntry in the powerTimerList
  446. PowerTimerList * plist = &(powerMonitor->powerTimerList);
  447. PowerTimerList::iterator it;
  448. if (!(powerMonitor->powerTimerList).empty() ) {
  449. it = plist->begin();
  450. int found = 0;
  451. while (it!= plist->end() ) {
  452. if (*it == this) {
  453. found = 1;
  454. break;
  455. }
  456. it++;
  457. }
  458. if (found) {
  459. plist->erase(it);
  460. }
  461. }
  462. delete this;
  463. }
  464. //**************************************************************
  465. PowerMonitor::PowerMonitor(WirelessPhyExt * phy) {
  466. // initialize, the NOISE is the environmental noise
  467. wirelessPhyExt = phy;
  468. CS_Thresh = wirelessPhyExt->CSThresh_; //  monitor_Thresh = CS_Thresh;
  469. monitor_Thresh = wirelessPhyExt->PowerMonitorThresh_;
  470. powerLevel = wirelessPhyExt->noise_floor_; // noise floor is -99dbm
  471. state = IDLE;
  472. }
  473. void PowerMonitor::recordPowerLevel(double signalPower, double duration) {
  474. // to reduce the number of entries recorded in the powerTimerList
  475. if (signalPower < monitor_Thresh )
  476. return;
  477. PowerTimer * pTimer;
  478. // create a powerTimer according to the duration and record the power level
  479. // insert to the powerTimerList
  480. if (duration > 0) {
  481. pTimer = new PowerTimer(signalPower,duration,this);
  482. }
  483. powerLevel += signalPower; // update the powerLevel
  484. powerTimerList.push_back(pTimer); // record the pointer to the powerTimer
  485. // when this Powertimer expires, this portion of power will be substracted from the total power level;
  486. if (state == IDLE && powerLevel >= CS_Thresh) {
  487. wirelessPhyExt->sendCSBusyIndication();
  488. state = BUSY;
  489. }
  490. }
  491. double PowerMonitor::getPowerLevel() {
  492. if (powerLevel > wirelessPhyExt->noise_floor_)
  493. return powerLevel;
  494. else
  495. return wirelessPhyExt->noise_floor_;
  496. }
  497. void PowerMonitor::setPowerLevel(double power) {
  498. powerLevel = power;
  499. }
  500. double PowerMonitor::SINR(double Pr) {
  501. if (getPowerLevel()-Pr<=0) {
  502. // cout<<"PowerLevel lower than Pr"<<endl;exit(-1);
  503. // char msg[1000];
  504. // sprintf(msg,"PowerLevel %f lower than Pr %f = %f",getPowerLevel()*1e9,Pr*1e9,(getPowerLevel()-Pr));
  505. // wirelessPhyExt->log("PMX",msg);
  506. // exit(-1);
  507. return 0.0; //internal event contention, new msg arrives betweeen the expire of two timers.
  508. }
  509. return Pr/(getPowerLevel()-Pr);
  510. }
  511. double WirelessPhyExt::getDist(double Pr, double Pt, double Gt, double Gr,
  512.     double hr, double ht, double L, double lambda)
  513. {
  514. if (propagation_) {
  515. return propagation_->getDist(Pr, Pt, Gt, Gr, hr, ht, L,
  516.      lambda);
  517. }
  518. return 0;
  519. }