25#include "IEEE802_11.h"
26#include "IEEE802_11_Phy.h"
27#include "IEEE802_11_MAC_Frame.h"
29static double get_RTS_CTS_Time(PIEEE802_11_MAC_VAR mac, PIEEE802_11_PHY_VAR phy)
32 return ceil(2 * (
double)phy->plmeCharacteristics.aSIFSTime
33 + get_preamble_time(phy)
34 + ((getCTSSize() * 8) / phy->dControlFrameDataRate));
37double calculate_RTS_duration(NETSIM_ID txId,
39 NetSim_PACKET* packet)
41 NETSIM_ID rxId = packet->nReceiverId;
42 NETSIM_ID rxIf = fn_NetSim_Stack_GetConnectedInterface(txId, txIf, rxId);
44 PIEEE802_11_PHY_VAR phy = IEEE802_11_PHY(txId, txIf);
45 fn_NetSim_IEEE802_11_SetDataRate(txId, txIf, rxId, rxIf, packet, pstruEventDetails->dEventTime);
46 double aggregateSize = 0;
48 while (packet != NULL)
50 if (packet->pstruMacData != NULL)
52 aggregateSize += (packet->pstruMacData->dPayload +
53 getMacOverhead(phy, packet->pstruMacData->dPayload));
55 packet = packet->pstruNextPacket;
57 double packetTime = fn_NetSim_IEEE802_11_CalculateTransmissionTime(
61 double ctsTime = (getCTSSize() * 8.0) / phy->dControlFrameDataRate;
62 double ackTime = (getAckSize(phy) * 8.0) / phy->dControlFrameDataRate;
63 double rtsTime = (getRTSSize()*8.0) / phy->dBroadcastFrameDataRate;
65 return ceil(get_preamble_time(phy) +
67 phy->plmeCharacteristics.aSIFSTime +
68 get_preamble_time(phy) +
70 phy->plmeCharacteristics.aSIFSTime +
71 get_preamble_time(phy) +
73 phy->plmeCharacteristics.aSIFSTime +
74 get_preamble_time(phy) +
78double calculate_CTS_duration(NETSIM_ID d,
82 PIEEE802_11_PHY_VAR phy = IEEE802_11_PHY(d, i);
83 double rtsTime = (getRTSSize() * 8.0) / phy->dControlFrameDataRate;
84 return ceil(rtsduration -
85 (phy->plmeCharacteristics.aSIFSTime +
86 get_preamble_time(phy) +
90static bool decide_RTS_CTS_Mechanism()
93 NetSim_PACKET* p=IEEE802_11_CURR_MAC->currentProcessingPacket;
95 if (isBroadcastPacket(p) || isMulticastPacket(p))
98 if (isIEEE802_11_CtrlPacket(p))
102 d+=p->pstruMacData->dPayload;
103 p=p->pstruNextPacket;
105 return (d >= IEEE802_11_CURR_MAC->dot11RTSThreshold);
108void fn_NetSim_IEEE802_11_RTS_CTS_Init()
110 PIEEE802_11_MAC_VAR mac = IEEE802_11_CURR_MAC;
112 if(!decide_RTS_CTS_Mechanism())
115 mac->waitingforCTS=mac->currentProcessingPacket;
116 double d = calculate_RTS_duration(pstruEventDetails->nDeviceId,
117 pstruEventDetails->nInterfaceId,
118 mac->currentProcessingPacket);
119 mac->currentProcessingPacket = fn_NetSim_IEEE802_11_CreateRTSPacket(mac->waitingforCTS, d);
121 mac->metrics.nRTSSentCount++;
124 mac->dPacketProcessingEndTime += get_RTS_CTS_Time(mac,IEEE802_11_CURR_PHY);
128void fn_NetSim_IEEE802_11_RTS_CTS_ProcessRTS()
130 pstruEventDetails->dEventTime += IEEE802_11_CURR_PHY->SIFS;
131 pstruEventDetails->nSubEventType = SEND_CTS;
132 pstruEventDetails->nEventType = MAC_OUT_EVENT;
133 fnpAddEvent(pstruEventDetails);
134 IEEE802_11_Change_Mac_State(IEEE802_11_CURR_MAC,IEEE802_11_MACSTATE_TXing_CTS);
136 IEEE802_11_CURR_MAC->metrics.nRTSReceivedCount++;
139void fn_NetSim_IEEE802_11_RTS_CTS_SendCTS()
141 PIEEE802_11_MAC_VAR mac = IEEE802_11_CURR_MAC;
142 if (mac->dNAV > pstruEventDetails->dEventTime)
145 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
149 NetSim_PACKET* packet=fn_NetSim_IEEE802_11_CreateCTSPacket(pstruEventDetails->pPacket);
151 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
154 pstruEventDetails->dPacketSize = packet->pstruMacData->dPacketSize;
155 pstruEventDetails->nSubEventType = 0;
156 pstruEventDetails->nEventType = PHYSICAL_OUT_EVENT;
157 pstruEventDetails->pPacket = packet;
158 fnpAddEvent(pstruEventDetails);
160 IEEE802_11_CURR_MAC->metrics.nCTSSentCount++;
163void fn_NetSim_IEEE802_11_RTS_CTS_AddCTSTimeOut(NetSim_PACKET* packet,NETSIM_ID devId,NETSIM_ID devIf)
165 ptrIEEE802_11_HDR hdr = packet->pstruMacData->Packet_MACProtocol;
167 NetSim_EVENTDETAILS pevent;
168 PIEEE802_11_PHY_VAR phy = IEEE802_11_PHY(devId,devIf);
169 PIEEE802_11_MAC_VAR mac = IEEE802_11_MAC(devId, hdr->sendInterfaceId);
172 ctstime = ceil(packet->pstruPhyData->dStartTime
173 + phy->plmeCharacteristics.aSIFSTime
174 + get_preamble_time(phy)
175 + ((getCTSSize() * 8)/phy->dControlFrameDataRate));
177 pevent.dEventTime=ctstime+2;
178 pevent.dPacketSize=0;
179 pevent.nDeviceId=devId;
180 pevent.nDeviceType=DEVICE_TYPE(devId);
181 pevent.nEventType=TIMER_EVENT;
182 pevent.nInterfaceId= hdr->sendInterfaceId;
183 pevent.nPacketId=packet->nPacketId;
184 pevent.nProtocolId=MAC_PROTOCOL_IEEE802_11;
185 if(packet->pstruAppData)
187 pevent.nSegmentId=packet->pstruAppData->nSegmentId;
188 pevent.nApplicationId=packet->pstruAppData->nApplicationId;
193 pevent.nApplicationId=0;
195 pevent.nSubEventType=CTS_TIMEOUT;
197 pevent.szOtherDetails=NULL;
198 mac->EVENTID.ctsTimeout = fnpAddEvent(&pevent);
201void fn_NetSim_IEEE802_11_RTS_CTS_CTSTimeOut()
203 PIEEE802_11_MAC_VAR mac = IEEE802_11_CURR_MAC;
204 IEEE802_11_Change_Mac_State(mac, IEEE802_11_MACSTATE_MAC_IDLE);
205 if (fn_NetSim_IEEE802_11_CSMACA_CheckRetryLimit(mac, 1))
208 fn_NetSim_IEEE802_11_CSMACA_IncreaseCW(mac);
209 fn_NetSim_IEEE802_11_CSMACA_Init();
213 if (mac->waitingforCTS)
215 NetSim_PACKET* pstruPacket = mac->waitingforCTS;
217 if (pstruPacket->DropNotification)
218 pstruPacket->DropNotification(pstruPacket);
219 fn_NetSim_Packet_FreePacket(mac->currentProcessingPacket);
220 fn_NetSim_Packet_FreePacket(mac->waitingforCTS);
221 mac->currentProcessingPacket = NULL;
222 mac->waitingforCTS = NULL;
224 mac->nRetryCount = 0;
225 fn_NetSim_IEEE802_11_CSMACA_Init();
229void fn_NetSim_IEEE802_11_RTS_CTS_ProcessCTS()
231 PIEEE802_11_MAC_VAR mac=IEEE802_11_CURR_MAC;
232 fnDeleteEvent(mac->EVENTID.ctsTimeout);
233 fn_NetSim_Packet_FreePacket(mac->currentProcessingPacket);
234 mac->currentProcessingPacket=mac->waitingforCTS;
235 mac->waitingforCTS=NULL;
236 mac->metrics.nCTSReceivedCount++;
238 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
239 pstruEventDetails->pPacket=NULL;
241 pstruEventDetails->dEventTime += IEEE802_11_CURR_PHY->SIFS;
242 pstruEventDetails->nSubEventType = SEND_MPDU;
243 pstruEventDetails->nEventType = MAC_OUT_EVENT;
244 if(mac->currentProcessingPacket->pstruAppData)
246 pstruEventDetails->nApplicationId = mac->currentProcessingPacket->pstruAppData->nApplicationId;
247 pstruEventDetails->nSegmentId = mac->currentProcessingPacket->pstruAppData->nSegmentId;
251 pstruEventDetails->nApplicationId = 0;
252 pstruEventDetails->nSegmentId = 0;
254 pstruEventDetails->nPacketId = mac->currentProcessingPacket->nPacketId;
255 fnpAddEvent(pstruEventDetails);
256 IEEE802_11_Change_Mac_State(IEEE802_11_CURR_MAC,IEEE802_11_MACSTATE_TXing_MPDU);