📄 errormodel80211.cc
字号:
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include "config.h"#include "ErrorModel80211.h"int ErrorModel80211::initialized_=0;int ErrorModel80211::isShortPreamble_=0;int ErrorModel80211::noise1_=-94; //gotten from Orinoco card specification. Configurable.int ErrorModel80211::noise2_=-91;int ErrorModel80211::noise55_=-87;int ErrorModel80211::noise11_=-82;double ErrorModel80211::noiseW1_; //In Watt.double ErrorModel80211::noiseW2_;double ErrorModel80211::noiseW55_;double ErrorModel80211::noiseW11_;double ErrorModel80211::ber_snr_[EM80211_NUM_MOD][EM80211_MAX_SNR+1];double ErrorModel80211::preamble_succProb_[EM80211_MAX_SNR+1];double ErrorModel80211::plcp_succProb_[EM80211_MAX_SNR+1];double ErrorModel80211::ack_succProb_[EM80211_NUM_MOD][EM80211_MAX_SNR+1];double ErrorModel80211::rts_succProb_[EM80211_NUM_MOD][EM80211_MAX_SNR+1];double ErrorModel80211::cts_succProb_[EM80211_NUM_MOD][EM80211_MAX_SNR+1];static class ErrorModel80211Class: public TclClass{public: ErrorModel80211Class() : TclClass("ErrorModel80211") {} TclObject* create(int argc, const char * const * argv) { return (new ErrorModel80211()); } virtual void bind(); virtual int method(int argc, const char * const * argv);} class_errormodel80211;void ErrorModel80211Class::bind(){ TclClass::bind(); add_method("shortpreamble"); add_method("noise1"); add_method("noise2"); add_method("noise55"); add_method("noise11"); add_method("LoadBerSnrFile");}int ErrorModel80211Class::method(int ac, const char* const * av){ Tcl& tcl = Tcl::instance(); int argc = ac - 2; const char* const * argv = av+2; if(argc == 2) { if(strcmp(argv[1],"shortpreamble")==0) { tcl.resultf("%d",ErrorModel80211::isShortPreamble_); return (TCL_OK); }else if(strcmp(argv[1],"noise1")==0) { tcl.resultf("%d",ErrorModel80211::noise1_); return (TCL_OK); }else if(strcmp(argv[1],"noise2")==0) { tcl.resultf("%d",ErrorModel80211::noise2_); return (TCL_OK); }else if(strcmp(argv[1],"noise55")==0) { tcl.resultf("%d",ErrorModel80211::noise55_); return (TCL_OK); }else if(strcmp(argv[1],"noise11")==0) { tcl.resultf("%d",ErrorModel80211::noise11_); return (TCL_OK); } }else if(argc == 3 ) { if(strcmp(argv[1],"shortpreamble")==0) { ErrorModel80211::isShortPreamble_ = atoi(argv[2]); return (TCL_OK); }else if(strcmp(argv[1],"noise1")==0) { ErrorModel80211::noise1_ = atoi(argv[2]); ErrorModel80211::noiseW1_ = pow(10, ErrorModel80211::noise1_/10)/1000; return (TCL_OK); }else if(strcmp(argv[1],"noise2")==0) { ErrorModel80211::noise2_ = atoi(argv[2]); ErrorModel80211::noiseW2_ = pow(10, ErrorModel80211::noise2_/10)/1000; return (TCL_OK); }else if(strcmp(argv[1],"noise55")==0) { ErrorModel80211::noise55_= atoi(argv[2]); ErrorModel80211::noiseW55_ = pow(10, ErrorModel80211::noise55_/10)/1000; return (TCL_OK); }else if(strcmp(argv[1],"noise11")==0) { ErrorModel80211::noise11_ = atoi(argv[2]); ErrorModel80211::noiseW11_ = pow(10, ErrorModel80211::noise11_/10)/1000; return (TCL_OK); }else if(strcmp(argv[1],"LoadBerSnrFile")==0) { int rc; rc = ErrorModel80211::initialize(argv[2]); if(rc == TCL_OK) ErrorModel80211::initialized_=1; return rc; } } return TclClass::method(ac,av);}int ErrorModel80211::initialize(const char* const& filename){ FILE *fin; char line[100]; int i,j,snr; int min,max; double d1,d2,d3,d4; i=0;j=0; min=EM80211_MAX_SNR; max=0; for(i=0;i<EM80211_NUM_MOD;i++) for(j=0;j<=EM80211_MAX_SNR;j++) ber_snr_[i][j]=-1; fin = fopen(filename,"r"); if(fin==NULL) { printf("%s can not be opened! Please check the file name for ber_snr table. \n", filename); return(-1); } while(fgets(line,100,fin)!=NULL) { sscanf(line, "%d %lf %lf %lf %lf",&snr,&d1,&d2,&d3,&d4); if((snr>=0)&&(snr<=EM80211_MAX_SNR)) { ber_snr_[0][snr]=d1; ber_snr_[1][snr]=d2; ber_snr_[2][snr]=d3; ber_snr_[3][snr]=d4; if(snr<min) min = snr; if(snr>max) max = snr; } } for(i=0;i<EM80211_NUM_MOD;i++) { ber_snr_[i][0] = 1; for(j=1;j<min;j++) ber_snr_[i][j] = ber_snr_[i][min]; for(j=max+1;j<=EM80211_MAX_SNR;j++) ber_snr_[i][j] = ber_snr_[i][max]; } fclose(fin); preCalculate(); //printTables(); printf("ErrorModel80211 is initialized successfully with %s \n",filename); initialized_ = 1; return TCL_OK;}void ErrorModel80211::preCalculate(){ int preamble_len; int plcp_mode; int i,j; if(isShortPreamble_) { preamble_len = EM80211_SPREAMBLE_L; plcp_mode = EM80211_QPSK; } else { preamble_len = EM80211_LPREAMBLE_L; plcp_mode=EM80211_BPSK; } for(i=0;i<=EM80211_MAX_SNR;i++) { preamble_succProb_[i] = pow((1-ber_snr_[0][i]),preamble_len); plcp_succProb_[i] = pow((1-ber_snr_[plcp_mode][i]),EM80211_PLCP_L); } for(i=0;i<=EM80211_MAX_SNR;i++) { for(j=0;j<EM80211_NUM_MOD;j++) { ack_succProb_[j][i]=pow((1-ber_snr_[j][i]),EM80211_ACK_L); rts_succProb_[j][i]=pow((1-ber_snr_[j][i]),EM80211_RTS_L); cts_succProb_[j][i]=pow((1-ber_snr_[j][i]),EM80211_CTS_L); } } return;}void ErrorModel80211::printTables(){ int i; printf("SNR BER_mod1 BER_mod2 BER_mod3 BER_mod4....\n"); for(i=0;i<=EM80211_MAX_SNR;i++) { printf("%d %E %E %E %E\n",i,ber_snr_[0][i],ber_snr_[1][i],ber_snr_[2][i],ber_snr_[3][i]); } printf("\n\n Preamble Success Probaility ....\n"); for(i=0;i<=EM80211_MAX_SNR;i++) { printf("%d %E\n",i,preamble_succProb_[i]); } printf("\n\n PLCP header success probability....\n"); for(i=0;i<=EM80211_MAX_SNR;i++) { printf("%d %E\n",i,plcp_succProb_[i]); } printf("\n\n Successful probalility of ACK frame without PHY header ....\n"); for(i=0;i<=EM80211_MAX_SNR;i++) { printf("%d %E %E %E %E\n",i,ack_succProb_[0][i],ack_succProb_[1][i],ack_succProb_[2][i],ack_succProb_[3][i]); } printf("\n\n Successful probalility of RTS frame ....\n"); for(i=0;i<=EM80211_MAX_SNR;i++) { printf("%d %E %E %E %E\n",i,rts_succProb_[0][i],rts_succProb_[1][i],rts_succProb_[2][i],rts_succProb_[3][i]); } printf("\n\n Successful probalility of CTS frame ....\n"); for(i=0;i<=EM80211_MAX_SNR;i++) { printf("%d %E %E %E %E\n",i,cts_succProb_[0][i],cts_succProb_[1][i],cts_succProb_[2][i],cts_succProb_[3][i]); } }double ErrorModel80211::frameErrorRate( int frameType, double signal, double interference, double rate, int fullLen, int* snr_return){ int mode,len; double fer; double noise; double ex_snr; int snr,snr_pre,snr_plcp; if(initialized_==0) return 0; if (rate < 1.5E6 ){ noise = noiseW1_; mode = EM80211_BPSK; } else if (rate < 2.5E6 ) { noise = noiseW2_; mode = EM80211_QPSK; } else if (rate < 6.5E6 ) { noise = noiseW55_; mode = EM80211_CCK55; } else { noise = noiseW11_; mode = EM80211_CCK11; } ex_snr = 10*log10(signal/(noise+interference)); if(ex_snr>0) { if(ex_snr > EM80211_MAX_SNR) snr = EM80211_MAX_SNR; else snr = (int) ex_snr; } else snr = 0; *snr_return = snr; ex_snr = 10*log10(signal/(noiseW1_+interference)); if(ex_snr>0) { if(ex_snr > EM80211_MAX_SNR) snr_pre = EM80211_MAX_SNR; else snr_pre = (int) ex_snr; } else snr_pre = 0; if(!isShortPreamble_) snr_plcp = snr_pre; else { ex_snr = 10*log10(signal/(noiseW2_+interference)); if(ex_snr>0) { if(ex_snr > EM80211_MAX_SNR) snr_plcp = EM80211_MAX_SNR; else snr_plcp = (int) ex_snr; } else snr_plcp = 0; } if(snr > EM80211_MAX_SNR) snr = EM80211_MAX_SNR; if(frameType == EM80211_ACK) return 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*ack_succProb_[mode][snr]; else if(frameType == EM80211_RTS) return 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*rts_succProb_[mode][snr]; else if(frameType == EM80211_CTS) return 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*cts_succProb_[mode][snr]; if(isShortPreamble_) len = fullLen - (EM80211_SPREAMBLE_L+EM80211_PLCP_L)/8; else len = fullLen - (EM80211_LPREAMBLE_L+EM80211_PLCP_L)/8; fer = 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*pow((1-ber_snr_[mode][snr]),len*8); //printf("ErrorModel80211.cc --- SNR: %d, Length: %d, fer: %E\n",snr,fullLen, fer); return fer;}double ErrorModel80211::ferBySnr(int frameType, int snr, int len, double rate){ double fer; int snr_pre,snr_plcp,mode; if(initialized_ == 0) return 0; snr_pre = snr + snrDeltaBetweenRates(1E6,rate); if(rate < 1.5E6) mode = EM80211_BPSK; else if(rate <2.5E6) mode = EM80211_QPSK; else if(rate <6E6) mode = EM80211_CCK55; else mode = EM80211_CCK11; if(!isShortPreamble_) snr_plcp = snr_pre; else snr_plcp = snr_pre + (noise2_-noise1_); if(snr_pre > EM80211_MAX_SNR) snr_pre = EM80211_MAX_SNR; if(snr_plcp >EM80211_MAX_SNR) snr_plcp = EM80211_MAX_SNR; if(snr > EM80211_MAX_SNR) snr = EM80211_MAX_SNR; if(frameType == EM80211_ACK) return 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*ack_succProb_[mode][snr]; else if(frameType == EM80211_RTS) return 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*rts_succProb_[mode][snr]; else if(frameType == EM80211_CTS) return 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*cts_succProb_[mode][snr]; fer = 1-preamble_succProb_[snr_pre]*plcp_succProb_[snr_plcp]*pow((1-ber_snr_[mode][snr]),len*8); return fer;}/*rate1 should always less than or equal to rate2*/int ErrorModel80211::snrDeltaBetweenRates(double rate1, double rate2){ if (rate1 < 1.5E6 ) { if(rate2 <1.5E6) return 0; else if(rate2 <2.5E6) return (noise2_-noise1_); else if(rate2 < 6.5E6) return (noise55_-noise1_); else return (noise11_-noise2_); }else if(rate1 < 2.5E6) { if(rate2 <2.5E6) return 0; else if(rate2 <6.5E6) return (noise55_-noise2_); else return (noise11_-noise2_); }else if(rate1 <6.5E6) { if(rate2 <6.5E6) return 0; else return (noise11_-noise55_); } else return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -