NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
IEEE802_11_Phy.c
1/************************************************************************************
2* Copyright (C) 2023 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* This source code is licensed per the NetSim license agreement. *
12* *
13* No portion of this source code may be used as the basis for a derivative work, *
14* or used, for any purpose other than its intended use per the NetSim license *
15* agreement. *
16* *
17* This source code and the algorithms contained within it are confidential trade *
18* secrets of TETCOS and may not be used as the basis for any other software, *
19* hardware, product or service. *
20* *
21* Author: Shashi Kant Suman *
22* *
23* ----------------------------------------------------------------------------------*/
24#include "main.h"
25#include "IEEE802_11.h"
26#include "IEEE802_11_Phy.h"
27#include "IEEE802_11_MAC_Frame.h"
28#include "IEEE802_11_PhyFrame.h"
29#include "NetSim_utility.h"
30#include "Medium.h"
31#include "AdvancedPlots.h"
32#pragma comment(lib,"AdvancedPlots.lib")
33
34double DSSSPhy_get_min_rxSensitivity();
35double ofdmphy_get_min_rxSensitivity(double bandwidth);
36double HTPhy_get_min_rxSensitivity(double bandwidth, UINT NSS);
37double HEPhy_get_min_rxSensitivity(double bandwidth, UINT NSS);
38double fn_NetSim_IEEE802_11_GetMinRxSensitivity(NETSIM_ID txId, NETSIM_ID txIf);
39
40#define SPEED_OF_LIGHT 299.792458 // meter per micro sec
41static double calculate_propagation_delay(NetSim_PACKET* packet)
42{
43 NETSIM_ID tx=packet->nTransmitterId;
44 NETSIM_ID rx=packet->nReceiverId;
45 double d=fn_NetSim_Utilities_CalculateDistance(DEVICE_POSITION(tx),DEVICE_POSITION(rx));
46 return d/SPEED_OF_LIGHT;
47}
48
49/**
50~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
51This function is used to configure the PhySical Layer parameters of device.
52Configure the Preamble and PLCP header length.
53Configure Control and broadcast frame data rate.
54Calculate DIFS, EIFS and RIFS values.
55Assign CS Threshold Value.
56~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57*/
58int fn_NetSim_IEEE802_11_PHY_Init(NETSIM_ID nDeviceId,NETSIM_ID nInterfaceId)
59{
60 PIEEE802_11_PHY_VAR pstruPhyVar=IEEE802_11_PHY(nDeviceId,nInterfaceId);
61
62 //Turn on the radio
63 pstruPhyVar->radio.radioState = RX_ON_IDLE;
64
65 switch(pstruPhyVar->PhyType)
66 {
67 case OFDM: //Table 18-17—OFDM PHY characteristics page 1623
68 switch((int)pstruPhyVar->dChannelBandwidth)
69 {
70 case 20:
71 pstruPhyVar->plmeCharacteristics.aPLCPHeaderLength = 4 ; //MicroSecs
72 pstruPhyVar->plmeCharacteristics.aPreambleLength = 16; //MicroSecs
73 pstruPhyVar->plmeCharacteristics.aCCATime = 4; //MicroSecs
74 pstruPhyVar->plmeCharacteristics.aMACProcessingDelay = 2;//MicroSecs
75 pstruPhyVar->plmeCharacteristics.aMPDUDurationFactor = 0;
76 pstruPhyVar->plmeCharacteristics.aMPDUMaxLength = 4095;
77 pstruPhyVar->plmeCharacteristics.aPHY_RX_START_Delay = 25;//MicroSecs
78 pstruPhyVar->plmeCharacteristics.aRxPLCPDelay = 1; //MicroSecs
79 pstruPhyVar->plmeCharacteristics.aRxRFDelay = 1; //MicroSecs
80 pstruPhyVar->plmeCharacteristics.aRxTxSwitchTime = 1; // MicroSecs
81 pstruPhyVar->plmeCharacteristics.aRxTxTurnaroundTime = 2;//MicroSecs
82 pstruPhyVar->plmeCharacteristics.aTxPLCPDelay = 1; //MicroSecs
83 pstruPhyVar->plmeCharacteristics.aTxRampOnTime = 1; //MicroSecs
84 //Assign Control frame and broadcast frame data rate
85 pstruPhyVar->dControlFrameDataRate = CONTRL_FRAME_RATE_11A_AND_G;
86 pstruPhyVar->dBroadcastFrameDataRate = CONTRL_FRAME_RATE_11A_AND_G;
87 break;
88 case 10:
89 pstruPhyVar->plmeCharacteristics.aPLCPHeaderLength = 8 ; //MicroSecs
90 pstruPhyVar->plmeCharacteristics.aPreambleLength = 32; //MicroSecs
91 pstruPhyVar->plmeCharacteristics.aCCATime = 8; //MicroSecs
92 pstruPhyVar->plmeCharacteristics.aMACProcessingDelay = 2;//MicroSecs
93 pstruPhyVar->plmeCharacteristics.aMPDUDurationFactor = 0;
94 pstruPhyVar->plmeCharacteristics.aMPDUMaxLength = 4095;
95 pstruPhyVar->plmeCharacteristics.aPHY_RX_START_Delay = 49;//MicroSecs
96 pstruPhyVar->plmeCharacteristics.aRxPLCPDelay = 1; //MicroSecs
97 pstruPhyVar->plmeCharacteristics.aRxRFDelay = 1; //MicroSecs
98 pstruPhyVar->plmeCharacteristics.aRxTxSwitchTime = 1; // MicroSecs
99 pstruPhyVar->plmeCharacteristics.aRxTxTurnaroundTime = 2;//MicroSecs
100 pstruPhyVar->plmeCharacteristics.aTxPLCPDelay = 1; //MicroSecs
101 pstruPhyVar->plmeCharacteristics.aTxRampOnTime = 1; //MicroSecs
102 //Assign Control frame and broadcast frame data rate
103 pstruPhyVar->dControlFrameDataRate = CONTRL_FRAME_RATE_11P;
104 pstruPhyVar->dBroadcastFrameDataRate = CONTRL_FRAME_RATE_11P;
105 break;
106 case 5:
107 pstruPhyVar->plmeCharacteristics.aPLCPHeaderLength = 16; //MicroSecs
108 pstruPhyVar->plmeCharacteristics.aPreambleLength = 64; //MicroSecs
109 pstruPhyVar->plmeCharacteristics.aCCATime = 16; //MicroSecs
110 pstruPhyVar->plmeCharacteristics.aMACProcessingDelay = 2;//MicroSecs
111 pstruPhyVar->plmeCharacteristics.aMPDUDurationFactor = 0;
112 pstruPhyVar->plmeCharacteristics.aMPDUMaxLength = 4095;
113 pstruPhyVar->plmeCharacteristics.aPHY_RX_START_Delay = 97;//MicroSecs
114 pstruPhyVar->plmeCharacteristics.aRxPLCPDelay = 1; //MicroSecs
115 pstruPhyVar->plmeCharacteristics.aRxRFDelay = 1; //MicroSecs
116 pstruPhyVar->plmeCharacteristics.aRxTxSwitchTime = 1; // MicroSecs
117 pstruPhyVar->plmeCharacteristics.aRxTxTurnaroundTime = 2;//MicroSecs
118 pstruPhyVar->plmeCharacteristics.aTxPLCPDelay = 1; //MicroSecs
119 pstruPhyVar->plmeCharacteristics.aTxRampOnTime = 1; //MicroSecs
120 //Assign Control frame and broadcast frame data rate
121 pstruPhyVar->dControlFrameDataRate = CONTRL_FRAME_RATE_11P;
122 pstruPhyVar->dBroadcastFrameDataRate = CONTRL_FRAME_RATE_11P;
123 break;
124 }
125 fn_NetSim_IEEE802_11_OFDMPhy_SetEDThreshold(pstruPhyVar);
126 break;
127 case HT:
128 fn_NetSim_IEEE802_11n_OFDM_MIMO_init(nDeviceId,nInterfaceId);
129 fn_NetSim_IEEE802_11_HTPhy_SetEDThreshold(pstruPhyVar);
130 break;
131 case VHT:
132 fn_NetSim_IEEE802_11ac_OFDM_MIMO_init(nDeviceId,nInterfaceId);
133 fn_NetSim_IEEE802_11_HTPhy_SetEDThreshold(pstruPhyVar);
134 break;
135 case HE:
136 fn_NetSim_IEEE802_11ax_OFDM_MIMO_init(nDeviceId,nInterfaceId);
137 fn_NetSim_IEEE802_11_HEPhy_SetEDThreshold(pstruPhyVar);
138 break;
139
140 case DSSS:
141 default:
142 pstruPhyVar->plmeCharacteristics.aPLCPHeaderLength = 48; //MicroSecs
143 pstruPhyVar->plmeCharacteristics.aPreambleLength = 144; //MicroSecs
144 pstruPhyVar->plmeCharacteristics.aCCATime = 15; //MicroSecs
145 pstruPhyVar->plmeCharacteristics.aMACProcessingDelay = 2;//MicroSecs
146 pstruPhyVar->plmeCharacteristics.aMPDUDurationFactor = 0;
147 pstruPhyVar->plmeCharacteristics.aMPDUMaxLength = 8192;
148 pstruPhyVar->plmeCharacteristics.aPHY_RX_START_Delay = 192;//MicroSecs
149 pstruPhyVar->plmeCharacteristics.aRxPLCPDelay = 1; //MicroSecs
150 pstruPhyVar->plmeCharacteristics.aRxRFDelay = 1; //MicroSecs
151 pstruPhyVar->plmeCharacteristics.aRxTxSwitchTime = 4; // MicroSecs
152 pstruPhyVar->plmeCharacteristics.aRxTxTurnaroundTime = 5;//MicroSecs
153 pstruPhyVar->plmeCharacteristics.aTxPLCPDelay = 1; //MicroSecs
154 pstruPhyVar->plmeCharacteristics.aTxRampOnTime = 1; //MicroSecs
155 pstruPhyVar->dControlFrameDataRate = CONTRL_FRAME_RATE_11B; //2
156 pstruPhyVar->dBroadcastFrameDataRate = CONTRL_FRAME_RATE_11B;//2
157 fn_NetSim_IEEE802_11_DSSPhy_SetEDThreshold(pstruPhyVar);
158 break;
159 }
160
161 pstruPhyVar->SIFS = pstruPhyVar->plmeCharacteristics.aSIFSTime;
162 pstruPhyVar->DIFS = pstruPhyVar->plmeCharacteristics.aSIFSTime + (2 * pstruPhyVar->plmeCharacteristics.aSlotTime);
163 pstruPhyVar->EIFS = pstruPhyVar->plmeCharacteristics.aSIFSTime + pstruPhyVar->DIFS + (int) (ACK_SIZE * 8.0 / pstruPhyVar->dControlFrameDataRate) + 1;
164 pstruPhyVar->PIFS = pstruPhyVar->plmeCharacteristics.aSIFSTime + pstruPhyVar->plmeCharacteristics.aSlotTime;
165 return 0;
166}
167
168bool isMediumIdle(NETSIM_ID d, NETSIM_ID in)
169{
170 PIEEE802_11_MAC_VAR mac = IEEE802_11_MAC(d, in);
171 return medium_isIdle(d, mac->parentInterfaceId);
172}
173
174double get_preamble_time(PIEEE802_11_PHY_VAR phy)
175{
176 double dPreambleTime = 0;
177 switch(phy->PhyProtocol)
178 {
179 case IEEE_802_11b:
180 case IEEE_802_11a:
181 case IEEE_802_11g:
182 case IEEE_802_11p:
183 dPreambleTime = (double)(phy->plmeCharacteristics.aPreambleLength+phy->plmeCharacteristics.aPLCPHeaderLength);
184 break;
185 case IEEE_802_11n:
186 dPreambleTime = get_11n_preamble_time(phy);
187 break;
188 case IEEE_802_11ac:
189 dPreambleTime = get_11ac_preamble_time(phy);
190 break;
191 case IEEE_802_11ax:
192 dPreambleTime = get_11ax_preamble_time(phy);
193 break;
194 default:
195 fnNetSimError("Unknown phy protocol %d in %s.",phy->PhyProtocol,__FUNCTION__);
196 }
197 return dPreambleTime;
198}
199
200int fn_NetSim_IEEE802_11_PhyOut()
201{
202 NETSIM_ID srcid=pstruEventDetails->nDeviceId;
203 NETSIM_ID srcif=pstruEventDetails->nInterfaceId;
204
205 PIEEE802_11_PHY_VAR phy = IEEE802_11_CURR_PHY;
206 NetSim_PACKET* packet=pstruEventDetails->pPacket;
207 double time = pstruEventDetails->dEventTime;
208 double dTransmissionTime;
209 double dPropagationDelay;
210 double dPreambleTime;
211 int flag=0;
212 NetSim_PACKET* last=NULL;
213 bool transmitflag;
214 UINT64 transmissionId = 0;
215 while(packet)
216 {
217 NETSIM_ID destId = packet->nReceiverId;
218 NETSIM_ID destif = fn_NetSim_Stack_GetConnectedInterface(srcid, srcif, destId);
219
220 last = packet;
221
222 packet->pstruPhyData->dArrivalTime=pstruEventDetails->dEventTime;
223 packet->pstruPhyData->dStartTime=time;
224 packet->pstruPhyData->dEndTime=time;
225
226 packet->pstruPhyData->dPayload=packet->pstruMacData->dPacketSize;
227 packet->pstruPhyData->dOverhead=0;
228 packet->pstruPhyData->dPacketSize=packet->pstruPhyData->dPayload+
229 packet->pstruPhyData->dOverhead;
230
231 fn_NetSim_IEEE802_11_SetDataRate(srcid, srcif,
232 destId, destif,
233 packet, packet->pstruPhyData->dArrivalTime);
234
235 fn_NetSim_IEEE802_11_Add_Phy_Header(packet, &transmissionId);
236
237 packet->pstruPhyData->nPhyMedium=PHY_MEDIUM_WIRELESS;
238
239 if(!flag)
240 dPreambleTime = get_preamble_time(phy);
241 else
242 dPreambleTime = 0;
243
244 dTransmissionTime = fn_NetSim_IEEE802_11_CalculateTransmissionTime(packet->pstruPhyData->dPayload
245 ,pstruEventDetails->nDeviceId,
246 pstruEventDetails->nInterfaceId);
247 dPropagationDelay = 0.01;
248
249 time+=dTransmissionTime+dPreambleTime;
250 packet->pstruPhyData->dStartTime=time;
251 packet->pstruPhyData->dEndTime=packet->pstruPhyData->dStartTime+dPropagationDelay;
252
253 if(wireshark_trace.convert_sim_to_real_packet &&
254 DEVICE_MACLAYER(pstruEventDetails->nDeviceId,pstruEventDetails->nInterfaceId)->isWiresharkWriter)
255 {
256 wireshark_trace.convert_sim_to_real_packet(packet,
257 wireshark_trace.pcapWriterlist[pstruEventDetails->nDeviceId-1][pstruEventDetails->nInterfaceId-1],
258 pstruEventDetails->dEventTime);
259 }
260 packet = packet->pstruNextPacket;
261 flag=1;
262 }
263
264 if (!validate_processing_time(time,
265 pstruEventDetails->nDeviceId,
266 pstruEventDetails->nInterfaceId))
267 return -1;
268 packet = pstruEventDetails->pPacket;
269 if (packet == NULL) { return -2; }
270 // Transmit the packet
271 if(packet->nReceiverId)
272 {
273 transmitflag = fn_NetSim_IEEE802_11_TransmitFrame(packet,srcid,srcif);
274 if(!isIEEE802_11_CtrlPacket(packet) &&
275 !isMulticastPacket(packet) &&
276 !isBroadcastPacket(packet))
277 fn_NetSim_IEEE802_11_CSMACA_AddAckTimeOut(last,srcid,srcif);
278 else if(packet->nControlDataType == WLAN_RTS)
279 fn_NetSim_IEEE802_11_RTS_CTS_AddCTSTimeOut(packet,srcid,srcif);
280
281 if(!transmitflag) //Packet is not transmitted
282 fn_NetSim_Packet_FreePacket(packet);
283 }
284 else
285 {
286 transmitflag = fn_NetSim_IEEE802_11_TransmitBroadcastFrame(packet,srcid,srcif);
287
288 if (!transmitflag)
289 {
290 NETSIM_ID srcSendIf = get_send_interface_id(packet);
291 PIEEE802_11_MAC_VAR srcMac = IEEE802_11_MAC(packet->nTransmitterId, srcSendIf);
292 set_mac_state_after_txend(srcMac);
293 }
294 fn_NetSim_Packet_FreePacket(packet);
295 }
296 return 0;
297}
298
299int fn_NetSim_IEEE802_11_PhyIn()
300{
301 NetSim_PACKET* packet = pstruEventDetails->pPacket;
302 ptrIEEE802_11_PHY_HDR hdr = PACKET_PHYPROTOCOLDATA(packet);
303 PIEEE802_11_PHY_VAR phy = IEEE802_11_CURR_PHY;
304 PIEEE802_11_MAC_VAR srcMac;
305 PIEEE802_11_PHY_VAR srcPhy;
306 PACKET_STATUS status;
307 NETSIM_ID ifid;
308 bool morefrag;
309
310 morefrag = is_more_fragment_coming(packet);
311
312 //Wireshark
313 if(wireshark_trace.convert_sim_to_real_packet &&
314 DEVICE_MACLAYER(pstruEventDetails->nDeviceId,pstruEventDetails->nInterfaceId)->isWiresharkWriter)
315 {
316 wireshark_trace.convert_sim_to_real_packet(pstruEventDetails->pPacket,
317 wireshark_trace.pcapWriterlist[pstruEventDetails->nDeviceId-1][pstruEventDetails->nInterfaceId-1],
318 pstruEventDetails->dEventTime);
319 }
320
321 ifid = fn_NetSim_Stack_GetConnectedInterface(pstruEventDetails->nDeviceId,
322 pstruEventDetails->nInterfaceId,
323 packet->nTransmitterId);
324
325 NETSIM_ID srcSendIf = get_send_interface_id(packet);
326 srcPhy = IEEE802_11_PHY(packet->nTransmitterId, ifid);
327 srcMac = IEEE802_11_MAC(packet->nTransmitterId, srcSendIf);
328 if (morefrag)
329 {
330 if (is_first_packet(packet))
331 {
332 }
333 }
334 else
335 {
336 if (set_radio_state(packet->nTransmitterId, ifid,
337 RX_ON_IDLE, pstruEventDetails->nDeviceId,
338 hdr->transmissionId))
339 set_mac_state_after_txend(srcMac);
340
341
342 }
343 IEEE_802_11RadioMeasurements_Log(packet, packet->nTransmitterId,
344 ifid,
345 pstruEventDetails->nDeviceId,
346 pstruEventDetails->nInterfaceId);
347
348 medium_notify_packet_received(packet);
349
350 double pdbm = GET_RX_POWER_dbm(packet->nTransmitterId,
351 ifid,
352 pstruEventDetails->nDeviceId,
353 pstruEventDetails->nInterfaceId,
354 packet->pstruPhyData->dArrivalTime);
355 if (pdbm < srcPhy->dCurrentRxSensitivity_dbm)
356 {
357 set_radio_state(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId,
358 RX_ON_IDLE, packet->nTransmitterId,
359 hdr->transmissionId);
360 return -1; // dest is not in range
361 }
362
363
364
365 if (isIEEE802_11_CtrlPacket(packet) || !morefrag)
366 set_radio_state(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId,
367 RX_ON_IDLE, packet->nTransmitterId,
368 hdr->transmissionId);
369
370
371 if(phy->firstpacketstatus==PacketStatus_Collided)
372 packet->nPacketStatus=PacketStatus_Collided;
373 /*else if(phy->firstpacketstatus==PacketStatus_Error)
374 packet->nPacketStatus=PacketStatus_Error;*/
375 LinkPacketLog();
376 if(packet->nPacketStatus==PacketStatus_Collided)
377 {
378 if(!isIEEE802_11_CtrlPacket(packet) && is_first_packet(packet))
379 phy->firstpacketstatus = PacketStatus_Collided;
380
381 fn_NetSim_WritePacketTrace(packet);
382 fn_NetSim_Metrics_Add(packet);
383 fn_NetSim_Packet_FreePacket(packet);
384 goto RET_PHYIN;
385 }
386
387 status = packet->nPacketStatus;
388 if(status == PacketStatus_Error)
389 {
390 if(!isIEEE802_11_CtrlPacket(packet) && is_first_packet(packet))
391 phy->firstpacketstatus = PacketStatus_Error;
392
393 // call function to write packet trace and calculate metrics
394 packet->pstruPhyData->nPacketErrorFlag = PacketStatus_Error;
395 packet->nPacketStatus=PacketStatus_Error;
396 fn_NetSim_WritePacketTrace(packet);
397 fn_NetSim_Metrics_Add(packet);
398 fn_NetSim_Packet_FreePacket(packet);
399 goto RET_PHYIN;
400 }
401 else //Packet is not error. Continue
402 {
403 // call function to write packet trace and calculate metrics
404 packet->pstruPhyData->nPacketErrorFlag = PacketStatus_NoError;
405 packet->nPacketStatus =PacketStatus_NoError;
406 fn_NetSim_WritePacketTrace(packet);
407 fn_NetSim_Metrics_Add(packet);
408 }
409
410 packet->pstruPhyData->dArrivalTime =packet->pstruPhyData->dEndTime;
411 packet->pstruPhyData->dStartTime =packet->pstruPhyData->dEndTime;
412 packet->pstruPhyData->dPayload = packet->pstruPhyData->dPacketSize - packet->pstruPhyData->dOverhead;
413 packet->pstruPhyData->dPacketSize = packet->pstruPhyData->dPayload;
414 packet->pstruPhyData->dOverhead = 0;
415 packet->pstruPhyData->dEndTime =packet->pstruPhyData->dEndTime;
416 // Add MAC IN event
417 switch(packet->nControlDataType)
418 {
419 case WLAN_ACK:
420 pstruEventDetails->nSubEventType = RECEIVE_ACK;
421 break;
422 case WLAN_BlockACK:
423 pstruEventDetails->nSubEventType = RECEIVE_BLOCK_ACK;
424 break;
425 case WLAN_RTS:
426 pstruEventDetails->nSubEventType = RECEIVE_RTS;
427 break;
428 case WLAN_CTS:
429 pstruEventDetails->nSubEventType = RECEIVE_CTS;
430 break;
431 default:
432 pstruEventDetails->nSubEventType = RECEIVE_MPDU;
433 break;
434 }
435
436 ptrIEEE802_11_HDR machdr = packet->pstruMacData->Packet_MACProtocol;
437 if (machdr->recvInterfaceId)
438 pstruEventDetails->nInterfaceId = machdr->recvInterfaceId;
439
440 pstruEventDetails->nEventType = MAC_IN_EVENT;
441 pstruEventDetails->pPacket = packet;
442 fnpAddEvent(pstruEventDetails);
443RET_PHYIN:
444 if (!morefrag)
445 {
446 phy->firstpacketstatus = PacketStatus_NoError;
447 }
448 return 0;
449}
450
451static void wlanphy_update_medium_param(NETSIM_ID d, NETSIM_ID in)
452{
453 PIEEE802_11_PHY_VAR pstruPhy = IEEE802_11_PHY(d, in);
454
455 switch (pstruPhy->PhyProtocol)
456 {
457 case IEEE_802_11b:
458 medium_update_datarate(d, in, pstruPhy->PHY_TYPE.dsssPhy.dDataRate);
459 medium_update_modulation(d, in, pstruPhy->PHY_TYPE.dsssPhy.modulation, pstruPhy->PHY_TYPE.dsssPhy.dCodeRate);
460 medium_update_MCS(d, in, pstruPhy->MCS, strWLANProtocol[pstruPhy->PhyProtocol], strBERMODEL[pstruPhy->Ber_Model]);
461 break;
462 case IEEE_802_11a:
463 case IEEE_802_11g:
464 case IEEE_802_11p:
465 medium_update_datarate(d, in, pstruPhy->PHY_TYPE.ofdmPhy.dDataRate);
466 medium_update_modulation(d, in, pstruPhy->PHY_TYPE.ofdmPhy.modulation, pstruPhy->PHY_TYPE.ofdmPhy.dCodingRate);
467 medium_update_MCS(d, in, pstruPhy->MCS, strWLANProtocol[pstruPhy->PhyProtocol], strBERMODEL[pstruPhy->Ber_Model]);
468 break;
469 case IEEE_802_11n:
470 case IEEE_802_11ac:
471 medium_update_datarate(d, in, pstruPhy->PHY_TYPE.ofdmPhy_11n.dDataRate);
472 medium_update_modulation(d, in, pstruPhy->PHY_TYPE.ofdmPhy_11n.modulation, pstruPhy->PHY_TYPE.ofdmPhy_11n.dCodingRate);
473 medium_update_MCS(d, in, pstruPhy->MCS, strWLANProtocol[pstruPhy->PhyProtocol], strBERMODEL[pstruPhy->Ber_Model]);
474 break;
475 case IEEE_802_11ax:
476 medium_update_datarate(d, in, pstruPhy->PHY_TYPE.ofdmPhy_11ax.dDataRate);
477 medium_update_modulation(d, in, pstruPhy->PHY_TYPE.ofdmPhy_11ax.modulation, pstruPhy->PHY_TYPE.ofdmPhy_11ax.dCodingRate);
478 medium_update_MCS(d, in, pstruPhy->MCS, strWLANProtocol[pstruPhy->PhyProtocol], strBERMODEL[pstruPhy->Ber_Model]);
479 break;
480 default:
481 fnNetSimError("IEEE802.11--- Unknown phy protocol type %d in %s\n", pstruPhy->PhyProtocol, __FUNCTION__);
482 break;
483 }
484}
485
486/**
487Calculate and return Transmission time for one packet.
488*/
489double fn_NetSim_IEEE802_11_CalculateTransmissionTime(double size, NETSIM_ID nDevId, NETSIM_ID nInterfaceId)
490{
491 double dTxTime = 0.0;
492 PIEEE802_11_PHY_VAR pstruPhy = IEEE802_11_PHY(nDevId,nInterfaceId);
493
494 switch (pstruPhy->PhyProtocol)
495 {
496 case IEEE_802_11b:
497 return ceil(size *(8 / pstruPhy->PHY_TYPE.dsssPhy.dDataRate));
498 break;
499 case IEEE_802_11a:
500 case IEEE_802_11g:
501 case IEEE_802_11p:
502 return ceil(size *(8 / pstruPhy->PHY_TYPE.ofdmPhy.dDataRate));
503 case IEEE_802_11n:
504 case IEEE_802_11ac:
505 return (ceil(size * (8 * 1000.0 / pstruPhy->PHY_TYPE.ofdmPhy_11n.dDataRate))) / 1000.0;
506 case IEEE_802_11ax:
507 return (ceil(size * (8 * 1000.0 / pstruPhy->PHY_TYPE.ofdmPhy_11ax.dDataRate))) / 1000.0;
508 default:
509 fnNetSimError("IEEE802.11--- Unknown phy protocol type %d in Calculate Transmission Time\n", pstruPhy->PhyProtocol);
510 break;
511 }
512 return dTxTime;
513}
514
515
516bool CheckFrequencyInterfrence(double dFrequency1,double dFrequency2,double bandwidth)
517{
518 if(dFrequency1 > dFrequency2)
519 {
520 if( (dFrequency1 - dFrequency2) >= bandwidth )
521 return false; // no interference
522 else
523 return true; // interference
524 }
525 else
526 {
527 if( (dFrequency2 - dFrequency1) >= bandwidth )
528 return false; // no interference
529 else
530 return true; // interference
531 }
532}
533
534/**
535Transmit the packet in the Medium, i.e from Physical out to Physical In.
536While transmitting check whether the Receiver radio state is CHANNEL_IDLE and also
537is the receiver is reachable, that is not an out off reach. If both condition
538satisfied then add the PHY IN EVENT, else drop the frame.
539*/
540bool fn_NetSim_IEEE802_11_TransmitFrame(NetSim_PACKET* pstruPacket, NETSIM_ID nDevId, NETSIM_ID nInterfaceId)
541{
542 PIEEE802_11_PHY_VAR srcPhy=IEEE802_11_PHY(nDevId,nInterfaceId);
543 PIEEE802_11_PHY_VAR destPhy;
544
545 NetSim_PACKET *pstruPacketList=pstruPacket;
546 ptrIEEE802_11_PHY_HDR hdr = PACKET_PHYPROTOCOLDATA(pstruPacket);
547 NetSim_EVENTDETAILS pevent;
548 NETSIM_ID destId=pstruPacket->nReceiverId;
549 NETSIM_ID destif=fn_NetSim_Stack_GetConnectedInterface(nDevId,nInterfaceId,destId);
550
551 destPhy=IEEE802_11_PHY(destId,destif);
552 if (destPhy == NULL)
553 {
554 fnNetSimError("No dest phy layer is found for device %d:%d in function %s",
555 destId, destif, __FUNCTION__);
556 return false;
557 }
558
559 //Update the transmitter and receiver
560 while(pstruPacketList)
561 {
562 pstruPacketList->nReceiverId = destId;
563 pstruPacketList->nTransmitterId = nDevId;
564 pstruPacketList=pstruPacketList->pstruNextPacket;
565 }
566
567 if (!set_radio_state(nDevId, nInterfaceId, TRX_ON_BUSY, destId, hdr->transmissionId))
568 return false; // src is off
569
570 // Change the Receiver state
571 if (set_radio_state(destId, destif, RX_ON_BUSY, nDevId, hdr->transmissionId))
572 {
573 fn_NetSim_IEEE802_11_CSMA_UpdateNAV(destId, destif, pstruPacket);
574 }
575
576 destPhy->dCurrentRxSensitivity_dbm=srcPhy->dCurrentRxSensitivity_dbm;
577 pstruPacketList=pstruPacket;
578 while(pstruPacketList)
579 {
580 pstruPacket=pstruPacketList;
581 pstruPacketList = pstruPacketList->pstruNextPacket;
582 pstruPacket->pstruNextPacket=NULL;
583
584 memcpy(&pevent,pstruEventDetails,sizeof* pstruEventDetails);
585 pevent.dEventTime = pstruPacket->pstruPhyData->dEndTime;
586 pevent.dPacketSize = pstruPacket->pstruPhyData->dPacketSize;
587 if(pstruPacket->pstruAppData)
588 {
589 pevent.nApplicationId = pstruPacket->pstruAppData->nApplicationId;
590 pevent.nSegmentId = pstruPacket->pstruAppData->nSegmentId;
591 }
592 else
593 {
594 pevent.nApplicationId = 0;
595 pevent.nSegmentId = 0;
596 }
597 pevent.nDeviceId = destId;
598 pevent.nDeviceType = DEVICE_TYPE(destId);
599 pevent.nEventType = PHYSICAL_IN_EVENT;
600 pevent.nInterfaceId = destif;
601 pevent.nPacketId = pstruPacket->nPacketId;
602 pevent.nProtocolId = MAC_PROTOCOL_IEEE802_11;
603 pevent.pPacket=pstruPacket;
604 pevent.nSubEventType = 0;
605 fnpAddEvent(&pevent);
606
607 wlanphy_update_medium_param(nDevId, nInterfaceId);
608 medium_notify_packet_send(pstruPacket,
609 nDevId,
610 nInterfaceId,
611 destId,
612 destif);
613 }
614 return true;
615}
616
617bool fn_NetSim_IEEE802_11_TransmitBroadcastFrame(NetSim_PACKET* pstruPacket, NETSIM_ID nDevId, NETSIM_ID nInterfaceId)
618{
619 bool isTransmitted = false;
620 NetSim_LINKS* link;
621 NETSIM_ID i;
622 link=DEVICE_PHYLAYER(nDevId,nInterfaceId)->pstruNetSimLinks;
623 switch(link->nLinkType)
624 {
625 case LinkType_P2MP:
626 {
627 if(link->puniDevList.pstrup2MP.nCenterDeviceId !=nDevId)
628 {
629 bool transmitflag;
630 NetSim_PACKET* packet= fn_NetSim_Packet_CopyPacketList(pstruPacket);
631 packet->nReceiverId=link->puniDevList.pstrup2MP.nCenterDeviceId;
632 transmitflag = fn_NetSim_IEEE802_11_TransmitFrame(packet,nDevId,nInterfaceId);
633 if (!transmitflag)
634 fn_NetSim_Packet_FreePacket(packet);
635 else
636 isTransmitted = true;
637 }
638 else
639 {
640 for(i=0;i<link->puniDevList.pstrup2MP.nConnectedDeviceCount-1;i++)
641 {
642 bool transmitflag;
643 NetSim_PACKET* packet= fn_NetSim_Packet_CopyPacketList(pstruPacket);
644 packet->nReceiverId=link->puniDevList.pstrup2MP.anDevIds[i];
645 transmitflag = fn_NetSim_IEEE802_11_TransmitFrame(packet,nDevId,nInterfaceId);
646 if(!transmitflag)
647 fn_NetSim_Packet_FreePacket(packet);
648 else
649 isTransmitted = true;
650 }
651 }
652 }
653 break;
654 case LinkType_MP2MP:
655 for(i=0;i<link->puniDevList.pstruMP2MP.nConnectedDeviceCount;i++)
656 {
657 if(link->puniDevList.pstruMP2MP.anDevIds[i]!=nDevId)
658 {
659 bool transmitflag;
660 NetSim_PACKET* packet= fn_NetSim_Packet_CopyPacketList(pstruPacket);
661 packet->nReceiverId=link->puniDevList.pstruMP2MP.anDevIds[i];
662 transmitflag = fn_NetSim_IEEE802_11_TransmitFrame(packet,nDevId,nInterfaceId);
663 if(!transmitflag)
664 fn_NetSim_Packet_FreePacket(packet);
665 else
666 isTransmitted = true;
667 }
668 }
669 break;
670 case LinkType_P2P:
671 {
672 bool transmitflag;
673 NetSim_PACKET* packet= fn_NetSim_Packet_CopyPacketList(pstruPacket);
674 if(link->puniDevList.pstruP2P.nFirstDeviceId!=nDevId)
675 pstruPacket->nReceiverId=link->puniDevList.pstruP2P.nFirstDeviceId;
676 else if(link->puniDevList.pstruP2P.nSecondDeviceId!=nDevId)
677 pstruPacket->nReceiverId=link->puniDevList.pstruP2P.nSecondDeviceId;
678 transmitflag = fn_NetSim_IEEE802_11_TransmitFrame(packet,nDevId,nInterfaceId);
679 if(!transmitflag)
680 fn_NetSim_Packet_FreePacket(packet);
681 else
682 isTransmitted = true;
683 }
684 break;
685 default:
686 fnNetSimError("Unknown link type in %s",__FUNCTION__);
687 break;
688 }
689 return isTransmitted;
690}
691
692/**
693This function used to compute the data rate with respect to the total received power
694set the received power value using received power range table for modulation(dbm)
695*/
696int fn_NetSim_IEEE802_11_SetDataRate(NETSIM_ID txId, NETSIM_ID txIf,
697 NETSIM_ID rxId, NETSIM_ID rxIf,
698 NetSim_PACKET* packet, double time)
699{
700 rxIf;
701 PIEEE802_11_PHY_VAR phy = IEEE802_11_PHY(txId, txIf);
702
703 switch (phy->PhyProtocol)
704 {
705 case IEEE_802_11b:
706 fn_NetSim_IEEE802_11_DSSSPhy_DataRate(txId, txIf, rxId, packet, time);
707 break;
708 case IEEE_802_11a:
709 case IEEE_802_11g:
710 case IEEE_802_11p:
711 fn_NetSim_IEEE802_11_OFDMPhy_DataRate(txId, txIf, rxId, packet, time);
712 break;
713 case IEEE_802_11n:
714 case IEEE_802_11ac:
715 fn_NetSim_IEEE802_11_HTPhy_DataRate(txId, txIf, rxId, packet, time);
716 break;
717 case IEEE_802_11ax:
718 fn_NetSim_IEEE802_11_HEPhy_DataRate(txId, txIf, rxId, packet, time);
719 break;
720 default:
721 fnNetSimError("IEEE802.11--- Unknown protocol %d in %s\n", phy->PhyProtocol, __FUNCTION__);
722 break;
723 }
724 return 0;
725}
726
727double fn_NetSim_IEEE802_11_GetMinRxSensitivity(NETSIM_ID txId, NETSIM_ID txIf)
728{
729 PIEEE802_11_PHY_VAR phy = IEEE802_11_PHY(txId, txIf);
730 double dInterferenceThreshold = 0.0;
731 switch (phy->PhyProtocol)
732 {
733 case IEEE_802_11b:
734 dInterferenceThreshold = DSSSPhy_get_min_rxSensitivity();
735 break;
736 case IEEE_802_11a:
737 case IEEE_802_11g:
738 case IEEE_802_11p:
739 dInterferenceThreshold = ofdmphy_get_min_rxSensitivity(phy->dChannelBandwidth);
740 break;
741 case IEEE_802_11n:
742 case IEEE_802_11ac:
743 dInterferenceThreshold = HTPhy_get_min_rxSensitivity(phy->dChannelBandwidth, phy->NSS);
744 break;
745 case IEEE_802_11ax:
746 dInterferenceThreshold = HEPhy_get_min_rxSensitivity(phy->dChannelBandwidth, phy->NSS);
747 break;
748 default:
749 fnNetSimError("IEEE802.11--- Unknown protocol %d in %s\n", phy->PhyProtocol, __FUNCTION__);
750 break;
751 }
752 return dInterferenceThreshold;
753}