source: proiecte/ptvs/src/vnsim/network/dsrc/MAC80211.java @ 31

Last change on this file since 31 was 31, checked in by (none), 14 years ago
File size: 7.3 KB
Line 
1/************************************************************************************
2 * Copyright (C) 2008 by Politehnica University of Bucharest and Rutgers University
3 * All rights reserved.
4 * Refer to LICENSE for terms and conditions of use.
5 ***********************************************************************************/
6//Petroaca -
7package vnsim.network.dsrc;
8
9
10import java.io.ByteArrayInputStream;
11import java.util.Random;
12
13import java.util.ArrayList;
14
15import vnsim.core.events.ReceiveEvent;
16import vnsim.core.events.SendEvent;
17import vnsim.map.object.Globals;
18
19
20
21public class MAC80211
22{
23        private int ChannelState;
24       
25        private int RXState,TXState;
26       
27        private int currentTime;
28       
29        private DsrcFrame currentFrame;
30       
31        private static final double relError= 1E-12;
32       
33        //the timer which decides how many simulation times the station will wait until it will reschedule the packet
34        private int backoffTimer;
35       
36        //the sinr threshold for the BPSK code rate
37        private double SINRThreshold=Globals.SINRThresholdBPSK;
38       
39        private Random randBackoff;
40       
41        //contention window ; varies according to the transmission success or failure
42        private int CWSafety,CWVehicleState,CW;
43       
44        //the EDCA mechanism
45        //the safety Access Category in EDCA
46        private ArrayList<SendEvent> ACSafety;
47       
48        //the vehicle state Access Category in EDCA
49        private ArrayList<SendEvent> ACVehicleState;
50       
51        private double receptionRate;
52       
53        private int receivedOk;
54       
55        public MAC80211(int currentTime)
56        {
57                this.ChannelState=Globals.CCA_IDLE;
58               
59                this.RXState=Globals.RX_IDLE;
60                this.TXState=Globals.TX_IDLE;
61               
62                this.currentTime=currentTime;
63                this.currentFrame=new DsrcFrame();
64               
65                this.randBackoff=new Random();
66               
67                this.CWVehicleState=2;
68               
69                this.CWSafety=1;
70               
71                this.CW=0;
72               
73                this.backoffTimer=this.randBackoff.nextInt(this.CWSafety+1);
74               
75                /*
76                this.CWVehicleState=7;
77                this.ACSafety=new ArrayList<SendEvent>();
78                this.ACVehicleState=new ArrayList<SendEvent>();
79                */
80               
81                this.receptionRate=0;
82                this.receivedOk=0;
83        }
84
85        public int getChannelState()
86        {
87                return this.ChannelState;
88        }
89       
90        public void setChannelState(int set)
91        {
92                this.ChannelState=set;
93        }
94       
95        public byte[] recvFromPhysical(ReceiveEvent re,double sinr,int currentTime)
96        {
97               
98               
99                //first check SINR to see if frame is corrupted
100                if(re.getSender()==null)
101                {
102                        if(sinr<this.SINRThreshold)
103                        {
104                                Globals.DSRC_PACKETS_LOST_CORRUPTED++;
105                                return null;
106                        }
107                }
108               
109               
110                //CRC check and BER
111                //should calculate the SINR and BER of the header of the frame in a different modulation than the rest of the frame
112                //calculate PER
113                double preambleBits=Globals.DSRC_PREAMBLE_LENGTH*8,headerBits=Globals.DSRC_PHYHEADER_LENGHT*8,dataBits=0;
114               
115                ByteArrayInputStream byteStream = new ByteArrayInputStream(re.getMessage());
116               
117                dataBits=byteStream.available()*8;
118               
119                double per;
120                if((per=calculatePER(sinr,preambleBits,headerBits,dataBits))>Globals.DSRC_PER_THRESHOLD)
121                {
122                        //per checked ok
123                        //return data to application
124                        this.RXState=Globals.RX_RECV;
125                        Globals.DSRC_PACKETS_RECEIVED_OK++;
126                        this.receivedOk++;
127                        return re.getMessage();
128                }
129                //packet dropped due to bad per check
130               
131                Globals.DSRC_PACKETS_LOST_PER++;
132               
133                return null;
134        }
135       
136        public byte[] sendToPhysical(byte[] message,int currentTime)
137        {
138               
139                //DsrcFrame frame=new DsrcFrame();
140               
141                //check channel state ; employ backoff timer
142                if(this.ChannelState==Globals.CCA_BUSY)
143                {
144                        //channel busy ; pause backoff timer
145                        //this.setBackoffTimer(this.backoffTimer+1);
146                       
147                        //the reason for the faliure to send
148                        if(this.RXState!=Globals.RX_RECV)
149                                Globals.DSRC_PACKETS_SEND_FALIURE_RX++;
150                        else
151                                Globals.DSRC_PACKETS_SEND_FALIURE_NOISE++;
152                       
153                        if(this.TXState!=Globals.TX_RECV)
154                                this.TXState=Globals.TX_RECV;
155                        return null;
156                }
157               
158                //EDCA scheduler - sets the CW to the respective value depending on the message priority
159                this.EDCAScheduler(message[0]);
160                //if(this.TXState==Globals.TX_IDLE)
161                //{
162                        if(this.backoffTimer==0)
163                        {
164                                this.setBackoffTimer(this.randBackoff.nextInt(this.CW+1));
165                                this.TXState=Globals.TX_IDLE;
166                               
167                                return message;
168
169                        }
170                        else
171                        {
172                                this.backoffTimer--;
173                                this.TXState=Globals.TX_RECV;
174                                return null;
175                        }
176                                        //}
177                //return null;
178        }
179       
180        public void refreshFrameTime(int currentTime)
181        {
182                if(currentTime-this.currentTime>=Globals.WIRELESS_TRANSMISSION_FRAMES)
183                {
184                        this.RXState=Globals.RX_IDLE;
185                        this.ChannelState=Globals.CCA_IDLE;
186                       
187                        if(currentTime%4==0)
188                                this.receivedOk=0;
189                }
190               
191                this.currentTime=currentTime;
192               
193        }
194       
195        public double calculatePER(double sinr,double preambleNbits,double headerNbits,double dataNbits)
196        {
197                double psr=1;
198               
199                psr*=calculateBER(sinr,preambleNbits,Globals.DSRC_DATA_RATE);
200                psr*=calculateBER(sinr,headerNbits,Globals.DSRC_PCLP_RATE);
201                psr*=calculateBER(sinr,dataNbits,Globals.DSRC_DATA_RATE);
202               
203                return 1-psr;
204               
205        }
206       
207        public double calculateBER(double sinr,double nbits,double dataRate)
208        {
209                double ber=BPSKBER(sinr,dataRate);
210               
211                double csr=Math.pow(1-ber, nbits);
212               
213                return csr;
214        }
215       
216        public double BPSKBER(double sinr,double dataRate)
217        {
218                double EbNo=sinr * Globals.DSRC_SIGNAL_SPREAD/dataRate;
219               
220                double z=Math.sqrt(EbNo);
221               
222                double ber=0.5 * erfc(z);
223               
224                return ber;
225        }
226       
227        public double erf(double x)
228        {
229                final double twoSqrtPi=2/Math.sqrt(Math.PI);
230               
231                if(Math.abs(x) > 2.2)
232                        return 1.0-erfc(x);
233               
234                double sum=x,term=x,xsqr=x*x;
235               
236                int j=1;
237               
238                do{
239                        term*= xsqr/j;
240                        sum-= term/(2*j+1);
241                        ++j;
242                        term*= xsqr/j;
243                        sum+= term/(2*j+1);
244                        ++j;
245                } while (Math.abs(term/sum) > relError);
246               
247                return twoSqrtPi*sum;
248               
249        }
250       
251        public double erfc(double x)
252        {
253                final double oneSqrtPi=1/Math.sqrt(Math.PI);
254               
255               
256                if(Math.abs(x) < 2.2)
257                        return 1.0-erf(x);
258               
259                if(x<0)
260                        return 2.0-erfc(-x);
261               
262                double a=1, b=x;                //last two convergent numerators
263                double c=x, d=x*x+0.5;          //last two convergent denominators
264                double q1, q2= b/d;             //last two convergents (a/c and b/d)
265                double n= 1.0, t;
266               
267                do {
268                t= a*n+b*x;
269                a= b;
270                b= t;
271                t= c*n+d*x;
272                c= d;
273                d= t;
274                n+= 0.5;
275                q1= q2;
276                q2= b/d;
277                } while (Math.abs(q1-q2)/q2 > relError);
278               
279                return oneSqrtPi*Math.exp(-x*x)*q2;
280        }
281       
282        public void setBackoffTimer(int set)
283        {
284                this.backoffTimer=(set>this.CWSafety)?this.CWSafety:set;
285               
286        }
287       
288        public int getBackoffTimer()
289        {
290                return this.backoffTimer;
291        }
292       
293        public void recalculateCW(int totalPackets,int currentTime)
294        {
295                if(currentTime%4==0 && totalPackets!=0)
296                {
297                        double aux=((double)this.receivedOk/totalPackets*100);
298                       
299                        if(aux-this.receptionRate>Globals.RECEPTION_RATE_THRESHOLD)
300                        {
301                                this.receptionRate=aux;
302                                this.CWSafety=(this.CWSafety==0)?0:this.CWSafety-1;
303                                this.CWVehicleState=(this.CWVehicleState==0)?0:this.CWVehicleState-1;
304                                return;
305                        }
306                       
307                        if(-(aux-this.receptionRate)>Globals.RECEPTION_RATE_THRESHOLD)
308                        {
309                                this.receptionRate=aux;
310                                this.CWSafety++;
311                                this.CWVehicleState++;
312                        }
313                }
314        }
315       
316        public void EDCAScheduler(int messageType)
317        {
318                //to be completed with other message types
319                switch(messageType)
320                {
321                case Globals.PROT_EMERGENCY:
322                                        this.CW=this.CWSafety;
323                                        break;
324                default:        this.CW=this.CWVehicleState;
325                                        break;
326                }
327        }
328}
Note: See TracBrowser for help on using the repository browser.