NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
LTENR_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
25#pragma region HEADER_FILES
26#include "stdafx.h"
27#include "LTENR_MAC.h"
28#include "LTENR_NetworkSlicing.h"
29#pragma endregion
30
31#pragma region MAC_INIT
32void fn_NetSim_LTENR_MAC_Init()
33{
34
35}
36
37void fn_NetSim_LTENR_UEMAC_Init(NETSIM_ID ueId, NETSIM_ID ueIf)
38{
39}
40
41static LTENR_GnbSchedulingType fn_NetSim_LTENR_SchedulingType(char* var) {
42 if (!_stricmp(var, "ROUND_ROBIN"))
43 return LTENR_MAC_SCHEDULING_ROUNDROBIN;
44 else if (!_stricmp(var, "PROPORTIONAL_FAIR"))
45 return LTENR_MAC_SCHEDULING_PROPORTIONALFAIR;
46 else if (!_stricmp(var, "MAX_THROUGHPUT"))
47 return LTENR_MAC_SCHEDULING_MAXTHROUGHTPUT;
48 else if (!_stricmp(var, "FAIR_SCHEDULING"))
49 return LTENR_MAC_SCHEDULING_FAIR_SCHEDULING;
50 else if (!_stricmp(var, "PFS_WITH_RATE_GUARANTEE"))
51 return LTENR_MAC_SCHEDULING_PF_WITH_RG;
52 else {
53 fnNetSimError("Unknown Scheduling Type");
54 return LTENR_MAC_SCHEDULING_ROUNDROBIN;
55 }
56}
57
58void fn_NetSim_LTENR_GNBMAC_Init(NETSIM_ID gnbId, NETSIM_ID gnbIf)
59{
60 ptrLTENR_GNBMAC mac = calloc(1, sizeof * mac);
61 mac->gnbId = gnbId;
62 mac->gnbIf = gnbIf;
63 LTENR_GNBMAC_SET(gnbId, gnbIf, mac);
64
65 if (fn_NetSim_LTENR_IS_S1_INTERFACE_EXISTS(gnbId)) {
66 LTENR_GNB_SETEPC(gnbId, gnbIf, &mac->epcId, &mac->epcIf);
67 }
68}
69#pragma endregion
70
71#pragma region MAC_TEMP_FUNCTION
72
73void macOut()
74{
75 NetSim_PACKET* packet = pstruEventDetails->pPacket;
76 NETSIM_ID d = pstruEventDetails->nDeviceId;
77 NETSIM_ID in = pstruEventDetails->nInterfaceId;
78 NETSIM_ID rin = LTENR_FIND_ASSOCIATEINTERFACE(d, in, packet->nReceiverId);
79
80 if (LTENR_IS_UPLANE_MSG(packet))
81 {
82 if (isGNB(d, in)) fn_NetSim_LTENR_HARQ_StoreDLPacket();
83 else fn_NetSim_LTENR_HARQ_StoreULPacket();
84 }
85 else
86 {
87 pstruEventDetails->nEventType = PHYSICAL_OUT_EVENT;
88 fnpAddEvent(pstruEventDetails);
89 }
90}
91
92void macIn()
93{
94 NETSIM_ID d = pstruEventDetails->nDeviceId;
95 NETSIM_ID in = pstruEventDetails->nInterfaceId;
96 NETSIM_ID remote;
97 NetSim_PACKET* packet = pstruEventDetails->pPacket;
98 //ptrLTENR_MSG msg = packet->pstruMacData->Packet_MACProtocol;
99 NetSim_EVENTDETAILS pevent;
100 memcpy(&pevent, pstruEventDetails, sizeof pevent);
101
102 while (packet)
103 {
104 memcpy(pstruEventDetails, &pevent, sizeof * pstruEventDetails);
105 pstruEventDetails->pPacket = packet;
106 packet = packet->pstruNextPacket;
107 pstruEventDetails->pPacket->pstruNextPacket = NULL;
108 remote = pstruEventDetails->pPacket->nTransmitterId;
109 NETSIM_ID rin = LTENR_FIND_ASSOCIATEINTERFACE(d, in, remote);
110 pstruEventDetails->pPacket->pstruPhyData->dStartTime = ldEventTime;
111 pstruEventDetails->pPacket->pstruPhyData->dArrivalTime = ldEventTime;
112
113 //Association might change due to handover. Check for valid association
114 if (rin == 0)
115 {
116 pstruEventDetails->pPacket->nPacketStatus = PacketStatus_Dropped;
117 pstruEventDetails->pPacket->pstruPhyData->dEndTime = ldEventTime;
118 fn_NetSim_WritePacketTrace(pstruEventDetails->pPacket);
119 if((isLTENRControlPacket(pstruEventDetails->pPacket)))
120 LTENR_CallRLCIn();
121 else
122 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
123 }
124 else
125 {
126 pstruEventDetails->pPacket->pstruPhyData->dEndTime = ldEventTime;
127 pstruEventDetails->pPacket->nPacketStatus = PacketStatus_NoError;
128 fn_NetSim_WritePacketTrace(pstruEventDetails->pPacket);
129 LTENR_CallRLCIn();
130 }
131 }
132}
133#pragma endregion
134
135#pragma region MAC_SCHEDULERINTERFACE
136ptrLTENR_UESCHEDULERINFO LTENR_MACScheduler_FindInfoForUE(ptrLTENR_SCHEDULERINFO si,
137 NETSIM_ID d, NETSIM_ID in,
138 bool isUplink)
139{
140 ptrLTENR_UESCHEDULERINFO info = isUplink ? si->uplinkInfo : si->downlinkInfo;
141 while (info)
142 {
143 if (info->ueId == d && info->ueIf == in)
144 return info;
145 info = info->next;
146 }
147 return NULL;
148}
149
150static void LTENR_MACScheduler_RemoveInfoForUE(ptrLTENR_SCHEDULERINFO si,
151 NETSIM_ID d, NETSIM_ID in,
152 bool isUplink)
153{
154 ptrLTENR_UESCHEDULERINFO info = isUplink ? si->uplinkInfo : si->downlinkInfo;
155 ptrLTENR_UESCHEDULERINFO p = NULL;
156 while (info)
157 {
158 if (info->ueId == d && info->ueIf == in)
159 {
160 if (!p)
161 {
162 if (isUplink)
163 si->uplinkInfo = info->next;
164 else
165 si->downlinkInfo = info->next;
166
167 free(info);
168 break;
169 }
170 else
171 {
172 p->next = info->next;
173 free(info);
174 break;
175 }
176 }
177 p = info;
178 info = info->next;
179 }
180}
181
182static ptrLTENR_UESCHEDULERINFO LTENR_MACScheduler_InitInfoForUE(ptrLTENR_SCHEDULERINFO si,
183 NETSIM_ID d, NETSIM_ID in,
184 bool isUplink)
185{
186 ptrLTENR_UESCHEDULERINFO info = calloc(1, sizeof * info);
187 info->ueId = d;
188 info->ueIf = in;
189 ptrLTENR_UESCHEDULERINFO l = isUplink ? si->uplinkInfo : si->downlinkInfo;
190 if (l)
191 {
192 while (l->next)
193 l = l->next;
194 l->next = info;
195 }
196 else
197 {
198 if (isUplink) si->uplinkInfo = info;
199 else si->downlinkInfo = info;
200 }
201 return info;
202}
203
204static void LTENR_MACScheduler_UpdateInfoForUE(ptrLTENR_GNBMAC mac, ptrLTENR_GNBPHY phy,
205 ptrLTENR_ASSOCIATEDUEPHYINFO assocInfo,
206 ptrLTENR_UESCHEDULERINFO info, bool isUplink, int CA_ID)
207{
208 ptrLTENR_UEPHY uePhy = LTENR_UEPHY_GET(assocInfo->ueId, assocInfo->ueIf);
209 UINT layerCount = LTENR_PHY_GET_LAYER_COUNT(uePhy, isUplink);
210
211 UINT64 bitsPerPRB = 0,TBS = 0;
212
213 if (fn_NetSim_LTENR_HARQ_GetNDIFlag(assocInfo, isUplink, CA_ID) == false)
214 {
215 info->NDI = false;
216 info->PRBReqdForHARQRetransmission = fn_NetSim_LTENR_HARQ_GetPRBReqdForRetx(assocInfo, isUplink, CA_ID);
217 info->bitsPerPRB = 0;
218 return;
219 }
220
221 info->NDI = true;
222 info->PRBReqdForHARQRetransmission = 0;
223
224 for (UINT i = 0; i < layerCount; i++)
225 {
226 ptrLTENR_AMCINFO amc = isUplink ? assocInfo->uplinkAMCInfo[CA_ID][i] : assocInfo->downlinkAMCInfo[CA_ID][i];
227 if (amc->cqiTable.CQIIndex != 0) {
228 TBS = LTENR_calculateTBSSize(phy, 1, amc->mcsTable, CA_ID);
229 bitsPerPRB += TBS;
230 info->bitsPerPRBLayer[i] = TBS;
231 }
232 }
233
234 ptrLTENR_SCHEDULERINFO si = mac->schedulerInfo[CA_ID];
235
236 if (fn_NetSim_LTENR_RRC_isActive(mac->gnbId, mac->gnbIf, assocInfo->ueId, assocInfo->ueIf)) {
237 info->bitsPerPRB = bitsPerPRB;
238 //assert(info->bitsPerPRB != 0);
239 si->isUERRCSetUpCompleted = true;
240 }
241 else info->bitsPerPRB = 0;
242
243 if (isUplink)
244 info->bufferSize = fn_NetSim_LTENR_RLC_BufferStatusNotificaton(assocInfo->ueId, assocInfo->ueIf,
245 mac->gnbId, mac->gnbIf,
246 LTENR_LOGICALCHANNEL_DTCH);
247 else
248 info->bufferSize = fn_NetSim_LTENR_RLC_BufferStatusNotificaton(mac->gnbId, mac->gnbIf,
249 assocInfo->ueId, assocInfo->ueIf,
250 LTENR_LOGICALCHANNEL_DTCH);
251}
252
253static void LTENR_MAC_AddSchedulerStausForUE(ptrLTENR_GNBMAC mac, ptrLTENR_GNBPHY phy,
254 ptrLTENR_ASSOCIATEDUEPHYINFO assocInfo, ptrLTENR_SCHEDULERINFO si, int CA_ID)
255{
256 ptrLTENR_UESCHEDULERINFO uinfo = LTENR_MACScheduler_FindInfoForUE(si, assocInfo->ueId, assocInfo->ueIf, true);
257 ptrLTENR_UESCHEDULERINFO dinfo = LTENR_MACScheduler_FindInfoForUE(si, assocInfo->ueId, assocInfo->ueIf, false);
258 if (!uinfo)
259 uinfo = LTENR_MACScheduler_InitInfoForUE(si, assocInfo->ueId, assocInfo->ueIf, true);
260 if (!dinfo)
261 dinfo = LTENR_MACScheduler_InitInfoForUE(si, assocInfo->ueId, assocInfo->ueIf, false);
262
263 if(si->slotType == SLOT_UPLINK)
264 {
265 LTENR_MACScheduler_UpdateInfoForUE(mac, phy, assocInfo, uinfo, true, CA_ID);
266 ptrLTENR_PROTODATA pd = LTENR_PROTODATA_GET(uinfo->ueId,uinfo->ueIf);
267 uinfo->rateGuarantee = pd->ULrateGuarantee;
268 if (si->schedulingType == LTENR_MAC_SCHEDULING_PF_WITH_RG &&
269 nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_DYNAMIC)
270 {
271 UINT ueSliceId = nws->ueSliceId[uinfo->ueId];
272 uinfo->slice_lower_bound = (nws->Info[ueSliceId].uplinkBandwidth.minResourceShare)/100;
273 uinfo->slice_upper_bound = (nws->Info[ueSliceId].uplinkBandwidth.maxResourceShare)/100;
274 }
275 else
276 {
277 uinfo->slice_lower_bound = MIN_RESOURCE_SHARE;
278 uinfo->slice_upper_bound = MAX_RESOURCE_SHARE;
279 }
280 }
281 else if(si->slotType == SLOT_DOWNLINK)
282 {
283 LTENR_MACScheduler_UpdateInfoForUE(mac, phy, assocInfo, dinfo, false, CA_ID);
284 ptrLTENR_PROTODATA pd = LTENR_PROTODATA_GET(dinfo->ueId, dinfo->ueIf);
285 dinfo->rateGuarantee = pd->DLrateGuarantee;
286 if (si->schedulingType == LTENR_MAC_SCHEDULING_PF_WITH_RG &&
287 nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_DYNAMIC)
288 {
289 UINT ueSliceId = nws->ueSliceId[dinfo->ueId];
290 dinfo->slice_lower_bound = (nws->Info[ueSliceId].downlinkBandwidth.minResourceShare)/100;
291 dinfo->slice_upper_bound = (nws->Info[ueSliceId].downlinkBandwidth.maxResourceShare)/100;
292 }
293 else
294 {
295 dinfo->slice_lower_bound = MIN_RESOURCE_SHARE;
296 dinfo->slice_upper_bound = MAX_RESOURCE_SHARE;
297 }
298 }
299 if (si->slotType == SLOT_DOWNLINK) si->TotalPRBReqdForHARQRetransmission += dinfo->PRBReqdForHARQRetransmission;
300 else si->TotalPRBReqdForHARQRetransmission += uinfo->PRBReqdForHARQRetransmission;
301}
302
303static void LTENR_MAC_InitSchedulerStatus(ptrLTENR_GNBMAC mac)
304{
305 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(mac->gnbId, mac->gnbIf);
306 int CA_ID = phy->currentFrameInfo->Current_CA_ID;
307 ptrLTENR_CA ca = phy->spectrumConfig->CA[CA_ID];
308 ptrLTENR_SPECTRUMCONFIG sc = phy->spectrumConfig;
309 ptrLTENR_SCHEDULERINFO info = NULL;
310
311 if (mac->schedulerInfo[CA_ID])
312 {
313 info = mac->schedulerInfo[CA_ID];
314 info->slotType = phy->currentFrameInfo->slotType;
315
316 ptrLTENR_PROTODATA pd = LTENR_PROTODATA_GET(mac->gnbId, mac->gnbIf);
317 info->schedulingType = fn_NetSim_LTENR_SchedulingType(pd->schedulingType);
318 info->alpha = pd->EWMA_Learning_Rate;
319 }
320 else
321 {
322 info = calloc(1, sizeof * info);
323 mac->schedulerInfo[CA_ID] = info;
324 info->gnbId = mac->gnbId;
325 info->gnbIf = mac->gnbIf;
326 info->PRBCount = ca->PRBCount;
327 info->OH_DL = ca->OverheadDL;
328 info->OH_UL = ca->OverheadUL;
329 info->slotType = phy->currentFrameInfo->slotType;
330
331 ptrLTENR_PROTODATA pd = LTENR_PROTODATA_GET(mac->gnbId, mac->gnbIf);
332 info->schedulingType = fn_NetSim_LTENR_SchedulingType(pd->schedulingType);
333 }
334
335 info->TotalPRBReqdForHARQRetransmission = 0;
336
337 ptrLTENR_ASSOCIATEDUEPHYINFO assocInfo = phy->associatedUEPhyInfo;
338 while (assocInfo)
339 {
340 if (assocInfo->isAssociated)
341 LTENR_MAC_AddSchedulerStausForUE(mac, phy, assocInfo, info, CA_ID);
342 else
343 {
344 ptrLTENR_UESCHEDULERINFO uinfo = LTENR_MACScheduler_FindInfoForUE(info, assocInfo->ueId, assocInfo->ueIf, true);
345 ptrLTENR_UESCHEDULERINFO dinfo = LTENR_MACScheduler_FindInfoForUE(info, assocInfo->ueId, assocInfo->ueIf, false);
346 if (uinfo)
347 LTENR_MACScheduler_RemoveInfoForUE(info, assocInfo->ueId, assocInfo->ueIf, true);
348 if (dinfo)
349 LTENR_MACScheduler_RemoveInfoForUE(info, assocInfo->ueId, assocInfo->ueIf, false);
350 }
351 LTENR_ASSOCIATEDUEPHYINFO_NEXT(assocInfo);
352 }
353}
354#pragma endregion
355
356#pragma region MAC_RLC_INTERFACE
357static void LTENR_MAC_NotifyRLCForTransmission_forControl(NETSIM_ID d, NETSIM_ID in,
358 NETSIM_ID r, NETSIM_ID rin)
359{
360 fn_NetSim_LTENR_RLC_TransmissionStatusNotification(d, in,
361 r, rin,
362 0,
363 LTENR_LOGICALCHANNEL_BCCH);
364 fn_NetSim_LTENR_RLC_TransmissionStatusNotification(d, in,
365 r, rin,
366 0,
367 LTENR_LOGICALCHANNEL_CCCH);
368 fn_NetSim_LTENR_RLC_TransmissionStatusNotification(d, in,
369 r, rin,
370 0,
371 LTENR_LOGICALCHANNEL_DCCH);
372 fn_NetSim_LTENR_RLC_TransmissionStatusNotification(d, in,
373 r, rin,
374 0,
375 LTENR_LOGICALCHANNEL_PCCH);
376}
377
378static void LTENR_MAC_NotifyRLCForTransmission_forDTCH(NETSIM_ID d, NETSIM_ID in,
379 ptrLTENR_UESCHEDULERINFO si, bool isUplink)
380{
381 while (si)
382 {
383 if (isUplink)
384 fn_NetSim_LTENR_RLC_TransmissionStatusNotification(si->ueId, si->ueIf,
385 d, in, (UINT)(si->allocatedPRBCount*si->bitsPerPRB/8.0),
386 LTENR_LOGICALCHANNEL_DTCH);
387 else
388 fn_NetSim_LTENR_RLC_TransmissionStatusNotification(d, in,
389 si->ueId, si->ueIf,
390 (UINT)(si->allocatedPRBCount * si->bitsPerPRB / 8.0),
391 LTENR_LOGICALCHANNEL_DTCH);
392 si = si->next;
393 }
394}
395
396void LTENR_MAC_NotifyRLCForTransmission(ptrLTENR_GNBMAC mac)
397{
398 NETSIM_ID gnbId = mac->gnbId;
399 NETSIM_ID gnbIf = mac->gnbIf;
400 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(gnbId, gnbIf);
401 int CA_ID = phy->currentFrameInfo->Current_CA_ID;
402 ptrLTENR_SCHEDULERINFO si = mac->schedulerInfo[CA_ID];
403
404 LTENR_SLOTTYPE slotType = si->slotType;
405
406 ptrLTENR_ASSOCIATEDUEPHYINFO assocInfo = phy->associatedUEPhyInfo;
407
408 // bwp modify
409 while (assocInfo)
410 {
411 if (assocInfo->isAssociated)
412 {
413 if (slotType == SLOT_UPLINK || slotType == SLOT_MIXED)
414 LTENR_MAC_NotifyRLCForTransmission_forControl(assocInfo->ueId, assocInfo->ueIf,
415 gnbId, gnbIf);
416
417 if (slotType == SLOT_DOWNLINK || slotType == SLOT_MIXED)
418 LTENR_MAC_NotifyRLCForTransmission_forControl(gnbId, gnbIf,
419 assocInfo->ueId, assocInfo->ueIf);
420 }
421 LTENR_ASSOCIATEDUEPHYINFO_NEXT(assocInfo);
422 }
423
424 if (slotType == SLOT_DOWNLINK || slotType == SLOT_MIXED)
425 LTENR_MAC_NotifyRLCForTransmission_forControl(gnbId, gnbIf,
426 0, 0);//for rrc MIB and SIB1 broadcast msg
427
428 if (slotType == SLOT_UPLINK || slotType == SLOT_MIXED)
429 LTENR_MAC_NotifyRLCForTransmission_forDTCH(gnbId, gnbIf, si->uplinkInfo, true);
430
431 if (slotType == SLOT_DOWNLINK || slotType == SLOT_MIXED)
432 LTENR_MAC_NotifyRLCForTransmission_forDTCH(gnbId, gnbIf, si->downlinkInfo, false);
433}
434#pragma endregion
435
436#pragma region MAC_PHY_INTERFACE
437void LTENR_NotifyMACForStartingSlot()
438{
439 NETSIM_ID gnbId = pstruEventDetails->nDeviceId;
440 NETSIM_ID gnbIf = pstruEventDetails->nInterfaceId;
441 ptrLTENR_GNBMAC mac = LTENR_GNBMAC_GET(gnbId, gnbIf);
442 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(gnbId, gnbIf);
443 int CA_ID = phy->currentFrameInfo->Current_CA_ID;
444
445 fn_NetSim_LTENR_HARQ_HandleSlotStart(gnbId, gnbIf, CA_ID);
446
447 LTENR_MAC_InitSchedulerStatus(mac);
448
449 LTENR_PRB_Scheduler(mac->schedulerInfo[CA_ID]);
450
451 fn_NetSim_LTENR_HARQ_AllocateCBG(gnbId, gnbIf, CA_ID);
452
453 //print_ltenr_log("Allocated PRB = %d and CA_ID= %d\n", mac->schedulerInfo[CA_ID]->downlinkInfo->allocatedPRBCount, CA_ID);
454
455 //notify RLC for transmission status
456 LTENR_MAC_NotifyRLCForTransmission(mac);
457
458 fn_NetSim_LTENR_HARQ_Transmit(gnbId, gnbIf, CA_ID);
459}
460#pragma endregion