NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
P2P.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 "P2P.h"
26#include "P2P_Enum.h"
27#include "AdvancedPlots.h"
28#pragma comment(lib,"AdvancedPlots.lib")
29
30//Function prototype
31static void add_event_link_up();
32static int fn_NetSim_P2P_CalulateReceivedPower();
33int P2P_MacOut_Handler();
34int P2P_MacIn_Handler();
35int P2P_PhyOut_Handler();
36int P2P_PhyIn_Handler();
37
38/**
39This function is called by NetworkStack.dll, whenever the event gets triggered
40inside the NetworkStack.dll for the Mac/Phy layer P2P protocol
41It includes MAC_OUT, MAC_IN, PHY_OUT, PHY_IN and TIMER_EVENT.
42*/
43_declspec (dllexport) int fn_NetSim_P2P_Run()
44{
45 switch (pstruEventDetails->nEventType)
46 {
47 case MAC_OUT_EVENT:
48 P2P_MacOut_Handler();
49 break;
50 case MAC_IN_EVENT:
51 P2P_MacIn_Handler();
52 break;
53 case PHYSICAL_OUT_EVENT:
54 P2P_PhyOut_Handler();
55 break;
56 case PHYSICAL_IN_EVENT:
57 P2P_PhyIn_Handler();
58 break;
59 case TIMER_EVENT:
60 {
61 switch (pstruEventDetails->nSubEventType)
62 {
63 case P2P_LINK_UP:
64 notify_interface_up(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId);
65 break;
66 case P2P_LINK_DOWN:
67 notify_interface_down(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId);
68 break;
69 }
70 }
71 break;
72 }
73 return 0;
74}
75
76PHY_MODULATION getModulationFromString(char* val)
77{
78 if (!_stricmp(val, "QPSK"))
79 return Modulation_QPSK;
80 else if (!_stricmp(val, "BPSK"))
81 return Modulation_BPSK;
82 else if (!_stricmp(val, "16QAM"))
83 return Modulation_16_QAM;
84 else if (!_stricmp(val, "64QAM"))
85 return Modulation_64_QAM;
86 else if (!_stricmp(val, "GMSK"))
87 return Modulation_GMSK;
88 else
89 {
90 fnNetSimError("Unknown modulation %s for P2P protocol. Assigning QPSK\n", val);
91 return Modulation_QPSK;
92 }
93}
94
95static void configure_wireless_P2P(NETSIM_ID d, NETSIM_ID in, void* xmlNetSimNode)
96{
97 char* szVal;
98 ptrP2P_NODE_PHY phy = P2P_PHY(d, in);
99 if (!phy)
100 {
101 phy = (ptrP2P_NODE_PHY)calloc(1, sizeof* phy);
102 DEVICE_PHYVAR(d, in) = phy;
103 }
104 phy->iswireless = true;
105 //Get the CENTRAL_FREQUENCY
106 phy->dCenteralFrequency = fn_NetSim_Config_read_Frequency(xmlNetSimNode, "CENTRAL_FREQUENCY", P2P_CENTRAL_FREQUENCY_DEFAULT, "MHz");
107
108 phy->dBandwidth = fn_NetSim_Config_read_Frequency(xmlNetSimNode, "BANDWIDTH", P2P_BANDWIDTH_DEFAULT, "MHz");
109
110 phy->dTXPower = fn_NetSim_Config_read_txPower(xmlNetSimNode, "TX_POWER", P2P_TX_POWER_DEFAULT, "mW");
111
112 phy->dDataRate = fn_NetSim_Config_read_dataRate(xmlNetSimNode, "DATA_RATE", P2P_DATA_RATE_DEFAULT, "mbps");
113
114 phy->dReceiverSensitivity = fn_NetSim_Config_read_txPower(xmlNetSimNode, "RECEIVER_SENSITIVITY", P2P_RECEIVER_SENSITIVITY_DBM_DEFAULT, "dBM");
115
116 //Get the modulation
117 getXmlVar(&szVal, MODULATION_TECHNIQUE, xmlNetSimNode, 1, _STRING, P2P);
118 phy->modulation = getModulationFromString(szVal);
119
120 getXmlVar(&phy->dAntennaHeight, ANTENNA_HEIGHT, xmlNetSimNode, 1, _DOUBLE, P2P);
121 getXmlVar(&phy->dAntennaGain, ANTENNA_GAIN, xmlNetSimNode, 1, _DOUBLE, P2P);
122 getXmlVar(&phy->d0, D0, xmlNetSimNode, 0, _DOUBLE, P2P);
123 getXmlVar(&phy->pld0, PL_D0, xmlNetSimNode, 0, _DOUBLE, P2P);
124}
125
126/**
127This function is called by NetworkStack.dll, while configuring the device
128Mac/Phy layer for P2P protocol.
129*/
130_declspec(dllexport) int fn_NetSim_P2P_Configure(void** var)
131{
132 char* tag;
133 void* xmlNetSimNode;
134 NETSIM_ID nDeviceId;
135 NETSIM_ID nInterfaceId;
136 LAYER_TYPE nLayerType;
137 char* szVal;
138
139 tag = (char*)var[0];
140 xmlNetSimNode = var[2];
141 if (!strcmp(tag, "PROTOCOL_PROPERTY"))
142 {
143 NETWORK = (struct stru_NetSim_Network*)var[1];
144 nDeviceId = *((NETSIM_ID*)var[3]);
145 nInterfaceId = *((NETSIM_ID*)var[4]);
146 nLayerType = *((LAYER_TYPE*)var[5]);
147 switch (nLayerType)
148 {
149 case MAC_LAYER:
150 {
151 //Get the MAC address
152 szVal = fn_NetSim_xmlConfig_GetVal(xmlNetSimNode, "MAC_ADDRESS", 1);
153 if (szVal)
154 {
155 DEVICE_MACLAYER(nDeviceId, nInterfaceId)->szMacAddress = STR_TO_MAC(szVal);
156 free(szVal);
157 }
158
159 ptrP2P_NODE_MAC mac = P2P_MAC(nDeviceId, nInterfaceId);
160 if (!mac)
161 {
162 mac = (ptrP2P_NODE_MAC)calloc(1, sizeof * mac);
163 DEVICE_MACVAR(nDeviceId, nInterfaceId) = mac;
164 }
165 }
166 break;
167 case PHYSICAL_LAYER:
168 {
169 getXmlVar(&szVal, CONNECTION_MEDIUM, xmlNetSimNode, 1, _STRING, P2P);
170 if (!_stricmp(szVal, "wireless"))
171 configure_wireless_P2P(nDeviceId, nInterfaceId, xmlNetSimNode);
172 free(szVal);
173 }
174 break;
175 default:
176 fnNetSimError("%d layer is not implemented for P2P protocol\n", nLayerType);
177 break;
178 }
179 }
180 return 0;
181}
182
183/**
184This function initializes the P2P parameters.
185*/
186_declspec (dllexport) int fn_NetSim_P2P_Init()
187{
188 init_linkpacketlog();
189 add_event_link_up();
190 fn_NetSim_P2P_CalulateReceivedPower();
191 return 0;
192}
193
194/**
195This function is called by NetworkStack.dll, once simulation end to free the
196allocated memory for the network.
197*/
198_declspec(dllexport) int fn_NetSim_P2P_Finish()
199{
200 LinkPacketLog_close();
201 for (UINT i = 0; i < NETWORK->nDeviceCount; i++)
202 {
203 if (DEVICE(i + 1) == NULL) continue;
204 for (UINT j = 0; j < DEVICE(i + 1)->nNumOfInterface; j++)
205 {
206 if (isVirtualInterface(i + 1, j + 1)) return -1;
207 if (DEVICE_INTERFACE(i + 1, j + 1) == NULL) continue;
208 if (DEVICE_MACPROTOCOL(i + 1, j + 1) != MAC_PROTOCOL_P2P) continue;
209
210 ptrP2P_NODE_MAC mac = P2P_MAC(i + 1, j + 1);
211 free(mac);
212
213 ptrP2P_NODE_PHY phy = P2P_PHY(i + 1, j + 1);
214 free(phy);
215 }
216 }
217 return 0;
218}
219
220/**
221This function is called by NetworkStack.dll, while writing the event trace
222to get the sub event as a string.
223*/
224_declspec (dllexport) char *fn_NetSim_P2P_Trace(int nSubEvent)
225{
226 return GetStringP2P_Subevent(nSubEvent);
227}
228
229/**
230This function is called by NetworkStack.dll, to free the P2P protocol
231*/
232_declspec(dllexport) int fn_NetSim_P2P_FreePacket(NetSim_PACKET* pstruPacket)
233{
234 pstruPacket;
235 return 0;
236}
237
238/**
239This function is called by NetworkStack.dll, to copy the P2P protocol from source packet to destination.
240*/
241_declspec(dllexport) int fn_NetSim_P2P_CopyPacket(NetSim_PACKET* pstruDestPacket, NetSim_PACKET* pstruSrcPacket)
242{
243 pstruDestPacket;
244 pstruSrcPacket;
245 return 0;
246}
247
248/**
249This function write the Metrics in Metrics.txt
250*/
251_declspec(dllexport) int fn_NetSim_P2P_Metrics(PMETRICSWRITER metricsWriter)
252{
253 metricsWriter;
254 return 0;
255}
256
257/**
258This function will return the string to write packet trace heading.
259*/
260_declspec(dllexport) char* fn_NetSim_P2P_ConfigPacketTrace(const void* xmlNetSimNode)
261{
262 xmlNetSimNode;
263 return "";
264}
265
266/**
267This function will return the string to write packet trace.
268*/
269_declspec(dllexport) int fn_NetSim_P2P_WritePacketTrace(NetSim_PACKET* pstruPacket, char** ppszTrace)
270{
271 pstruPacket;
272 ppszTrace;
273 return 0;
274}
275
276static void p2p_gettxinfo(NETSIM_ID nTxId,
277 NETSIM_ID nTxInterface,
278 NETSIM_ID nRxId,
279 NETSIM_ID nRxInterface,
280 PTX_INFO Txinfo)
281{
282 ptrP2P_NODE_PHY txphy = (ptrP2P_NODE_PHY)DEVICE_PHYVAR(nTxId, nTxInterface);
283 ptrP2P_NODE_PHY rxphy = (ptrP2P_NODE_PHY)DEVICE_PHYVAR(nRxId, nRxInterface);
284
285 Txinfo->dCentralFrequency = txphy->dCenteralFrequency;
286 Txinfo->dRxAntennaHeight = rxphy->dAntennaHeight;
287 Txinfo->dRxGain = rxphy->dAntennaGain;
288 Txinfo->dTxAntennaHeight = txphy->dAntennaHeight;
289 Txinfo->dTxGain = txphy->dAntennaGain;
290 Txinfo->dTxPower_mw = (double)txphy->dTXPower;
291 Txinfo->dTxPower_dbm = MW_TO_DBM(Txinfo->dTxPower_mw);
292 Txinfo->dTx_Rx_Distance = DEVICE_DISTANCE(nTxId, nRxId);
293 Txinfo->d0 = txphy->d0;
294}
295
296static bool CheckFrequencyInterfrence(double dFrequency1, double dFrequency2, double bandwidth)
297{
298 if (dFrequency1 > dFrequency2)
299 {
300 if ((dFrequency1 - dFrequency2) >= bandwidth)
301 return false; // no interference
302 else
303 return true; // interference
304 }
305 else
306 {
307 if ((dFrequency2 - dFrequency1) >= bandwidth)
308 return false; // no interference
309 else
310 return true; // interference
311 }
312}
313
314static bool check_interference(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri)
315{
316 ptrP2P_NODE_PHY tp = (ptrP2P_NODE_PHY)DEVICE_PHYVAR(t, ti);
317 ptrP2P_NODE_PHY rp = (ptrP2P_NODE_PHY)DEVICE_PHYVAR(r, ri);
318 return CheckFrequencyInterfrence(tp->dCenteralFrequency, rp->dCenteralFrequency, tp->dBandwidth);
319}
320
321static int p2p_CalculateReceivedPower(NETSIM_ID tx, NETSIM_ID txi, NETSIM_ID rx, NETSIM_ID rxi)
322{
323 //Distance will change between Tx and Rx due to mobility.
324 // So update the power from both side
325 PTX_INFO info = get_tx_info(propagationHandle, tx, txi, rx, rxi);
326 info->dTx_Rx_Distance = DEVICE_DISTANCE(tx, rx);
327 propagation_calculate_received_power(propagationHandle,
328 tx, txi, rx, rxi, pstruEventDetails->dEventTime);
329 return 1;
330}
331
332static int fn_NetSim_P2P_CalulateReceivedPower()
333{
334 NETSIM_ID t, ti, r, ri;
335
336 propagationHandle = propagation_init(MAC_PROTOCOL_P2P, NULL,
337 p2p_gettxinfo, check_interference);
338
339 for (t = 0; t < NETWORK->nDeviceCount; t++)
340 {
341 for (ti = 0; ti < DEVICE(t + 1)->nNumOfInterface; ti++)
342 {
343 if (!isP2PConfigured(t + 1, ti + 1))
344 continue;
345 if (!isP2PWireless(t + 1, ti + 1))
346 continue;
347 for (r = 0; r < NETWORK->nDeviceCount; r++)
348 {
349 for (ri = 0; ri < DEVICE(r + 1)->nNumOfInterface; ri++)
350 {
351 if (!isP2PConfigured(r + 1, ri + 1))
352 continue;
353 if (!isP2PWireless(r + 1, ri + 1))
354 continue;
355 p2p_CalculateReceivedPower(t + 1, ti + 1, r + 1, ri + 1);
356 }
357 }
358 }
359 }
360 return 0;
361}
362
363int fn_NetSim_P2P_LinkStateChanged(NETSIM_ID linkId,
364 LINK_STATE newState)
365{
366 NetSim_LINKS* link = NETWORK->ppstruNetSimLinks[linkId-1];
367 NETSIM_ID d1 = link->puniDevList.pstruP2P.nFirstDeviceId;
368 NETSIM_ID d2 = link->puniDevList.pstruP2P.nSecondDeviceId;
369 NETSIM_ID i1 = link->puniDevList.pstruP2P.nFirstInterfaceId;
370 NETSIM_ID i2 = link->puniDevList.pstruP2P.nSecondInterfaceId;
371
372 NETSIM_ID subevent;
373 if (newState == LINKSTATE_UP)
374 subevent = P2P_LINK_UP;
375 else
376 subevent = P2P_LINK_DOWN;
377 NetSim_EVENTDETAILS pevent;
378 memset(&pevent, 0, sizeof pevent);
379
380 if (isP2PConfigured(d1, i1))
381 {
382 pevent.dEventTime = pstruEventDetails->dEventTime;
383 pevent.nDeviceId = d1;
384 pevent.nDeviceType = DEVICE_TYPE(d1);
385 pevent.nEventType = TIMER_EVENT;
386 pevent.nInterfaceId = i1;
387 pevent.nProtocolId = MAC_PROTOCOL_P2P;
388 pevent.nSubEventType = subevent;
389 fnpAddEvent(&pevent);
390 }
391
392 if (isP2PConfigured(d2, i2))
393 {
394 pevent.dEventTime = pstruEventDetails->dEventTime;
395 pevent.nDeviceId = d2;
396 pevent.nDeviceType = DEVICE_TYPE(d2);
397 pevent.nEventType = TIMER_EVENT;
398 pevent.nInterfaceId = i2;
399 pevent.nProtocolId = MAC_PROTOCOL_P2P;
400 pevent.nSubEventType = subevent;
401 fnpAddEvent(&pevent);
402 }
403 return 0;
404}
405
406static void add_event_link_up()
407{
408 NETSIM_ID d, i;
409
410 NetSim_EVENTDETAILS pevent;
411 memset(&pevent, 0, sizeof pevent);
412
413 for (d = 0; d < NETWORK->nDeviceCount; d++)
414 {
415 for (i = 0; i < DEVICE(d + 1)->nNumOfInterface; i++)
416 {
417 if(!isP2PConfigured(d+1,i+1))
418 continue;
419
420 //Register link failure model callback
421 fn_NetSim_Link_RegisterLinkFailureCallback(DEVICE_PHYLAYER(d + 1, i + 1)->pstruNetSimLinks->nLinkId,
422 fn_NetSim_P2P_LinkStateChanged);
423 pevent.nDeviceId = d + 1;
424 pevent.nDeviceType = DEVICE_TYPE(d + 1);
425 pevent.nEventType = TIMER_EVENT;
426 pevent.nInterfaceId = i + 1;
427 pevent.nProtocolId = MAC_PROTOCOL_P2P;
428 pevent.nSubEventType = P2P_LINK_UP;
429 fnpAddEvent(&pevent);
430 }
431 }
432}