NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
Component 11/Satellite/Satellite_PropagationModel.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_PHY.h"
27#include "Satellite_MAC.h"
28#include "Satellite_Frame.h"
29
30#pragma region FUNCTIONPROTOTYPE
31
32static FILE* fpRMlog = NULL;
33
34static void create_tx_info_for_ut(NETSIM_ID d, NETSIM_ID in,
35 PTX_INFO info, LINKTYPE linkType);
36static void create_tx_info_for_gw(NETSIM_ID d, NETSIM_ID in,
37 PTX_INFO info, LINKTYPE linkType);
38static void fill_propagation_from_link(NETSIM_ID d, NETSIM_ID in,
39 PPROPAGATION prop);
40#pragma endregion
41
42#pragma region PROPAGATIONMODEL_INIT
43void satellite_propgation_ut_init(NETSIM_ID d, NETSIM_ID in)
44{
45 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(d, in);
46 ptrSATELLITE_UT_MAC mac = SATELLITE_UTMAC_GET(d, in);
47
48 TX_INFO txInfo;
49 create_tx_info_for_ut(d, in, &txInfo, LINKTYPE_RETURN);
50
51 PROPAGATION prop;
52 fill_propagation_from_link(d, in, &prop);
53
54 phy->txPropagationInfo = propagation_create_propagation_info(d, in,
55 mac->satelliteId, mac->satelliteIf,
56 NULL, &txInfo, &prop);
57
58 create_tx_info_for_ut(d, in, &txInfo, LINKTYPE_FORWARD);
59 phy->rxPropagationInfo = propagation_create_propagation_info(mac->satelliteId, mac->satelliteIf,
60 d, in,
61 NULL, &txInfo, &prop);
62}
63
64void satellite_propgation_gw_init(NETSIM_ID d, NETSIM_ID in)
65{
66 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(d, in);
67 ptrSATELLITE_GW_MAC mac = SATELLITE_GWMAC_GET(d, in);
68
69 TX_INFO txInfo;
70 create_tx_info_for_gw(d, in, &txInfo, LINKTYPE_FORWARD);
71
72 PROPAGATION prop;
73 fill_propagation_from_link(d, in, &prop);
74
75 phy->txPropagationInfo = propagation_create_propagation_info(d, in,
76 mac->satelliteId, mac->satelliteIf,
77 NULL, &txInfo, &prop);
78
79 create_tx_info_for_gw(d, in, &txInfo, LINKTYPE_RETURN);
80 phy->rxPropagationInfo = propagation_create_propagation_info(mac->satelliteId, mac->satelliteIf,
81 d, in,
82 NULL, &txInfo, &prop);
83}
84#pragma endregion
85
86#pragma region PROPAGATIONMODEL_HELPER
87static void create_tx_info_for_ut(NETSIM_ID d, NETSIM_ID in,
88 PTX_INFO info, LINKTYPE linkType)
89{
90 memset(info, 0, sizeof * info);
91 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(d, in);
92 ptrSATELLITE_UT_MAC mac = SATELLITE_UTMAC_GET(d, in);
93
94 NETSIM_ID s = mac->satelliteId;
95 NETSIM_ID sin = mac->satelliteIf;
96 ptrSATELLITE_MAC smac = SATELLITE_MAC_GET(s, sin);
97 ptrSATELLITE_PHY sphy = SATELLITE_PHY_GET(s, sin);
98
99 if (linkType == LINKTYPE_FORWARD)
100 {
101 ptrSUPERFRAME sf = smac->forwardFLinkSuperFrame;
102 info->dRxGain = phy->rxAntennaGain_db;
103 info->dTxGain = sphy->txAntennaGain_db;
104 info->dTxPower_dbm = sphy->txPower_dbm;
105 info->dTxPower_mw = sphy->txPower_mw;
106 info->dCentralFrequency = sf->centralFrequency_Hz / MHZ;
107 }
108 else if (linkType == LINKTYPE_RETURN)
109 {
110 ptrSUPERFRAME sf = smac->returnLinkSuperFrame;
111 info->dTxGain = phy->txAntennaGain_db;
112 info->dRxGain = sphy->rxAntennaGain_db;
113 info->dTxPower_dbm = phy->txPower_dbm;
114 info->dTxPower_mw = phy->txPower_mw;
115 info->dCentralFrequency = sf->centralFrequency_Hz / MHZ;
116 }
117
118 info->d0 = 1;
119 info->dTx_Rx_Distance = DEVICE_DISTANCE(d, s);
120}
121
122static void fill_propagation_from_link(NETSIM_ID d, NETSIM_ID in,
123 PPROPAGATION prop)
124{
125 memset(prop, 0, sizeof * prop);
126 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
127 memcpy(prop, link->puniMedProp.pstruWirelessLink.propagation, sizeof * prop);
128 prop->pathlossVar.d0 = 1;
129}
130
131static void create_tx_info_for_gw(NETSIM_ID d, NETSIM_ID in,
132 PTX_INFO info, LINKTYPE linkType)
133{
134 memset(info, 0, sizeof * info);
135 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(d, in);
136 ptrSATELLITE_GW_MAC mac = SATELLITE_GWMAC_GET(d, in);
137
138 NETSIM_ID s = mac->satelliteId;
139 NETSIM_ID sin = mac->satelliteIf;
140 ptrSATELLITE_MAC smac = SATELLITE_MAC_GET(s, sin);
141 ptrSATELLITE_PHY sphy = SATELLITE_PHY_GET(s, sin);
142
143 if (linkType == LINKTYPE_FORWARD)
144 {
145 ptrSUPERFRAME sf = smac->forwardFLinkSuperFrame;
146 info->dTxGain = phy->txAntennaGain_db;
147 info->dRxGain = sphy->rxAntennaGain_db;
148 info->dTxPower_dbm = phy->txPower_dbm;
149 info->dTxPower_mw = phy->txPower_mw;
150 info->dCentralFrequency = sf->centralFrequency_Hz / MHZ;
151 }
152 else if (linkType == LINKTYPE_RETURN)
153 {
154 ptrSUPERFRAME sf = smac->returnLinkSuperFrame;
155 info->dRxGain = phy->rxAntennaGain_db;
156 info->dTxGain = sphy->txAntennaGain_db;
157 info->dTxPower_dbm = sphy->txPower_dbm;
158 info->dTxPower_mw = sphy->txPower_mw;
159 info->dCentralFrequency = sf->centralFrequency_Hz / MHZ;
160 }
161
162 info->d0 = 1;
163 info->dTx_Rx_Distance = DEVICE_DISTANCE(d, s);
164}
165#pragma endregion
166
167#pragma region PROPAGATIONMODEL_CALCULATE
168void satellite_propagation_ut_calculate_rxpower(NETSIM_ID d, NETSIM_ID in, double time)
169{
170 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(d, in);
171 _propagation_calculate_received_power(phy->txPropagationInfo, time);
172 _propagation_calculate_received_power(phy->rxPropagationInfo, time);
173}
174
175void satellite_propagation_gw_calculate_rxpower(NETSIM_ID d, NETSIM_ID in, double time)
176{
177 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(d, in);
178 _propagation_calculate_received_power(phy->txPropagationInfo, time);
179 _propagation_calculate_received_power(phy->rxPropagationInfo, time);
180}
181#pragma endregion
182
183#pragma region SATELLITE_PACKET_ERROR
184static double satellite_get_rx_power_dbm(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri)
185{
186 if (isUT(t, ti))
187 {
188 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(t, ti);
189 return _propagation_get_received_power_dbm(phy->txPropagationInfo, 0);
190 }
191 else if (isGW(t, ti))
192 {
193 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(t, ti);
194 return _propagation_get_received_power_dbm(phy->txPropagationInfo, 0);
195 }
196 else
197 {
198 if (isUT(r, ri))
199 {
200 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(r, ri);
201 return _propagation_get_received_power_dbm(phy->rxPropagationInfo, 0);
202 }
203 else if (isGW(r, ri))
204 {
205 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(r, ri);
206 return _propagation_get_received_power_dbm(phy->rxPropagationInfo, 0);
207 }
208 }
209 return 0;
210}
211
212static double satellite_get_tx_power_db(NETSIM_ID t, NETSIM_ID ti)
213{
214 if (isUT(t, ti))
215 {
216 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(t, ti);
217 return phy->txPower_dbm;
218 }
219 else if (isGW(t, ti))
220 {
221 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(t, ti);
222 return phy->txPower_dbm;
223 }
224 else if (isSATELLITE(t, ti))
225 {
226 ptrSATELLITE_PHY phy = SATELLITE_PHY_GET(t, ti);
227 return phy->txPower_dbm;
228 }
229 return 0;
230}
231
232static double satellite_get_totalloss_db(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri, double Time)
233{
234 if (isUT(t, ti))
235 {
236 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(t, ti);
237 return propagation_get_Totalloss(phy->txPropagationInfo, Time);
238 }
239 else if (isGW(t, ti))
240 {
241 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(t, ti);
242 return propagation_get_Totalloss(phy->txPropagationInfo, Time);
243 }
244 else
245 {
246 if (isUT(r, ri))
247 {
248 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(r, ri);
249 return propagation_get_Totalloss(phy->rxPropagationInfo, Time);
250 }
251 else if (isGW(r, ri))
252 {
253 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(r, ri);
254 return propagation_get_Totalloss(phy->rxPropagationInfo, Time);
255 }
256 }
257 return 0;
258}
259
260static double satellite_get_pathloss_db(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri, double Time)
261{
262 if (isUT(t, ti))
263 {
264 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(t, ti);
265 return propagation_get_Pathloss(phy->txPropagationInfo, Time);
266 }
267 else if (isGW(t, ti))
268 {
269 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(t, ti);
270 return propagation_get_Pathloss(phy->txPropagationInfo, Time);
271 }
272 else
273 {
274 if (isUT(r, ri))
275 {
276 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(r, ri);
277 return propagation_get_Pathloss(phy->rxPropagationInfo, Time);
278 }
279 else if (isGW(r, ri))
280 {
281 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(r, ri);
282 return propagation_get_Pathloss(phy->rxPropagationInfo, Time);
283 }
284 }
285 return 0;
286}
287
288static double satellite_get_fading_loss_db(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri)
289{
290 if (isUT(t, ti))
291 {
292 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(t, ti);
293 return _propagation_calculate_fadingloss(phy->txPropagationInfo);
294 }
295 else if (isGW(t, ti))
296 {
297 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(t, ti);
298 return _propagation_calculate_fadingloss(phy->txPropagationInfo);
299 }
300 else
301 {
302 if (isUT(r, ri))
303 {
304 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(r, ri);
305 return _propagation_calculate_fadingloss(phy->rxPropagationInfo);
306 }
307 else if (isGW(r, ri))
308 {
309 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(r, ri);
310 return _propagation_calculate_fadingloss(phy->rxPropagationInfo);
311 }
312 }
313 return 0;
314}
315
316#define BOLTZMAAN_CONSTANT 1.38064852e-23 // m2 kg s-2 K-1
317static double satellite_calculate_noise(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri)
318{
319 double noise_w = 0;
320 if (isUT(t, ti))
321 {
322 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(t, ti);
323 ptrSATELLITE_PHY sphy = SATELLITE_PHY_GET(r, ri);
324 noise_w = BOLTZMAAN_CONSTANT * phy->tempeature_k * sphy->returnLinkSuperFrame->carrierConfig->allocatedBandwidth_Hz;
325 }
326 else if (isGW(t, ti))
327 {
328 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(t, ti);
329 ptrSATELLITE_PHY sphy = SATELLITE_PHY_GET(r, ri);
330 noise_w = BOLTZMAAN_CONSTANT * phy->tempeature_k * sphy->forwardLinkSuperFrame->carrierConfig->allocatedBandwidth_Hz;
331 }
332 else
333 {
334 if (isUT(r, ri))
335 {
336 ptrSATELLITE_UT_PHY phy = SATELLITE_UTPHY_GET(r, ri);
337 ptrSATELLITE_PHY sphy = SATELLITE_PHY_GET(t, ti);
338 noise_w = BOLTZMAAN_CONSTANT * phy->tempeature_k * sphy->forwardLinkSuperFrame->carrierConfig->allocatedBandwidth_Hz;
339 }
340 else if (isGW(r, ri))
341 {
342 ptrSATELLITE_GW_PHY phy = SATELLITE_GWPHY_GET(r, ri);
343 ptrSATELLITE_PHY sphy = SATELLITE_PHY_GET(t, ti);
344 noise_w = BOLTZMAAN_CONSTANT * phy->tempeature_k * sphy->returnLinkSuperFrame->carrierConfig->allocatedBandwidth_Hz;
345 }
346 }
347
348 return MW_TO_DBM(noise_w * 1000);
349}
350
351static double satellite_calculate_snr(double pdbm, double ndbm)
352{
353 return MW_TO_DBM(DBM_TO_MW(pdbm) / DBM_TO_MW(ndbm));
354}
355
356static ptrSUPERFRAME find_superframe(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri)
357{
358 if (isUT(t, ti))
359 {
360 ptrSATELLITE_PHY phy = SATELLITE_PHY_GET(r, ri);
361 return phy->returnLinkSuperFrame;
362 }
363 else if (isGW(t, ti))
364 {
365 ptrSATELLITE_PHY phy = SATELLITE_PHY_GET(r, ri);
366 return phy->forwardLinkSuperFrame;
367 }
368 else
369 {
370 if (isUT(r, ri))
371 {
372 ptrSATELLITE_PHY phy = SATELLITE_PHY_GET(t, ti);
373 return phy->forwardLinkSuperFrame;
374 }
375 else if (isGW(r, ri))
376 {
377 ptrSATELLITE_PHY phy = SATELLITE_PHY_GET(t, ti);
378 return phy->returnLinkSuperFrame;
379 }
380 }
381 return NULL;
382}
383
384static double satellite_calculate_ber(ptrSUPERFRAME sf, double snr)
385{
386 ptrCARRIERCONF cc = sf->carrierConfig;
387 if (cc->berModel == BERMODEL_Fixed)
388 return cc->berValue;
389 else if (cc->berModel == BERMODEL_File)
390 return calculate_ber(snr, cc->berTable, cc->berTableLen);
391 else if (cc->berModel == BERMODEL_Model)
392 {
393 double dataRate = sf->slotConfig->bitsPerSlot / sf->slotConfig->slotLength_us;
394 return Calculate_ber_by_calculation(snr, cc->modulation, dataRate, cc->allocatedBandwidth_Hz / MHZ);
395 }
396 return 0;
397}
398
399static PACKET_STATUS satellite_isPacketErrored(ptrSUPERFRAME sf, double bytes, double snr)
400{
401 double ber = satellite_calculate_ber(sf, snr);
402 return fn_NetSim_Packet_DecideError(ber, bytes);
403}
404
405static void init_radio_measurements_log()
406{
407 if (get_protocol_log_status("SATELLITE_PROPAGATION_LOG"))
408{
409 char s[BUFSIZ];
410 sprintf(s, "%s/log/Satellite_Radio_Measurements_Log.csv",
411 pszIOPath);
412 fpRMlog = fopen(s, "w");
413 if (!fpRMlog)
414 {
415 fnSystemError("Unable to open %s\n", s);
416 perror(s);
417 return NULL;
418 }
419 fprintf(fpRMlog, "Time(ms),Transmitter Name,Receiver Name,Tx_Power(dBm),PathLoss(dB),FadingLoss(dB),TotalLoss(dB),Rx_Power(dBm),Noise(dBm),SNR(dB)\n");
420 if (nDbgFlag) fflush(fpRMlog);
421 }
422}
423
424static void log_radio_measurements(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri, double tx_power, double pathloss, double f, double n,
425 double totalloss, double p, double snr)
426{
427 if (fpRMlog == NULL) return;
428
429 fprintf(fpRMlog, "%lf,%s,%s,%lf,%lf,%lf,%lf,%lf,%lf,%lf,\n",
430 (ldEventTime/MILLISECOND), DEVICE_NAME(t), DEVICE_NAME(r), tx_power, pathloss, f, totalloss, p, n, snr);
431 if (nDbgFlag) fflush(fpRMlog);
432}
433
434static void close_radio_measurements_log()
435{
436 if (fpRMlog)
437 fclose(fpRMlog);
438 }
439
440void Satellite_RadioMeasurements_Init()
441{
442 init_radio_measurements_log();
443}
444
445void Satellite_RadioMeasurements_Finish()
446{
447 close_radio_measurements_log();
448}
449
450void satellite_check_for_packet_error(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri,
451 NetSim_PACKET* packet)
452{
453 double pdbm = satellite_get_rx_power_dbm(t, ti, r, ri);
454 double fdb = satellite_get_fading_loss_db(t, ti, r, ri);
455 pdbm -= fdb;
456
457 double ndbm = satellite_calculate_noise(t, ti, r, ri);
458 double snr = satellite_calculate_snr(pdbm, ndbm);
459
460 double pathloss = satellite_get_pathloss_db(t, ti, r, ri, ldEventTime);
461 double tx_power = satellite_get_tx_power_db(t, ti);
462 double totalloss = satellite_get_totalloss_db(t, ti, r, ri, ldEventTime);
463
464 log_radio_measurements(t, ti, r, ri, tx_power, pathloss, fdb, ndbm, totalloss, pdbm + fdb, snr);
465
466 double bytes = packet->pstruPhyData->dPacketSize;
467
468 ptrSUPERFRAME sf = find_superframe(t, ti, r, ri);
469 packet->nPacketStatus = satellite_isPacketErrored(sf, bytes, snr);
470}
471#pragma endregion