NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
Component 11/Satellite/Satellite_SuperFrame.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 "SATELLITE.h"
26#include "Satellite_MAC.h"
27#include "Satellite_PHY.h"
28
29#pragma region EVENT_OTHER_DETAILS
30typedef struct stru_eventdetails
31{
32 ptrSUPERFRAME sf;
33 ptrCARRIER carrier;
34 ptrFRAME fr;
35}EVENTDETAILS, * ptrEVENTDETAILS;
36
37static ptrEVENTDETAILS form_eventdetails(ptrSUPERFRAME sf, ptrFRAME fr, ptrCARRIER carrier)
38{
39 ptrEVENTDETAILS ev = calloc(1, sizeof * ev);
40 ev->fr = fr;
41 ev->sf = sf;
42 ev->carrier = carrier;
43 return ev;
44}
45
46static void clear_eventdetails(ptrEVENTDETAILS ev)
47{
48 free(ev);
49}
50
51static ptrSUPERFRAME get_curr_superframe()
52{
53 ptrEVENTDETAILS ev = pstruEventDetails->szOtherDetails;
54 return ev->sf;
55}
56
57static ptrFRAME get_curr_frame()
58{
59 ptrEVENTDETAILS ev = pstruEventDetails->szOtherDetails;
60 return ev->fr;
61}
62
63static ptrCARRIER get_curr_carrier()
64{
65 ptrEVENTDETAILS ev = pstruEventDetails->szOtherDetails;
66 return ev->carrier;
67}
68#pragma endregion
69
70#pragma region FUNCTION_PROTOTYPE
71static void add_superframe_event(NETSIM_ID d, NETSIM_ID in, double time, ptrSUPERFRAME sf);
72static void frame_send_packet(NETSIM_ID d, NETSIM_ID in,
73 ptrSUPERFRAME sf, ptrFRAME fr, ptrCARRIER cr);
74#pragma endregion
75
76#pragma region UTILITY
77ptrSUPERFRAME satellite_get_return_superframe(NETSIM_ID d, NETSIM_ID in)
78{
79 ptrSATELLITE_MAC mac = SATELLITE_MAC_GET(d, in);
80 return mac->returnLinkSuperFrame;
81}
82
83ptrSUPERFRAME satellite_get_forward_superframe(NETSIM_ID d, NETSIM_ID in)
84{
85 ptrSATELLITE_MAC mac = SATELLITE_MAC_GET(d, in);
86 return mac->forwardFLinkSuperFrame;
87}
88#pragma endregion
89
90#pragma region SUPERFRAME_INIT
91ptrSUPERFRAME superframe_alloc(LINKTYPE linkType,
92 NETSIM_ID d, NETSIM_ID in)
93{
94 ptrSUPERFRAME sf = calloc(1, sizeof * sf);
95 sf->carrierConfig = calloc(1, sizeof * sf->carrierConfig);
96 sf->slotConfig = calloc(1, sizeof * sf->slotConfig);
97 sf->frameConfig = calloc(1, sizeof * sf->frameConfig);
98 sf->linkType = linkType;
99
100 ptrSATELLITE_MAC mac = SATELLITE_MAC_GET(d, in);
101 ptrSATELLITE_PHY phy = SATELLITE_PHY_GET(d, in);
102
103 if (linkType == LINKTYPE_FORWARD)
104 {
105 mac->forwardFLinkSuperFrame = sf;
106 phy->forwardLinkSuperFrame = sf;
107 }
108 else if (linkType == LINKTYPE_RETURN)
109 {
110 mac->returnLinkSuperFrame = sf;
111 phy->returnLinkSuperFrame = sf;
112 }
113
114 return sf;
115}
116
117static void form_frames(ptrSUPERFRAME sf, ptrCARRIER carrier)
118{
119 UINT i;
120
121 carrier->frameCount = sf->frameConfig->framesPerSuperframe;
122 carrier->frames = calloc(carrier->frameCount, sizeof * carrier->frames);
123
124 double startTime = 0;
125 for (i = 0; i < carrier->frameCount; i++)
126 {
127 ptrFRAME fr = calloc(1, sizeof * fr);
128 carrier->frames[i] = fr;
129
130 fr->relativeFrameStartTime = startTime;
131
132 fr->relativeFrameEndTime = sf->frameConfig->frameLength_us + startTime;
133 fr->bandwidth_Hz = carrier->bandwidth_Hz;
134 fr->carrierId = carrier->carrierId;
135 fr->frameId = i + 1;
136 fr->isRandomAccess = false;
137
138 startTime = fr->relativeFrameEndTime;
139 }
140}
141
142static UINT calculate_bitsPerSlot(ptrSUPERFRAME sf)
143{
144 return (UINT)floor((double)sf->slotConfig->symbolPerSlot *
145 (double)sf->slotConfig->modulationBits *
146 sf->carrierConfig->codingRate);
147}
148
149static UINT getModulationBits(PHY_MODULATION modulation)
150{
151 switch (modulation)
152 {
153 case Modulation_QPSK:
154 {
155 return 2;
156 break;
157 }
158 case Modulation_8PSK:
159 {
160 return 3;
161 break;
162 }
163 case Modulation_16APSK:
164 case Modulation_16_QAM:
165 {
166 return 4;
167 break;
168 }
169 case Modulation_32APSK:
170 {
171 return 5;
172 break;
173 }
174 default:
175 {
176 fnNetSimError("Unsupported modulation %s for satellite network\n",
177 strPHY_MODULATION[modulation]);
178 return 0;
179 break;
180 }
181 }
182}
183
184static void form_carrier(ptrSUPERFRAME sf)
185{
186 UINT i;
187
188 sf->carrierCount = (UINT)floor(sf->bandwidth_Hz / sf->carrierConfig->allocatedBandwidth_Hz);
189 sf->carriers = calloc(sf->carrierCount, sizeof * sf->carriers);
190 print_satellite_log("Carrier count = %d\n", sf->carrierCount);
191 satellite_log_add_tab();
192
193 for (i = 0; i < sf->carrierCount; i++)
194 {
195 print_satellite_log("Forming carrier %d\n", i + 1);
196
197 sf->carriers[i] = calloc(1, sizeof * sf->carriers[i]);
198 ptrCARRIER cr = sf->carriers[i];
199 cr->bandwidth_Hz = sf->carrierConfig->allocatedBandwidth_Hz;
200 cr->carrierId = i + 1;
201 cr->centerFrequency_Hz = sf->baseFreqnecy_Hz + cr->bandwidth_Hz * (i + 0.5);
202
203 print_satellite_log("Carrier Id = %d\n", i + 1);
204 print_satellite_log("carrier allocated bandwidth = %lf Hz\n", cr->bandwidth_Hz);
205 print_satellite_log("Central frequency = %lf Hz\n", cr->centerFrequency_Hz);
206 print_satellite_log("\n");
207 }
208 satellite_log_remove_tab();
209 print_satellite_log("\n");
210}
211
212static void configure_superframe(ptrSUPERFRAME sf)
213{
214 sf->bandwidth_Hz = sf->frameConfig->frameBandwidth_Hz;
215 sf->centralFrequency_Hz = sf->baseFreqnecy_Hz + sf->bandwidth_Hz / 2.0;
216 sf->slotConfig->symbolRate = (UINT)sf->carrierConfig->effectiveBandwidth_Hz;
217 sf->slotConfig->modulationBits = getModulationBits(sf->carrierConfig->modulation);
218
219 UINT slots = sf->frameConfig->slotCountInFrame + sf->frameConfig->plHdrSize_inSlots;
220 UINT dataSymbols = slots * sf->slotConfig->symbolPerSlot;
221 UINT pilotSlot = (UINT)floor((double)slots / sf->frameConfig->pilotBlockInterval_inSlots);
222 UINT pilotSymbol = pilotSlot * sf->frameConfig->pilotBlockSize_inSymbols;
223 UINT totalSymbol = pilotSymbol + dataSymbols;
224
225 sf->frameConfig->frameLength_us = (((double)totalSymbol) / sf->slotConfig->symbolRate) * SECOND;
226 sf->frameConfig->pilotBlockLength_us = (((double)sf->frameConfig->pilotBlockSize_inSymbols) / sf->slotConfig->symbolRate) * SECOND;
227 sf->slotConfig->slotLength_us = (((double)sf->slotConfig->symbolPerSlot) / sf->slotConfig->symbolRate) * SECOND;
228 sf->superFrameDuration_us = sf->frameConfig->frameLength_us * sf->frameConfig->framesPerSuperframe;
229 sf->slotConfig->bitsPerSlot = calculate_bitsPerSlot(sf);
230 sf->frameConfig->bitsPerFrame = sf->slotConfig->bitsPerSlot * sf->frameConfig->slotCountInFrame;
231
232 print_satellite_log("Frame length = %lf us\n", sf->frameConfig->frameLength_us);
233 print_satellite_log("Pilot block length = %lf us\n", sf->frameConfig->pilotBlockLength_us);
234 print_satellite_log("Slot length = %lf us\n", sf->slotConfig->slotLength_us);
235 print_satellite_log("Superframe Duration = %lf us\n", sf->superFrameDuration_us);
236 print_satellite_log("Bits per slot = %d\n", sf->slotConfig->bitsPerSlot);
237 print_satellite_log("Bits per frame = %d\n", sf->frameConfig->bitsPerFrame);
238 print_satellite_log("Superframe duration = %0.3lf us\n", sf->superFrameDuration_us);
239 print_satellite_log("Superframe bandwidth = %lf Hz\n", sf->bandwidth_Hz);
240 print_satellite_log("Central frquency = %lf Hz\n", sf->centralFrequency_Hz);
241}
242
243static void form_superframe(ptrSUPERFRAME sf)
244{
245 UINT i;
246
247 configure_superframe(sf);
248 form_carrier(sf);
249
250 for (i = 0; i < sf->carrierCount; i++)
251 form_frames(sf, sf->carriers[i]);
252}
253
254static void set_max_payload_size(NETSIM_ID d, NETSIM_ID in,
255 UINT bits)
256{
257 UINT bytes = bits / 8;
258 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
259 NETSIM_ID i;
260 for (i = 0; i < link->puniDevList.pstrup2MP.nConnectedDeviceCount - 1; i++)
261 {
262 NETSIM_ID c = link->puniDevList.pstrup2MP.anDevIds[i];
263 NETSIM_ID cin = link->puniDevList.pstrup2MP.anDevInterfaceIds[i];
264 DEVICE_MACLAYER(c, cin)->dFragmentSize = (double)bytes;
265 }
266}
267
268static void set_max_unit_size(ptrSUPERFRAME sf, UINT maxBitsCount)
269{
270 double maxBytes = floor(maxBitsCount / 8.0);
271 UINT i;
272 for (i = 0; i < sf->bufferCount; i++)
273 satellite_buffer_setMaxUnitSizeInBytes(sf->buffers[i], maxBytes);
274}
275
276void superframe_init(NETSIM_ID d,NETSIM_ID in)
277{
278 ptrSATELLITE_MAC mac = SATELLITE_MAC_GET(d, in);
279 ptrSUPERFRAME rsf = mac->returnLinkSuperFrame;
280 ptrSUPERFRAME fsf = mac->forwardFLinkSuperFrame;
281
282 print_satellite_log("\n\nForming return superframe for satellite %d-%d.\n", d, in);
283 form_superframe(rsf);
284
285 print_satellite_log("\n\nForming forward superframe for satellite %d-%d.\n", d, in);
286 form_superframe(fsf);
287
288 set_max_payload_size(d, in, min(rsf->frameConfig->bitsPerFrame, fsf->frameConfig->bitsPerFrame));
289 set_max_unit_size(rsf, min(rsf->frameConfig->bitsPerFrame, fsf->frameConfig->bitsPerFrame));
290 set_max_unit_size(fsf, min(rsf->frameConfig->bitsPerFrame, fsf->frameConfig->bitsPerFrame));
291 add_superframe_event(d, in, 0, rsf);
292 add_superframe_event(d, in, 0, fsf);
293}
294#pragma endregion
295
296#pragma region SUPERFRAME_RESET
297static void reset_carrier(ptrSUPERFRAME sf, ptrCARRIER cr)
298{
299 sf;
300 UINT i;
301 for (i = 0; i < cr->frameCount; i++)
302 {
303 cr->frames[i]->frameStartTime = 0;
304 cr->frames[i]->frameEndTime = 0;
305 }
306}
307
308static void reset_superframe(ptrSUPERFRAME sf)
309{
310 UINT i;
311 for (i = 0; i < sf->carrierCount; i++)
312 reset_carrier(sf, sf->carriers[i]);
313
314 sf->startTime_us = 0;
315 sf->endTime_us = 0;
316}
317#pragma endregion
318
319#pragma region FRAME_EVENT
320static void add_frame_start_event(NETSIM_ID d, NETSIM_ID in,
321 ptrSUPERFRAME sf, ptrFRAME fr, ptrCARRIER cr)
322{
323 NetSim_EVENTDETAILS pevent;
324 memset(&pevent, 0, sizeof pevent);
325 pevent.dEventTime = fr->frameStartTime;
326 pevent.nDeviceId = d;
327 pevent.nDeviceType = DEVICE_TYPE(d);
328 pevent.nEventType = TIMER_EVENT;
329 pevent.nInterfaceId = in;
330 pevent.nProtocolId = MAC_PROTOCOL_SATELLITE;
331 pevent.nSubEventType = SUBEVENT_FRAME_START;
332 pevent.szOtherDetails = form_eventdetails(sf, fr, cr);
333 fnpAddEvent(&pevent);
334}
335
336void satellite_frame_start()
337{
338 NETSIM_ID d = pstruEventDetails->nDeviceId;
339 NETSIM_ID in = pstruEventDetails->nInterfaceId;
340 double time = pstruEventDetails->dEventTime;
341 ptrFRAME fr = get_curr_frame();
342 ptrCARRIER cr = get_curr_carrier();
343 ptrSUPERFRAME sf = get_curr_superframe();
344 clear_eventdetails(pstruEventDetails->szOtherDetails);
345
346 print_satellite_log("Satellite %d-%d, Time %0.3lf us. Starting Frame\n",
347 d, in, time);
348 satellite_log_add_tab();
349 print_satellite_log("Frame start time = %0.3lf us\n", fr->frameStartTime);
350 print_satellite_log("Frame end time = %0.3lf us\n", fr->frameEndTime);
351
352 satellite_allocate_slot(d, in, sf, fr);
353 frame_send_packet(d, in, sf, fr, cr);
354 satellite_log_remove_tab();
355}
356#pragma endregion
357
358#pragma region SUPERFRAME_EVENT
359static void add_superframe_event(NETSIM_ID d, NETSIM_ID in, double time, ptrSUPERFRAME sf)
360{
361 NetSim_EVENTDETAILS pevent;
362 memset(&pevent, 0, sizeof pevent);
363 pevent.dEventTime = time;
364 pevent.nDeviceId = d;
365 pevent.nDeviceType = DEVICE_TYPE(d);
366 pevent.nEventType = TIMER_EVENT;
367 pevent.nInterfaceId = in;
368 pevent.nProtocolId = MAC_PROTOCOL_SATELLITE;
369 pevent.nSubEventType = SUBEVENT_SUPERFRAME_START;
370 pevent.szOtherDetails = form_eventdetails(sf, NULL, NULL);
371 fnpAddEvent(&pevent);
372}
373
374static void start_superframe(ptrSATELLITE_MAC mac, ptrSUPERFRAME sf, double time)
375{
376 sf->startTime_us = time;
377 sf->endTime_us = sf->superFrameDuration_us + time;
378 sf->superFrameId++;
379 print_satellite_log("Superframe Id = %d\n", sf->superFrameId);
380 print_satellite_log("Superframe start time = %0.3lf us\n", sf->startTime_us);
381 print_satellite_log("Superframe end time = %0.3lf us\n", sf->endTime_us);
382 print_satellite_log("Link Type = %s\n", strLINKTYPE[sf->linkType]);
383
384 UINT i, j;
385 for (i = 0; i < sf->carrierCount; i++)
386 {
387 ptrCARRIER carrier = sf->carriers[i];
388 for (j = 0; j < carrier->frameCount; j++)
389 {
390 ptrFRAME fr = carrier->frames[j];
391 fr->frameStartTime = fr->relativeFrameStartTime + time;
392 fr->frameEndTime = fr->relativeFrameEndTime + time;
393 print_satellite_log("Frame %d start time = %0.3lf us\n", i + 1, fr->frameStartTime);
394 print_satellite_log("Frame %d end time = %0.3lf us\n", i + 1, fr->frameEndTime);
395 print_satellite_log("Adding frame %d start event\n", i + 1);
396 add_frame_start_event(mac->satelliteId, mac->satelliteIf, sf, fr, carrier);
397 }
398 }
399}
400
401void satellite_superframe_start()
402{
403 NETSIM_ID d = pstruEventDetails->nDeviceId;
404 NETSIM_ID in = pstruEventDetails->nInterfaceId;
405 ptrSATELLITE_MAC mac = SATELLITE_MAC_GET(d, in);
406 ptrSUPERFRAME sf = get_curr_superframe();
407 clear_eventdetails(pstruEventDetails->szOtherDetails);
408
409 if (sf->bufferCount == 0)
410 satellite_form_bufferList(d, in, sf);
411
412 double time = pstruEventDetails->dEventTime;
413
414 print_satellite_log("Satellite %d-%d, Time %0.3lf us\n",
415 d, in, time);
416 satellite_log_add_tab();
417 print_satellite_log("Resetting previous superframe\n");
418 reset_superframe(sf);
419 print_satellite_log("Starting new superframe\n");
420 start_superframe(mac, sf, time);
421
422 //Add next superframe start event
423 time += sf->superFrameDuration_us;
424 add_superframe_event(d, in, time, sf);
425 print_satellite_log("Adding next superframe start event at %0.3lf us\n", time);
426 satellite_log_remove_tab();
427}
428#pragma endregion
429
430#pragma region FRAME_SEND
431static void send_packet_to_phy(NetSim_PACKET* packet,
432 NETSIM_ID d, NETSIM_ID in)
433{
434 packet->pstruMacData->dPacketSize = packet->pstruMacData->dPayload + packet->pstruMacData->dOverhead;
435 packet->pstruPhyData->dPayload = packet->pstruMacData->dPacketSize;
436 packet->pstruPhyData->dPacketSize = packet->pstruPhyData->dOverhead +
437 packet->pstruPhyData->dPayload;
438
439 NetSim_EVENTDETAILS pevent;
440 memset(&pevent, 0, sizeof pevent);
441 pevent.dEventTime = packet->pstruMacData->dEndTime;
442 pevent.dPacketSize = packet->pstruMacData->dPacketSize;
443
444 if (packet->pstruAppData)
445 {
446 pevent.nApplicationId = packet->pstruAppData->nApplicationId;
447 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
448 }
449
450 pevent.nDeviceId = packet->nTransmitterId;
451 pevent.nDeviceType = DEVICE_TYPE(packet->nTransmitterId);
452 pevent.nEventType = PHYSICAL_OUT_EVENT;
453 pevent.nInterfaceId = fn_NetSim_Stack_GetConnectedInterface(d, in, packet->nTransmitterId);;
454 pevent.nPacketId = packet->nPacketId;
455 pevent.nProtocolId = MAC_PROTOCOL_SATELLITE;
456 pevent.pPacket = packet;
457 fnpAddEvent(&pevent);
458}
459
460static void update_time(NetSim_PACKET* packet, double* startTime,
461 UINT bitsPerFrame, double frameDuration)
462{
463 UINT bitsCount = (UINT)packet->pstruMacData->dPayload * 8;
464 double duration = ((bitsCount * 1.0) / bitsPerFrame) * frameDuration;
465
466 packet->pstruMacData->dEndTime = *startTime;
467 packet->pstruMacData->dStartTime = *startTime;
468
469 packet->pstruPhyData->dArrivalTime = *startTime;
470 packet->pstruPhyData->dStartTime = *startTime + duration;
471
472 *startTime += duration;
473}
474
475static void frame_send_packet(NETSIM_ID d, NETSIM_ID in,
476 ptrSUPERFRAME sf, ptrFRAME fr, ptrCARRIER cr)
477{
478 (void)cr;
479
480 double st = fr->frameStartTime;
481 double frDur = fr->frameEndTime - fr->frameStartTime;
482 NetSim_PACKET* packet;
483 while (fr->head)
484 {
485 packet = fr->head;
486 fr->head = packet->pstruNextPacket;
487 if (fr->head == NULL) fr->tail = NULL;
488 packet->pstruNextPacket = NULL;
489
490 update_time(packet, &st, sf->frameConfig->bitsPerFrame, frDur);
491
492 send_packet_to_phy(packet, d, in);
493
494 }
495}
496#pragma endregion