ofdmphy.cc
上传用户:hzie11
上传日期:2013-10-07
资源大小:1487k
文件大小:7k
源码类别:

网络

开发平台:

C/C++

  1. /* This software was developed at the National Institute of Standards and
  2.  * Technology by employees of the Federal Government in the course of
  3.  * their official duties. Pursuant to title 17 Section 105 of the United
  4.  * States Code this software is not subject to copyright protection and
  5.  * is in the public domain.
  6.  * NIST assumes no responsibility whatsoever for its use by other parties,
  7.  * and makes no guarantees, expressed or implied, about its quality,
  8.  * reliability, or any other characteristic.
  9.  * <BR>
  10.  * We would appreciate acknowledgement if the software is used.
  11.  * <BR>
  12.  * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
  13.  * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
  14.  * FROM THE USE OF THIS SOFTWARE.
  15.  * </PRE></P>
  16.  * @author  rouil
  17.  */
  18. #include "ofdmphy.h"
  19. #include "mac802_16pkt.h"
  20. //#define DEBUG_WIMAX 1
  21. /**
  22.  * Tcl hook for creating the physical layer
  23.  */
  24. static class OFDMPhyClass: public TclClass {
  25. public:
  26.         OFDMPhyClass() : TclClass("Phy/WirelessPhy/OFDM") {}
  27.         TclObject* create(int, const char*const*) {
  28.                 return (new OFDMPhy);
  29.         }
  30. } class_OfdmPhy;
  31. OFDMPhy::OFDMPhy() : WirelessPhy()
  32. {
  33.   //bind attributes
  34.   bind ("g_", &g_);
  35.   //bind ("rtg_", &rtg_);
  36.   //bind ("ttg_", &ttg_);
  37.   //bind ("fbandwidth_", &fbandwidth_);
  38.   //default modulation is BPSK
  39.   modulation_ = OFDM_BPSK_1_2;
  40.   Tcl& tcl = Tcl::instance();
  41.   tcl.evalf("Mac/802_16 set fbandwidth_");
  42.   fbandwidth_ = atof (tcl.result()); 
  43.   state_ = OFDM_IDLE;
  44.   activated_ = true;
  45.   updateFs ();
  46. }
  47. /*
  48.  * Activate node
  49.  */
  50. void OFDMPhy::node_on ()
  51. {
  52.   activated_ = true;
  53. }
  54. /*
  55.  * Deactivate node
  56.  */
  57. void OFDMPhy::node_off ()
  58. {
  59.   activated_ = false;
  60. }
  61. /**
  62.  * Change the frequency at which the phy is operating
  63.  * @param freq The new frequency
  64.  */
  65. void OFDMPhy::setFrequency (double freq)
  66. {
  67.   freq_ = freq;
  68.   lambda_ = SPEED_OF_LIGHT / freq_;
  69. }
  70. /**
  71.  * Set the new modulation for the physical layer
  72.  */
  73. void OFDMPhy::setModulation (Ofdm_mod_rate modulation) {
  74.   modulation_ = modulation;
  75. }
  76. /**
  77.  * Return the current modulation
  78.  */
  79. Ofdm_mod_rate OFDMPhy::getModulation () {
  80.   return modulation_;
  81. }
  82. /**
  83.  * Set the new transmitting power
  84.  */
  85. void OFDMPhy::setTxPower (double power) {
  86.   Pt_ = power;
  87. }
  88. /**
  89.  * Return the current transmitting power
  90.  */
  91. double OFDMPhy::getTxPower () {
  92.   return getPt();
  93. }
  94. /** 
  95.  * Update the PS information
  96.  */
  97. void OFDMPhy::updateFs () {
  98.   /* The PS=4*Fs with Fs=floor (n.BW/8000)*8000
  99.    * and n=8/7 is channel bandwidth multiple of 1.75Mhz
  100.    * n=86/75 is channel bandwidth multiple of 1.5Mhz
  101.    * n=144/125 is channel bandwidth multiple of 1.25Mhz
  102.    * n=316/275 is channel bandwidth multiple of 2.75Mhz
  103.    * n=57/50 is channel bandwidth multiple of 2.0Mhz
  104.    * n=8/7 for all other cases
  105.    */
  106.   double n; 
  107.   if (((int) (fbandwidth_ / 1.75)) * 1.75 == fbandwidth_) {
  108.     n = 8.0/7;
  109.   } else if (((int) (fbandwidth_ / 1.5)) * 1.5 == fbandwidth_) {
  110.     n = 86.0/75;
  111.   } else if (((int) (fbandwidth_ / 1.25)) * 1.25 == fbandwidth_) {
  112.     n = 144.0/125;
  113.   } else if (((int) (fbandwidth_ / 2.75)) * 2.75 == fbandwidth_) {
  114.     n = 316.0/275;
  115.   } else if (((int) (fbandwidth_ / 2.0)) * 2.0 == fbandwidth_) {
  116.     n = 57.0/50;
  117.   } else {
  118.     n = 8.0/7;
  119.   }
  120.   fs_ = floor (n*fbandwidth_/8000) * 8000;
  121. #ifdef DEBUG_WIMAX
  122.   printf ("Fs updated. Bw=%f, n=%f, new value is %en", fbandwidth_, n, fs_);
  123. #endif
  124. }
  125. /*
  126.  * Compute the transmission time for a packet of size sdusize and
  127.  * using the given modulation
  128.  * @param sdusize Size in bytes of the data to send
  129.  * @param mod The modulation to use
  130.  */
  131. double OFDMPhy::getTrxTime (int sdusize, Ofdm_mod_rate mod) {
  132.   //we compute the number of symbols required
  133.   int nb_symbols, bpsymb;
  134.   switch (mod) {
  135.   case OFDM_BPSK_1_2:
  136.     bpsymb = OFDM_BPSK_1_2_bpsymb;
  137.     break;
  138.   case OFDM_QPSK_1_2:
  139.     bpsymb = OFDM_QPSK_1_2_bpsymb;
  140.     break;
  141.   case OFDM_QPSK_3_4:
  142.     bpsymb = OFDM_QPSK_3_4_bpsymb;
  143.     break;
  144.   case OFDM_16QAM_1_2:
  145.     bpsymb = OFDM_16QAM_1_2_bpsymb;
  146.     break;
  147.   case OFDM_16QAM_3_4:
  148.     bpsymb = OFDM_16QAM_3_4_bpsymb;
  149.     break;
  150.   case OFDM_64QAM_2_3:
  151.     bpsymb = OFDM_64QAM_2_3_bpsymb;
  152.     break;
  153.   case OFDM_64QAM_3_4:
  154.     bpsymb = OFDM_64QAM_3_4_bpsymb;
  155.     break;
  156.   default:
  157.     printf ("Error: unknown modulation: method getTrxTime in file ofdmphy.ccn");
  158.     exit (1);
  159.   }
  160. #ifdef DEBUG_WIMAX
  161.   printf ("Nb symbols=%dn", (int) (ceil(((double)sdusize*8)/bpsymb)));
  162. #endif
  163.   nb_symbols = (int) (ceil(((double)sdusize*8)/bpsymb));
  164.   return (nb_symbols*getSymbolTime ());
  165. }
  166. /*
  167.  * Return the maximum size in bytes that can be sent for the given 
  168.  * nb symbols and modulation
  169.  */
  170. int OFDMPhy::getMaxPktSize (double nbsymbols, Ofdm_mod_rate mod)
  171. {
  172.   int bpsymb;
  173.   switch (mod) {
  174.   case OFDM_BPSK_1_2:
  175.     bpsymb = OFDM_BPSK_1_2_bpsymb;
  176.     break;
  177.   case OFDM_QPSK_1_2:
  178.     bpsymb = OFDM_QPSK_1_2_bpsymb;
  179.     break;
  180.   case OFDM_QPSK_3_4:
  181.     bpsymb = OFDM_QPSK_3_4_bpsymb;
  182.     break;
  183.   case OFDM_16QAM_1_2:
  184.     bpsymb = OFDM_16QAM_1_2_bpsymb;
  185.     break;
  186.   case OFDM_16QAM_3_4:
  187.     bpsymb = OFDM_16QAM_3_4_bpsymb;
  188.     break;
  189.   case OFDM_64QAM_2_3:
  190.     bpsymb = OFDM_64QAM_2_3_bpsymb;
  191.     break;
  192.   case OFDM_64QAM_3_4:
  193.     bpsymb = OFDM_64QAM_3_4_bpsymb;
  194.     break;
  195.   default:
  196.     printf ("Error: unknown modulation: method getTrxTime in file ofdmphy.ccn");
  197.     exit (1);
  198.   }
  199.   return (int)(nbsymbols*bpsymb)/8;
  200. }
  201. /**
  202.  * Return the OFDM symbol duration time
  203.  */
  204. double OFDMPhy::getSymbolTime () 
  205.   //printf ("fs=%e, Subcarrier spacing=%en", fs_, fs_/((double)NFFT));
  206.   return (1+g_)*((double)NFFT)/fs_; 
  207. }
  208. /*
  209.  * Set the mode for physical layer
  210.  * The Mac layer is in charge of know when to change the state by 
  211.  * request the delay for the Rx2Tx and Tx2Rx
  212.  */
  213. void OFDMPhy::setMode (Ofdm_phy_state mode)
  214. {
  215.   state_ = mode;
  216. }
  217. /* Redefine the method for sending a packet
  218.  * Add physical layer information
  219.  * @param p The packet to be sent
  220.  */
  221. void OFDMPhy::sendDown(Packet *p)
  222. {
  223.   hdr_mac802_16* wph = HDR_MAC802_16(p);
  224.   /* Check phy status */
  225.   if (state_ != OFDM_SEND) {
  226.     printf ("Warning: OFDM not in sending state. Drop packet.n");
  227.     Packet::free (p);
  228.     return;
  229.   }
  230. #ifdef DEBUG_WIMAX
  231.   printf ("OFDM phy sending packet. Modulation is %d, cyclic prefix is %fn", 
  232.   modulation_, g_);
  233. #endif 
  234.   wph->phy_info.freq_ = freq_;
  235.   wph->phy_info.modulation_ = modulation_;
  236.   wph->phy_info.g_ = g_;
  237.   //the packet can be sent
  238.   WirelessPhy::sendDown (p);
  239. }
  240. /* Redefine the method for receiving a packet
  241.  * Add physical layer information
  242.  * @param p The packet to be sent
  243.  */
  244. int OFDMPhy::sendUp(Packet *p)
  245. {
  246.   hdr_mac802_16* wph = HDR_MAC802_16(p);
  247.   if (!activated_)
  248.     return 0;
  249.   if (freq_ != wph->phy_info.freq_) {
  250. #ifdef DEBUG_WIMAX
  251.     printf ("drop packet because frequency is different (%f, %f)n", freq_,wph->phy_info.freq_);
  252. #endif 
  253.     return 0;
  254.   }
  255.   /* Check phy status */
  256.   if (state_ != OFDM_RECV) {
  257. #ifdef DEBUG_WIMAX
  258.     printf ("Warning: OFDM phy not in receiving state. Drop packet.n");
  259. #endif 
  260.     return 0;
  261.   }
  262. #ifdef DEBUG_WIMAX
  263.   printf ("OFDM phy receiving packet with mod=%d and cp=%fn", wph->phy_info.modulation_,wph->phy_info.g_);
  264. #endif 
  265.   
  266.   //the packet can be received
  267.   return WirelessPhy::sendUp (p);
  268. }