NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
RTS_CTS.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
29static double get_RTS_CTS_Time(PIEEE802_11_MAC_VAR mac, PIEEE802_11_PHY_VAR phy)
30{
31 mac;
32 return ceil(2 * (double)phy->plmeCharacteristics.aSIFSTime
33 + get_preamble_time(phy)
34 + ((getCTSSize() * 8) / phy->dControlFrameDataRate));
35}
36
37double calculate_RTS_duration(NETSIM_ID txId,
38 NETSIM_ID txIf,
39 NetSim_PACKET* packet)
40{
41 NETSIM_ID rxId = packet->nReceiverId;
42 NETSIM_ID rxIf = fn_NetSim_Stack_GetConnectedInterface(txId, txIf, rxId);
43
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;
47
48 while (packet != NULL)
49 {
50 if (packet->pstruMacData != NULL)
51 {
52 aggregateSize += (packet->pstruMacData->dPayload +
53 getMacOverhead(phy, packet->pstruMacData->dPayload));
54 }
55 packet = packet->pstruNextPacket;
56 }
57 double packetTime = fn_NetSim_IEEE802_11_CalculateTransmissionTime(
58 aggregateSize,
59 txId,
60 txIf);
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;
64
65 return ceil(get_preamble_time(phy) +
66 rtsTime +
67 phy->plmeCharacteristics.aSIFSTime +
68 get_preamble_time(phy) +
69 ctsTime +
70 phy->plmeCharacteristics.aSIFSTime +
71 get_preamble_time(phy) +
72 packetTime +
73 phy->plmeCharacteristics.aSIFSTime +
74 get_preamble_time(phy) +
75 ackTime);
76}
77
78double calculate_CTS_duration(NETSIM_ID d,
79 NETSIM_ID i,
80 double rtsduration)
81{
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) +
87 rtsTime));
88}
89
90static bool decide_RTS_CTS_Mechanism()
91{
92 double d=0;
93 NetSim_PACKET* p=IEEE802_11_CURR_MAC->currentProcessingPacket;
94
95 if (isBroadcastPacket(p) || isMulticastPacket(p))
96 return false; //Broadcast or multicast packet
97
98 if (isIEEE802_11_CtrlPacket(p))
99 return false; //No RTS CTS for IEEE802.11 control packet
100 while(p)
101 {
102 d+=p->pstruMacData->dPayload;
103 p=p->pstruNextPacket;
104 }
105 return (d >= IEEE802_11_CURR_MAC->dot11RTSThreshold);
106}
107
108void fn_NetSim_IEEE802_11_RTS_CTS_Init()
109{
110 PIEEE802_11_MAC_VAR mac = IEEE802_11_CURR_MAC;
111
112 if(!decide_RTS_CTS_Mechanism())
113 return; //NO RTS-CTS
114
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);
120
121 mac->metrics.nRTSSentCount++;
122
123 //Update the packet processing time
124 mac->dPacketProcessingEndTime += get_RTS_CTS_Time(mac,IEEE802_11_CURR_PHY);
125
126}
127
128void fn_NetSim_IEEE802_11_RTS_CTS_ProcessRTS()
129{
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);
135
136 IEEE802_11_CURR_MAC->metrics.nRTSReceivedCount++;
137}
138
139void fn_NetSim_IEEE802_11_RTS_CTS_SendCTS()
140{
141 PIEEE802_11_MAC_VAR mac = IEEE802_11_CURR_MAC;
142 if (mac->dNAV > pstruEventDetails->dEventTime)
143 {
144 //Virtual CS Condition
145 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
146 return;
147 }
148
149 NetSim_PACKET* packet=fn_NetSim_IEEE802_11_CreateCTSPacket(pstruEventDetails->pPacket);
150 //Free the RTS packet
151 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
152
153 //Send CTS to phy
154 pstruEventDetails->dPacketSize = packet->pstruMacData->dPacketSize;
155 pstruEventDetails->nSubEventType = 0;
156 pstruEventDetails->nEventType = PHYSICAL_OUT_EVENT;
157 pstruEventDetails->pPacket = packet;
158 fnpAddEvent(pstruEventDetails);
159
160 IEEE802_11_CURR_MAC->metrics.nCTSSentCount++;
161}
162
163void fn_NetSim_IEEE802_11_RTS_CTS_AddCTSTimeOut(NetSim_PACKET* packet,NETSIM_ID devId,NETSIM_ID devIf)
164{
165 ptrIEEE802_11_HDR hdr = packet->pstruMacData->Packet_MACProtocol;
166
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);
170 double ctstime;
171
172 ctstime = ceil(packet->pstruPhyData->dStartTime
173 + phy->plmeCharacteristics.aSIFSTime
174 + get_preamble_time(phy)
175 + ((getCTSSize() * 8)/phy->dControlFrameDataRate));
176
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)
186 {
187 pevent.nSegmentId=packet->pstruAppData->nSegmentId;
188 pevent.nApplicationId=packet->pstruAppData->nApplicationId;
189 }
190 else
191 {
192 pevent.nSegmentId=0;
193 pevent.nApplicationId=0;
194 }
195 pevent.nSubEventType=CTS_TIMEOUT;
196 pevent.pPacket=NULL;
197 pevent.szOtherDetails=NULL;
198 mac->EVENTID.ctsTimeout = fnpAddEvent(&pevent);
199}
200
201void fn_NetSim_IEEE802_11_RTS_CTS_CTSTimeOut()
202{
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))
206 {
207 mac->nRetryCount++;
208 fn_NetSim_IEEE802_11_CSMACA_IncreaseCW(mac);
209 fn_NetSim_IEEE802_11_CSMACA_Init();
210 }
211 else
212 {
213 if (mac->waitingforCTS)
214 {
215 NetSim_PACKET* pstruPacket = mac->waitingforCTS;
216
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;
223 }
224 mac->nRetryCount = 0;
225 fn_NetSim_IEEE802_11_CSMACA_Init();
226 }
227}
228
229void fn_NetSim_IEEE802_11_RTS_CTS_ProcessCTS()
230{
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++;
237 //Free CTS packet
238 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
239 pstruEventDetails->pPacket=NULL;
240
241 pstruEventDetails->dEventTime += IEEE802_11_CURR_PHY->SIFS;
242 pstruEventDetails->nSubEventType = SEND_MPDU;
243 pstruEventDetails->nEventType = MAC_OUT_EVENT;
244 if(mac->currentProcessingPacket->pstruAppData)
245 {
246 pstruEventDetails->nApplicationId = mac->currentProcessingPacket->pstruAppData->nApplicationId;
247 pstruEventDetails->nSegmentId = mac->currentProcessingPacket->pstruAppData->nSegmentId;
248 }
249 else
250 {
251 pstruEventDetails->nApplicationId = 0;
252 pstruEventDetails->nSegmentId = 0;
253 }
254 pstruEventDetails->nPacketId = mac->currentProcessingPacket->nPacketId;
255 fnpAddEvent(pstruEventDetails);
256 IEEE802_11_Change_Mac_State(IEEE802_11_CURR_MAC,IEEE802_11_MACSTATE_TXing_MPDU);
257}