NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
P2P_Phy.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#define LIGHT_SPEED 299792458.0
31
32double get_propagation_delay(NETSIM_ID i, NETSIM_ID j)
33{
34 double d = fn_NetSim_Utilities_CalculateDistance(DEVICE_POSITION(i), DEVICE_POSITION(j));
35 return (d / LIGHT_SPEED)*SECOND;
36}
37
38#define calculate_tx_time(size,rate) ((size * 8.0) / rate)
39
40static void add_phy_in(NetSim_PACKET* packet,
41 NETSIM_ID d,
42 NETSIM_ID in,
43 NETSIM_ID c,
44 NETSIM_ID ci)
45{
46 in;
47 packet->nTransmitterId = d;
48 packet->nReceiverId = c;
49 NetSim_EVENTDETAILS pevent;
50 pevent.dEventTime = packet->pstruPhyData->dEndTime;
51 pevent.dPacketSize = packet->pstruPhyData->dPacketSize;
52 if (packet->pstruAppData)
53 {
54 pevent.nApplicationId = packet->pstruAppData->nApplicationId;
55 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
56 }
57 else
58 {
59 pevent.nApplicationId = 0;
60 pevent.nSegmentId = 0;
61 }
62 pevent.nDeviceId = c;
63 pevent.nDeviceType = DEVICE_TYPE(c);
64 pevent.nEventType = PHYSICAL_IN_EVENT;
65 pevent.nInterfaceId = ci;
66 pevent.nPacketId = packet->nPacketId;
67 pevent.nProtocolId = DEVICE_MACLAYER(c, ci)->nMacProtocolId;
68 pevent.nSubEventType = 0;
69 pevent.pPacket = packet;
70 pevent.szOtherDetails = NULL;
71 fnpAddEvent(&pevent);
72}
73
74static double transmit_over_wired(NetSim_PACKET* packet, NETSIM_ID nDeviceId, NETSIM_ID nInterfaceId)
75{
76 NETSIM_ID c, ci;
77 NetSim_PHYSICALLAYER* phy = DEVICE_PHYLAYER(nDeviceId, nInterfaceId);
78 NetSim_LINKS* link = phy->pstruNetSimLinks;
79 fn_NetSim_Stack_GetConnectedDevice(nDeviceId, nInterfaceId, &c, &ci);
80 double dDataRate = link->puniMedProp.pstruWiredLink.dDataRateUp;
81 double dPropagationDelay = link->puniMedProp.pstruWiredLink.dPropagationDelayUp;
82
83 double txTime = calculate_tx_time(packet->pstruPhyData->dPacketSize,
84 dDataRate);
85 if (packet->pstruMacData->dEndTime <= phy->dLastPacketEndTime)
86 packet->pstruPhyData->dArrivalTime = phy->dLastPacketEndTime;
87 else
88 packet->pstruPhyData->dArrivalTime = packet->pstruMacData->dEndTime;
89 packet->pstruPhyData->dStartTime = packet->pstruPhyData->dArrivalTime + txTime;
90 packet->pstruPhyData->dEndTime = packet->pstruPhyData->dStartTime + dPropagationDelay;
91 add_phy_in(packet, nDeviceId, nInterfaceId, c, ci);
92 phy->dLastPacketEndTime = packet->pstruPhyData->dStartTime;
93 return phy->dLastPacketEndTime;
94}
95
96static double wireless_transmit(NetSim_PACKET* packet,
97 NETSIM_ID d,
98 NETSIM_ID in,
99 NETSIM_ID c,
100 NETSIM_ID ci)
101{
102 NetSim_PHYSICALLAYER* phy = DEVICE_PHYLAYER(d, in);
103 ptrP2P_NODE_PHY sphy = P2P_PHY(d, in);
104 ptrP2P_NODE_PHY dphy = P2P_PHY(c, ci);
105
106 double txtime = calculate_tx_time(packet->pstruPhyData->dPacketSize, sphy->dDataRate);
107 if (packet->pstruMacData->dEndTime <= phy->dLastPacketEndTime)
108 packet->pstruPhyData->dArrivalTime = phy->dLastPacketEndTime;
109 else
110 packet->pstruPhyData->dArrivalTime = packet->pstruMacData->dEndTime;
111
112 double time = packet->pstruPhyData->dArrivalTime;
113
114 phy->dLastPacketEndTime = time + txtime;
115
116 double pdbm = propagation_get_received_power_dbm(propagationHandle, d, in, c, ci, time);
117 if (pdbm < dphy->dReceiverSensitivity)
118 {
119 fn_NetSim_Packet_FreePacket(packet);
120 return time + txtime;
121 }
122
123 double dPropagationDelay = get_propagation_delay(d, c);
124 packet->pstruPhyData->dStartTime = time + txtime;
125 packet->pstruPhyData->dEndTime = packet->pstruPhyData->dStartTime + dPropagationDelay;
126 add_phy_in(packet, d, in, c, ci);
127 phy->dLastPacketEndTime = packet->pstruPhyData->dStartTime;
128 return packet->pstruPhyData->dStartTime;
129}
130
131static double wireless_P2MP_unicast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
132{
133 NETSIM_ID c, ci;
134 c = packet->nReceiverId;
135 ci = fn_NetSim_Stack_GetConnectedInterface(d, in, c);
136 return wireless_transmit(packet, d, in, c, ci);
137}
138
139static double wireless_P2MP_broadcast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
140{
141 double time = packet->pstruPhyData->dArrivalTime;
142 double t;
143 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
144 NETSIM_ID i;
145 NETSIM_ID c, ci;
146 if (d == link->puniDevList.pstrup2MP.nCenterDeviceId)
147 {
148 for (i = 0; i < link->puniDevList.pstrup2MP.nConnectedDeviceCount; i++)
149 {
150 c = link->puniDevList.pstrup2MP.anDevIds[i];
151 ci = link->puniDevList.pstrup2MP.anDevInterfaceIds[i];
152 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
153 t = wireless_transmit(p, d, in, c, ci);
154 if (t > time)
155 time = t;
156 }
157 fn_NetSim_Packet_FreePacket(packet);
158 }
159 else
160 {
161 c = link->puniDevList.pstrup2MP.nCenterDeviceId;
162 ci = link->puniDevList.pstrup2MP.nCenterInterfaceId;
163 t = wireless_transmit(packet, d, in, c, ci);
164 if (t > time)
165 time = t;
166 }
167 return time;
168}
169
170static double wireless_MP2MP_unicast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
171{
172 NETSIM_ID c, ci;
173 c = packet->nReceiverId;
174 ci = fn_NetSim_Stack_GetConnectedInterface(d, in, c);
175 return wireless_transmit(packet, d, in, c, ci);
176}
177
178static double wireless_MP2MP_broadcast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
179{
180 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
181 NETSIM_ID i;
182 NETSIM_ID c, ci;
183 double time = packet->pstruPhyData->dArrivalTime;
184 double torg = DEVICE_PHYLAYER(d, in)->dLastPacketEndTime;
185 for (i = 0; i < link->puniDevList.pstruMP2MP.nConnectedDeviceCount; i++)
186 {
187 if (d == link->puniDevList.pstruMP2MP.anDevIds[i])
188 continue;
189 c = link->puniDevList.pstruMP2MP.anDevIds[i];
190 ci = link->puniDevList.pstruMP2MP.anDevInterfaceIds[i];
191 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
192 DEVICE_PHYLAYER(d, in)->dLastPacketEndTime = torg;
193 double t = wireless_transmit(p, d, in, c, ci);
194 if (t > time)
195 time = t;
196 }
197 DEVICE_PHYLAYER(d, in)->dLastPacketEndTime = time;
198 fn_NetSim_Packet_FreePacket(packet);
199 return time;
200}
201
202static double transmit_over_wireless(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
203{
204 NETSIM_ID c, ci;
205 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
206 if (link->nLinkType == LinkType_P2P)
207 {
208 fn_NetSim_Stack_GetConnectedDevice(d, in, &c, &ci);
209 return wireless_transmit(packet, d, in, c, ci);
210 }
211 else if(link->nLinkType == LinkType_P2MP)
212 {
213 if (packet->nReceiverId)
214 return wireless_P2MP_unicast(packet, d, in);
215 else
216 return wireless_P2MP_broadcast(packet, d, in);
217 }
218 else if (link->nLinkType == LinkType_MP2MP)
219 {
220 if (packet->nReceiverId)
221 return wireless_MP2MP_unicast(packet, d, in);
222 else
223 return wireless_MP2MP_broadcast(packet, d, in);
224 }
225 return packet->pstruPhyData->dArrivalTime;
226}
227
228static double fnTransmitPacket(NetSim_PACKET* pPacket, NETSIM_ID nDeviceId, NETSIM_ID nInterfaceId)
229{
230 NetSim_LINKS* link = DEVICE_PHYLAYER(nDeviceId, nInterfaceId)->pstruNetSimLinks;
231 if (link->isLinkFailureMode)
232 {
233 if (link->struLinkFailureModel.linkState == LINKSTATE_DOWN)
234 {
235 fn_NetSim_Packet_FreePacket(pPacket);
236 return pstruEventDetails->dEventTime;
237 }
238 }
239
240 if (link->nLinkMedium == PHY_MEDIUM_WIRED)
241 return transmit_over_wired(pPacket, nDeviceId, nInterfaceId);
242 else
243 return transmit_over_wireless(pPacket, nDeviceId, nInterfaceId);
244}
245
246int P2P_PhyOut_Handler()
247{
248 NETSIM_ID d = pstruEventDetails->nDeviceId;
249 NETSIM_ID in = pstruEventDetails->nInterfaceId;
250 NetSim_BUFFER* buf = DEVICE_ACCESSBUFFER(d, in);
251 NetSim_PACKET* pstruPacket = pstruEventDetails->pPacket;
252 pstruPacket->pstruPhyData->dArrivalTime = ldEventTime;
253 pstruPacket->pstruPhyData->dOverhead = 0;
254 pstruPacket->pstruPhyData->dPayload = pstruPacket->pstruMacData->dPacketSize;
255 pstruPacket->pstruPhyData->dPacketSize = pstruPacket->pstruPhyData->dOverhead + pstruPacket->pstruPhyData->dPayload;
256 //Transmit the packet.
257 double time = fnTransmitPacket(pstruEventDetails->pPacket, d, in);
258
259 NetSim_PACKET* p = fn_NetSim_Packet_GetPacketFromBuffer(buf, 0);
260 //Prepare event details for MAC out
261 pstruEventDetails->dEventTime = time;
262 pstruEventDetails->dPacketSize = 0;
263 pstruEventDetails->nDeviceId = d;
264 pstruEventDetails->nDeviceType = DEVICE_TYPE(d);
265 pstruEventDetails->nInterfaceId = in;
266 pstruEventDetails->nEventType = MAC_OUT_EVENT;
267 pstruEventDetails->nProtocolId = fn_NetSim_Stack_GetMacProtocol(d, in);
268 pstruEventDetails->pPacket = NULL;
269 if (p)
270 {
271 pstruEventDetails->nPacketId = p->nPacketId;
272 if (p->pstruAppData)
273 {
274 pstruEventDetails->nApplicationId = p->pstruAppData->nApplicationId;
275 pstruEventDetails->nSegmentId = p->pstruAppData->nSegmentId;
276 }
277 else
278 {
279 pstruEventDetails->nApplicationId = 0;
280 pstruEventDetails->nSegmentId = 0;
281 }
282 }
283 pstruEventDetails->nSubEventType = P2P_MAC_IDLE;
284 //Add MAC out Event
285 fnpAddEvent(pstruEventDetails);
286 return 0;
287}
288
289PACKET_STATUS P2P_Wireless_CalculateError(NETSIM_ID d, NETSIM_ID in, NetSim_PACKET* packet)
290{
291 NETSIM_ID c = packet->nTransmitterId;
292 NETSIM_ID ci = fn_NetSim_Stack_GetConnectedInterface(d, in, c);
293 ptrP2P_NODE_PHY phy = P2P_PHY(c, ci);
294 double rxPower = propagation_get_received_power_dbm(propagationHandle, c, ci, d, in, packet->pstruPhyData->dArrivalTime);
295 double pb = calculate_BER(phy->modulation,
296 rxPower, NEGATIVE_DBM,
297 phy->dBandwidth);
298
299 return fn_NetSim_Packet_DecideError(pb, packet->pstruPhyData->dPacketSize);
300}
301
302PACKET_STATUS P2P_Wired_CalculateError(NETSIM_ID d, NETSIM_ID in, NetSim_PACKET* packet)
303{
304 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
305 double pb = link->puniMedProp.pstruWiredLink.dErrorRateUp;
306 return fn_NetSim_Packet_DecideError(pb, packet->pstruPhyData->dPacketSize);
307}
308
309static void P2P_Calculate_Error()
310{
311 NETSIM_ID d = pstruEventDetails->nDeviceId;
312 NETSIM_ID in = pstruEventDetails->nInterfaceId;
313 NetSim_PACKET* packet = pstruEventDetails->pPacket;
314 if (isP2PWireless(d,in))
315 packet->nPacketStatus = P2P_Wireless_CalculateError(d, in, packet);
316 else
317 packet->nPacketStatus = P2P_Wired_CalculateError(d, in, packet);
318}
319
320int P2P_PhyIn_Handler()
321{
322 NetSim_PACKET* packet = pstruEventDetails->pPacket;
323 fnValidatePacket(packet);
324
325 P2P_Calculate_Error();
326 LinkPacketLog();
327 fn_NetSim_WritePacketTrace(packet);
328 //Place the packet to mac layer
329 //Write mac in event
330 packet->pstruPhyData->dArrivalTime = ldEventTime;
331 packet->pstruPhyData->dStartTime = ldEventTime;
332 packet->pstruPhyData->dEndTime = ldEventTime;
333 fn_NetSim_Metrics_Add(packet);
334
335 if (packet->nPacketStatus == PacketStatus_NoError)
336 {
337 //Prepare the mac in event details
338 pstruEventDetails->dEventTime = ldEventTime;
339 pstruEventDetails->nEventType = MAC_IN_EVENT;
340 //Add mac in event
341 fnpAddEvent(pstruEventDetails);
342 }
343 else
344 {
345 fn_NetSim_Packet_FreePacket(packet);
346 pstruEventDetails->pPacket = NULL;
347 }
348 return 0;
349}