bpsk.cc

00001 /*
00002  * Copyright (c) 2007 Regents of the SIGNET lab, University of Padova.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University of Padova (SIGNET lab) nor the 
00014  *    names of its contributors may be used to endorse or promote products 
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00018  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
00019  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00020  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00021  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00023  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00024  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00026  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00027  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include"bpsk.h"
00031 
00032 #include<rng.h>
00033 #include<iostream>
00034 
00035 static class MPhy_BpskClass : public TclClass {
00036 public:
00037   MPhy_BpskClass() : TclClass("Module/MPhy/BPSK") {}
00038   TclObject* create(int, const char*const*) {
00039     return (new MPhy_Bpsk);
00040   }
00041 } class_MPhy_Bpsk;
00042 
00043 
00044 bool MPhy_Bpsk::initialized = false;
00045 int MPhy_Bpsk::modid = -1;
00046 
00047 
00048 
00049 MPhy_Bpsk::MPhy_Bpsk()
00050   : PktRx(0), txPending(false)
00051 {
00052   if (!initialized) 
00053     {
00054       modid = MPhy::registerModulationType(BPSK_MODNAME);
00055       initialized = true;
00056     }
00057   bind("AcquisitionThreshold_dB_", &AcquisitionThreshold_dB_);
00058 }
00059 
00060 
00061 
00062 int MPhy_Bpsk::getModulationType(Packet*)
00063 {
00064   assert(initialized);
00065   return modid;
00066 }
00067 
00068 
00069 double  MPhy_Bpsk::getTxDuration(Packet* p)
00070 {
00071   hdr_cmn* ch = HDR_CMN(p);
00072   hdr_MPhy* ph = HDR_MPHY(p);
00073   
00074   // for BPSK the bandwidth is B = 2/T, 
00075   // where T is the symbol duration.
00076   // Here B is pre-determined by the Spectral Mask,
00077   // so we can calculate the bitrate R = 1/T = B/2
00078 
00079   double bitrate = ph->srcSpectralMask->getBandwidth() / 2.0 ;
00080   double txduration = (ch->size() * 8.0 / bitrate);
00081   if (txduration <=0)
00082     {
00083       cerr << " ch->size(): " << ch->size()
00084            << " bitrate: " << bitrate 
00085            << std::endl;
00086     }
00087   assert(txduration > 0);
00088   
00089   if (debug_)
00090     cerr << showpoint << NOW << " " <<  __PRETTY_FUNCTION__ 
00091          << " packet size: " << ch->size() 
00092          << " tx duration: " << txduration 
00093          << endl;
00094   
00095   return (txduration);
00096 } 
00097 
00098 
00099 void MPhy_Bpsk::startTx(Packet* p)
00100 {
00101   // we abort any ongoing rx activity
00102   PktRx = 0;
00103   txPending = true;
00104   sendDown(p);
00105 
00106 }
00107 
00108 
00109 void MPhy_Bpsk::endTx(Packet* p)
00110 {
00111   txPending = false;
00112   // Notify the MAC
00113   Phy2MacEndTx(p);
00114 }
00115 
00116 
00117 
00118 void MPhy_Bpsk::startRx(Packet* p)
00119 {
00120   hdr_MPhy* ph = HDR_MPHY(p);
00121 
00122   /* ideal synchronization */
00123 
00124 
00125   if ( (PktRx == 0) && (txPending == false) )
00126     {
00127       // The receiver is is not synchronized on any transmission
00128       // so we can sync on this packet
00129 
00130       double snr_dB = 10*log10(ph->Pr / ph->Pn);
00131 
00132       //std::cerr << "snr_dB: " << snr_dB << " AcquisitionThreshold_dB_: " << AcquisitionThreshold_dB_ ;
00133 
00134       if(snr_dB > AcquisitionThreshold_dB_)
00135         {
00136           //std::cerr << " above threshold "<< std::endl;
00137           if (ph->modulationType == modid)
00138             {
00139               // This is a BPSK packet so we sync on it
00140               PktRx = p;
00141               
00142               // Notify the MAC
00143               Phy2MacStartRx(p);
00144               return;
00145             }    
00146         }
00147       else
00148         {
00149           //std::cerr << " below threshold "<< std::endl;
00150         }
00151     }
00152 
00153 }
00154 
00155 
00156 void MPhy_Bpsk::endRx(Packet* p)
00157 {
00158 
00159   if (PktRx != 0)
00160     {
00161                 
00162       hdr_cmn* ch = HDR_CMN(p);
00163       hdr_cmn* rxch = HDR_CMN(PktRx);
00164         
00165         
00166       // NOT RELIABLE!!! packets sometimes have uid == 0!!!             
00167       //      if ( ch->uid()  == rxch->uid() )
00168       if (PktRx == p)
00169         {  
00170           // We had synchronized onto this packet so we now try to see if
00171           // it has been received correctly
00172 
00173           double per_ni; // packet error rate due to noise and/or interference
00174           double per_n;  // packet error rate due to noise only 
00175         
00176           hdr_MPhy* ph = HDR_MPHY(p);
00177         
00178           int nbits = ch->size()*8;
00179           per_n = getPER(ph->Pr/ph->Pn, nbits);
00180           per_ni = getPER(ph->Pr/(ph->Pn + ph->Pi), nbits);
00181 
00182 
00183           double x = RNG::defaultrng()->uniform_double();
00184           bool error_ni = x <= per_ni;
00185           bool error_n = x <= per_n;
00186         
00187           ch->error() = error_ni || error_n ;
00188                         
00189 //        if (error_ni)
00190 //          {
00191 //            drop(p,1,MPHY_DROP_ERROR_INTERFERENCE);
00192 //          }
00193 //        else if (error_n)
00194 //          {
00195 //            drop(p,1,MPHY_DROP_ERROR_NOISE);
00196 //          }
00197 //        else          
00198 //          {
00199 //            sendUp(p);
00200 //          }
00201 
00202           // always send up; the PHY is not responsible for discarding erroneous packets
00203           sendUp(p);
00204 
00205         
00206           PktRx = 0; // We can now sync onto another packet
00207         }
00208       else
00209         {
00210           // We synchronized on another packet, so we are
00211           // not attempting to receive this transmission
00212           Packet::free(p);
00213         }
00214     }
00215   else
00216     {
00217       // We did not synchronize on any packet, so we are
00218       // not attempting to receive this transmission
00219       Packet::free(p);
00220     }
00221         
00222 }
00223 
00224 
00225 double MPhy_Bpsk::getPER(double snr, int nbits)
00226 {
00227   double ber = 0.5*erfc(sqrt(snr));  
00228   double per = 1-pow(1 - ber, nbits );
00229   return per;
00230 }
00231 
00232 
00233 

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2