27#include "AdvancedPlots.h"
28#pragma comment(lib,"AdvancedPlots.lib")
30#define LIGHT_SPEED 299792458.0
32double get_propagation_delay(NETSIM_ID i, NETSIM_ID j)
34 double d = fn_NetSim_Utilities_CalculateDistance(DEVICE_POSITION(i), DEVICE_POSITION(j));
35 return (d / LIGHT_SPEED)*SECOND;
38#define calculate_tx_time(size,rate) ((size * 8.0) / rate)
40static void add_phy_in(NetSim_PACKET* packet,
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)
54 pevent.nApplicationId = packet->pstruAppData->nApplicationId;
55 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
59 pevent.nApplicationId = 0;
60 pevent.nSegmentId = 0;
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;
74static double transmit_over_wired(NetSim_PACKET* packet, NETSIM_ID nDeviceId, NETSIM_ID nInterfaceId)
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;
83 double txTime = calculate_tx_time(packet->pstruPhyData->dPacketSize,
85 if (packet->pstruMacData->dEndTime <= phy->dLastPacketEndTime)
86 packet->pstruPhyData->dArrivalTime = phy->dLastPacketEndTime;
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;
96static double wireless_transmit(NetSim_PACKET* packet,
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);
106 double txtime = calculate_tx_time(packet->pstruPhyData->dPacketSize, sphy->dDataRate);
107 if (packet->pstruMacData->dEndTime <= phy->dLastPacketEndTime)
108 packet->pstruPhyData->dArrivalTime = phy->dLastPacketEndTime;
110 packet->pstruPhyData->dArrivalTime = packet->pstruMacData->dEndTime;
112 double time = packet->pstruPhyData->dArrivalTime;
114 phy->dLastPacketEndTime = time + txtime;
116 double pdbm = propagation_get_received_power_dbm(propagationHandle, d, in, c, ci, time);
117 if (pdbm < dphy->dReceiverSensitivity)
119 fn_NetSim_Packet_FreePacket(packet);
120 return time + txtime;
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;
131static double wireless_P2MP_unicast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
134 c = packet->nReceiverId;
135 ci = fn_NetSim_Stack_GetConnectedInterface(d, in, c);
136 return wireless_transmit(packet, d, in, c, ci);
139static double wireless_P2MP_broadcast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
141 double time = packet->pstruPhyData->dArrivalTime;
143 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
146 if (d == link->puniDevList.pstrup2MP.nCenterDeviceId)
148 for (i = 0; i < link->puniDevList.pstrup2MP.nConnectedDeviceCount; i++)
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);
157 fn_NetSim_Packet_FreePacket(packet);
161 c = link->puniDevList.pstrup2MP.nCenterDeviceId;
162 ci = link->puniDevList.pstrup2MP.nCenterInterfaceId;
163 t = wireless_transmit(packet, d, in, c, ci);
170static double wireless_MP2MP_unicast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
173 c = packet->nReceiverId;
174 ci = fn_NetSim_Stack_GetConnectedInterface(d, in, c);
175 return wireless_transmit(packet, d, in, c, ci);
178static double wireless_MP2MP_broadcast(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
180 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
183 double time = packet->pstruPhyData->dArrivalTime;
184 double torg = DEVICE_PHYLAYER(d, in)->dLastPacketEndTime;
185 for (i = 0; i < link->puniDevList.pstruMP2MP.nConnectedDeviceCount; i++)
187 if (d == link->puniDevList.pstruMP2MP.anDevIds[i])
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);
197 DEVICE_PHYLAYER(d, in)->dLastPacketEndTime = time;
198 fn_NetSim_Packet_FreePacket(packet);
202static double transmit_over_wireless(NetSim_PACKET* packet, NETSIM_ID d, NETSIM_ID in)
205 NetSim_LINKS* link = DEVICE_PHYLAYER(d, in)->pstruNetSimLinks;
206 if (link->nLinkType == LinkType_P2P)
208 fn_NetSim_Stack_GetConnectedDevice(d, in, &c, &ci);
209 return wireless_transmit(packet, d, in, c, ci);
211 else if(link->nLinkType == LinkType_P2MP)
213 if (packet->nReceiverId)
214 return wireless_P2MP_unicast(packet, d, in);
216 return wireless_P2MP_broadcast(packet, d, in);
218 else if (link->nLinkType == LinkType_MP2MP)
220 if (packet->nReceiverId)
221 return wireless_MP2MP_unicast(packet, d, in);
223 return wireless_MP2MP_broadcast(packet, d, in);
225 return packet->pstruPhyData->dArrivalTime;
228static double fnTransmitPacket(NetSim_PACKET* pPacket, NETSIM_ID nDeviceId, NETSIM_ID nInterfaceId)
230 NetSim_LINKS* link = DEVICE_PHYLAYER(nDeviceId, nInterfaceId)->pstruNetSimLinks;
231 if (link->isLinkFailureMode)
233 if (link->struLinkFailureModel.linkState == LINKSTATE_DOWN)
235 fn_NetSim_Packet_FreePacket(pPacket);
236 return pstruEventDetails->dEventTime;
240 if (link->nLinkMedium == PHY_MEDIUM_WIRED)
241 return transmit_over_wired(pPacket, nDeviceId, nInterfaceId);
243 return transmit_over_wireless(pPacket, nDeviceId, nInterfaceId);
246int P2P_PhyOut_Handler()
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;
257 double time = fnTransmitPacket(pstruEventDetails->pPacket, d, in);
259 NetSim_PACKET* p = fn_NetSim_Packet_GetPacketFromBuffer(buf, 0);
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;
271 pstruEventDetails->nPacketId = p->nPacketId;
274 pstruEventDetails->nApplicationId = p->pstruAppData->nApplicationId;
275 pstruEventDetails->nSegmentId = p->pstruAppData->nSegmentId;
279 pstruEventDetails->nApplicationId = 0;
280 pstruEventDetails->nSegmentId = 0;
283 pstruEventDetails->nSubEventType = P2P_MAC_IDLE;
285 fnpAddEvent(pstruEventDetails);
289PACKET_STATUS P2P_Wireless_CalculateError(NETSIM_ID d, NETSIM_ID in, NetSim_PACKET* packet)
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,
299 return fn_NetSim_Packet_DecideError(pb, packet->pstruPhyData->dPacketSize);
302PACKET_STATUS P2P_Wired_CalculateError(NETSIM_ID d, NETSIM_ID in, NetSim_PACKET* packet)
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);
309static void P2P_Calculate_Error()
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);
317 packet->nPacketStatus = P2P_Wired_CalculateError(d, in, packet);
320int P2P_PhyIn_Handler()
322 NetSim_PACKET* packet = pstruEventDetails->pPacket;
323 fnValidatePacket(packet);
325 P2P_Calculate_Error();
327 fn_NetSim_WritePacketTrace(packet);
330 packet->pstruPhyData->dArrivalTime = ldEventTime;
331 packet->pstruPhyData->dStartTime = ldEventTime;
332 packet->pstruPhyData->dEndTime = ldEventTime;
333 fn_NetSim_Metrics_Add(packet);
335 if (packet->nPacketStatus == PacketStatus_NoError)
338 pstruEventDetails->dEventTime = ldEventTime;
339 pstruEventDetails->nEventType = MAC_IN_EVENT;
341 fnpAddEvent(pstruEventDetails);
345 fn_NetSim_Packet_FreePacket(packet);
346 pstruEventDetails->pPacket = NULL;