00001 /* 00002 * Copyright (C) 2007 00003 * Mercedes-Benz Research & Development North America, Inc.and 00004 * University of Karlsruhe (TH) 00005 * All rights reserved. 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License, 00009 * version 2, as published by the Free Software Foundation. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 00019 * 00020 * 00021 * The copyright of this module includes the following 00022 * linking-with-specific-other-licenses addition: 00023 * 00024 * In addition, as a special exception, the copyright holders of 00025 * this module give you permission to combine (via static or 00026 * dynamic linking) this module with free software programs or 00027 * libraries that are released under the GNU LGPL and with code 00028 * included in the standard release of ns-2 under the Apache 2.0 00029 * license or under otherwise-compatible licenses with advertising 00030 * requirements (or modified versions of such code, with unchanged 00031 * license). You may copy and distribute such a system following the 00032 * terms of the GNU GPL for this module and the licenses of the 00033 * other code concerned, provided that you include the source code of 00034 * that other code when and as the GNU GPL requires distribution of 00035 * source code. 00036 * 00037 * Note that people who make modified versions of this module 00038 * are not obligated to grant this special exception for their 00039 * modified versions; it is their choice whether to do so. The GNU 00040 * General Public License gives permission to release a modified 00041 * version without this exception; this exception also makes it 00042 * possible to release a modified version which carries forward this 00043 * exception. 00044 * 00045 */ 00046 00047 /* 00048 * This code was designed and developed by: 00049 * 00050 * Qi Chen : qi.chen@daimler.com 00051 * Felix Schmidt-Eisenlohr : felix.schmidt-eisenlohr@kit.edu 00052 * Daniel Jiang : daniel.jiang@daimler.com 00053 * 00054 * For further information see: 00055 * http://dsn.tm.uni-karlsruhe.de/english/Overhaul_NS-2.php 00056 */ 00057 00058 #ifndef ns_WirelessPhyExt_h 00059 #define ns_WirelessPhyExt_h 00060 00061 #include "phy.h" 00062 #include "propagation.h" 00063 #include "modulation.h" 00064 #include "omni-antenna.h" 00065 #include "mobilenode.h" 00066 #include "timer-handler.h" 00067 #include <list> 00068 #include <packet.h> 00069 00070 typedef enum PhyState {SEARCHING = 0, PreRXing = 1, RXing = 2, TXing = 3}; 00071 00072 typedef struct ModulationParam { 00073 int schemeIndex; 00074 char schemeName[10]; 00075 double SINR_dB; 00076 double SINR_ratio; 00077 int NDBPS; //Data Bits Per Symbol 00078 } ModulationParam; 00079 00080 const struct ModulationParam modulation_table[4] = { 00081 // mod name SINRdB SINR NDBPS bit 00082 { 0, "BPSK", 4, 2.5118, 24 }, { 1, "QPSK", 7, 5.0118, 48 }, { 2, 00083 "QAM16", 12, 15.848, 96 }, { 3, "QAM64", 20, 100.00, 216 } }; 00084 00085 class Phy; 00086 class WirelessPhyExt; 00087 class Propagation; 00088 class PowerMonitor; 00089 00090 //**************************************************************/ 00091 class TX_Timer : public TimerHandler { 00092 public: 00093 TX_Timer(WirelessPhyExt * w) : 00094 TimerHandler() { 00095 wirelessPhyExt = w; 00096 } 00097 protected: 00098 void expire(Event *e); 00099 private: 00100 WirelessPhyExt * wirelessPhyExt; 00101 }; 00102 00103 class RX_Timer : public TimerHandler { 00104 public: 00105 RX_Timer(WirelessPhyExt * w) : 00106 TimerHandler() { 00107 wirelessPhyExt = w; 00108 } 00109 void expire(Event *e); 00110 private: 00111 WirelessPhyExt * wirelessPhyExt; 00112 }; 00113 00114 class PreRX_Timer : public TimerHandler { 00115 public: 00116 PreRX_Timer(WirelessPhyExt * w) : 00117 TimerHandler() { 00118 wirelessPhyExt = w; 00119 } 00120 void expire(Event *e); 00121 private: 00122 WirelessPhyExt * wirelessPhyExt; 00123 }; 00124 00125 //**************************************************************/ 00126 // 1.0 WirelessPhyExt 00127 //**************************************************************/ 00128 00129 /* 00130 The PHY is in the Searching state when it is neither in transmission nor reception of a frame. Within this state, the PHY evaluates each transmission event notification from the Wireless Channel object it is attached to for potentially receivable frames. If a frame arrives with sufficient received signal strength for preamble detection (i.e. SINR > BPSK threshold), the PHY moves into the PreRXing state. 00131 The PHY stays in the PreRXing state for the duration of preamble and Signal portion of the PLCP header. If the SINR of this frame stays above the BPSK and 1/2 coding rate reception threshold throughout this period, the PHY moves into the RXing state to stay for the frame duration. If a later arriving frame from the channel has sufficient received signal strength to prevent proper preamble and PLCP header reception for the current frame, the PHY moves back to the Searching state. However, if this later frame has sufficiently higher signal strength for its own preamble to be heard above others, it will trigger preamble capture, which means the PHY stays in the PreRXing state with a reset timer for the new frame. 00132 Within the RXing state, the PHY handles the reception of the body of the current frame. It monitors the SINR throughout the frame body duration. If the SINR drops below the threshold required by the modulation and coding rate used for the frame body at any time while in this state, the PHY marks the frame with an error flag. After RXing timeout, the PHY moves back to the Searching state. It also passes the frame to the MAC, where the error flag is directly used for the CRC check decision. 00133 If the frame body capture feature is enabled, then it is possible for a later arriving frame to trigger the PHY to move back to the PreRXing state for the new frame in the manner described in section 3.3.2. Otherwise, the later arriving frame has no chance of being received and is only tracked by the power monitor as an interference source. 00134 A transmit command from the MAC will move the PHY into the TXing state for the duration of a frame transmission regardless what the PHY is doing at the moment. The expiration of the transmission timer ends the TXing state. If a frame comes in from the channel when the PHY is in the TXing state, it is ignored and only tracked by the power monitor as interference. 00135 Usually the MAC will not issue a transmit command while the PHY is in the PreRXing or RXing state because of the carrier sense mechanism. However, the IEEE 802.11 standard mandates the receiver of a unicast data frame addressed to itself to turn around after SIFS and transmit an ACK frame regardless of the channel condition. Similarly, the receiver of a RTS frame, if it has an empty NAV (Network Allocation Vector), will wait for SIFS and then transmit a CTS frame regardless of the channel condition. Such scenarios are represented by the two dashed lines shown in the state machine. The PHY is designed to drop and clean up the frame it is attempting to receive and move into TXing state when this happens. 00136 The MAC, however, should never issue a transmit command when the PHY is still in the TXing state. The new frame has little chance of being received within its intended audience because others in general have no means to tell that a new frame is suddenly started. Therefore, the PHY is designed to issue an error and halt the simulator when this event happens because it means the MAC above has a critical error in design or implementation. 00137 00138 */ 00139 00140 class WirelessPhyExt : public WirelessPhy { 00141 public: 00142 WirelessPhyExt(); 00143 // inline double getAntennaZ() { return ant_->getZ(); } 00144 inline double getL() const { 00145 return L_; 00146 } 00147 inline double getLambda() const { 00148 return lambda_; 00149 } 00150 inline Node* node(void) const { 00151 return node_; 00152 } 00153 void setState(int newstate); 00154 00155 virtual int command(int argc, const char*const* argv); 00156 virtual void dump(void) const; 00157 00158 //timer handlers 00159 void handle_TXtimeout(); 00160 void handle_RXtimeout(); 00161 void handle_PreRXtimeout(); 00162 00163 //signalling to MAC layer 00164 void sendCSBusyIndication(); 00165 void sendCSIdleIndication(); 00166 00167 //ns2 calls 00168 void sendDown(Packet *p); 00169 int sendUp(Packet *p); 00170 00171 int discard(Packet *p, double power, char* reason); 00172 double getDist(double Pr, double Pt, double Gt, double Gr, 00173 double hr, double ht, double L, double lambda); 00174 inline double getAntennaZ() { return ant_->getZ(); } 00175 00176 00177 private: 00178 // variables to be bound 00179 double lambda_; // wavelength (m) 00180 double CSThresh_; // carrier sense threshold (W) fixed by chipset 00181 double CPThresh_; // capture threshold 00182 double RXThresh_; // capture threshold 00183 double Pt_; // transmitted signal power (W) 00184 double freq_; // frequency 00185 double L_; // system loss factor 00186 double HeaderDuration_; // preamble+SIGNAL 00187 int BasicModulationScheme_; 00188 int PreambleCaptureSwitch_; //PreambleCaptureSwitch 00189 int DataCaptureSwitch_; //DataCaptureSwitch 00190 double SINR_PreambleCapture_; 00191 double SINR_DataCapture_; 00192 00193 int PHY_DBG; 00194 double trace_dist_; 00195 double noise_floor_; 00196 double PowerMonitorThresh_; 00197 00198 Propagation *propagation_; 00199 Antenna *ant_; 00200 PowerMonitor *powerMonitor; 00201 TX_Timer tX_Timer; 00202 RX_Timer rX_Timer; 00203 PreRX_Timer preRX_Timer; 00204 int state; 00205 00206 Packet *pkt_RX; 00207 double SINR_Th_RX; //SINR threshold for decode data according to the modulation scheme 00208 double power_RX; 00209 00210 void log(char * event, char* additional); // print out state informration 00211 double SINR_Th(int modulationScheme); 00212 inline int initialized() { 00213 return (node_ && uptarget_ && downtarget_ && propagation_); 00214 } 00215 00216 friend class TX_Timer; 00217 friend class RX_Timer; 00218 friend class PreRX_Timer; 00219 friend class PowerMonitor; 00220 friend class PowerTimer; 00221 }; 00222 00223 //**************************************************************/ 00224 // 2.0 PowerMonitor 00225 //**************************************************************/ 00226 /* 00227 The power monitor module corresponds to the PMD (Physical Media Dependent) sub-layer within the PHY. PMD is the only sub-layer that directly interacts with the analog RF signals. Therefore, all information on received signals is processed and managed in this module. 00228 The power monitor module keeps track of all the noise and interferences experienced by the node individually for their respective durations. Whenever the cumulative interference and noise level rises crosses the carrier sense threshold, it signals the MAC on physical carrier sense status changes. It should be noted that a node's own transmission is treated as carrier sense busy through this signaling interface as well. 00229 */ 00230 //**************************************************************/ 00231 class PowerTimer : public TimerHandler { 00232 public: 00233 PowerTimer(double power, double duration, PowerMonitor *); 00234 inline double getPower() { 00235 return signalPower; 00236 } 00237 void expire(Event *); //virtual function, which must be implemented 00238 protected: 00239 double signalPower; 00240 00241 private: 00242 PowerMonitor * powerMonitor; 00243 }; 00244 00245 //**************************************************************/ 00246 typedef PowerTimer* pTimer; 00247 typedef std::list<PowerTimer *> PowerTimerList; 00248 00249 typedef enum PowerMonitorState {IDLE = 0, BUSY = 1}; 00250 00251 class PowerMonitor { 00252 public: 00253 PowerMonitor(WirelessPhyExt *); 00254 void recordPowerLevel(double power, double duration); 00255 double getPowerLevel(); 00256 void setPowerLevel(double); 00257 double SINR(double Pr); 00258 00259 private: 00260 double CS_Thresh; 00261 double monitor_Thresh;//packet with power > monitor_thresh will be recorded in the monitor 00262 double powerLevel; 00263 WirelessPhyExt * wirelessPhyExt; 00264 PowerTimerList powerTimerList; 00265 int state; 00266 friend class PowerTimer; 00267 }; 00268 00269 #endif /* !ns_WirelessPhyExt_h */