NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
IEEE802_11_Mac.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_MAC_Frame.h"
27#include "IEEE802_11_Phy.h"
28
29//Function prototype
30static void fn_NetSim_IEEE802_11_MacInit(bool* isInterfaceUsed);
31static void forward_to_other_interface(NetSim_PACKET* packet);
32static void add_to_mac_queue(NetSim_PACKET* packet);
33
34void fn_NetSim_IEEE802_11_MacOut()
35{
36 NETSIM_ID d = pstruEventDetails->nDeviceId;
37 NETSIM_ID ifCount = DEVICE(d)->nNumOfInterface;
38 NETSIM_ID i;
39
40 switch(pstruEventDetails->nSubEventType)
41 {
42 case 0:
43 {
44 bool* isInterfaceUsed = calloc(ifCount, sizeof * isInterfaceUsed);
45 fn_NetSim_IEEE802_11_MacInit(isInterfaceUsed);
46 for (i = 0; i < ifCount; i++)
47 {
48 if (isInterfaceUsed[i])
49 {
50 pstruEventDetails->nInterfaceId = i + 1;
51 fn_NetSim_IEEE802_11_CSMACA_Init();
52 }
53 }
54 free(isInterfaceUsed);
55 }
56 break;
57 case CS:
58 if(fn_NetSim_IEEE802_11_CSMACA_CS())
59 fn_NetSim_IEEE802_11_CSMACA_CheckNAV();
60 break;
61 case IEEE802_11_EVENT_DIFS_FAILED:
62 ieee802_11_csmaca_difs_failed(IEEE802_11_CURR_MAC);
63 break;
64 case IEEE802_11_EVENT_DIFS_END:
65 fn_NetSim_IEEE802_11_CSMACA_DIFSEnd();
66 break;
67 case IEEE802_11_EVENT_AIFS_FAILED:
68 ieee802_11_csmaca_aifs_failed(IEEE802_11_CURR_MAC);
69 break;
70 case IEEE802_11_EVENT_AIFS_END:
71 fn_NetSim_IEEE802_11_CSMACA_AIFSEnd();
72 break;
73 case IEEE802_11_EVENT_BACKOFF:
74 if(fn_NetSim_IEEE802_11_CSMACA_Backoff())
75 fn_NetSim_IEEE802_11_SendToPhy();
76 break;
77 case IEEE802_11_EVENT_BACKOFF_PAUSED:
78 ieee802_11_csmaca_pause_backoff(IEEE802_11_CURR_MAC);
79 break;
80 case SEND_ACK:
81 if(IEEE802_11_CURR_MAC->macAggregationStatus)
82 fn_NetSim_IEEE802_11_CSMACA_SendBlockACK();
83 else
84 fn_NetSim_IEEE802_11_CSMACA_SendACK();
85 break;
86 case SEND_CTS:
87 fn_NetSim_IEEE802_11_RTS_CTS_SendCTS();
88 break;
89 case SEND_MPDU:
90 fn_NetSim_IEEE802_11_SendToPhy();
91 break;
92 default:
93 fnNetSimError("Unknown sub-event %d for IEEE802_11 MAC OUT.",pstruEventDetails->nSubEventType);
94 break;
95 }
96}
97
98int fn_NetSim_IEEE802_11_MacIn()
99{
100 NETSIM_ID d = pstruEventDetails->nDeviceId;
101 PIEEE802_11_MAC_VAR mac = IEEE802_11_CURR_MAC;
102 NetSim_EVENTDETAILS pevent;
103 NetSim_PACKET* packet = pstruEventDetails->pPacket;
104 NetSim_PACKET* data;
105
106 if(isIEEE802_11_CtrlPacket(packet))
107 {
108 fn_NetSim_Process_CtrlPacket();
109 return 0;
110 }
111
112 mac->metrics.nReceivedFrameCount++;
113
114 memcpy(&pevent,pstruEventDetails,sizeof pevent);
115 data = fn_NetSim_Packet_CopyPacket(packet);
116 if(DEVICE_NWLAYER(d))
117 {
118 fn_NetSim_IEEE802_11_FreePacket(packet);
119 packet->pstruMacData->nMACProtocol = MAC_PROTOCOL_NULL;
120 pevent.nInterfaceId = mac->parentInterfaceId;
121 pevent.nSubEventType=0;
122 pevent.nProtocolId = fn_NetSim_Stack_GetNWProtocol(d);
123 pevent.nEventType=NETWORK_IN_EVENT;
124 fnpAddEvent(&pevent);
125 }
126 else
127 {
128 if(mac->BSSType==INFRASTRUCTURE)
129 {
130 if (isBroadcastPacket(packet) || isMulticastPacket(packet))
131 {
132 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
133 fn_NetSim_802_11_InfrastructureBSS_UpdateReceiver(packet);
134 add_to_mac_queue(packet);
135 forward_to_other_interface(p);
136 }
137 else
138 {
139 if (isPacketforsameInfrastructureBSS(mac, packet))
140 {
141 fn_NetSim_802_11_InfrastructureBSS_UpdateReceiver(packet);
142 add_to_mac_queue(packet);
143 }
144 else
145 forward_to_other_interface(packet);
146 }
147 }
148 else if(mac->BSSType==MESH)
149 {
150 if(isPacketforsameMeshBSS(mac,packet))
151 {
152 fn_NetSim_802_11_MeshBSS_UpdateReceiver(packet);
153 add_to_mac_queue(packet);
154 }
155 else
156 forward_to_other_interface(packet);
157 }
158 else
159 {
160 fnNetSimError("BSSType %d is not implemented for IEEE802.11 protocol");
161 return -1;
162 }
163 }
164 if (!isBroadcastPacket(data) &&
165 !isMulticastPacket(data)) //No ack for broadcast or multicast
166 {
167 memcpy(&pevent, pstruEventDetails, sizeof pevent);
168
169 //Add event to send ack
170 pevent.nEventType=MAC_OUT_EVENT;
171 pevent.nSubEventType=SEND_ACK;
172 pevent.pPacket=data;
173 fnpAddEvent(&pevent);
174 IEEE802_11_Change_Mac_State(IEEE802_11_CURR_MAC,IEEE802_11_MACSTATE_TXing_ACK);
175 }
176 return 0;
177}
178
179static void fn_NetSim_IEEE802_11_MacInit(bool* isInterfaceUsed)
180{
181 NETSIM_ID d = pstruEventDetails->nDeviceId;
182 NETSIM_ID in = pstruEventDetails->nInterfaceId;
183 PIEEE802_11_MAC_VAR mac=IEEE802_11_CURR_MAC;
184 NetSim_BUFFER* pstruBuffer = DEVICE_ACCESSBUFFER(d, in);
185
186 if (mac->currentProcessingPacket)
187 {
188 isInterfaceUsed[in - 1] = true;
189 }
190
191 if (mac->parentInterfaceId != in)
192 {
193 isInterfaceUsed[in - 1] = true;
194 }
195
196 if (isPacketInQueue(d, in))
197 isInterfaceUsed[in - 1] = true;
198
199 while(fn_NetSim_GetBufferStatus(pstruBuffer))
200 {
201 NetSim_PACKET* pstruPacket = fn_NetSim_Packet_GetPacketFromBuffer(pstruBuffer,1);
202
203 if(mac->BSSType==INFRASTRUCTURE)
204 {
205 if(isPacketforsameInfrastructureBSS(mac,pstruPacket))
206 fn_NetSim_802_11_InfrastructureBSS_UpdateReceiver(pstruPacket);
207 else
208 {
209 fn_NetSim_Packet_FreePacket(pstruPacket);
210 continue;
211 }
212 }
213 else if(mac->BSSType==MESH)
214 {
215 if(isPacketforsameMeshBSS(mac,pstruPacket))
216 fn_NetSim_802_11_MeshBSS_UpdateReceiver(pstruPacket);
217 else
218 {
219 fn_NetSim_Packet_FreePacket(pstruPacket);
220 continue;
221 }
222 }
223 else
224 {
225 fnNetSimError("BSSType %d is not implemented for IEEE802.11 protocol", mac->BSSType);
226 return;
227 }
228
229 pstruPacket->pstruMacData->dArrivalTime = pstruEventDetails->dEventTime ;
230 pstruPacket->pstruMacData->dPayload = pstruPacket->pstruNetworkData->dPacketSize;
231
232 //Call IEEE802.11e
233 NETSIM_ID vin = add_to_queue(d, in, pstruPacket);
234 if (vin)
235 isInterfaceUsed[vin - 1] = true;
236 }
237 return;
238}
239
240void IEEE802_11_Change_Mac_State(PIEEE802_11_MAC_VAR mac,IEEE802_11_MAC_STATE state)
241{
242 print_ieee802_11_log("Device %d, interface %d, changing mac state from %s to %s.",
243 mac->deviceId,
244 mac->interfaceId,
245 strIEEE802_11_MAC_STATE[mac->currMacState],
246 strIEEE802_11_MAC_STATE[state]);
247 mac->prevMacState=mac->currMacState;
248 mac->currMacState=state;
249}
250
251void set_mac_state_after_txend(PIEEE802_11_MAC_VAR mac)
252{
253 switch(mac->currMacState)
254 {
255 case IEEE802_11_MACSTATE_MAC_IDLE:
256 break;
257 case IEEE802_11_MACSTATE_TXing_ACK:
258 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_MAC_IDLE);
259 break;
260 case IEEE802_11_MACSTATE_TXing_MPDU:
261 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_Wait_ACK);
262 break;
263 case IEEE802_11_MACSTATE_Txing_BroadCast:
264 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_MAC_IDLE);
265 break;
266 case IEEE802_11_MACSTATE_TXing_CTS:
267 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_MAC_IDLE);
268 break;
269 case IEEE802_11_MACSTATE_TXing_RTS:
270 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_Wait_CTS);
271 break;
272 default:
273 fnNetSimError("Unknown mac state %d is %s",mac->currMacState,__FUNCTION__);
274 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_MAC_IDLE);
275 }
276}
277
278void set_mac_state_for_tx(PIEEE802_11_MAC_VAR mac,NetSim_PACKET* p)
279{
280 switch(p->nControlDataType)
281 {
282 case WLAN_RTS:
283 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_TXing_RTS);
284 break;
285 case WLAN_CTS:
286 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_TXing_CTS);
287 break;
288 case WLAN_ACK:
289 IEEE802_11_Change_Mac_State(mac,IEEE802_11_MACSTATE_TXing_ACK);
290 break;
291 default:
292 if(isBroadcastPacket(p) || isMulticastPacket(p))
293 IEEE802_11_Change_Mac_State(mac, IEEE802_11_MACSTATE_Txing_BroadCast);
294 else
295 IEEE802_11_Change_Mac_State(mac, IEEE802_11_MACSTATE_TXing_MPDU);
296 break;
297 }
298}
299
300bool isMacTransmittingState(PIEEE802_11_MAC_VAR mac)
301{
302 if (mac->currMacState == IEEE802_11_MACSTATE_TXing_MPDU ||
303 mac->currMacState == IEEE802_11_MACSTATE_Txing_BroadCast ||
304 mac->currMacState == IEEE802_11_MACSTATE_TXing_ACK ||
305 mac->currMacState == IEEE802_11_MACSTATE_TXing_RTS ||
306 mac->currMacState == IEEE802_11_MACSTATE_TXing_CTS)
307 return true;
308 return false;
309}
310
311bool isMacReceivingState(PIEEE802_11_MAC_VAR mac)
312{
313 if (mac->currMacState == IEEE802_11_MACSTATE_Wait_ACK ||
314 mac->currMacState == IEEE802_11_MACSTATE_Wait_CTS ||
315 mac->currMacState == IEEE802_11_MACSTATE_Wait_BlockACK ||
316 mac->currMacState == IEEE802_11_MACSTATE_Wait_DATA)
317 return true;
318 return false;
319}
320
321bool isMacIdle(PIEEE802_11_MAC_VAR mac)
322{
323 if (mac->currMacState == IEEE802_11_MACSTATE_MAC_IDLE ||
324 mac->currMacState == IEEE802_11_MACSTATE_WF_NAV ||
325 mac->currMacState == IEEE802_11_MACSTATE_Wait_DIFS ||
326 mac->currMacState == IEEE802_11_MACSTATE_Wait_AIFS ||
327 mac->currMacState == IEEE802_11_MACSTATE_BACKING_OFF)
328 return true;
329 return false;
330}
331
332void fn_NetSim_IEEE802_11_SendToPhy()
333{
334 double dPacketSize=0;
335 NETSIM_ID nDeviceId = pstruEventDetails->nDeviceId;
336 NETSIM_ID nInterfaceId = pstruEventDetails->nInterfaceId;
337 PIEEE802_11_MAC_VAR mac = IEEE802_11_CURR_MAC;
338
339 NetSim_PACKET *p=mac->currentProcessingPacket;
340 NetSim_PACKET* pstruPacket;
341 unsigned int i=1;
342
343 if(!mac->currentProcessingPacket)
344 {
345 fnNetSimError("%s is called without mac->currentProcessingPacket",__FUNCTION__);
346 return;
347 }
348 set_mac_state_for_tx(mac,p);
349 ieee802_11_edcaf_set_txop_time(mac, ldEventTime);
350
351 if(!isBroadcastPacket(mac->currentProcessingPacket) &&
352 !isMulticastPacket(mac->currentProcessingPacket))
353 pstruPacket = fn_NetSim_Packet_CopyPacketList(mac->currentProcessingPacket);
354 else
355 {
356 pstruPacket = mac->currentProcessingPacket;
357 mac->currentProcessingPacket = NULL;
358 }
359
360 pstruEventDetails->pPacket = pstruPacket;
361 // Add the MAC header
362 while(pstruPacket)
363 {
364 if(!isIEEE802_11_CtrlPacket(pstruPacket))
365 {
366 fn_NetSim_IEEE802_11_Add_MAC_Header(nDeviceId,nInterfaceId,pstruPacket,i);
367 mac->metrics.nTransmittedFrameCount++;
368 }
369 dPacketSize += pstruPacket->pstruMacData->dPacketSize;
370 pstruPacket=pstruPacket->pstruNextPacket;
371 i++;
372 }
373 pstruPacket = pstruEventDetails->pPacket;
374 pstruPacket->nTransmitterId = pstruEventDetails->nDeviceId;
375
376 pstruEventDetails->nInterfaceId = mac->parentInterfaceId;
377 pstruEventDetails->nEventType = PHYSICAL_OUT_EVENT;
378 pstruEventDetails->nPacketId = pstruPacket->nPacketId;
379 if(pstruPacket->pstruAppData)
380 {
381 pstruEventDetails->nSegmentId = pstruPacket->pstruAppData->nSegmentId;
382 pstruEventDetails->nApplicationId = pstruPacket->pstruAppData->nApplicationId;
383 }
384 else
385 {
386 pstruEventDetails->nApplicationId = 0;
387 pstruEventDetails->nSegmentId = 0;
388 }
389 pstruEventDetails->nSubEventType = IEEE802_11_PHY_TXSTART_REQUEST;
390 pstruEventDetails->dPacketSize = dPacketSize;
391 fnpAddEvent(pstruEventDetails);
392}
393
394static void forward_to_other_interface(NetSim_PACKET* packet)
395{
396 NetSim_EVENTDETAILS pevent;
397 NETSIM_ID i;
398 NETSIM_ID inf=pstruEventDetails->nInterfaceId;
399 NETSIM_ID d=pstruEventDetails->nDeviceId;
400
401 fn_NetSim_IEEE802_11_FreePacket(packet);
402 packet->pstruMacData->nMACProtocol = MAC_PROTOCOL_NULL;
403 packet->pstruMacData->Packet_MACProtocol=NULL;
404 packet->pstruMacData->dPacketSize=0;
405 packet->pstruMacData->dPayload=0;
406 packet->pstruMacData->dOverhead=0;
407 for(i=1;i<=DEVICE(d)->nNumOfInterface;i++)
408 {
409 NetSim_BUFFER* buf=DEVICE_ACCESSBUFFER(d,i);
410 NetSim_PACKET* p;
411
412 if(i==inf)
413 continue;
414
415 if (isVirtualInterface(d, i)) continue;
416
417 if(!fn_NetSim_GetBufferStatus(buf))
418 {
419 memcpy(&pevent, pstruEventDetails, sizeof pevent);
420 pevent.nInterfaceId=i;
421 pevent.nEventType=MAC_OUT_EVENT;
422 pevent.nProtocolId=fn_NetSim_Stack_GetMacProtocol(d,i);
423 pevent.nSubEventType=0;
424 pevent.pPacket=NULL;
425 fnpAddEvent(&pevent);
426 }
427 p=fn_NetSim_Packet_CopyPacket(packet);
428 fn_NetSim_Packet_AddPacketToList(buf,p,0);
429 }
430 fn_NetSim_Packet_FreePacket(packet);
431}
432
433static void add_to_mac_queue(NetSim_PACKET* packet)
434{
435 NETSIM_ID inf=pstruEventDetails->nInterfaceId;
436 NETSIM_ID d=pstruEventDetails->nDeviceId;
437 NetSim_BUFFER* buf=DEVICE_ACCESSBUFFER(d,inf);
438
439 fn_NetSim_IEEE802_11_FreePacket(packet);
440 packet->pstruMacData->nMACProtocol = MAC_PROTOCOL_NULL;
441 packet->pstruMacData->Packet_MACProtocol=NULL;
442 packet->pstruMacData->dPacketSize=0;
443 packet->pstruMacData->dPayload=0;
444 packet->pstruMacData->dOverhead=0;
445
446 if(!fn_NetSim_GetBufferStatus(buf))
447 {
448 pstruEventDetails->nInterfaceId=inf;
449 pstruEventDetails->nEventType=MAC_OUT_EVENT;
450 pstruEventDetails->nProtocolId=fn_NetSim_Stack_GetMacProtocol(d,inf);
451 pstruEventDetails->nSubEventType=0;
452 pstruEventDetails->pPacket=NULL;
453 fnpAddEvent(pstruEventDetails);
454 }
455 fn_NetSim_Packet_AddPacketToList(buf,packet,0);
456}
457
458void fn_NetSim_IEE802_11_MacReInit(NETSIM_ID nDeviceId,NETSIM_ID nInterfaceId)
459{
460 NetSim_EVENTDETAILS pevent;
461 memcpy(&pevent,pstruEventDetails,sizeof pevent);
462 pstruEventDetails->dEventTime += 0.1;
463 pstruEventDetails->nDeviceId=nDeviceId;
464 pstruEventDetails->nInterfaceId=nInterfaceId;
465 pstruEventDetails->nDeviceType=DEVICE_TYPE(nDeviceId);
466 pstruEventDetails->dPacketSize=0;
467 pstruEventDetails->nApplicationId=0;
468 pstruEventDetails->nEventType=MAC_OUT_EVENT;
469 pstruEventDetails->nPacketId=0;
470 pstruEventDetails->nSegmentId=0;
471 pstruEventDetails->nSubEventType=0;
472 pstruEventDetails->pPacket=NULL;
473 pstruEventDetails->szOtherDetails=NULL;
474 IEEE802_11_CURR_MAC->nRetryCount = 0;
475 fn_NetSim_IEEE802_11_CSMACA_Init();
476 memcpy(pstruEventDetails,&pevent,sizeof pevent);
477}
478
479double calculate_nav(NETSIM_ID d, NETSIM_ID i, NetSim_PACKET* packet)
480{
481 PIEEE802_11_PHY_VAR phy = IEEE802_11_PHY(d, i);
482 double nav = 0;
483 switch (packet->nControlDataType)
484 {
485 case WLAN_RTS:
486 {
487 double duration =(double) (((PIEEE802_11_RTS)((ptrIEEE802_11_HDR)(packet->pstruMacData->Packet_MACProtocol))->hdr)->Duration);
488 nav += ceil(packet->pstruPhyData->dStartTime +duration) + 3;
489 }
490 break;
491 case WLAN_CTS:
492 {
493 double duration = (double)(((PIEEE802_11_CTS)((ptrIEEE802_11_HDR)(packet->pstruMacData->Packet_MACProtocol))->hdr)->Duration);
494 nav += ceil(packet->pstruPhyData->dStartTime + duration) + 2;
495 }
496 break;
497 case WLAN_ACK:
498 nav += ceil(packet->pstruPhyData->dStartTime);
499 break;
500 case WLAN_BlockACK:
501 nav += ceil(packet->pstruPhyData->dStartTime);
502 break;
503 default:
504 if (isBroadcastPacket(packet) ||
505 isMulticastPacket(packet))
506 {
507 nav += ceil(packet->pstruPhyData->dStartTime) + 1;
508 }
509 else
510 {
511 nav += ceil(packet->pstruPhyData->dStartTime
512 + phy->plmeCharacteristics.aSIFSTime
513 + get_preamble_time(phy)
514 + ((getAckSize(phy) * 8) / phy->dControlFrameDataRate)) + 1;
515 }
516 break;
517 }
518 return nav;
519}