NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
LTENR_PRB.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: Kumar Gaurav *
22* *
23* ----------------------------------------------------------------------------------*/
24#pragma region HEADER_FILES
25#include "stdafx.h"
26#include "LTENR_MAC.h"
27#include "LTE_NR.h"
28#include "LTENR_NetworkSlicing.h"
29#include "LTENR_PHY.h"
30#pragma endregion
31
32#pragma region LOG
33static FILE* fpPRBLog = NULL;
34static FILE* fpSLICELog = NULL;
35void fn_NetSim_LTE_MAC_PRBLOG()
36{
37 if (get_protocol_log_status("LTENR_Radio_Resource_Allocation"))
38 {
39 char str[BUFSIZ];
40
41 if (isNTNScenario())
42 sprintf(str, "%s\\%s", pszIOLogPath, "NTN_Radio_Resource_Allocation.csv");
43 else
44 sprintf(str, "%s\\%s", pszIOLogPath, "LTENR_Radio_Resource_Allocation.csv");
45 fpPRBLog = fopen(str, "w");
46 if (!fpPRBLog)
47 {
48 perror(str);
49 fnSystemError("Unable to open LTENR_Radio_Resource_Allocation.csv file");
50 }
51 else
52 {
53 fprintf(fpPRBLog, "%s,%s,%s,%s,",
54 "gNB ID", "CC ID", "Slot ID", "Slot");
55
56 fprintf(fpPRBLog, "%s,%s,%s,%s,%s,",
57 "Total PRBs", "Control PRBs", "Slot Start Time(ms)", "Slot End Time(ms)", "UE ID");
58
59 fprintf(fpPRBLog, "%s,%s,%s,%s,%s,%s,",
60 "BitsPerPRB", "BufferFill(B)", "Allocated PRBs", "Rank", "EWMA MAC Throughput (Mbps)", "Index Bias");
61
62 if (nws->isSlicing)
63 {
64 if (isNTNScenario())
65 fprintf(fpPRBLog, "%s,", "Beam Id");
66 else
67 fprintf(fpPRBLog, "%s,%s,%s,",
68 "Slice ID", "Slice Type", "Slice Differentiator");
69 }
70
71 fprintf(fpPRBLog, "%s,%s,%s,",
72 "phi", "Lambda_L", "Lambda_U");
73
74 fprintf(fpPRBLog, "\n");
75
76 //fprintf(fpPRBLog, "var2 is past throughput performance for proportional fair scheduling algorithm\n");
77 if (nDbgFlag) fflush(fpPRBLog);
78 }
79 } //LTENR_PRB_LOG
80}
81
82void close_ltenr_PRB_log()
83{
84 if (fpPRBLog)
85 fclose(fpPRBLog);
86}
87
88static void write_prb_log(ptrLTENR_SCHEDULERINFO schedulerInfo, ptrLTENR_UESCHEDULERINFO list, UINT sliceId)
89{
90 if (fpPRBLog == NULL) return;
91
92 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(schedulerInfo->gnbId, schedulerInfo->gnbIf);
93 int CA_ID = phy->currentFrameInfo->Current_CA_ID;
94 LTENR_SLOTTYPE slotType = phy->frameInfo[CA_ID]->slotType;
95 double control_prb = (slotType == SLOT_UPLINK ? (ceil(schedulerInfo->OH_UL * schedulerInfo->PRBCount)) :
96 (ceil(schedulerInfo->OH_DL * schedulerInfo->PRBCount))) + schedulerInfo->TotalPRBReqdForHARQRetransmission;
97 while (list)
98 {
99 if(list->bufferSize<=0)
100 goto NEXTUE;
101 if (nws->rsrcSharingTechnique== LTENR_RESOURCE_SHARING_STATIC && nws->ueSliceId[list->ueId] != sliceId)
102 goto NEXTUE;
103 fprintf(fpPRBLog, "%d, %d, %d,%s,",
104 fn_NetSim_Stack_GetConfigIdOfDeviceById(schedulerInfo->gnbId), CA_ID + 1, phy->currentFrameInfo->slotId,
105 slotType == SLOT_UPLINK ? "Uplink" : "Downlink");
106
107 fprintf(fpPRBLog, "%u, %lf, %lf, %lf,%d,", schedulerInfo->PRBCount,
108 control_prb, phy->currentFrameInfo->slotStartTime / MILLISECOND,
109 phy->currentFrameInfo->slotEndTime / MILLISECOND, fn_NetSim_Stack_GetConfigIdOfDeviceById(list->ueId));
110 double ewma = schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PF_WITH_RG ?
111 list->dThetaAverage : list->var2;
112 fprintf(fpPRBLog, "%llu,%u,%u,%lf,%lf,",
113 list->bitsPerPRB, list->bufferSize,
114 list->allocatedPRBCount,
115 list->rank, ewma);
116 int slID = (nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_DYNAMIC)?nws->ueSliceId[list->ueId]: sliceId;
117 double nu = 0;
118 if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PF_WITH_RG)
119 {
120 nu = list->nu_i;
121 }
122 else
123 {
124 if (slotType == SLOT_UPLINK)
125 nu = nws->Info[slID].uplinkBandwidth.nu;
126 else
127 nu = nws->Info[slID].downlinkBandwidth.nu;
128 }
129 fprintf(fpPRBLog, "%lf,", nu);
130
131 if (nws->isSlicing)
132 {
133 if (isNTNScenario())
134 fprintf(fpPRBLog, "%d,", slID+1);
135
136 else
137 fprintf(fpPRBLog, "%d,%s,%d,",
138 slID,
139 strSLICE_SERVICE_TYPE[nws->Info[slID].sliceServiceType],
140 nws->Info[slID].sliceDifferentiator);
141 }
142
143 fprintf(fpPRBLog, "%lf,%lf,%lf,",
144 list->dPhi,list->lambda_L,list->lambda_U);
145
146 fprintf(fpPRBLog, "\n");
147 NEXTUE:
148 list = list->next;
149 }
150
151 if (nDbgFlag) fflush(fpPRBLog);
152}
153
154static void fn_NetSim_PRB_Utilization_log(ptrLTENR_SCHEDULERINFO schedulerInfo, ptrLTENR_UESCHEDULERINFO list, UINT sliceId)
155{
156 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(schedulerInfo->gnbId, schedulerInfo->gnbIf);
157 int CA_ID = phy->currentFrameInfo->Current_CA_ID;
158 LTENR_SLOTTYPE slotType = phy->frameInfo[CA_ID]->slotType;
159 UINT control_prb = (slotType == SLOT_UPLINK ? (ceil(schedulerInfo->OH_UL * schedulerInfo->PRBCount)) :
160 (ceil(schedulerInfo->OH_DL * schedulerInfo->PRBCount)));
161 double slotStartTime = phy->currentFrameInfo->slotStartTime / MILLISECOND;
162 double availablePRBs = schedulerInfo->PRBCount - control_prb;
163 UINT slID = 0;
164
165 UINT sliceCount = nws->sliceCount + 1;
166 UINT* slicePRBMap = (UINT*)calloc(sliceCount, sizeof(UINT));
167 bool* sliceLogged = (bool*)calloc(sliceCount, sizeof(bool));
168 while (list)
169 {
170 if (nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_STATIC && nws->ueSliceId[list->ueId] != sliceId)
171 goto NEXTUE;
172 slID = (nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_DYNAMIC) ? nws->ueSliceId[list->ueId] : sliceId;
173
174 slicePRBMap[slID] += list->allocatedPRBCount;
175 sliceLogged[slID] = true;
176
177 NEXTUE:
178 list = list->next;
179 }
180
181 for (UINT i = 0; i < sliceCount;i++)
182 {
183 if (sliceLogged[i])
184 {
185 if (slotType == SLOT_UPLINK)
186 {
187 LTENR_PRBUtilization_AddEntry(schedulerInfo->gnbId, CA_ID, i, 1, slicePRBMap[i], slotStartTime, availablePRBs, schedulerInfo->PRBCount, control_prb);
188 }
189 else
190 {
191 LTENR_PRBUtilization_AddEntry(schedulerInfo->gnbId, CA_ID, i, 0, slicePRBMap[i], slotStartTime, availablePRBs, schedulerInfo->PRBCount, control_prb);
192 }
193 }
194 }
195
196 free(slicePRBMap);
197 free(sliceLogged);
198}
199
200#pragma endregion
201
202
203#pragma region SORTING_OF_RANK
204ptrLTENR_UESCHEDULERINFO LTENR_PRB_SortingofRank(ptrLTENR_UESCHEDULERINFO list)
205{
206 ptrLTENR_UESCHEDULERINFO head = NULL;
207 ptrLTENR_UESCHEDULERINFO tail = NULL;
208 ptrLTENR_UESCHEDULERINFO t = NULL;
209 while (list)
210 {
211 if (!head)
212 {
213 //first member
214 head = list;
215 tail = list;
216 list = list->next;
217 head->next = NULL;
218 continue;
219 }
220
221 if (list->rank >= head->rank)
222 {
223 // Rank is less and head rank. So place at head
224 t = list->next;
225 list->next = head;
226 head = list;
227 list = t;
228 continue;
229 }
230
231 if (list->rank <= tail->rank)
232 {
233 // Rank is more than tail rank, so place as tail
234 t = list->next;
235 tail->next = list;
236 tail = list;
237 list = t;
238 tail->next = NULL;
239 continue;
240 }
241
242 //Middle
243 t = list->next;
244 ptrLTENR_UESCHEDULERINFO info = head;
245 while (info->next && info->next->rank > list->rank)
246 {
247 info = info->next;
248 }
249
250 // Insert the node in the middle
251 list->next = info->next;
252 info->next = list;
253
254 // Move to next node
255 list = t;
256 }
257 return head;
258}
259#pragma endregion
260
261#pragma region SET_RANK
262static void LTENR_PRB_SetRank(ptrLTENR_UESCHEDULERINFO list, ptrLTENR_SCHEDULERINFO schedulerInfo) {
263 double sigmaofBitperPRB = 0;
264 ptrLTENR_UESCHEDULERINFO current = list;
265 if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_ROUNDROBIN) {//RR
266 while (list) {
267 list->rank = 1.0;
268 list->initRank = 1.0;
269 list = list->next;
270 }
271 }
272
273 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PROPORTIONALFAIR) {//fair proportional
274 while (list)
275 {
276 list->rank = 1;
277 list->initRank = 1;
278 list->var2 = 1;
279 list = list->next;
280 }
281 }
282 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_FAIR_SCHEDULING) {//fair scheduling
283 double product = 1;
284 while (current) {
285 sigmaofBitperPRB += current->bitsPerPRB;
286 current = current->next;
287 }
288 current = list;
289 while (current) {
290 if (sigmaofBitperPRB) {
291 current->rank = (double)(current->bitsPerPRB / sigmaofBitperPRB);
292 product *= current->rank;
293 current->initRank = current->rank;
294 }
295 current = current->next;
296 }
297 //for FAIR
298 current = list;
299 while (current) {
300 if (current->rank) {
301 current->rank = product / current->rank;
302 current->initRank = current->rank;
303 }
304 current = current->next;
305 }
306 }
307}
308#pragma endregion
309
310#pragma region UPDATE_AND_RESET_RANK
311static void LTENR_PRB_ResetAllocationPRBCount(ptrLTENR_UESCHEDULERINFO list) {
312 NETSIM_ID gnbId = pstruEventDetails->nDeviceId;
313 NETSIM_ID gnbIf = pstruEventDetails->nInterfaceId;
314 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(gnbId, gnbIf);
315 int CA_ID = phy->currentFrameInfo->Current_CA_ID;
316 ptrLTENR_CA ca = phy->spectrumConfig->CA[CA_ID];
317
318 while (list) {
319 double rate = ((list->allocatedPRBCount * list->bitsPerPRB) / ca->slotDuration_us);
320 list->averageThroughput = list->averageThroughput + nws->EWMA_Learning_Rate*
321 (rate - list->averageThroughput);
322 list->allocatedPRBCount = 0;
323 list = list->next;
324 }
325}
326
327static void LTENR_PRB_UpdateRank_RoundRobin(ptrLTENR_UESCHEDULERINFO list) {
328 bool isanyzero = false;
329 ptrLTENR_UESCHEDULERINFO info = list;
330 while (list) {
331 list->rank = (list->rank - (list->allocatedPRBCount / initTotalPRBAvailable)); //+ list->initRank;
332 if (list->rank <= 0)
333 isanyzero = true;
334 list = list->next;
335 }
336 if (isanyzero)
337 {
338 list = info;
339 while (list)
340 {
341 list->rank += 1;
342 list = list->next;
343 }
344 }
345}
346
347//static void LTENR_PRB_UpdateIndexBias_ProportionalFair(ptrLTENR_UESCHEDULERINFO list)
348//{
349// NETSIM_ID gnbId = pstruEventDetails->nDeviceId;
350// NETSIM_ID gnbIf = pstruEventDetails->nInterfaceId;
351// ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(gnbId, gnbIf);
352//
353//#pragma warning (disable : 4047)
354// int CA_ID = pstruEventDetails->szOtherDetails;
355//#pragma warning (default : 4047)
356//
357// LTENR_SLOTTYPE slotType = phy->frameInfo[CA_ID]->slotType;
358// for (int sliceId = 0; sliceId <= nws->sliceCount; sliceId++)
359// {
360// if (nws->Info[sliceId].sliceServiceType == SLICE_SERVICE_TYPE_NONE)
361// {
362// if(slotType == SLOT_DOWNLINK)
363// nws->Info[sliceId].downlinkBandwidth.nu = 0;
364// else if(slotType == SLOT_UPLINK)
365// nws->Info[sliceId].uplinkBandwidth.nu = 0;
366// else
367// fnNetSimError("Unknown slot type %s in %s\n",
368// strLTENR_SLOTTYPE[slotType],
369// __FUNCTION__);
370// }
371// else
372// {//check downlink/uplink
373// if (slotType == SLOT_DOWNLINK)
374// {
375// nws->Info[sliceId].downlinkBandwidth.nu = nws->Info[sliceId].downlinkBandwidth.nu + nws->LagrangeMultiplierLearningRate *
376// (/*nws->Info[sliceId].downlinkBandwidth.aggregateRateGuarantee_mbps*/list->rateGuarantee - nws->Info[sliceId].downlinkBandwidth.sumAvgThroughput);
377//
378// nws->Info[sliceId].downlinkBandwidth.nu = (nws->Info[sliceId].downlinkBandwidth.nu < 0) ?
379// 0 : (nws->Info[sliceId].downlinkBandwidth.nu > 10) ?
380// 10 : nws->Info[sliceId].downlinkBandwidth.nu;
381// }
382// else if(slotType == SLOT_UPLINK)
383// {
384// nws->Info[sliceId].uplinkBandwidth.nu = nws->Info[sliceId].uplinkBandwidth.nu + nws->LagrangeMultiplierLearningRate *
385// (/*nws->Info[sliceId].uplinkBandwidth.aggregateRateGuarantee_mbps*/list->rateGuarantee - nws->Info[sliceId].uplinkBandwidth.sumAvgThroughput);
386// nws->Info[sliceId].uplinkBandwidth.nu = (nws->Info[sliceId].uplinkBandwidth.nu < 0) ?
387// 0 : (nws->Info[sliceId].uplinkBandwidth.nu > 10) ?
388// 10 : nws->Info[sliceId].uplinkBandwidth.nu;
389// }
390// else
391// {
392// fnNetSimError("Unknown slot type %s in %s\n",
393// strLTENR_SLOTTYPE[slotType],
394// __FUNCTION__);
395// }
396// }
397//
398// }
399//}
400//
401static void LTENR_PRB_UpdateSumAvgThroughput_ProportionalFair(ptrLTENR_UESCHEDULERINFO list)
402{
403 NETSIM_ID gnbId = pstruEventDetails->nDeviceId;
404 NETSIM_ID gnbIf = pstruEventDetails->nInterfaceId;
405 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(gnbId, gnbIf);
406
407#pragma warning (disable : 4047)
408 int CA_ID = pstruEventDetails->szOtherDetails;
409#pragma warning (default : 4047)
410
411 LTENR_SLOTTYPE slotType = phy->frameInfo[CA_ID]->slotType;
412
413 for(int sliceId =0; sliceId <=nws->sliceCount; sliceId++)
414 {
415 ptrLTENR_UESCHEDULERINFO temp = list;
416 if (slotType == SLOT_DOWNLINK)
417 nws->Info[sliceId].downlinkBandwidth.sumAvgThroughput = 0;
418 else if(slotType == SLOT_UPLINK)
419 nws->Info[sliceId].uplinkBandwidth.sumAvgThroughput = 0;
420 else
421 fnNetSimError("Unknown slot type %s in %s\n",
422 strLTENR_SLOTTYPE[slotType],
423 __FUNCTION__);
424 while (temp)
425 {
426 if (nws->ueSliceId[temp->ueId] == sliceId)
427 {
428 if (slotType == SLOT_DOWNLINK)
429 nws->Info[sliceId].downlinkBandwidth.sumAvgThroughput += temp->averageThroughput;///slottime(microsecond));
430 else if(slotType == SLOT_UPLINK)
431 nws->Info[sliceId].uplinkBandwidth.sumAvgThroughput += temp->averageThroughput;
432 else
433 fnNetSimError("Unknown slot type %s in %s\n",
434 strLTENR_SLOTTYPE[slotType],
435 __FUNCTION__);
436 }
437 temp = temp->next;
438 }
439 }
440}
441
442static void LTENR_PRB_UpdateRank_ProportionalFair(ptrLTENR_UESCHEDULERINFO list, double alpha)
443{
444 if (list->bufferSize > 0)
445 {
446 LTENR_PRB_UpdateSumAvgThroughput_ProportionalFair(list);
447 //LTENR_PRB_UpdateIndexBias_ProportionalFair(list);
448 }
449 while (list)
450 {
451 // Tj(t) = (1-1/alpha)*Tj(t-1) + (1/alpha)*Tj^(t)
452 // past throughput performance at t = (1-1/alpha)past_throughput_performance_at_(t-1) + (1/alpha)*(allocatedPRB * bits_per_prb)
453 //list->var2 = (1 - 1.0 / alpha) * list->var2 + (1.0 / alpha) * ((double)(list->allocatedPRBCount * list->bitsPerPRB));
454 list->var2 = list->averageThroughput;
455 if (list->var2 == 0) list->var2 = 1;
456 list = list->next;
457 }
458}
459
460static void LTENR_PRB_InitRank_ProportionalFair(ptrLTENR_UESCHEDULERINFO list)
461{
462 NETSIM_ID gnbId = pstruEventDetails->nDeviceId;
463 NETSIM_ID gnbIf = pstruEventDetails->nInterfaceId;
464 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(gnbId, gnbIf);
465
466#pragma warning (disable : 4047)
467 int CA_ID = pstruEventDetails->szOtherDetails;
468#pragma warning (default : 4047)
469
470 LTENR_SLOTTYPE slotType = phy->frameInfo[CA_ID]->slotType;
471
472 while (list)
473 {
474 // Compute R_i(k,t) = S(M_i,k(t),1)/tau = bits_per_prb/TTI = bits_per_prb assuming TTI = 1
475 // rank = R_j(k,t)/Tj(k,t) = bits_per_prb/past_throughput_performance.
476 if (list->var2 == 0)
477 list->var2 = 1; // past throughput performance become 0 due to handover. Resetting back to 1
478 if (slotType == SLOT_DOWNLINK)
479 list->rank = list->bitsPerPRB *((1.0 / list->var2) + nws->Info[nws->ueSliceId[list->ueId]].downlinkBandwidth.nu);
480 else if(slotType == SLOT_UPLINK)
481 list->rank = list->bitsPerPRB *((1.0 / list->var2) + nws->Info[nws->ueSliceId[list->ueId]].uplinkBandwidth.nu);
482 else
483 fnNetSimError("Unknown slot type %s in %s\n",
484 strLTENR_SLOTTYPE[slotType],
485 __FUNCTION__);
486 list = list->next;
487 }
488}
489
490static void LTENR_PRB_InitRank_MaxThroughput(ptrLTENR_UESCHEDULERINFO list)
491{
492 ptrLTENR_UESCHEDULERINFO info = list;
493 while (info)
494 {
495 info->rank = info->bitsPerPRB;
496 info = info->next;
497 }
498}
499
500static void LTENR_PRB_UpdateRank_FAIR(ptrLTENR_UESCHEDULERINFO list) {
501 double min_rank = INT_MAX;
502 double product = 1;
503 bool isnegative = false;
504 ptrLTENR_UESCHEDULERINFO current = list;
505 while (current) {
506 if (current->initRank < min_rank)
507 min_rank = current->initRank;
508 product *= current->rank;
509 current = current->next;
510 }
511 current = list;
512 while (current) {
513 current->rank = current->rank - (min_rank * (current->allocatedPRBCount / initTotalPRBAvailable));
514 if (current->rank <= 0)
515 isnegative = true;
516 current = current->next;
517 }
518 current = list;
519 if (isnegative) {
520 while (current) {
521 current->rank = current->rank + current->initRank;
522 current = current->next;
523 }
524 }
525}
526#pragma endregion
527
528#pragma region ALLOCATE_RESOURCE
529static void NTN_AllocatePRB(ptrLTENR_SCHEDULERINFO schedulerInfo, ptrLTENR_UESCHEDULERINFO* curr, UINT totalPRBAvailable, UINT sliceId)
530{
531 ptrLTENR_UESCHEDULERINFO current = *curr;
532 if (schedulerInfo->isUERRCSetUpCompleted == false) return;
533
534 if (!schedulerInfo->isPRBRankInit)
535 {
536 //first time to set rank
537 LTENR_PRB_SetRank(schedulerInfo->downlinkInfo, schedulerInfo);
538 LTENR_PRB_SetRank(schedulerInfo->uplinkInfo, schedulerInfo);
539 schedulerInfo->isPRBRankInit = TRUE;
540 }
541
542 if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PROPORTIONALFAIR)
543 LTENR_PRB_InitRank_ProportionalFair(current);
544 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_MAXTHROUGHTPUT)
545 LTENR_PRB_InitRank_MaxThroughput(current);
546
547 current = *curr;
548 UINT totalPRB = totalPRBAvailable;
549 current = LTENR_PRB_SortingofRank(current);
550 ptrLTENR_UESCHEDULERINFO current1 = current;
551 *curr = current;
552
553 while (current && totalPRBAvailable > 0)
554 {
555 if (nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_STATIC &&
556 nws->ueSliceId[current->ueId] != sliceId)
557 goto NEXTUE;
558 if (current->bitsPerPRB > 0)
559 {
560 UINT PRBallocation = (UINT)ceil(current->bufferSize * 8.0 / (current->bitsPerPRB));
561
562 if (PRBallocation < totalPRBAvailable) {
563 current->allocatedPRBCount += PRBallocation;
564 totalPRBAvailable -= current->allocatedPRBCount;
565 }
566 else
567 {
568 ptrLTENR_BwpSwitch bwp_switch = LTENR_BWP_Switch(schedulerInfo, current1, PRBallocation);
569
570 if (bwp_switch->bwp_active) {
571 if (PRBallocation > bwp_switch->prb_count) {
572 current->allocatedPRBCount = bwp_switch->prb_count;
573 totalPRBAvailable = 0;
574 }
575 else if (PRBallocation <= bwp_switch->prb_count) {
576 current->allocatedPRBCount = PRBallocation;
577 totalPRBAvailable = bwp_switch->prb_count - PRBallocation;
578 }
579 }
580 else if (!bwp_switch->bwp_active)
581 {
582 current->allocatedPRBCount = totalPRBAvailable;
583 totalPRBAvailable = 0;
584 }
585 free(bwp_switch);
586 }
587 }
588 NEXTUE:
589 current = current->next;
590 }
591
592 if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_FAIR_SCHEDULING)
593 LTENR_PRB_UpdateRank_FAIR(current1);
594 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_ROUNDROBIN)
595 LTENR_PRB_UpdateRank_RoundRobin(current1);
596 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PROPORTIONALFAIR)
597 LTENR_PRB_UpdateRank_ProportionalFair(current1, schedulerInfo->alpha);
598
599 write_prb_log(schedulerInfo, current1, sliceId);
600 fn_NetSim_PRB_Utilization_log(schedulerInfo, current1, sliceId);
601}
602
603static void LTENR_PRB_AllocatePRB(ptrLTENR_SCHEDULERINFO schedulerInfo, ptrLTENR_UESCHEDULERINFO* curr, UINT totalPRBAvailable, UINT sliceId)
604{
605 ptrLTENR_UESCHEDULERINFO current = *curr;
606 if (schedulerInfo->isUERRCSetUpCompleted == false) return;
607
608 //call pfs rg and return
609 if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PF_WITH_RG)
610 {
611 //PFS_RG_AllocatePRB(current, schedulerInfo, sliceId);
612 //write_prb_log(schedulerInfo, current, sliceId);
613 //ptrLTENR_UESCHEDULERINFO currentCopy = current;
614 PFS_RG_AllocatePRB(&current, schedulerInfo, sliceId);
615 *curr = current;
616 write_prb_log(schedulerInfo, current, sliceId);
617 fn_NetSim_PRB_Utilization_log(schedulerInfo, current, sliceId);
618 return;
619 }
620
621 if (!schedulerInfo->isPRBRankInit)
622 {
623 //first time to set rank
624 LTENR_PRB_SetRank(schedulerInfo->downlinkInfo, schedulerInfo);
625 LTENR_PRB_SetRank(schedulerInfo->uplinkInfo, schedulerInfo);
626 schedulerInfo->isPRBRankInit = TRUE;
627 }
628
629 if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PROPORTIONALFAIR)
630 LTENR_PRB_InitRank_ProportionalFair(current);
631 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_MAXTHROUGHTPUT)
632 LTENR_PRB_InitRank_MaxThroughput(current);
633
634 current = *curr;
635 UINT totalPRB = totalPRBAvailable;
636 current = LTENR_PRB_SortingofRank(current);
637 ptrLTENR_UESCHEDULERINFO current1 = current;
638 *curr = current;
639
640 while (current && totalPRBAvailable > 0)
641 {
642 if (nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_STATIC &&
643 nws->ueSliceId[current->ueId] != sliceId)
644 goto NEXTUE;
645 if (current->bitsPerPRB > 0)
646 {
647 UINT PRBallocation = (UINT)ceil(current->bufferSize * 8.0 / (current->bitsPerPRB));
648
649 if (PRBallocation < totalPRBAvailable) {
650 current->allocatedPRBCount += PRBallocation;
651 totalPRBAvailable -= current->allocatedPRBCount;
652 }
653 else
654 {
655 ptrLTENR_BwpSwitch bwp_switch = LTENR_BWP_Switch(schedulerInfo, current1, PRBallocation);
656
657 if (bwp_switch->bwp_active) {
658 if (PRBallocation > bwp_switch->prb_count) {
659 current->allocatedPRBCount = bwp_switch->prb_count;
660 totalPRBAvailable = 0;
661 }
662 else if (PRBallocation <= bwp_switch->prb_count) {
663 current->allocatedPRBCount = PRBallocation;
664 totalPRBAvailable = bwp_switch->prb_count - PRBallocation;
665 }
666 }
667 else if (!bwp_switch->bwp_active)
668 {
669 current->allocatedPRBCount = totalPRBAvailable;
670 totalPRBAvailable = 0;
671 }
672 free(bwp_switch);
673 }
674 }
675 NEXTUE:
676 current = current->next;
677 }
678 if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_FAIR_SCHEDULING)
679 LTENR_PRB_UpdateRank_FAIR(current1);
680 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_ROUNDROBIN)
681 LTENR_PRB_UpdateRank_RoundRobin(current1);
682 else if (schedulerInfo->schedulingType == LTENR_MAC_SCHEDULING_PROPORTIONALFAIR)
683 LTENR_PRB_UpdateRank_ProportionalFair(current1, schedulerInfo->alpha);
684
685 write_prb_log(schedulerInfo, current1, sliceId);
686 fn_NetSim_PRB_Utilization_log(schedulerInfo, current1, sliceId);
687}
688
689static int sumofAllocation(ptrLTENR_UESCHEDULERINFO list)
690{
691 int totalPRBAllocated = 0;
692 while (list) {
693 totalPRBAllocated += list->allocatedPRBCount;
694 list = list->next;
695 }
696 return totalPRBAllocated;
697}
698#pragma endregion
699
700#pragma region RESOURCE_SCHEDULER
701
702void LTENR_PRB_Scheduler(ptrLTENR_SCHEDULERINFO schedulerInfo) {
703 NETSIM_ID gnbId = pstruEventDetails->nDeviceId;
704 NETSIM_ID gnbIf = pstruEventDetails->nInterfaceId;
705 ptrLTENR_GNBPHY phy = LTENR_GNBPHY_GET(gnbId, gnbIf);
706 int CA_ID = phy->currentFrameInfo->Current_CA_ID;
707 LTENR_SLOTTYPE slotType = phy->frameInfo[CA_ID]->slotType;
708 UINT totalPRBAvailable = schedulerInfo->PRBCount;
709 initTotalPRBAvailable = totalPRBAvailable;
710
711 if (slotType == SLOT_UPLINK) {
712 if (!schedulerInfo->uplinkInfo) {
713 return;
714 }
715
716 totalPRBAvailable -= (UINT)ceil(totalPRBAvailable * schedulerInfo->OH_UL);//allocate PRB for overhead
717 LTENR_PRB_ResetAllocationPRBCount(schedulerInfo->uplinkInfo);
718 //LTENR_PRB_ResetAllocationPRBCount(schedulerInfo->downlinkInfo);
719 //Subtract prb reqd for retransmission
720 totalPRBAvailable -= schedulerInfo->TotalPRBReqdForHARQRetransmission;
721
722 //Network Slicing
723 //slice id, slice type, slice differentiator to PRB log if slicing is enabled
724 ptrLTENR_PROTODATA pd = LTENR_PROTODATA_GET(gnbId, gnbIf);
725 if (nws->isSlicing && nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_STATIC)
726 {
727 double PRB_fraction = (double)totalPRBAvailable / 100;
728 UINT PRBforSlice = totalPRBAvailable;
729 for (int i = 0; i <= nws->sliceCount; i++)
730 {
731 PRBforSlice = (UINT)(PRB_fraction * nws->Info[i].uplinkBandwidth.resourceAllocationPercentage);
732 LTENR_PRB_AllocatePRB(schedulerInfo, &schedulerInfo->uplinkInfo, PRBforSlice, i);
733 }
734 }
735 else
736 LTENR_PRB_AllocatePRB(schedulerInfo, &schedulerInfo->uplinkInfo, totalPRBAvailable, 0);
737 }
738
739 else if (schedulerInfo->slotType == SLOT_DOWNLINK) {
740 if (!schedulerInfo->downlinkInfo) {
741 return;
742 }
743
744 totalPRBAvailable -= (UINT)ceil(totalPRBAvailable * schedulerInfo->OH_DL);//allocate PRB for overhead
745 LTENR_PRB_ResetAllocationPRBCount(schedulerInfo->downlinkInfo);
746 //LTENR_PRB_ResetAllocationPRBCount(schedulerInfo->uplinkInfo);
747 //Subtract prb reqd for retransmission
748 totalPRBAvailable -= schedulerInfo->TotalPRBReqdForHARQRetransmission;
749
750 //Network Slicing
751 ptrLTENR_PROTODATA pd = LTENR_PROTODATA_GET(gnbId, gnbIf);
752
753 if (isNTNScenario())
754 {
755 ptrNTN_PROPAGATIONCONFIG ntnInfo = getNTN_PropInfo();
756 UINT PRBforSlice ;
757 for (int i = 0; i <ntnInfo->beamCount; i++)
758 {
759 PRBforSlice = (UINT)(totalPRBAvailable/ntnInfo->channelCount);
760 NTN_AllocatePRB(schedulerInfo, &schedulerInfo->downlinkInfo, totalPRBAvailable, i);
761 }
762 return;
763 }
764
765 if (nws->isSlicing && nws->rsrcSharingTechnique == LTENR_RESOURCE_SHARING_STATIC)
766 {
767 double PRB_fraction = (double)totalPRBAvailable / 100;
768 UINT PRBforSlice = totalPRBAvailable;
769 for (int i = 0; i <= nws->sliceCount; i++)
770 {
771 PRBforSlice = (UINT)(PRB_fraction * nws->Info[i].downlinkBandwidth.resourceAllocationPercentage);
772 LTENR_PRB_AllocatePRB(schedulerInfo, &schedulerInfo->downlinkInfo, PRBforSlice, i);
773 }
774 }
775 else
776 LTENR_PRB_AllocatePRB(schedulerInfo, &schedulerInfo->downlinkInfo, totalPRBAvailable, 0);
777 }
778
779 else
780 {
781 fnNetSimError("Unknown slot type %s in %s\n",
782 strLTENR_SLOTTYPE[schedulerInfo->slotType],
783 __FUNCTION__);
784 }
785}
786#pragma endregion